Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 31 additions & 23 deletions Bitkit/ViewModels/AppViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,32 @@ extension AppViewModel {
// MARK: LDK Node Events

extension AppViewModel {
/// Shows the "received" sheet for an incoming on-chain tx, unless it was already shown.
/// Used by both the received (mempool) and confirmed (straight-to-confirmed) LDK events so a
/// tx that skips the mempool still notifies the user. See issue #455.
private func presentReceivedSheetForOnchainTransaction(txid: String, amountSats: Int64) {
guard amountSats > 0 else { return }
let sats = UInt64(amountSats)

Task {
// 500ms delay so the activity is written to the DB before the dedup/filter checks read it.
try? await Task.sleep(nanoseconds: 500_000_000)

if await CoreService.shared.activity.isOnchainActivitySeen(txid: txid) {
return
}

let shouldShow = await CoreService.shared.activity.shouldShowReceivedSheet(txid: txid, value: sats)
guard shouldShow else { return }

await CoreService.shared.activity.markOnchainActivityAsSeen(txid: txid)

await MainActor.run {
sheetViewModel.showSheet(.receivedTx, data: ReceivedTxSheetDetails(type: .onchain, sats: sats))
}
}
}

func handleLdkNodeEvent(_ event: Event) {
switch event {
case let .paymentReceived(paymentId, _, amountMsat, _):
Expand Down Expand Up @@ -922,30 +948,12 @@ extension AppViewModel {
// MARK: New Onchain Transaction Events

case let .onchainTransactionReceived(txid, details):
// Show notification for incoming transactions
if details.amountSats > 0 {
let sats = UInt64(abs(Int64(details.amountSats)))

Task {
// Show sheet for new transactions or replacements with value changes
try? await Task.sleep(nanoseconds: 500_000_000) // 500ms delay

if await CoreService.shared.activity.isOnchainActivitySeen(txid: txid) {
return
}

let shouldShow = await CoreService.shared.activity.shouldShowReceivedSheet(txid: txid, value: sats)
guard shouldShow else { return }

await CoreService.shared.activity.markOnchainActivityAsSeen(txid: txid)

await MainActor.run {
sheetViewModel.showSheet(.receivedTx, data: ReceivedTxSheetDetails(type: .onchain, sats: sats))
}
}
}
case let .onchainTransactionConfirmed(txid, _, blockHeight, _, _):
// Show notification for incoming transactions seen in the mempool
presentReceivedSheetForOnchainTransaction(txid: txid, amountSats: details.amountSats)
case let .onchainTransactionConfirmed(txid, _, blockHeight, _, details):
Logger.info("Transaction confirmed: \(txid) at block \(blockHeight)")
// Also notify when a tx goes straight to confirmed without a prior received event
presentReceivedSheetForOnchainTransaction(txid: txid, amountSats: details.amountSats)
Comment thread
CypherPoet marked this conversation as resolved.
case let .onchainTransactionReplaced(txid, conflicts):
Logger.info("Transaction replaced: \(txid) by \(conflicts.count) conflict(s)")
Task {
Expand Down
1 change: 1 addition & 0 deletions changelog.d/next/588.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Incoming on-chain transactions that confirm before being seen in the mempool now show the received notification.