Skip to content

Commit de8b02c

Browse files
committed
feat: filter received sheet for RBF/channel close
1 parent 53aa345 commit de8b02c

File tree

5 files changed

+68
-11
lines changed

5 files changed

+68
-11
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ dependencies {
195195
// Crypto
196196
implementation(libs.bouncycastle.provider.jdk)
197197
implementation(libs.ldk.node.android) { exclude(group = "net.java.dev.jna", module = "jna") }
198-
implementation(libs.bitkitcore)
198+
implementation(libs.bitkit.core)
199199
implementation(libs.vss)
200200
// Firebase
201201
implementation(platform(libs.firebase.bom))

app/src/main/java/to/bitkit/repositories/ActivityRepo.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.synonym.bitkitcore.ActivityTags
77
import com.synonym.bitkitcore.ClosedChannelDetails
88
import com.synonym.bitkitcore.IcJitEntry
99
import com.synonym.bitkitcore.LightningActivity
10+
import com.synonym.bitkitcore.OnchainActivity
1011
import com.synonym.bitkitcore.PaymentState
1112
import com.synonym.bitkitcore.PaymentType
1213
import com.synonym.bitkitcore.SortDirection
@@ -191,6 +192,42 @@ class ActivityRepo @Inject constructor(
191192
}
192193
}
193194

195+
private suspend fun getOnchainActivityByTxId(txid: String): OnchainActivity? {
196+
return coreService.activity.getOnchainActivityByTxId(txid)
197+
}
198+
199+
/**
200+
* Determines whether to show the payment received sheet for an onchain transaction.
201+
* Returns false for:
202+
* - Zero value transactions
203+
* - Channel closure transactions (transfers to savings)
204+
* - RBF replacement transactions with the same value as the original
205+
*/
206+
suspend fun shouldShowReceivedSheet(txid: String, value: ULong): Boolean = withContext(bgDispatcher) {
207+
if (value == 0uL) return@withContext false
208+
209+
if (findClosedChannelForTransaction(txid) != null) {
210+
Logger.debug("Skipping received sheet for channel closure tx: $txid", context = TAG)
211+
return@withContext false
212+
}
213+
214+
val onchainActivity = getOnchainActivityByTxId(txid)
215+
if (onchainActivity != null && onchainActivity.boostTxIds.isNotEmpty()) {
216+
for (replacedTxid in onchainActivity.boostTxIds) {
217+
val replacedActivity = getOnchainActivityByTxId(replacedTxid)
218+
if (replacedActivity != null && replacedActivity.value == value) {
219+
Logger.info(
220+
"Skipping received sheet for RBF replacement $txid with same value as $replacedTxid",
221+
context = TAG
222+
)
223+
return@withContext false
224+
}
225+
}
226+
}
227+
228+
return@withContext true
229+
}
230+
194231
/**
195232
* Gets a specific activity by payment hash or txID with retry logic
196233
*/

app/src/main/java/to/bitkit/services/CoreService.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.synonym.bitkitcore.deleteActivityById
2929
import com.synonym.bitkitcore.estimateOrderFeeFull
3030
import com.synonym.bitkitcore.getActivities
3131
import com.synonym.bitkitcore.getActivityById
32+
import com.synonym.bitkitcore.getActivityByTxId
3233
import com.synonym.bitkitcore.getAllClosedChannels
3334
import com.synonym.bitkitcore.getAllUniqueTags
3435
import com.synonym.bitkitcore.getCjitEntries
@@ -248,6 +249,10 @@ class ActivityService(
248249
}
249250
}
250251

252+
suspend fun getOnchainActivityByTxId(txId: String): OnchainActivity? = ServiceQueue.CORE.background {
253+
getActivityByTxId(txId = txId)
254+
}
255+
251256
suspend fun get(
252257
filter: ActivityFilter? = null,
253258
txType: PaymentType? = null,

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,30 @@ class AppViewModel @Inject constructor(
292292
is Event.PaymentForwarded -> Unit
293293

294294
is Event.OnchainTransactionReceived -> {
295-
showNewTransactionSheet(
296-
NewTransactionSheetDetails(
297-
type = NewTransactionSheetType.ONCHAIN,
298-
direction = NewTransactionSheetDirection.RECEIVED,
299-
paymentHashOrTxId = event.txid,
300-
sats = event.details.amountSats.toLong(),
301-
),
302-
event,
303-
)
295+
// Show notification for incoming transactions
296+
val sats = event.details.amountSats
297+
if (sats > 0) {
298+
launch(bgDispatcher) {
299+
delay(500)
300+
val shouldShow = activityRepo.shouldShowReceivedSheet(
301+
txid = event.txid,
302+
value = sats.toULong()
303+
)
304+
if (!shouldShow) {
305+
Logger.info("Skipping received sheet for tx: ${event.txid}", context = TAG)
306+
return@launch
307+
}
308+
showNewTransactionSheet(
309+
NewTransactionSheetDetails(
310+
type = NewTransactionSheetType.ONCHAIN,
311+
direction = NewTransactionSheetDirection.RECEIVED,
312+
paymentHashOrTxId = event.txid,
313+
sats = sats,
314+
),
315+
event,
316+
)
317+
}
318+
}
304319
}
305320

306321
is Event.OnchainTransactionConfirmed -> Unit

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ activity-compose = { module = "androidx.activity:activity-compose", version.ref
4444
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
4545
barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" }
4646
biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" }
47-
bitkitcore = { module = "com.synonym:bitkit-core-android", version = "0.1.27" }
47+
bitkit-core = { module = "com.synonym:bitkit-core-android", version = "0.1.30" }
4848
bouncycastle-provider-jdk = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bouncyCastle" }
4949
camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camera" }
5050
camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camera" }

0 commit comments

Comments
 (0)