Skip to content

Commit d6e3e11

Browse files
authored
deps: bdk-swift 2.2.0
1 parent a33e0d3 commit d6e3e11

File tree

8 files changed

+100
-196
lines changed

8 files changed

+100
-196
lines changed

.github/workflows/ios.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ jobs:
2525
- name: List Devices
2626
run: xcrun xctrace list devices 2>&1
2727
- name: Build
28-
run: xcodebuild build-for-testing -scheme BDKSwiftExampleWallet -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.0'
28+
run: xcodebuild build-for-testing -scheme BDKSwiftExampleWallet -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.1'
2929
- name: Run tests
30-
run: xcodebuild test-without-building -scheme BDKSwiftExampleWallet -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.0'
30+
run: xcodebuild test-without-building -scheme BDKSwiftExampleWallet -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.1'

BDKSwiftExampleWallet.xcodeproj/project.pbxproj

Lines changed: 37 additions & 100 deletions
Large diffs are not rendered by default.

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

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,26 @@ extension CbfClient {
1212
// Track monitoring tasks per client for clean cancellation
1313
private static var monitoringTasks: [ObjectIdentifier: Task<Void, Never>] = [:]
1414
private static var warningTasks: [ObjectIdentifier: Task<Void, Never>] = [:]
15-
private static var logTasks: [ObjectIdentifier: Task<Void, Never>] = [:]
1615
private static var heartbeatTasks: [ObjectIdentifier: Task<Void, Never>] = [:]
1716
private static var lastInfoAt: [ObjectIdentifier: Date] = [:]
1817
private static let monitoringTasksQueue = DispatchQueue(label: "cbf.monitoring.tasks")
1918

20-
static func createComponents(wallet: Wallet) -> (client: CbfClient, node: CbfNode) {
19+
static func createComponents(
20+
wallet: Wallet,
21+
scanType: ScanType,
22+
peers: [Peer]
23+
) -> (client: CbfClient, node: CbfNode) {
2124
do {
25+
let network = wallet.network()
26+
let dataDir = Constants.Config.Kyoto.dbPath
27+
print(
28+
"[Kyoto] Preparing CBF components – network: \(network), dataDir: \(dataDir), peers: \(peers.count), scanType: \(scanType)"
29+
)
2230

2331
let components = try CbfBuilder()
24-
.logLevel(logLevel: .debug)
25-
.scanType(scanType: .sync)
26-
.dataDir(dataDir: Constants.Config.Kyoto.dbPath)
27-
.peers(peers: Constants.Networks.Signet.Regular.kyotoPeers)
32+
.scanType(scanType: scanType)
33+
.dataDir(dataDir: dataDir)
34+
.peers(peers: peers)
2835
.build(wallet: wallet)
2936

3037
components.node.run()
@@ -47,34 +54,29 @@ extension CbfClient {
4754
let info = try await self.nextInfo()
4855
CbfClient.monitoringTasksQueue.sync { Self.lastInfoAt[id] = Date() }
4956
switch info {
50-
case .progress(let progress):
57+
case .progress(let chainHeight, let filtersDownloadedPercent):
5158
await MainActor.run {
5259
NotificationCenter.default.post(
5360
name: NSNotification.Name("KyotoProgressUpdate"),
5461
object: nil,
55-
userInfo: ["progress": progress]
62+
userInfo: [
63+
"progress": filtersDownloadedPercent,
64+
"height": Int(chainHeight),
65+
]
5666
)
57-
}
58-
case .newChainHeight(let height):
59-
await MainActor.run {
6067
NotificationCenter.default.post(
6168
name: NSNotification.Name("KyotoChainHeightUpdate"),
6269
object: nil,
63-
userInfo: ["height": height]
70+
userInfo: ["height": Int(chainHeight)]
6471
)
6572
NotificationCenter.default.post(
6673
name: NSNotification.Name("KyotoConnectionUpdate"),
6774
object: nil,
6875
userInfo: ["connected": true]
6976
)
7077
}
71-
case .stateUpdate(let nodeState):
78+
case .blockReceived(_):
7279
await MainActor.run {
73-
NotificationCenter.default.post(
74-
name: NSNotification.Name("KyotoStateUpdate"),
75-
object: nil,
76-
userInfo: ["state": nodeState]
77-
)
7880
NotificationCenter.default.post(
7981
name: NSNotification.Name("KyotoConnectionUpdate"),
8082
object: nil,
@@ -89,8 +91,6 @@ extension CbfClient {
8991
userInfo: ["connected": true]
9092
)
9193
}
92-
default:
93-
break
9494
}
9595
} catch is CancellationError {
9696
break
@@ -149,23 +149,6 @@ extension CbfClient {
149149
Self.warningTasks[id] = warnings
150150
}
151151

152-
// Log listener for detailed debugging
153-
let logs = Task { [self] in
154-
while true {
155-
if Task.isCancelled { break }
156-
do {
157-
let log = try await self.nextLog()
158-
} catch is CancellationError {
159-
break
160-
} catch {
161-
// ignore
162-
}
163-
}
164-
}
165-
166-
Self.monitoringTasksQueue.sync {
167-
Self.logTasks[id] = logs
168-
}
169152
}
170153

171154
func stopBackgroundMonitoring() {
@@ -175,7 +158,6 @@ extension CbfClient {
175158
task.cancel()
176159
if let hb = Self.heartbeatTasks.removeValue(forKey: id) { hb.cancel() }
177160
if let wt = Self.warningTasks.removeValue(forKey: id) { wt.cancel() }
178-
if let lt = Self.logTasks.removeValue(forKey: id) { lt.cancel() }
179161
Self.lastInfoAt.removeValue(forKey: id)
180162
}
181163
}
@@ -184,11 +166,9 @@ extension CbfClient {
184166
Self.monitoringTasksQueue.sync {
185167
for (_, task) in Self.monitoringTasks { task.cancel() }
186168
for (_, wt) in Self.warningTasks { wt.cancel() }
187-
for (_, lt) in Self.logTasks { lt.cancel() }
188169
for (_, hb) in Self.heartbeatTasks { hb.cancel() }
189170
Self.monitoringTasks.removeAll()
190171
Self.warningTasks.removeAll()
191-
Self.logTasks.removeAll()
192172
Self.heartbeatTasks.removeAll()
193173
Self.lastInfoAt.removeAll()
194174
}

BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ enum BlockchainClientType: String, CaseIterable {
1717
struct BlockchainClient {
1818
let sync: @Sendable (SyncRequest, UInt64) async throws -> Update
1919
let fullScan: @Sendable (FullScanRequest, UInt64, UInt64) async throws -> Update
20-
let broadcast: @Sendable (Transaction) throws -> Void
20+
let broadcast: @Sendable (Transaction) async throws -> Void
2121
let getUrl: @Sendable () -> String
2222
let getType: @Sendable () -> BlockchainClientType
2323
let supportsFullScan: @Sendable () -> Bool = { true }
@@ -55,7 +55,24 @@ extension BlockchainClient {
5555

5656
try FileManager.default.ensureDirectoryExists(at: Constants.Config.Kyoto.dbDirectoryURL)
5757

58-
let components = CbfClient.createComponents(wallet: wallet)
58+
let scanType: ScanType
59+
if BDKService.shared.needsFullScanOfWallet() {
60+
let addressType = BDKService.shared.getAddressType()
61+
let checkpoint: RecoveryPoint =
62+
addressType == .bip86 ? .taprootActivation : .segwitActivation
63+
scanType = .recovery(
64+
usedScriptIndex: 1000,
65+
checkpoint: checkpoint
66+
)
67+
} else {
68+
scanType = .sync
69+
}
70+
71+
let components = CbfClient.createComponents(
72+
wallet: wallet,
73+
scanType: scanType,
74+
peers: Constants.Networks.Signet.Regular.kyotoPeers
75+
)
5976
cbfComponents = components
6077
return components
6178
}
@@ -73,7 +90,7 @@ extension BlockchainClient {
7390
},
7491
broadcast: { tx in
7592
let components = try getOrCreateComponents()
76-
try components.client.broadcast(transaction: tx)
93+
try await components.client.broadcast(transaction: tx)
7794
},
7895
getUrl: { peer },
7996
getType: { .kyoto }
@@ -213,30 +230,30 @@ private class BDKService {
213230
publicKey: DescriptorPublicKey,
214231
fingerprint: String,
215232
network: Network
216-
) -> (descriptor: Descriptor, changeDescriptor: Descriptor) {
233+
) throws -> (descriptor: Descriptor, changeDescriptor: Descriptor) {
217234
switch addressType {
218235
case .bip86:
219-
let descriptor = Descriptor.newBip86Public(
236+
let descriptor = try Descriptor.newBip86Public(
220237
publicKey: publicKey,
221238
fingerprint: fingerprint,
222239
keychainKind: .external,
223240
network: network
224241
)
225-
let changeDescriptor = Descriptor.newBip86Public(
242+
let changeDescriptor = try Descriptor.newBip86Public(
226243
publicKey: publicKey,
227244
fingerprint: fingerprint,
228245
keychainKind: .internal,
229246
network: network
230247
)
231248
return (descriptor, changeDescriptor)
232249
case .bip84:
233-
let descriptor = Descriptor.newBip84Public(
250+
let descriptor = try Descriptor.newBip84Public(
234251
publicKey: publicKey,
235252
fingerprint: fingerprint,
236253
keychainKind: .external,
237254
network: network
238255
)
239-
let changeDescriptor = Descriptor.newBip84Public(
256+
let changeDescriptor = try Descriptor.newBip84Public(
240257
publicKey: publicKey,
241258
fingerprint: fingerprint,
242259
keychainKind: .internal,
@@ -417,7 +434,7 @@ private class BDKService {
417434
let descriptorPublicKey = try DescriptorPublicKey.fromString(publicKey: xpubString)
418435
let fingerprint = descriptorPublicKey.masterFingerprint()
419436
let currentAddressType = getCurrentAddressType()
420-
let descriptors = createPublicDescriptors(
437+
let descriptors = try createPublicDescriptors(
421438
for: currentAddressType,
422439
publicKey: descriptorPublicKey,
423440
fingerprint: fingerprint,
@@ -556,7 +573,7 @@ private class BDKService {
556573
let isSigned = try wallet.sign(psbt: psbt)
557574
if isSigned {
558575
let transaction = try psbt.extractTx()
559-
try self.blockchainClient.broadcast(transaction)
576+
try await self.blockchainClient.broadcast(transaction)
560577

561578
if self.clientType == .kyoto {
562579
let lastSeen = UInt64(Date().timeIntervalSince1970)

BDKSwiftExampleWallet/View Model/WalletViewModel.swift

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ class WalletViewModel {
4747
}
4848
var isKyotoConnected: Bool = false
4949
var currentBlockHeight: UInt32 = 0
50-
var kyotoNodeState: NodeState?
5150

5251
private var updateProgress: @Sendable (UInt64, UInt64) -> Void {
5352
{ [weak self] inspected, total in
@@ -105,6 +104,9 @@ class WalletViewModel {
105104
if self.bdkClient.getClientType() != .kyoto { return }
106105
if let progress = notification.userInfo?["progress"] as? Float {
107106
self.updateKyotoProgress(progress)
107+
if let height = notification.userInfo?["height"] as? Int {
108+
self.currentBlockHeight = UInt32(max(height, 0))
109+
}
108110
// Consider any progress update as evidence of an active connection
109111
// so the UI does not falsely show a red disconnected indicator while syncing.
110112
if progress > 0 {
@@ -148,8 +150,8 @@ class WalletViewModel {
148150
guard let self else { return }
149151
// Ignore Kyoto updates unless client type is Kyoto
150152
if self.bdkClient.getClientType() != .kyoto { return }
151-
if let height = notification.userInfo?["height"] as? UInt32 {
152-
self.currentBlockHeight = height
153+
if let height = notification.userInfo?["height"] as? Int {
154+
self.currentBlockHeight = UInt32(max(height, 0))
153155
// Receiving chain height implies we have peer connectivity
154156
self.isKyotoConnected = true
155157
// Ensure UI reflects syncing as soon as we see chain activity
@@ -162,23 +164,6 @@ class WalletViewModel {
162164
}
163165
}
164166
}
165-
166-
NotificationCenter.default.addObserver(
167-
forName: NSNotification.Name("KyotoStateUpdate"),
168-
object: nil,
169-
queue: .main
170-
) { [weak self] notification in
171-
guard let self else { return }
172-
if self.bdkClient.getClientType() != .kyoto { return }
173-
if let nodeState = notification.userInfo?["state"] as? NodeState {
174-
self.kyotoNodeState = nodeState
175-
if nodeState == .transactionsSynced {
176-
self.walletSyncState = .synced
177-
} else {
178-
self.walletSyncState = .syncing
179-
}
180-
}
181-
}
182167
}
183168

184169
private func fullScanWithProgress() async {

BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// Created by Rubens Machion on 24/04/25.
66
//
77

8-
import BitcoinDevKit
98
import SwiftUI
109

1110
struct ActivityHomeHeaderView: View {
@@ -18,7 +17,6 @@ struct ActivityHomeHeaderView: View {
1817
let isKyotoClient: Bool
1918
let isKyotoConnected: Bool
2019
let currentBlockHeight: UInt32
21-
let kyotoNodeState: NodeState?
2220

2321
let showAllTransactions: () -> Void
2422

@@ -209,25 +207,13 @@ struct ActivityHomeHeaderView: View {
209207

210208
extension ActivityHomeHeaderView {
211209
fileprivate var kyotoStatusText: String? {
212-
guard isKyotoClient, let kyotoNodeState else { return nil }
213-
// Kyoto's NodeState reflects the next stage it will enter, so describe upcoming work.
214-
switch kyotoNodeState {
215-
case .behind:
216-
// Still acquiring header tips, so call out the header sync explicitly.
217-
return "Getting headers..."
218-
case .headersSynced:
219-
// Kyoto reports this once headers are already finished, so surface the next
220-
// actionable phase the node is entering rather than the completed step.
221-
return "Preparing filters..."
222-
case .filterHeadersSynced:
223-
// Filter headers are ready; actual filter scanning starts next.
224-
return "Scanning filters..."
225-
case .filtersSynced:
226-
// Filters are exhausted; the node now gossips for matching blocks/txs.
227-
return "Fetching matches..."
228-
case .transactionsSynced:
229-
// No further phases—fall back to showing percent + standard synced UI.
210+
guard isKyotoClient else { return nil }
211+
if walletSyncState == .synced || progress >= 100 {
230212
return nil
231213
}
214+
if progress <= 0 {
215+
return isKyotoConnected ? "Getting headers..." : "Connecting..."
216+
}
217+
return "Scanning filters..."
232218
}
233219
}

BDKSwiftExampleWallet/View/WalletView.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ struct WalletView: View {
5151
needsFullScan: viewModel.needsFullScan,
5252
isKyotoClient: viewModel.isKyotoClient,
5353
isKyotoConnected: viewModel.isKyotoConnected,
54-
currentBlockHeight: viewModel.currentBlockHeight,
55-
kyotoNodeState: viewModel.kyotoNodeState
54+
currentBlockHeight: viewModel.currentBlockHeight
5655
) {
5756
showAllTransactions = true
5857
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ Download the app on [TestFlight](https://testflight.apple.com/join/A3nAuYvZ).
1010

1111
## Build
1212

13-
### BDK 1.0
13+
### BDK Version
1414

15-
The `main` branch of BDK Swift Example Wallet uses [bdk-swift](https://github.com/bitcoindevkit/bdk-swift) 1.0+.
15+
The `main` branch of BDK Swift Example Wallet uses [bdk-swift](https://github.com/bitcoindevkit/bdk-swift) 2.0+.
1616

1717
## Functionality
1818

0 commit comments

Comments
 (0)