Skip to content

Commit eaff22b

Browse files
committed
wip: issue-320
1 parent d6e3e11 commit eaff22b

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

BDKSwiftExampleWallet/Extensions/BDK+Extensions/CbfClient+Extensions.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,24 @@ extension CbfClient {
128128
if Task.isCancelled { break }
129129
do {
130130
let warning = try await self.nextWarning()
131-
if case .needConnections = warning {
131+
switch warning {
132+
case .needConnections:
132133
await MainActor.run {
133134
NotificationCenter.default.post(
134135
name: NSNotification.Name("KyotoConnectionUpdate"),
135136
object: nil,
136137
userInfo: ["connected": false]
137138
)
138139
}
140+
case let .transactionRejected(wtxid, reason):
141+
BDKService.shared.handleKyotoRejectedTransaction(wtxidHex: wtxid)
142+
if let reason {
143+
print("Kyoto rejected tx \(wtxid): \(reason)")
144+
} else {
145+
print("Kyoto rejected tx \(wtxid)")
146+
}
147+
default:
148+
break
139149
}
140150
} catch is CancellationError {
141151
break

BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ extension BlockchainClient {
9898
}
9999
}
100100

101-
private class BDKService {
101+
final class BDKService {
102102
static let shared: BDKService = BDKService()
103103

104104
private var balance: Balance?
@@ -110,6 +110,8 @@ private class BDKService {
110110
private(set) var network: Network
111111
private var blockchainURL: String
112112
internal private(set) var wallet: Wallet?
113+
private var kyotoPendingTxs: [String: Txid] = [:]
114+
private let kyotoPendingTxQueue = DispatchQueue(label: "bdk.service.kyoto.pending")
113115

114116
init(keyClient: KeyClient = .live) {
115117
self.keyClient = keyClient
@@ -532,6 +534,7 @@ private class BDKService {
532534
try? keyClient.deleteEsplora()
533535

534536
needsFullScan = true
537+
clearKyotoTrackedTransactions()
535538
}
536539

537540
func getBackupInfo() throws -> BackupInfo {
@@ -576,6 +579,7 @@ private class BDKService {
576579
try await self.blockchainClient.broadcast(transaction)
577580

578581
if self.clientType == .kyoto {
582+
trackKyotoBroadcast(transaction)
579583
let lastSeen = UInt64(Date().timeIntervalSince1970)
580584
let unconfirmedTx = UnconfirmedTx(tx: transaction, lastSeen: lastSeen)
581585
wallet.applyUnconfirmedTxs(unconfirmedTxs: [unconfirmedTx])
@@ -589,6 +593,40 @@ private class BDKService {
589593
}
590594
}
591595

596+
private func trackKyotoBroadcast(_ transaction: Transaction) {
597+
let wtxidData = transaction.computeWtxid().serialize()
598+
let wtxidHex = [UInt8](wtxidData).hexString.lowercased()
599+
let txid = transaction.computeTxid()
600+
kyotoPendingTxQueue.sync {
601+
kyotoPendingTxs[wtxidHex] = txid
602+
}
603+
}
604+
605+
private func takeKyotoTx(for wtxidHex: String) -> Txid? {
606+
kyotoPendingTxQueue.sync {
607+
kyotoPendingTxs.removeValue(forKey: wtxidHex.lowercased())
608+
}
609+
}
610+
611+
private func clearKyotoTrackedTransactions() {
612+
kyotoPendingTxQueue.sync {
613+
kyotoPendingTxs.removeAll()
614+
}
615+
}
616+
617+
func handleKyotoRejectedTransaction(wtxidHex: String) {
618+
guard let txid = takeKyotoTx(for: wtxidHex) else { return }
619+
guard let wallet = self.wallet else { return }
620+
let evictedTx = EvictedTx(
621+
txid: txid,
622+
evictedAt: UInt64(Date().timeIntervalSince1970)
623+
)
624+
wallet.applyEvictedTxs(evictedTxs: [evictedTx])
625+
if let persister = self.persister {
626+
try? wallet.persist(persister: persister)
627+
}
628+
}
629+
592630
func syncWithInspector(inspector: SyncScriptInspector) async throws {
593631
guard let wallet = self.wallet else { throw WalletError.walletNotFound }
594632
let syncRequest = try wallet.startSyncWithRevealedSpks()

0 commit comments

Comments
 (0)