From 658f76e1757e6ce49c523bb3e5cf2bf2c10f4266 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 11:28:57 -0300 Subject: [PATCH 01/52] feat: xpub persistence --- .../btc-circle-blue.imageset/Contents.json | 15 +++++ .../btc-circle-blue.svg | 4 ++ Bitkit/Models/HwAddressType.swift | 56 +++++++++++++++++++ .../Localization/en.lproj/Localizable.strings | 5 ++ .../Trezor/TrezorKnownDeviceStorage.swift | 35 ++++++++++++ .../ViewModels/Trezor/TrezorViewModel.swift | 35 ++++++++++-- changelog.d/next/hw-wallet-home.added.md | 1 + 7 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/Contents.json create mode 100644 Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/btc-circle-blue.svg create mode 100644 Bitkit/Models/HwAddressType.swift create mode 100644 changelog.d/next/hw-wallet-home.added.md diff --git a/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/Contents.json b/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/Contents.json new file mode 100644 index 000000000..ee51d1f73 --- /dev/null +++ b/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "btc-circle-blue.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/btc-circle-blue.svg b/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/btc-circle-blue.svg new file mode 100644 index 000000000..5fa214834 --- /dev/null +++ b/Bitkit/Assets.xcassets/icons/btc-circle-blue.imageset/btc-circle-blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Bitkit/Models/HwAddressType.swift b/Bitkit/Models/HwAddressType.swift new file mode 100644 index 000000000..1b7e1af70 --- /dev/null +++ b/Bitkit/Models/HwAddressType.swift @@ -0,0 +1,56 @@ +import BitkitCore + +/// Bitcoin account address types tracked for hardware (watch-only) wallets. +/// Mirrors the four BIP account levels Bitkit derives account xpubs for. +/// `allCases` order matches bitkit-android's `ALL_ADDRESS_TYPES`. +enum HwAddressType: CaseIterable { + case legacy + case nestedSegwit + case nativeSegwit + case taproot + + /// Storage key used in `TrezorKnownDevice.xpubs` and address-type settings. + var settingsString: String { + switch self { + case .legacy: "legacy" + case .nestedSegwit: "nestedSegwit" + case .nativeSegwit: "nativeSegwit" + case .taproot: "taproot" + } + } + + /// bitkit-core account type used when starting a watcher for this address type. + var accountType: AccountType { + switch self { + case .legacy: .legacy + case .nestedSegwit: .wrappedSegwit + case .nativeSegwit: .nativeSegwit + case .taproot: .taproot + } + } + + private var purpose: Int { + switch self { + case .legacy: 44 + case .nestedSegwit: 49 + case .nativeSegwit: 84 + case .taproot: 86 + } + } + + /// Account-level derivation path, e.g. `m/84'/0'/0'` (coin type `1'` for non-mainnet). + func accountDerivationPath(network: TrezorCoinType) -> String { + let coinType = network == .bitcoin ? 0 : 1 + return "m/\(purpose)'/\(coinType)'/0'" + } + + init?(settingsString: String) { + switch settingsString { + case "legacy": self = .legacy + case "nestedSegwit": self = .nestedSegwit + case "nativeSegwit": self = .nativeSegwit + case "taproot": self = .taproot + default: return nil + } + } +} diff --git a/Bitkit/Resources/Localization/en.lproj/Localizable.strings b/Bitkit/Resources/Localization/en.lproj/Localizable.strings index 9b7951617..3d36cb1f8 100644 --- a/Bitkit/Resources/Localization/en.lproj/Localizable.strings +++ b/Bitkit/Resources/Localization/en.lproj/Localizable.strings @@ -31,6 +31,11 @@ "cards__support__description" = "Get assistance"; "cards__hardware__title" = "Hardware"; "cards__hardware__description" = "Connect device"; +"hardware__intro_title" = "Hardware Wallet"; +"hardware__intro_header" = "Add your hardware wallet"; +"hardware__intro_text" = "Connect your hardware device to watch or manage your long-term funds."; +"hardware__pairing_title" = "Pair Device"; +"hardware__pairing_text" = "Enter the 6-digit code shown on your hardware device."; "cards__buyBitcoin__title" = "Buy"; "cards__buyBitcoin__description" = "Buy some bitcoin"; "cards__btFailed__title" = "Failed"; diff --git a/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift b/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift index 76c7894c1..8b96d67c9 100644 --- a/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift +++ b/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift @@ -9,6 +9,41 @@ struct TrezorKnownDevice: Codable, Identifiable { var label: String? var model: String? var lastConnectedAt: Date + /// Account-level extended public keys keyed by `HwAddressType.settingsString`. + /// Persisted so watch-only balances/activity stay available while disconnected. + var xpubs: [String: String] + + init( + id: String, + name: String, + path: String, + transportType: String, + label: String? = nil, + model: String? = nil, + lastConnectedAt: Date, + xpubs: [String: String] = [:] + ) { + self.id = id + self.name = name + self.path = path + self.transportType = transportType + self.label = label + self.model = model + self.lastConnectedAt = lastConnectedAt + self.xpubs = xpubs + } + + init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + id = try container.decode(String.self, forKey: .id) + name = try container.decode(String.self, forKey: .name) + path = try container.decode(String.self, forKey: .path) + transportType = try container.decode(String.self, forKey: .transportType) + label = try container.decodeIfPresent(String.self, forKey: .label) + model = try container.decodeIfPresent(String.self, forKey: .model) + lastConnectedAt = try container.decode(Date.self, forKey: .lastConnectedAt) + xpubs = try container.decodeIfPresent([String: String].self, forKey: .xpubs) ?? [:] + } } /// Persists known Trezor device metadata in UserDefaults diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index b077bf9d1..7c4b04dae 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -559,7 +559,7 @@ class TrezorViewModel { deviceFeatures = features showConfirmOnDevice = false - saveCurrentDeviceAsKnown() + await saveCurrentDeviceAsKnown() trezorLog("Connected to Trezor: \(device.path)") } catch { let errorMsg = errorMessage(from: error) @@ -837,9 +837,13 @@ class TrezorViewModel { knownDevices = TrezorKnownDeviceStorage.loadAll() } - /// Save the currently connected device as a known device - func saveCurrentDeviceAsKnown() { + /// Save the currently connected device as a known device, capturing its account + /// xpubs so watch-only balances/activity stay available while disconnected. + func saveCurrentDeviceAsKnown() async { guard let device = connectedDevice else { return } + let previous = TrezorKnownDeviceStorage.loadAll().first { $0.id == device.id } + let fetched = await fetchAccountXpubs() + let mergedXpubs = (previous?.xpubs ?? [:]).merging(fetched) { _, new in new } let known = TrezorKnownDevice( id: device.id, name: device.name ?? "Trezor", @@ -847,11 +851,32 @@ class TrezorViewModel { transportType: device.transportType == .bluetooth ? "bluetooth" : "usb", label: device.label ?? deviceFeatures?.label, model: device.model ?? deviceFeatures?.model, - lastConnectedAt: Date() + lastConnectedAt: Date(), + xpubs: mergedXpubs ) TrezorKnownDeviceStorage.save(known) loadKnownDevices() - trezorLog("Saved known device: \(known.name)") + trezorLog("Saved known device: \(known.name) with \(mergedXpubs.count) xpubs") + } + + /// Read the account-level xpub for every address type from the connected device. + /// Per-type failures are swallowed so a single missing type doesn't block the rest. + func fetchAccountXpubs() async -> [String: String] { + var result: [String: String] = [:] + for addressType in HwAddressType.allCases { + do { + let params = TrezorGetPublicKeyParams( + path: addressType.accountDerivationPath(network: selectedNetwork), + coin: selectedNetwork, + showOnTrezor: false + ) + let response = try await trezorService.getPublicKey(params: params) + result[addressType.settingsString] = response.xpub + } catch { + trezorLog("Could not read xpub for '\(addressType.settingsString)': \(error)", level: "warn") + } + } + return result } /// Forget a known device — removes from storage and clears credentials diff --git a/changelog.d/next/hw-wallet-home.added.md b/changelog.d/next/hw-wallet-home.added.md new file mode 100644 index 000000000..6b3d4c550 --- /dev/null +++ b/changelog.d/next/hw-wallet-home.added.md @@ -0,0 +1 @@ +Show paired Trezor hardware wallet balances and activity on the home screen, with sheets to enter the pairing code and to notify incoming hardware wallet transactions. From e4be493b8edd8f3d16cc3c408093496a4d3837c0 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 13:27:43 -0300 Subject: [PATCH 02/52] bump bitkit-core and adapt code --- Bitkit.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- Bitkit/Models/HwWallet.swift | 49 +++++++++ Bitkit/Services/CoreService.swift | 101 ++++++++++++------ Bitkit/Services/MigrationsService.swift | 8 +- .../Trezor/TrezorBridgeTransport.swift | 30 ++++-- Bitkit/Services/Trezor/TrezorTransport.swift | 16 +-- Bitkit/ViewModels/AppViewModel.swift | 1 + Bitkit/ViewModels/TransferViewModel.swift | 1 + Bitkit/ViewModels/WalletViewModel.swift | 8 +- Bitkit/Views/Gift/GiftLoading.swift | 1 + .../Activity/ActivityExplorerView.swift | 2 + .../Wallets/Activity/ActivityItemView.swift | 2 + .../Wallets/Send/SendConfirmationView.swift | 1 + Bitkit/Views/Wallets/Sheets/BoostSheet.swift | 1 + BitkitTests/ActivityListTest.swift | 14 +++ BitkitTests/ContactsManagerTests.swift | 3 + 17 files changed, 186 insertions(+), 58 deletions(-) create mode 100644 Bitkit/Models/HwWallet.swift diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index fff6b6c4a..503b87cce 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -1201,7 +1201,7 @@ repositoryURL = "https://github.com/synonymdev/bitkit-core"; requirement = { kind = exactVersion; - version = 0.1.66; + version = 0.3.2; }; }; 96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = { diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6a8a87a87..3882def7e 100644 --- a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/synonymdev/bitkit-core", "state" : { - "revision" : "99ffc3b610bdb199cbe3a35d9c9dc9435f769b85", - "version" : "0.1.66" + "revision" : "d95a061cb0062e89fa0107743989c3dc62d8f1b1", + "version" : "0.3.2" } }, { diff --git a/Bitkit/Models/HwWallet.swift b/Bitkit/Models/HwWallet.swift new file mode 100644 index 000000000..37d566c1f --- /dev/null +++ b/Bitkit/Models/HwWallet.swift @@ -0,0 +1,49 @@ +import BitkitCore +import Foundation + +/// A paired hardware wallet tracked as a watch-only balance. +struct HwWallet: Identifiable { + let id: String + let name: String + let model: String? + let isConnected: Bool + let balanceSats: UInt64 + let activities: [Activity] + let deviceIds: Set + + init( + id: String, + name: String, + model: String?, + isConnected: Bool, + balanceSats: UInt64, + activities: [Activity], + deviceIds: Set? = nil + ) { + self.id = id + self.name = name + self.model = model + self.isConnected = isConnected + self.balanceSats = balanceSats + self.activities = activities + self.deviceIds = deviceIds ?? [id] + } +} + +/// Per-device balance snapshot folded into the headline total via `BalanceState`. +struct HwWalletBalance: Codable, Equatable, Identifiable { + let id: String + let sats: UInt64 +} + +/// A newly detected inbound transaction to a watched hardware wallet. +struct HwWalletReceivedTx: Equatable { + let txid: String + let sats: UInt64 +} + +extension HwWallet { + var toBalance: HwWalletBalance { + HwWalletBalance(id: id, sats: balanceSats) + } +} diff --git a/Bitkit/Services/CoreService.swift b/Bitkit/Services/CoreService.swift index 50261c3d5..2ef034d70 100644 --- a/Bitkit/Services/CoreService.swift +++ b/Bitkit/Services/CoreService.swift @@ -3,6 +3,18 @@ import Combine import Foundation import LDKNode +/// Wallet scoping for bitkit-core's wallet-scoped activity storage (added in core 0.3.x). +/// The app's normal on-chain/Lightning wallet uses the core default (`"bitkit"`); paired +/// hardware wallets use their own derived id (see `HwWalletId`). +/// +/// Defined here (rather than its own file) because `CoreService.swift` is shared with the +/// notification and widget extension targets, so the type must live in a file those targets +/// already compile. +enum WalletScope { + /// The default Bitkit wallet id (`DEFAULT_WALLET_ID` in bitkit-core). + static let `default`: String = getDefaultWalletId() +} + // MARK: - Local Types (removed from BitkitCore in Trezor module rewrite) /// Address info with usage data @@ -110,6 +122,7 @@ class ActivityService { } return BitkitCore.TransactionDetails( + walletId: WalletScope.default, txId: txid, amountSats: details.amountSats, inputs: inputs, @@ -128,7 +141,7 @@ class ActivityService { func getTransactionDetails(txid: String) async throws -> BitkitCore.TransactionDetails? { try await ServiceQueue.background(.core) { - try BitkitCore.getTransactionDetails(txId: txid) + try BitkitCore.getTransactionDetails(walletId: WalletScope.default, txId: txid) } } @@ -136,7 +149,7 @@ class ActivityService { func isActivitySeen(id: String) async -> Bool { do { - if let activity = try getActivityById(activityId: id) { + if let activity = try getActivityById(walletId: WalletScope.default, activityId: id) { switch activity { case let .onchain(onchain): return onchain.seenAt != nil @@ -160,7 +173,7 @@ class ActivityService { do { try await ServiceQueue.background(.core) { - try BitkitCore.markActivityAsSeen(activityId: id, seenAt: timestamp) + try BitkitCore.markActivityAsSeen(walletId: WalletScope.default, activityId: id, seenAt: timestamp) self.activitiesChangedSubject.send() } } catch { @@ -201,7 +214,9 @@ class ActivityService { if !isSeen { try await ServiceQueue.background(.core) { - try BitkitCore.markActivityAsSeen(activityId: id, seenAt: timestamp) + try BitkitCore.markActivityAsSeen( + walletId: WalletScope.default, activityId: id, seenAt: timestamp + ) } didMarkAny = true } @@ -318,7 +333,15 @@ class ActivityService { try await ServiceQueue.background(.core) { // Get all activities and delete them one by one let activities = try getActivities( - filter: .all, txType: nil, tags: nil, search: nil, minDate: nil, maxDate: nil, limit: nil, sortDirection: nil + walletId: WalletScope.default, + filter: .all, + txType: nil, + tags: nil, + search: nil, + minDate: nil, + maxDate: nil, + limit: nil, + sortDirection: nil ) for activity in activities { let id: String = switch activity { @@ -326,7 +349,7 @@ class ActivityService { case let .onchain(on): on.id } - _ = try deleteActivityById(activityId: id) + _ = try deleteActivityById(walletId: WalletScope.default, activityId: id) } // Clear cache since all activities are deleted @@ -379,9 +402,9 @@ class ActivityService { let paymentTimestamp = payment.latestUpdateTimestamp // Look for existing activity by id first, then by txid (for migrated activities) - var existingActivity = try getActivityById(activityId: payment.id) + var existingActivity = try getActivityById(walletId: WalletScope.default, activityId: payment.id) if existingActivity == nil { - existingActivity = try BitkitCore.getActivityByTxId(txId: txid).map { .onchain($0) } + existingActivity = try BitkitCore.getActivityByTxId(walletId: WalletScope.default, txId: txid).map { .onchain($0) } } // Determine if confirmation status is changing @@ -483,6 +506,7 @@ class ActivityService { }() let onchain = OnchainActivity( + walletId: WalletScope.default, id: payment.id, txType: payment.direction == .outbound ? .sent : .received, txId: txid, @@ -699,7 +723,7 @@ class ActivityService { guard !(payment.status == .pending && payment.direction == .inbound) else { return } let paymentTimestamp = UInt64(payment.latestUpdateTimestamp) - let existingActivity = try getActivityById(activityId: payment.id) + let existingActivity = try getActivityById(walletId: WalletScope.default, activityId: payment.id) let existingLightning: LightningActivity? = if let existingActivity, case let .lightning(ln) = existingActivity { ln } else { nil } let state: BitkitCore.PaymentState = switch payment.status { @@ -727,6 +751,7 @@ class ActivityService { } let ln = LightningActivity( + walletId: WalletScope.default, id: payment.id, txType: payment.direction == .outbound ? .sent : .received, status: state, @@ -770,7 +795,7 @@ class ActivityService { for payment in payments { if case let .onchain(txid, _) = payment.kind { do { - let hadExistingActivity = try getActivityById(activityId: payment.id) != nil + let hadExistingActivity = try getActivityById(walletId: WalletScope.default, activityId: payment.id) != nil try await self.processOnchainPayment(payment, transactionDetails: nil) if hadExistingActivity { updatedCount += 1 @@ -783,7 +808,7 @@ class ActivityService { } } else if case .bolt11 = payment.kind { do { - let hadExistingActivity = try getActivityById(activityId: payment.id) != nil + let hadExistingActivity = try getActivityById(walletId: WalletScope.default, activityId: payment.id) != nil try await self.processLightningPayment(payment) if hadExistingActivity { updatedCount += 1 @@ -809,9 +834,11 @@ class ActivityService { /// Marks replacement transactions (with originalTxId in boostTxIds) as doesExist = false when original confirms /// Finds the channel ID associated with a transaction based on its direction - private func findChannelForTransaction(txid: String, direction: PaymentDirection, - transactionDetails: BitkitCore.TransactionDetails? = nil) async -> String? - { + private func findChannelForTransaction( + txid: String, + direction: PaymentDirection, + transactionDetails: BitkitCore.TransactionDetails? = nil + ) async -> String? { switch direction { case .inbound: // Check if this transaction is a channel close by checking if it spends a closed channel's funding UTXO @@ -933,9 +960,11 @@ class ActivityService { } /// Find the receiving address for an onchain transaction - private func findReceivingAddress(for txid: String, value: UInt64, - transactionDetails: BitkitCore.TransactionDetails? = nil) async throws -> String? - { + private func findReceivingAddress( + for txid: String, + value: UInt64, + transactionDetails: BitkitCore.TransactionDetails? = nil + ) async throws -> String? { let details = if let provided = transactionDetails { provided } else { await fetchTransactionDetails(txid: txid) } guard let details else { Logger.warn("Transaction details not available for \(txid)", context: "CoreService.findReceivingAddress") @@ -963,13 +992,13 @@ class ActivityService { func getActivity(id: String) async throws -> Activity? { try await ServiceQueue.background(.core) { - try getActivityById(activityId: id) + try getActivityById(walletId: WalletScope.default, activityId: id) } } func getOnchainActivityByTxId(txid: String) async throws -> OnchainActivity? { try await ServiceQueue.background(.core) { - try BitkitCore.getActivityByTxId(txId: txid) + try BitkitCore.getActivityByTxId(walletId: WalletScope.default, txId: txid) } } @@ -1003,6 +1032,7 @@ class ActivityService { ) async throws -> [Activity] { try await ServiceQueue.background(.core) { try getActivities( + walletId: WalletScope.default, filter: filter, txType: txType, tags: tags, @@ -1065,12 +1095,13 @@ class ActivityService { ) async { do { try await ServiceQueue.background(.core) { - if let _ = try? BitkitCore.getActivityByTxId(txId: txid) { + if let _ = try? BitkitCore.getActivityByTxId(walletId: WalletScope.default, txId: txid) { Logger.debug("Activity already exists for txid \(txid), skipping immediate creation", context: "ActivityService") return } let now = UInt64(Date().timeIntervalSince1970) let onchain = OnchainActivity( + walletId: WalletScope.default, id: txid, txType: .sent, txId: txid, @@ -1106,7 +1137,10 @@ class ActivityService { let normalizedContact = publicKey.map { PubkyPublicKeyFormat.normalized($0) ?? $0 } try await ServiceQueue.background(.core) { - guard let activity = try getActivityById(activityId: id) ?? (try? BitkitCore.getActivityByTxId(txId: id)).map(Activity.onchain) else { + guard let activity = try getActivityById(walletId: WalletScope.default, activityId: id) ?? (try? BitkitCore.getActivityByTxId( + walletId: WalletScope.default, + txId: id + )).map(Activity.onchain) else { throw AppError(message: "Activity not found", debugMessage: "Activity with ID \(id) not found") } @@ -1138,6 +1172,7 @@ class ActivityService { guard !activity.doesExist, activity.txType == .sent else { return false } let activities = try getActivities( + walletId: WalletScope.default, filter: .onchain, txType: nil, tags: nil, @@ -1161,12 +1196,12 @@ class ActivityService { func delete(id: String) async throws -> Bool { try await ServiceQueue.background(.core) { // Rebuild cache if deleting an onchain activity with boostTxIds - let activity = try? getActivityById(activityId: id) + let activity = try? getActivityById(walletId: WalletScope.default, activityId: id) if let activity, case let .onchain(onchain) = activity, !onchain.boostTxIds.isEmpty { await self.refreshBoostTxIdsCache() } - let result = try deleteActivityById(activityId: id) + let result = try deleteActivityById(walletId: WalletScope.default, activityId: id) self.activitiesChangedSubject.send() return result } @@ -1176,21 +1211,21 @@ class ActivityService { func appendTags(toActivity id: String, _ tags: [String]) async throws { try await ServiceQueue.background(.core) { - try addTags(activityId: id, tags: tags) + try addTags(walletId: WalletScope.default, activityId: id, tags: tags) self.activitiesChangedSubject.send() } } func dropTags(fromActivity id: String, _ tags: [String]) async throws { try await ServiceQueue.background(.core) { - try removeTags(activityId: id, tags: tags) + try removeTags(walletId: WalletScope.default, activityId: id, tags: tags) self.activitiesChangedSubject.send() } } func tags(forActivity id: String) async throws -> [String] { try await ServiceQueue.background(.core) { - try getTags(activityId: id) + try getTags(walletId: WalletScope.default, activityId: id) } } @@ -1223,34 +1258,34 @@ class ActivityService { func addPreActivityMetadataTags(paymentId: String, tags: [String]) async throws { try await ServiceQueue.background(.core) { - try BitkitCore.addPreActivityMetadataTags(paymentId: paymentId, tags: tags) + try BitkitCore.addPreActivityMetadataTags(walletId: WalletScope.default, paymentId: paymentId, tags: tags) self.metadataChangedSubject.send() } } func removePreActivityMetadataTags(paymentId: String, tags: [String]) async throws { try await ServiceQueue.background(.core) { - try BitkitCore.removePreActivityMetadataTags(paymentId: paymentId, tags: tags) + try BitkitCore.removePreActivityMetadataTags(walletId: WalletScope.default, paymentId: paymentId, tags: tags) self.metadataChangedSubject.send() } } func getPreActivityMetadata(searchKey: String, searchByAddress: Bool = false) async throws -> BitkitCore.PreActivityMetadata? { try await ServiceQueue.background(.core) { - try BitkitCore.getPreActivityMetadata(searchKey: searchKey, searchByAddress: searchByAddress) + try BitkitCore.getPreActivityMetadata(walletId: WalletScope.default, searchKey: searchKey, searchByAddress: searchByAddress) } } func deletePreActivityMetadata(paymentId: String) async throws { try await ServiceQueue.background(.core) { - try BitkitCore.deletePreActivityMetadata(paymentId: paymentId) + try BitkitCore.deletePreActivityMetadata(walletId: WalletScope.default, paymentId: paymentId) self.metadataChangedSubject.send() } } func resetPreActivityMetadataTags(paymentId: String) async throws { try await ServiceQueue.background(.core) { - try BitkitCore.resetPreActivityMetadataTags(paymentId: paymentId) + try BitkitCore.resetPreActivityMetadataTags(walletId: WalletScope.default, paymentId: paymentId) self.metadataChangedSubject.send() } } @@ -1272,7 +1307,7 @@ class ActivityService { func boostOnchainTransaction(activityId: String, feeRate: UInt32) async throws -> String { return try await ServiceQueue.background(.core) { // Get the existing activity - guard let existingActivity = try getActivityById(activityId: activityId) else { + guard let existingActivity = try getActivityById(walletId: WalletScope.default, activityId: activityId) else { throw AppError(message: "Activity not found", debugMessage: "Activity with ID \(activityId) not found") } @@ -1344,6 +1379,7 @@ class ActivityService { case .lightning: .lightning( LightningActivity( + walletId: WalletScope.default, id: id, txType: template.txType, status: template.status, @@ -1362,6 +1398,7 @@ class ActivityService { case .onchain: .onchain( OnchainActivity( + walletId: WalletScope.default, id: id, txType: template.txType, txId: String(repeating: "a", count: 64), diff --git a/Bitkit/Services/MigrationsService.swift b/Bitkit/Services/MigrationsService.swift index 5fce0e922..0a248d858 100644 --- a/Bitkit/Services/MigrationsService.swift +++ b/Bitkit/Services/MigrationsService.swift @@ -1400,6 +1400,7 @@ extension MigrationsService { let invoice = (item.address?.isEmpty == false) ? item.address! : "migrated:\(item.id)" let lightning = BitkitCore.LightningActivity( + walletId: WalletScope.default, id: item.id, txType: txType, status: status, @@ -1752,7 +1753,7 @@ extension MigrationsService { // Try to find on-chain activity by txId first if let onchain = try? await CoreService.shared.activity.getOnchainActivityByTxId(txid: activityId) { try await CoreService.shared.activity.upsertTags([ - ActivityTags(activityId: onchain.id, tags: tagList), + ActivityTags(walletId: WalletScope.default, activityId: onchain.id, tags: tagList), ]) applied += 1 } else if let activity = try? await CoreService.shared.activity.getActivity(id: activityId) { @@ -1760,12 +1761,12 @@ extension MigrationsService { switch activity { case .lightning: try await CoreService.shared.activity.upsertTags([ - ActivityTags(activityId: activityId, tags: tagList), + ActivityTags(walletId: WalletScope.default, activityId: activityId, tags: tagList), ]) applied += 1 case let .onchain(onchain): try await CoreService.shared.activity.upsertTags([ - ActivityTags(activityId: onchain.id, tags: tagList), + ActivityTags(walletId: WalletScope.default, activityId: onchain.id, tags: tagList), ]) applied += 1 } @@ -1843,6 +1844,7 @@ extension MigrationsService { let activityTimestamp = timestampSecs > 0 ? timestampSecs : now let onchain = BitkitCore.OnchainActivity( + walletId: WalletScope.default, id: item.id, txType: item.txType == "sent" ? .sent : .received, txId: txId, diff --git a/Bitkit/Services/Trezor/TrezorBridgeTransport.swift b/Bitkit/Services/Trezor/TrezorBridgeTransport.swift index 402f4f9d9..90138e9c8 100644 --- a/Bitkit/Services/Trezor/TrezorBridgeTransport.swift +++ b/Bitkit/Services/Trezor/TrezorBridgeTransport.swift @@ -78,10 +78,10 @@ final class TrezorBridgeTransport { sessionLock.unlock() debugLog("openDevice: \(path)") - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } catch { debugLog("openDevice FAILED: \(error.localizedDescription)") - return TrezorTransportWriteResult(success: false, error: error.localizedDescription) + return TrezorTransportWriteResult(success: false, error: error.localizedDescription, errorCode: nil) } } @@ -91,25 +91,29 @@ final class TrezorBridgeTransport { sessionLock.unlock() guard let session else { - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } do { _ = try post(path: "/release/\(Self.encode(session))") debugLog("closeDevice: \(path)") - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } catch { debugLog("closeDevice FAILED: \(error.localizedDescription)") - return TrezorTransportWriteResult(success: false, error: error.localizedDescription) + return TrezorTransportWriteResult(success: false, error: error.localizedDescription, errorCode: nil) } } func readChunk(path: String) -> TrezorTransportReadResult { - TrezorTransportReadResult(success: false, data: Data(), error: "Trezor Bridge uses callMessage for \(path)") + TrezorTransportReadResult(success: false, data: Data(), error: "Trezor Bridge uses callMessage for \(path)", errorCode: nil) } func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult { - TrezorTransportWriteResult(success: false, error: "Trezor Bridge uses callMessage for \(path) and ignored \(data.count) bytes") + TrezorTransportWriteResult( + success: false, + error: "Trezor Bridge uses callMessage for \(path) and ignored \(data.count) bytes", + errorCode: nil + ) } func callMessage(path: String, messageType: UInt16, data: Data) -> TrezorCallMessageResult { @@ -118,7 +122,13 @@ final class TrezorBridgeTransport { sessionLock.unlock() guard let session else { - return TrezorCallMessageResult(success: false, messageType: 0, data: Data(), error: "Trezor Bridge device not open: \(path)") + return TrezorCallMessageResult( + success: false, + messageType: 0, + data: Data(), + error: "Trezor Bridge device not open: \(path)", + errorCode: nil + ) } do { @@ -127,7 +137,7 @@ final class TrezorBridgeTransport { return try Self.decodeFrame(response) } catch { debugLog("callMessage FAILED: \(error.localizedDescription)") - return TrezorCallMessageResult(success: false, messageType: 0, data: Data(), error: error.localizedDescription) + return TrezorCallMessageResult(success: false, messageType: 0, data: Data(), error: error.localizedDescription, errorCode: nil) } } @@ -199,7 +209,7 @@ final class TrezorBridgeTransport { } let payload = bytes.subdata(in: headerSize ..< headerSize + Int(length)) - return TrezorCallMessageResult(success: true, messageType: messageType, data: payload, error: "") + return TrezorCallMessageResult(success: true, messageType: messageType, data: payload, error: "", errorCode: nil) } private static func toBridgePath(_ path: String) -> String { diff --git a/Bitkit/Services/Trezor/TrezorTransport.swift b/Bitkit/Services/Trezor/TrezorTransport.swift index 35e35c4c0..4649c718f 100644 --- a/Bitkit/Services/Trezor/TrezorTransport.swift +++ b/Bitkit/Services/Trezor/TrezorTransport.swift @@ -86,10 +86,10 @@ final class TrezorTransport: TrezorTransportCallback { throw error } - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } catch { debugLog("openDevice FAILED: \(error.localizedDescription)") - return TrezorTransportWriteResult(success: false, error: error.localizedDescription) + return TrezorTransportWriteResult(success: false, error: error.localizedDescription, errorCode: nil) } } @@ -102,11 +102,11 @@ final class TrezorTransport: TrezorTransportCallback { } guard path.hasPrefix("ble:") else { - return TrezorTransportWriteResult(success: false, error: "Invalid device path: \(path)") + return TrezorTransportWriteResult(success: false, error: "Invalid device path: \(path)", errorCode: nil) } bleManager.disconnect(path: path) - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } /// Read a chunk of data from the device @@ -123,10 +123,10 @@ final class TrezorTransport: TrezorTransportCallback { let data = try bleManager.readChunk(path: path) debugLog("readChunk: \(data.count) bytes") - return TrezorTransportReadResult(success: true, data: data, error: "") + return TrezorTransportReadResult(success: true, data: data, error: "", errorCode: nil) } catch { debugLog("readChunk FAILED: \(error.localizedDescription)") - return TrezorTransportReadResult(success: false, data: Data(), error: error.localizedDescription) + return TrezorTransportReadResult(success: false, data: Data(), error: error.localizedDescription, errorCode: nil) } } @@ -162,10 +162,10 @@ final class TrezorTransport: TrezorTransportCallback { throw error } - return TrezorTransportWriteResult(success: true, error: "") + return TrezorTransportWriteResult(success: true, error: "", errorCode: nil) } catch { debugLog("writeChunk FAILED: \(error.localizedDescription)") - return TrezorTransportWriteResult(success: false, error: error.localizedDescription) + return TrezorTransportWriteResult(success: false, error: error.localizedDescription, errorCode: nil) } } diff --git a/Bitkit/ViewModels/AppViewModel.swift b/Bitkit/ViewModels/AppViewModel.swift index 600e74916..8c8f1bb42 100644 --- a/Bitkit/ViewModels/AppViewModel.swift +++ b/Bitkit/ViewModels/AppViewModel.swift @@ -851,6 +851,7 @@ extension AppViewModel { let now = UInt64(Date().timeIntervalSince1970) let ln = LightningActivity( + walletId: WalletScope.default, id: channel.fundingTxo?.txid ?? "", txType: .received, status: .succeeded, diff --git a/Bitkit/ViewModels/TransferViewModel.swift b/Bitkit/ViewModels/TransferViewModel.swift index 5a903bc26..5c8d66b39 100644 --- a/Bitkit/ViewModels/TransferViewModel.swift +++ b/Bitkit/ViewModels/TransferViewModel.swift @@ -159,6 +159,7 @@ class TransferViewModel: ObservableObject { // Create pre-activity metadata for the transfer transaction let currentTime = UInt64(Date().timeIntervalSince1970) let preActivityMetadata = BitkitCore.PreActivityMetadata( + walletId: WalletScope.default, paymentId: txid, tags: [], paymentHash: nil, diff --git a/Bitkit/ViewModels/WalletViewModel.swift b/Bitkit/ViewModels/WalletViewModel.swift index 6646fc71a..beefc13de 100644 --- a/Bitkit/ViewModels/WalletViewModel.swift +++ b/Bitkit/ViewModels/WalletViewModel.swift @@ -385,8 +385,11 @@ class WalletViewModel: ObservableObject { case .unreachablePeers: Logger.warn("⚠️ [DEBUG] Simulating unreachable API peers") return [ - LnPeer(nodeId: "000000000000000000000000000000000000000000000000000000000000000001", - host: "192.0.2.1", port: 9735), + LnPeer( + nodeId: "000000000000000000000000000000000000000000000000000000000000000001", + host: "192.0.2.1", + port: 9735 + ), ] case .none: break @@ -1248,6 +1251,7 @@ class WalletViewModel: ObservableObject { let currentTime = UInt64(Date().timeIntervalSince1970) let preActivityMetadata = BitkitCore.PreActivityMetadata( + walletId: WalletScope.default, paymentId: paymentId, tags: tags, paymentHash: paymentHash, diff --git a/Bitkit/Views/Gift/GiftLoading.swift b/Bitkit/Views/Gift/GiftLoading.swift index b903db4c3..bc7c04a83 100644 --- a/Bitkit/Views/Gift/GiftLoading.swift +++ b/Bitkit/Views/Gift/GiftLoading.swift @@ -100,6 +100,7 @@ struct GiftLoading: View { // Create activity item for the received gift let lightningActivity = LightningActivity( + walletId: WalletScope.default, id: openedOrder.channel?.fundingTx.id ?? orderId, txType: .received, status: .succeeded, diff --git a/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift b/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift index b208e29b3..9f5653d24 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift @@ -273,6 +273,7 @@ struct ActivityExplorer_Previews: PreviewProvider { ActivityExplorerView( item: .lightning( LightningActivity( + walletId: WalletScope.default, id: "test-lightning-1", txType: .received, status: .succeeded, @@ -295,6 +296,7 @@ struct ActivityExplorer_Previews: PreviewProvider { ActivityExplorerView( item: .onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-onchain-1", txType: .received, txId: "9c60a69005cbdb7323f8f0551d5c6f79a8c9c27c32475e4a0ad4a47d305c629d", diff --git a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift index f9d7260d8..cba5f657f 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift @@ -644,6 +644,7 @@ struct ActivityItemView_Previews: PreviewProvider { ActivityItemView( item: .lightning( LightningActivity( + walletId: WalletScope.default, id: "test-lightning-1", txType: .sent, status: .succeeded, @@ -668,6 +669,7 @@ struct ActivityItemView_Previews: PreviewProvider { ActivityItemView( item: .onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-onchain-1", txType: .received, txId: "abc123", diff --git a/Bitkit/Views/Wallets/Send/SendConfirmationView.swift b/Bitkit/Views/Wallets/Send/SendConfirmationView.swift index 55547fc7b..9d1aae658 100644 --- a/Bitkit/Views/Wallets/Send/SendConfirmationView.swift +++ b/Bitkit/Views/Wallets/Send/SendConfirmationView.swift @@ -712,6 +712,7 @@ struct SendConfirmationView: View { ) async { let currentTime = UInt64(Date().timeIntervalSince1970) let preActivityMetadata = BitkitCore.PreActivityMetadata( + walletId: WalletScope.default, paymentId: paymentId, tags: tagManager.selectedTagsArray, paymentHash: paymentHash, diff --git a/Bitkit/Views/Wallets/Sheets/BoostSheet.swift b/Bitkit/Views/Wallets/Sheets/BoostSheet.swift index f514d47e2..107896edf 100644 --- a/Bitkit/Views/Wallets/Sheets/BoostSheet.swift +++ b/Bitkit/Views/Wallets/Sheets/BoostSheet.swift @@ -427,6 +427,7 @@ struct BoostSheet: View { BoostSheet( config: BoostSheetItem( onchainActivity: OnchainActivity( + walletId: WalletScope.default, id: "test-onchain-1", txType: .sent, txId: "abc123", diff --git a/BitkitTests/ActivityListTest.swift b/BitkitTests/ActivityListTest.swift index 3f065ddbc..3bdcb9d6e 100644 --- a/BitkitTests/ActivityListTest.swift +++ b/BitkitTests/ActivityListTest.swift @@ -33,6 +33,7 @@ final class ActivityTests: XCTestCase { // Create a lightning activity let lightningActivity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-lightning-1", txType: .sent, status: .succeeded, @@ -75,6 +76,7 @@ final class ActivityTests: XCTestCase { // Create an onchain activity let onchainActivity = Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-onchain-1", txType: .received, txId: "abc123", @@ -121,6 +123,7 @@ final class ActivityTests: XCTestCase { // Create and insert an activity let activity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-tags-1", txType: .sent, status: .succeeded, @@ -160,6 +163,7 @@ final class ActivityTests: XCTestCase { let activities = [ Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-tag-filter-1", txType: .sent, status: .succeeded, @@ -177,6 +181,7 @@ final class ActivityTests: XCTestCase { ), Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-tag-filter-2", txType: .sent, status: .succeeded, @@ -220,6 +225,7 @@ final class ActivityTests: XCTestCase { let activities = [ Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-unique-tags-1", txType: .sent, status: .succeeded, @@ -237,6 +243,7 @@ final class ActivityTests: XCTestCase { ), Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-unique-tags-2", txType: .received, txId: "abc123", @@ -300,6 +307,7 @@ final class ActivityTests: XCTestCase { // Create and insert an activity let initialActivity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-update-1", txType: .sent, status: .pending, @@ -321,6 +329,7 @@ final class ActivityTests: XCTestCase { // Create updated version let updatedActivity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-update-1", txType: .sent, status: .succeeded, @@ -446,6 +455,7 @@ final class ActivityTests: XCTestCase { // Create and insert an activity let activity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-delete-1", txType: .sent, status: .succeeded, @@ -484,6 +494,7 @@ final class ActivityTests: XCTestCase { let activities = [ Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-limit-1", txType: .sent, status: .succeeded, @@ -501,6 +512,7 @@ final class ActivityTests: XCTestCase { ), Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-limit-2", txType: .received, txId: "abc123", @@ -525,6 +537,7 @@ final class ActivityTests: XCTestCase { ), Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-limit-3", txType: .received, status: .succeeded, @@ -566,6 +579,7 @@ final class ActivityTests: XCTestCase { let timestamp = UInt64(Date().timeIntervalSince1970) return Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: id, txType: .sent, txId: txId, diff --git a/BitkitTests/ContactsManagerTests.swift b/BitkitTests/ContactsManagerTests.swift index 758e16501..badac61a3 100644 --- a/BitkitTests/ContactsManagerTests.swift +++ b/BitkitTests/ContactsManagerTests.swift @@ -40,6 +40,7 @@ final class ContactsManagerTests: XCTestCase { let contact = makeContact(publicKey: "pubky\(rawKey)") let activity = Activity.lightning( LightningActivity( + walletId: WalletScope.default, id: "test-lightning-contact", txType: .sent, status: .succeeded, @@ -64,6 +65,7 @@ final class ContactsManagerTests: XCTestCase { let contact = makeContact(publicKey: "pubky\(rawKey)") let activity = Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: "test-onchain-boosting-contact", txType: .sent, txId: "txid", @@ -94,6 +96,7 @@ final class ContactsManagerTests: XCTestCase { let replacedTxId = "replaced_tx_id" let activity = Activity.onchain( OnchainActivity( + walletId: WalletScope.default, id: replacedTxId, txType: .sent, txId: replacedTxId, From 8e1d8ad4a0c2a76bfc418db7688d8f96b18a2f9f Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 14:00:27 -0300 Subject: [PATCH 03/52] feat: adapt code to pesist activities via bitkit-core wallet-scoped storage --- Bitkit/AppScene.swift | 12 +- Bitkit/Models/HwWallet.swift | 10 +- Bitkit/Models/HwWalletId.swift | 24 ++ Bitkit/Services/HwWalletRepo.swift | 466 ++++++++++++++++++++++++++++ BitkitTests/HwWalletRepoTests.swift | 266 ++++++++++++++++ 5 files changed, 774 insertions(+), 4 deletions(-) create mode 100644 Bitkit/Models/HwWalletId.swift create mode 100644 Bitkit/Services/HwWalletRepo.swift create mode 100644 BitkitTests/HwWalletRepoTests.swift diff --git a/Bitkit/AppScene.swift b/Bitkit/AppScene.swift index 1507d7d06..646e4c67a 100644 --- a/Bitkit/AppScene.swift +++ b/Bitkit/AppScene.swift @@ -31,7 +31,8 @@ struct AppScene: View { @StateObject private var pubkyProfile = PubkyProfileManager() @StateObject private var contactsManager = ContactsManager() @State private var keyboardManager = KeyboardManager() - @State private var trezorViewModel = TrezorViewModel() + @State private var trezorViewModel: TrezorViewModel + @State private var hwWalletRepo: HwWalletRepo @State private var calculatorInputManager = CalculatorInputManager() @State private var hideSplash = false @@ -82,6 +83,10 @@ struct AppScene: View { _transferTracking = StateObject(wrappedValue: TransferTrackingManager(service: transferService)) + let trezor = TrezorViewModel() + _trezorViewModel = State(initialValue: trezor) + _hwWalletRepo = State(initialValue: HwWalletRepo(trezor: trezor)) + CoreService.shared.activity.setPrivatePaykitContactResolvers( invoice: { paymentHash in await PrivatePaykitService.shared.contactPublicKey(forPrivateInvoicePaymentHash: paymentHash) @@ -149,6 +154,7 @@ struct AppScene: View { .environmentObject(contactsManager) .environment(keyboardManager) .environment(trezorViewModel) + .environment(hwWalletRepo) .environment(calculatorInputManager) .onChange(of: pubkyProfile.authState, initial: true) { _, authState in if authState == .authenticated, let pk = pubkyProfile.publicKey { @@ -470,6 +476,9 @@ struct AppScene: View { await checkAndPerformRNMigration() try wallet.setWalletExistsState() + // Start watch-only hardware-wallet watchers (no-op until a device is paired). + hwWalletRepo.start() + // Setup TimedSheetManager with all timed sheets TimedSheetManager.shared.setup( sheetViewModel: sheets, @@ -601,6 +610,7 @@ struct AppScene: View { } if newPhase == .active { + hwWalletRepo.onAppForegrounded() if wallet.walletExists == true { Task { await clearDeliveredNotifications() diff --git a/Bitkit/Models/HwWallet.swift b/Bitkit/Models/HwWallet.swift index 37d566c1f..62b078cee 100644 --- a/Bitkit/Models/HwWallet.swift +++ b/Bitkit/Models/HwWallet.swift @@ -2,30 +2,34 @@ import BitkitCore import Foundation /// A paired hardware wallet tracked as a watch-only balance. +/// +/// Activities are NOT held here — they are persisted in bitkit-core scoped by `walletId` +/// and read back through the normal activity pipeline (see `HwWalletRepo`). struct HwWallet: Identifiable { let id: String + /// bitkit-core wallet id scoping this device's activities (see `HwWalletId`). + let walletId: String let name: String let model: String? let isConnected: Bool let balanceSats: UInt64 - let activities: [Activity] let deviceIds: Set init( id: String, + walletId: String, name: String, model: String?, isConnected: Bool, balanceSats: UInt64, - activities: [Activity], deviceIds: Set? = nil ) { self.id = id + self.walletId = walletId self.name = name self.model = model self.isConnected = isConnected self.balanceSats = balanceSats - self.activities = activities self.deviceIds = deviceIds ?? [id] } } diff --git a/Bitkit/Models/HwWalletId.swift b/Bitkit/Models/HwWalletId.swift new file mode 100644 index 000000000..40ffbd2d3 --- /dev/null +++ b/Bitkit/Models/HwWalletId.swift @@ -0,0 +1,24 @@ +import CryptoKit +import Foundation + +/// Derives a stable, app-level wallet id for a paired hardware wallet, used to scope its +/// activities in bitkit-core's wallet-scoped storage (core 0.3.x). +/// +/// ⚠️ INTERIM / PROVISIONAL. bitkit-core does not derive this — it only ships the default +/// `"bitkit"` id (`getDefaultWalletId()`), and the Android app has not yet adopted +/// wallet-scoped hardware storage. The exact format MUST be agreed cross-platform before +/// release so iOS and Android produce identical ids for the same device. This is the single +/// source of the derivation: swap it here when the shared scheme is finalized. +enum HwWalletId { + private static let prefix = "trezor:" + + /// Deterministic id derived from the device's account xpubs (transport-independent: the + /// same physical device paired over different transports shares its xpubs, hence its id). + /// Falls back to the device id when no xpubs were captured. + static func derive(xpubs: [String: String], fallbackId: String) -> String { + let sorted = xpubs.values.sorted() + guard !sorted.isEmpty else { return prefix + fallbackId } + let digest = SHA256.hash(data: Data(sorted.joined(separator: "\n").utf8)) + return prefix + Data(digest).hex + } +} diff --git a/Bitkit/Services/HwWalletRepo.swift b/Bitkit/Services/HwWalletRepo.swift new file mode 100644 index 000000000..6b62b26b1 --- /dev/null +++ b/Bitkit/Services/HwWalletRepo.swift @@ -0,0 +1,466 @@ +import BitkitCore +import Combine +import Foundation + +/// Production hardware-wallet business layer. Tracks paired Trezor devices as watch-only +/// balances by running one on-chain xpub watcher per (device, address type), aggregating the +/// per-device balance in memory, and persisting each device's on-chain activity into +/// bitkit-core scoped by a derived `walletId` (core 0.3.x wallet-scoped storage). +/// +/// Built on top of `TrezorViewModel`, which owns the device list, connect orchestration and the +/// underlying watcher transport. Adapts bitkit-android's `HwWalletRepo`. iOS supports Bluetooth +/// only, so the cross-transport (BLE+USB) dedup is reduced to a plain xpub-based identity and +/// USB-specific reconnect handling is omitted. +@Observable +@MainActor +final class HwWalletRepo { + private enum Constants { + static let watcherIdSeparator = "|" + static let watcherStartRetryDelay: Duration = .seconds(30) + static let defaultGapLimit: UInt32 = 20 + } + + // MARK: - Published state + + /// Paired hardware wallets, one per physical device, with aggregated balance. + private(set) var wallets: [HwWallet] = [] + + /// Sum of every paired wallet's balance. + private(set) var totalSats: UInt64 = 0 + + /// bitkit-core wallet ids for the paired hardware wallets — the activity list queries these. + private(set) var hwWalletIds: Set = [] + + /// Whether the known-device store has been read at least once. + private(set) var walletsLoaded = false + + /// Inbound transactions detected by a running watcher after its initial history sync. + let receivedTxPublisher = PassthroughSubject() + + // MARK: - Dependencies + + private weak var trezor: TrezorViewModel? + private let watcherService: TrezorWatcherServicing + private let monitoredTypesProvider: () -> Set + private let electrumUrlProvider: () -> String + private let networkProvider: () -> TrezorCoinType + private let persistActivities: ([Activity]) -> Void + private let deleteActivities: (String) -> Void + + // MARK: - Internal state + + private var knownDevices: [TrezorKnownDevice] = [] + private var connectedDeviceId: String? + private var watcherData: [String: HwWatcherData] = [:] + private var activeWatchers: Set = [] + private var activeWatcherElectrumUrls: [String: String] = [:] + private var retryingWatcherStarts: Set = [] + private var emittedReceivedTxIds: Set = [] + private var listeners: [String: TrezorEventListener] = [:] + + init( + trezor: TrezorViewModel? = nil, + watcherService: TrezorWatcherServicing = TrezorService.shared, + monitoredTypes: (() -> Set)? = nil, + electrumUrl: (() -> String)? = nil, + network: (() -> TrezorCoinType)? = nil, + persistActivities: (([Activity]) -> Void)? = nil, + deleteActivities: ((String) -> Void)? = nil + ) { + self.trezor = trezor + self.watcherService = watcherService + networkProvider = network ?? { TrezorViewModel.appDefaultCoinType } + monitoredTypesProvider = monitoredTypes ?? { + Set(SettingsViewModel.shared.addressTypesToMonitor.map(\.stringValue)) + } + electrumUrlProvider = electrumUrl ?? { TrezorViewModel.getElectrumUrl() } + self.persistActivities = persistActivities ?? { activities in + guard !activities.isEmpty else { return } + Task { + try? await ServiceQueue.background(.core) { + try BitkitCore.upsertActivities(activities: activities) + } + } + } + self.deleteActivities = deleteActivities ?? { walletId in + Task { + try? await ServiceQueue.background(.core) { + _ = try BitkitCore.deleteActivitiesByWalletId(walletId: walletId) + } + } + } + } + + // MARK: - Lifecycle + + /// Begin observing the Trezor device state and start the initial watcher sync. + func start() { + observeTrezorState() + refreshFromTrezor() + } + + /// Re-read device state and monitored settings, then reconcile watchers. + func refresh() { + refreshFromTrezor() + } + + /// On app foreground, ask the Trezor layer to reconnect a known device so the connection + /// indicator turns green again; watch-only balances stay live regardless. + func onAppForegrounded() { + guard let trezor else { return } + Task { await trezor.autoReconnect() } + } + + private func refreshFromTrezor() { + guard let trezor else { + syncWatchers() + recomputeDerivedState() + return + } + updateDevices(knownDevices: trezor.knownDevices, connectedDeviceId: trezor.connectedDevice?.id) + } + + private func observeTrezorState() { + guard let trezor else { return } + withObservationTracking { + _ = trezor.knownDevices.map { "\($0.id):\($0.xpubs.count)" } + _ = trezor.connectedDevice?.id + } onChange: { [weak self] in + Task { @MainActor in + guard let self else { return } + self.refreshFromTrezor() + self.observeTrezorState() + } + } + } + + /// Update the device snapshot and reconcile watchers. Exposed for tests so the engine can be + /// exercised without a live `TrezorViewModel`. + func updateDevices(knownDevices: [TrezorKnownDevice], connectedDeviceId: String?) { + self.knownDevices = knownDevices + self.connectedDeviceId = connectedDeviceId + walletsLoaded = true + syncWatchers() + recomputeDerivedState() + } + + // MARK: - Pairing passthroughs + + var needsPairingCode: Bool { + trezor?.showPairingCode ?? false + } + + func submitPairingCode(_ code: String) { + trezor?.submitPairingCode(code) + } + + func cancelPairingCode() { + trezor?.cancelPairingCode() + } + + // MARK: - Control + + func resetState() { + for watcherId in activeWatchers { + try? watcherService.stopWatcher(watcherId: watcherId) + } + for walletId in hwWalletIds { + deleteActivities(walletId) + } + activeWatchers.removeAll() + activeWatcherElectrumUrls.removeAll() + retryingWatcherStarts.removeAll() + emittedReceivedTxIds.removeAll() + listeners.removeAll() + watcherData.removeAll() + recomputeDerivedState() + } + + /// Remove a paired hardware wallet: stop its watchers, delete its stored activities, and + /// forget every device entry that shares the same xpub-derived identity, so the tile doesn't + /// reappear through another entry. + func removeDevice(id deviceId: String) async { + let group = deviceGroups().first { $0.ids.contains(deviceId) } + let ids = group?.ids ?? [deviceId] + for watcherId in activeWatchers where ids.contains(self.deviceId(fromWatcherId: watcherId)) { + _ = stopActiveWatcher(watcherId) + } + if let group { deleteActivities(group.walletId) } + if let trezor { + for id in ids { + await trezor.forgetDevice(id: id) + } + } + refreshFromTrezor() + } + + // MARK: - Watcher orchestration + + func syncWatchers() { + let monitored = monitoredTypesProvider() + let electrumUrl = electrumUrlProvider() + + var seen = Set() + var specs: [WatcherSpec] = [] + for device in knownDevices { + for (addressType, xpub) in device.xpubs where monitored.contains(addressType) { + guard seen.insert("\(addressType)\u{1}\(xpub)").inserted else { continue } + specs.append(WatcherSpec(deviceId: device.id, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) + } + } + let desiredIds = Set(specs.map(\.watcherId)) + + for spec in specs { + let isActive = activeWatchers.contains(spec.watcherId) + if isActive, activeWatcherElectrumUrls[spec.watcherId] == spec.electrumUrl { continue } + if isActive, !stopActiveWatcher(spec.watcherId) { continue } + startWatcher(spec) + } + + // A failed stop stays active so the next sync retries it; dropping it here would leave the + // orphaned watcher feeding watcherData as a ghost balance. + for staleId in activeWatchers.subtracting(desiredIds) { + _ = stopActiveWatcher(staleId) + } + } + + private func startWatcher(_ spec: WatcherSpec) { + guard let addressType = HwAddressType(settingsString: spec.addressType) else { return } + let network = networkProvider() + let params = WatcherParams( + watcherId: spec.watcherId, + extendedKey: spec.xpub, + electrumUrl: spec.electrumUrl, + network: toNetwork(network), + accountType: addressType.accountType, + gapLimit: Constants.defaultGapLimit + ) + let listener = TrezorEventListener { [weak self] id, event in + self?.handleWatcherEvent(watcherId: id, event: event) + } + listeners[spec.watcherId] = listener + + Task { @MainActor in + do { + try await watcherService.startWatcher(params: params, listener: listener) + activeWatchers.insert(spec.watcherId) + activeWatcherElectrumUrls[spec.watcherId] = spec.electrumUrl + retryingWatcherStarts.remove(spec.watcherId) + } catch { + listeners[spec.watcherId] = nil + Logger.warn("Retrying hardware watcher '\(spec.watcherId)' after start failure: \(error)") + scheduleWatcherStartRetry(spec.watcherId) + } + } + } + + @discardableResult + private func stopActiveWatcher(_ watcherId: String) -> Bool { + do { + try watcherService.stopWatcher(watcherId: watcherId) + activeWatchers.remove(watcherId) + activeWatcherElectrumUrls[watcherId] = nil + watcherData[watcherId] = nil + listeners[watcherId] = nil + return true + } catch { + return false + } + } + + private func scheduleWatcherStartRetry(_ watcherId: String) { + guard retryingWatcherStarts.insert(watcherId).inserted else { return } + Task { @MainActor in + try? await Task.sleep(for: Constants.watcherStartRetryDelay) + retryingWatcherStarts.remove(watcherId) + syncWatchers() + } + } + + // MARK: - Watcher events + + /// Update aggregated state from a watcher event. The first event after a watcher starts + /// delivers the full history (baseline); only later inbound txs are surfaced as received. + func handleWatcherEvent(watcherId: String, event: WatcherEvent) { + guard case let .transactionsChanged(transactions, balance, _, _, _) = event else { return } + let previous = watcherData[watcherId] + watcherData[watcherId] = HwWatcherData( + deviceId: deviceId(fromWatcherId: watcherId), + balanceSats: balance.total, + transactions: transactions + ) + recomputeDerivedState() + persistGroupActivities(forDevice: deviceId(fromWatcherId: watcherId)) + emitReceivedTxs(previous: previous, transactions: transactions) + } + + private func emitReceivedTxs(previous: HwWatcherData?, transactions: [HistoryTransaction]) { + guard let previous else { return } + let knownTxIds = Set(previous.transactions.map(\.txid)) + for tx in transactions where tx.direction == .received { + guard !knownTxIds.contains(tx.txid) else { continue } + guard emittedReceivedTxIds.insert(tx.txid).inserted else { continue } + receivedTxPublisher.send(HwWalletReceivedTx(txid: tx.txid, sats: tx.amount)) + } + } + + // MARK: - Persistence + + private func persistGroupActivities(forDevice deviceId: String) { + guard let group = deviceGroups().first(where: { $0.ids.contains(deviceId) }) else { return } + persistActivities(mergedActivities(for: group)) + } + + private func mergedActivities(for group: DeviceGroup) -> [Activity] { + let watchers = watcherData.values.filter { group.ids.contains($0.deviceId) } + let grouped = Dictionary(grouping: watchers.flatMap(\.transactions), by: \.txid) + return grouped.values.map { transactions in + let timestamp = transactions.compactMap(\.timestamp).min() ?? 0 + return onchainActivity(walletId: group.walletId, from: transactions, timestamp: timestamp) + } + } + + // MARK: - Aggregation + + private func recomputeDerivedState() { + let groups = deviceGroups() + + wallets = groups.map { group in + let connectedDevice = group.devices.first { $0.id == connectedDeviceId } + let device = connectedDevice ?? group.representative + let deviceWatchers = watcherData.values.filter { group.ids.contains($0.deviceId) } + return HwWallet( + id: device.id, + walletId: group.walletId, + name: displayName(of: device), + model: device.model, + isConnected: connectedDevice != nil, + balanceSats: deviceWatchers.reduce(UInt64(0)) { saturatingAdd($0, $1.balanceSats) }, + deviceIds: group.ids + ) + } + + totalSats = wallets.reduce(UInt64(0)) { saturatingAdd($0, $1.balanceSats) } + hwWalletIds = Set(groups.map(\.walletId)) + } + + /// Group device entries sharing an xpub identity (same physical device over different + /// transports), preserving first-seen order. Entries without captured xpubs are skipped. + private func deviceGroups() -> [DeviceGroup] { + var order: [String] = [] + var grouped: [String: [TrezorKnownDevice]] = [:] + for device in knownDevices where !device.xpubs.isEmpty { + let walletId = HwWalletId.derive(xpubs: device.xpubs, fallbackId: device.id) + if grouped[walletId] == nil { order.append(walletId) } + grouped[walletId, default: []].append(device) + } + return order.compactMap { walletId in + guard let devices = grouped[walletId] else { return nil } + return DeviceGroup(walletId: walletId, devices: devices) + } + } + + private func onchainActivity(walletId: String, from transactions: [HistoryTransaction], timestamp: UInt64) -> Activity { + let first = transactions[0] + let received = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.received) } + let sent = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.sent) } + let fee = transactions.compactMap(\.fee).max() ?? 0 + let txType: PaymentType = received > sent ? .received : .sent + let value: UInt64 + switch txType { + case .received: + value = received >= sent ? received - sent : 0 + case .sent: + let net = sent >= received ? sent - received : 0 + value = net >= fee ? net - fee : 0 + } + let confirmations = transactions.map(\.confirmations).max() ?? 0 + let confirmed = confirmations > 0 + return .onchain( + OnchainActivity( + walletId: walletId, + id: first.txid, + txType: txType, + txId: first.txid, + value: value, + fee: fee, + feeRate: 1, + address: "", + confirmed: confirmed, + timestamp: timestamp, + isBoosted: false, + boostTxIds: [], + isTransfer: false, + doesExist: true, + confirmTimestamp: confirmed ? timestamp : nil, + channelId: nil, + transferTxId: nil, + contact: nil, + createdAt: timestamp, + updatedAt: timestamp, + seenAt: nil + ) + ) + } + + // MARK: - Helpers + + /// The label is the user-set name stored on the device; without one (or with the factory + /// default that mirrors the model), fall back to the vendor-prefixed model. + private func displayName(of device: TrezorKnownDevice) -> String { + if let label = device.label, label != device.model { return label } + guard let model = device.model else { return "Trezor" } + return model.hasPrefix("Trezor") ? model : "Trezor \(model)" + } + + private func deviceId(fromWatcherId watcherId: String) -> String { + guard let range = watcherId.range(of: Constants.watcherIdSeparator) else { return watcherId } + return String(watcherId[.. BitkitCore.Network { + switch coin { + case .bitcoin: .bitcoin + case .testnet: .testnet + case .signet: .signet + case .regtest: .regtest + } + } + + private func saturatingAdd(_ a: UInt64, _ b: UInt64) -> UInt64 { + let (sum, overflow) = a.addingReportingOverflow(b) + return overflow ? .max : sum + } + + // MARK: - Supporting types + + private struct WatcherSpec { + let deviceId: String + let addressType: String + let xpub: String + let electrumUrl: String + + var watcherId: String { + "\(deviceId)\(Constants.watcherIdSeparator)\(addressType)" + } + } + + private struct DeviceGroup { + let walletId: String + let devices: [TrezorKnownDevice] + + var ids: Set { + Set(devices.map(\.id)) + } + + var representative: TrezorKnownDevice { + devices.max(by: { $0.lastConnectedAt < $1.lastConnectedAt }) ?? devices[0] + } + } + + private struct HwWatcherData { + let deviceId: String + let balanceSats: UInt64 + let transactions: [HistoryTransaction] + } +} diff --git a/BitkitTests/HwWalletRepoTests.swift b/BitkitTests/HwWalletRepoTests.swift new file mode 100644 index 000000000..3d23d718a --- /dev/null +++ b/BitkitTests/HwWalletRepoTests.swift @@ -0,0 +1,266 @@ +@testable import Bitkit +import BitkitCore +import Combine +import XCTest + +/// Engine tests for `HwWalletRepo`, adapting bitkit-android's `HwWalletRepoTest`. +/// The engine is driven directly (no live `TrezorViewModel`) via `updateDevices` and +/// `handleWatcherEvent`, with spies for the bitkit-core persistence side. +@MainActor +final class HwWalletRepoTests: XCTestCase { + // MARK: - Mocks & spies + + private final class MockWatcherService: TrezorWatcherServicing, @unchecked Sendable { + private(set) var startedParams: [WatcherParams] = [] + private(set) var stoppedWatcherIds: [String] = [] + + func startWatcher(params: WatcherParams, listener _: EventListener) async throws { + startedParams.append(params) + } + + func stopWatcher(watcherId: String) throws { + stoppedWatcherIds.append(watcherId) + } + + func stopAllWatchers() {} + } + + private var persisted: [[Activity]] = [] + private var deleted: [String] = [] + private var receivedTxs: [HwWalletReceivedTx] = [] + private var cancellables: Set = [] + + override func setUp() { + super.setUp() + persisted = [] + deleted = [] + receivedTxs = [] + cancellables = [] + } + + // MARK: - Factories + + private func makeViewModel( + watcherService: TrezorWatcherServicing = MockWatcherService(), + monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"] + ) -> HwWalletRepo { + let vm = HwWalletRepo( + trezor: nil, + watcherService: watcherService, + monitoredTypes: { monitored }, + electrumUrl: { "ssl://test:1" }, + network: { .regtest }, + persistActivities: { [weak self] in self?.persisted.append($0) }, + deleteActivities: { [weak self] in self?.deleted.append($0) } + ) + vm.receivedTxPublisher + .sink { [weak self] in self?.receivedTxs.append($0) } + .store(in: &cancellables) + return vm + } + + private func makeDevice( + id: String, + xpubs: [String: String], + label: String? = nil, + model: String? = "Safe 5", + lastConnectedAt: Date = Date(timeIntervalSince1970: 1000) + ) -> TrezorKnownDevice { + TrezorKnownDevice( + id: id, + name: id, + path: "ble:\(id)", + transportType: "bluetooth", + label: label, + model: model, + lastConnectedAt: lastConnectedAt, + xpubs: xpubs + ) + } + + private func makeTx( + txid: String, + received: UInt64, + sent: UInt64, + fee: UInt64? = nil, + direction: TxDirection, + confirmations: UInt32 = 1, + timestamp: UInt64? = 1_700_000_000 + ) -> HistoryTransaction { + let amount: UInt64 = direction == .received ? received : (sent >= received ? sent - received : 0) + return HistoryTransaction( + txid: txid, + received: received, + sent: sent, + net: Int64(received) - Int64(sent), + fee: fee, + amount: amount, + direction: direction, + blockHeight: confirmations > 0 ? 100 : nil, + timestamp: timestamp, + confirmations: confirmations + ) + } + + private func makeEvent(_ transactions: [HistoryTransaction], total: UInt64) -> WatcherEvent { + let balance = WalletBalance( + confirmed: total, immature: 0, trustedPending: 0, untrustedPending: 0, spendable: total, total: total + ) + return .transactionsChanged( + transactions: transactions, balance: balance, txCount: UInt32(transactions.count), blockHeight: 100, accountType: .nativeSegwit + ) + } + + private func watcherId(_ deviceId: String, _ addressType: String) -> String { + "\(deviceId)|\(addressType)" + } + + // MARK: - Tests + + func testPairedDeviceProducesWalletWithBalanceAndWalletId() { + let xpubs = ["nativeSegwit": "zpubNS"] + let device = makeDevice(id: "dev1", xpubs: xpubs, model: "Safe 5") + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "tx1", received: 50000, sent: 0, direction: .received)], total: 50000 + )) + + XCTAssertEqual(vm.wallets.count, 1) + let wallet = vm.wallets[0] + XCTAssertEqual(wallet.id, "dev1") + XCTAssertEqual(wallet.balanceSats, 50000) + XCTAssertEqual(wallet.name, "Trezor Safe 5") + XCTAssertTrue(wallet.isConnected) + XCTAssertEqual(vm.totalSats, 50000) + XCTAssertEqual(wallet.walletId, HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1")) + XCTAssertEqual(vm.hwWalletIds, [wallet.walletId]) + } + + func testBalanceAggregatesAcrossAddressTypes() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS", "taproot": "zpubTR"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "txNS", received: 30000, sent: 0, direction: .received)], total: 30000 + )) + vm.handleWatcherEvent(watcherId: watcherId("dev1", "taproot"), event: makeEvent( + [makeTx(txid: "txTR", received: 20000, sent: 0, direction: .received)], total: 20000 + )) + + XCTAssertEqual(vm.wallets.count, 1) + XCTAssertEqual(vm.wallets[0].balanceSats, 50000) + XCTAssertFalse(vm.wallets[0].isConnected) + } + + func testSamePhysicalDeviceDedupedByXpub() { + // Same xpubs, two device entries (e.g. re-paired) → one wallet, one walletId. + let xpubs = ["nativeSegwit": "zpubShared"] + let ble = makeDevice(id: "ble1", xpubs: xpubs, lastConnectedAt: Date(timeIntervalSince1970: 1000)) + let usb = makeDevice(id: "usb1", xpubs: xpubs, lastConnectedAt: Date(timeIntervalSince1970: 2000)) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [ble, usb], connectedDeviceId: nil) + + vm.handleWatcherEvent(watcherId: watcherId("ble1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "tx1", received: 70000, sent: 0, direction: .received)], total: 70000 + )) + + XCTAssertEqual(vm.wallets.count, 1) + XCTAssertEqual(vm.wallets[0].deviceIds, ["ble1", "usb1"]) + // Representative is the most recently connected entry. + XCTAssertEqual(vm.wallets[0].id, "usb1") + XCTAssertEqual(vm.hwWalletIds.count, 1) + } + + func testActivityPersistedWithDeviceWalletId() { + let xpubs = ["nativeSegwit": "zpubNS"] + let device = makeDevice(id: "dev1", xpubs: xpubs) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "txABC", received: 40000, sent: 0, direction: .received)], total: 40000 + )) + + let expectedWalletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + XCTAssertEqual(persisted.count, 1) + let activities = persisted[0] + XCTAssertEqual(activities.count, 1) + guard case let .onchain(onchain) = activities[0] else { return XCTFail("expected onchain activity") } + XCTAssertEqual(onchain.walletId, expectedWalletId) + XCTAssertEqual(onchain.txId, "txABC") + XCTAssertEqual(onchain.txType, .received) + XCTAssertEqual(onchain.value, 40000) + } + + func testReceivedTxDetection() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + let wid = watcherId("dev1", "nativeSegwit") + + // Baseline (first event) — must NOT emit, even for received txs. + vm.handleWatcherEvent(watcherId: wid, event: makeEvent( + [makeTx(txid: "old", received: 10000, sent: 0, direction: .received)], total: 10000 + )) + XCTAssertTrue(receivedTxs.isEmpty) + + // New inbound tx after baseline — emits once. + vm.handleWatcherEvent(watcherId: wid, event: makeEvent( + [ + makeTx(txid: "old", received: 10000, sent: 0, direction: .received), + makeTx(txid: "new", received: 25000, sent: 0, direction: .received), + ], total: 35000 + )) + XCTAssertEqual(receivedTxs.map(\.txid), ["new"]) + XCTAssertEqual(receivedTxs.first?.sats, 25000) + + // Outbound tx is ignored, and the same inbound is not re-emitted. + vm.handleWatcherEvent(watcherId: wid, event: makeEvent( + [ + makeTx(txid: "old", received: 10000, sent: 0, direction: .received), + makeTx(txid: "new", received: 25000, sent: 0, direction: .received), + makeTx(txid: "spend", received: 0, sent: 5000, fee: 200, direction: .sent), + ], total: 30000 + )) + XCTAssertEqual(receivedTxs.map(\.txid), ["new"]) + } + + func testMonitoredAddressTypeFiltering() async { + let mock = MockWatcherService() + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS", "taproot": "zpubTR"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + await waitUntil { mock.startedParams.count == 1 } + XCTAssertEqual(mock.startedParams.count, 1) + XCTAssertEqual(mock.startedParams.first?.watcherId, watcherId("dev1", "nativeSegwit")) + } + + func testResetStateDeletesStoredActivitiesAndClears() { + let xpubs = ["nativeSegwit": "zpubNS"] + let device = makeDevice(id: "dev1", xpubs: xpubs) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "tx1", received: 40000, sent: 0, direction: .received)], total: 40000 + )) + + let walletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + vm.resetState() + + XCTAssertEqual(deleted, [walletId]) + XCTAssertEqual(vm.totalSats, 0) + } + + // MARK: - Helpers + + private func waitUntil(timeout: TimeInterval = 2, _ condition: () -> Bool) async { + let deadline = Date().addingTimeInterval(timeout) + while !condition(), Date() < deadline { + try? await Task.sleep(nanoseconds: 10_000_000) + } + } +} From 4f8a292e560e36e3fdb926c29ce02139458ac05c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 14:20:06 -0300 Subject: [PATCH 04/52] feat: balance + home device row --- .../Contents.json | 16 +++ .../bluetooth-connected.svg | 8 ++ Bitkit/Components/HardwareWalletsGrid.swift | 98 +++++++++++++++++++ .../Trezor/HwWalletConnectionIcon.swift | 30 ++++++ .../Localization/en.lproj/Localizable.strings | 2 + Bitkit/Views/Home/HomeWalletView.swift | 16 ++- 6 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/Contents.json create mode 100644 Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/bluetooth-connected.svg create mode 100644 Bitkit/Components/HardwareWalletsGrid.swift create mode 100644 Bitkit/Components/Trezor/HwWalletConnectionIcon.swift diff --git a/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/Contents.json b/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/Contents.json new file mode 100644 index 000000000..3625a5352 --- /dev/null +++ b/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "bluetooth-connected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/bluetooth-connected.svg b/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/bluetooth-connected.svg new file mode 100644 index 000000000..9acbaa7dc --- /dev/null +++ b/Bitkit/Assets.xcassets/icons/bluetooth-connected.imageset/bluetooth-connected.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Bitkit/Components/HardwareWalletsGrid.swift b/Bitkit/Components/HardwareWalletsGrid.swift new file mode 100644 index 000000000..b0da4cdb6 --- /dev/null +++ b/Bitkit/Components/HardwareWalletsGrid.swift @@ -0,0 +1,98 @@ +import SwiftUI + +/// Two-column grid of paired hardware wallets shown on Home, under the Savings/Spending tiles. +/// Mirrors bitkit-android's `HwDevices` (rows chunked in pairs, divided like the on-chain tiles). +struct HardwareWalletsGrid: View { + let wallets: [HwWallet] + let onTap: (HwWallet) -> Void + + private var rows: [[HwWallet]] { + stride(from: 0, to: wallets.count, by: 2).map { Array(wallets[$0 ..< min($0 + 2, wallets.count)]) } + } + + var body: some View { + VStack(spacing: 16) { + ForEach(Array(rows.enumerated()), id: \.offset) { _, row in + HStack(spacing: 16) { + HardwareWalletCell(wallet: row[0], onTap: onTap) + + CustomDivider(color: .gray4, type: .vertical) + + if row.count > 1 { + HardwareWalletCell(wallet: row[1], onTap: onTap) + } else { + Color.clear.frame(maxWidth: .infinity) + } + } + .frame(height: 50) + } + } + } +} + +private struct HardwareWalletCell: View { + let wallet: HwWallet + let onTap: (HwWallet) -> Void + + var body: some View { + Button { + onTap(wallet) + } label: { + VStack(alignment: .leading) { + CaptionMText(wallet.name) + .lineLimit(1) + .padding(.bottom, 4) + + HStack(spacing: 4) { + Image("btc-circle-blue") + .resizable() + .scaledToFit() + .frame(width: 24, height: 24) + .padding(.trailing, 4) + + MoneyText( + sats: Int(clamping: wallet.balanceSats), + size: .subtitle, + enableHide: true, + symbolColor: .textPrimary + ) + + HwWalletConnectionIcon(isConnected: wallet.isConnected) + .frame(width: 16, height: 16) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .buttonStyle(.plain) + .accessibilityIdentifier("ActivityHardware") + } +} + +#Preview { + func wallet(_ id: String, _ name: String, connected: Bool, sats: UInt64) -> HwWallet { + HwWallet(id: id, walletId: "trezor:\(id)", name: name, model: name, isConnected: connected, balanceSats: sats) + } + + return VStack(spacing: 32) { + // Single device + HardwareWalletsGrid( + wallets: [wallet("1", "Trezor Safe 5", connected: true, sats: 1_234_567)], + onTap: { _ in } + ) + + CustomDivider() + + // Two devices (full 2-column row), one connected, one not + HardwareWalletsGrid( + wallets: [ + wallet("1", "Trezor Safe 5", connected: true, sats: 1_234_567), + wallet("2", "Trezor Model T", connected: false, sats: 89000), + ], + onTap: { _ in } + ) + } + .padding() + .environmentObject(CurrencyViewModel()) + .environmentObject(SettingsViewModel.shared) + .preferredColorScheme(.dark) +} diff --git a/Bitkit/Components/Trezor/HwWalletConnectionIcon.swift b/Bitkit/Components/Trezor/HwWalletConnectionIcon.swift new file mode 100644 index 000000000..91fb9a04a --- /dev/null +++ b/Bitkit/Components/Trezor/HwWalletConnectionIcon.swift @@ -0,0 +1,30 @@ +import SwiftUI + +/// Bluetooth connection indicator for a paired hardware wallet. iOS supports Bluetooth only, +/// so there is a single transport glyph — tinted green when connected, gray when disconnected. +/// Mirrors bitkit-android's `HwWalletConnectionIcon` (BLE branch). +struct HwWalletConnectionIcon: View { + let isConnected: Bool + + var body: some View { + Image("bluetooth-connected") + .renderingMode(.template) + .resizable() + .scaledToFit() + .foregroundColor(isConnected ? .greenAccent : .gray1) + .accessibilityLabel( + isConnected + ? t("hardware__connection_badge_connected_bluetooth") + : t("hardware__connection_badge_disconnected_bluetooth") + ) + } +} + +#Preview { + HStack(spacing: 24) { + HwWalletConnectionIcon(isConnected: true).frame(width: 16, height: 16) + HwWalletConnectionIcon(isConnected: false).frame(width: 16, height: 16) + } + .padding() + .preferredColorScheme(.dark) +} diff --git a/Bitkit/Resources/Localization/en.lproj/Localizable.strings b/Bitkit/Resources/Localization/en.lproj/Localizable.strings index 3d36cb1f8..234181839 100644 --- a/Bitkit/Resources/Localization/en.lproj/Localizable.strings +++ b/Bitkit/Resources/Localization/en.lproj/Localizable.strings @@ -31,6 +31,8 @@ "cards__support__description" = "Get assistance"; "cards__hardware__title" = "Hardware"; "cards__hardware__description" = "Connect device"; +"hardware__connection_badge_connected_bluetooth" = "Connected via Bluetooth"; +"hardware__connection_badge_disconnected_bluetooth" = "Disconnected via Bluetooth"; "hardware__intro_title" = "Hardware Wallet"; "hardware__intro_header" = "Add your hardware wallet"; "hardware__intro_text" = "Connect your hardware device to watch or manage your long-term funds."; diff --git a/Bitkit/Views/Home/HomeWalletView.swift b/Bitkit/Views/Home/HomeWalletView.swift index 603ff6d29..36cbcdf46 100644 --- a/Bitkit/Views/Home/HomeWalletView.swift +++ b/Bitkit/Views/Home/HomeWalletView.swift @@ -5,15 +5,22 @@ struct HomeWalletView: View { @EnvironmentObject var app: AppViewModel @EnvironmentObject var settings: SettingsViewModel @EnvironmentObject var wallet: WalletViewModel + @Environment(HwWalletRepo.self) private var hwWalletRepo var hasActivity: Bool { return activity.latestActivities?.isEmpty == false } + /// Headline total including watch-only hardware-wallet balances (keeps `totalBalanceSats` + /// semantics unchanged for send/transfer logic; only the headline folds hardware in). + private var headlineSats: Int { + wallet.totalBalanceSats + Int(clamping: hwWalletRepo.totalSats) + } + var body: some View { VStack(spacing: 0) { MoneyStack( - sats: wallet.totalBalanceSats, + sats: headlineSats, showSymbol: true, showEyeIcon: true, enableSwipeGesture: settings.swipeBalanceToHide, @@ -43,6 +50,13 @@ struct HomeWalletView: View { .frame(height: 50) .padding(.bottom, 32) + if !hwWalletRepo.wallets.isEmpty { + HardwareWalletsGrid(wallets: hwWalletRepo.wallets) { _ in + app.toast(type: .info, title: t("coming_soon__nav_title")) + } + .padding(.bottom, 32) + } + if hasActivity { ActivityLatest() From 02f2dfc7e65b9b5194a2e9db3ac8216ced9e4fa9 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 14:44:23 -0300 Subject: [PATCH 05/52] feat: hardware suggestion and sheet --- .../ledger.imageset/Contents.json | 12 +++ .../Illustrations/ledger.imageset/ledger.webp | Bin 0 -> 97258 bytes .../trezor.imageset/Contents.json | 12 +++ .../Illustrations/trezor.imageset/trezor.webp | Bin 0 -> 129882 bytes .../Trezor/HwDeviceIllustrations.swift | 45 +++++++++++ Bitkit/Components/Widgets/Suggestions.swift | 39 +++++----- Bitkit/MainNavView.swift | 27 +++++++ Bitkit/ViewModels/SheetViewModel.swift | 26 +++++++ Bitkit/Views/Sheets/HardwareIntroSheet.swift | 47 ++++++++++++ .../Views/Sheets/HardwarePairingSheet.swift | 72 ++++++++++++++++++ Bitkit/Views/Trezor/TrezorRootView.swift | 5 +- 11 files changed, 265 insertions(+), 20 deletions(-) create mode 100644 Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json create mode 100644 Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.webp create mode 100644 Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json create mode 100644 Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.webp create mode 100644 Bitkit/Components/Trezor/HwDeviceIllustrations.swift create mode 100644 Bitkit/Views/Sheets/HardwareIntroSheet.swift create mode 100644 Bitkit/Views/Sheets/HardwarePairingSheet.swift diff --git a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json new file mode 100644 index 000000000..abc1d8499 --- /dev/null +++ b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ledger.webp", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.webp b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.webp new file mode 100644 index 0000000000000000000000000000000000000000..304b85c78880a7436f08d2215ea2c316e9f4e130 GIT binary patch literal 97258 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 XTglU$_!bouYcqo6^1d_x00000h}lT7 literal 0 HcmV?d00001 diff --git a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json new file mode 100644 index 000000000..6f23bace6 --- /dev/null +++ b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "trezor.webp", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.webp b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.webp new file mode 100644 index 0000000000000000000000000000000000000000..e64e3936fed13e986970cbcd91dc4be7ddfbc59d GIT binary patch literal 129882 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�`1g4` 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ªQePc6050^zpS3u+rC&JmWt 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 An*aa+ literal 0 HcmV?d00001 diff --git a/Bitkit/Components/Trezor/HwDeviceIllustrations.swift b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift new file mode 100644 index 000000000..d192f6db1 --- /dev/null +++ b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift @@ -0,0 +1,45 @@ +import SwiftUI + +/// Staggered hardware-device hero used by the hardware intro sheet: a Trezor bleeding off the +/// left and a blurred Ledger bleeding off the right. Ports bitkit-android's `HwDeviceIllustrations`. +struct HwDeviceIllustrations: View { + private enum Ratio { + static let imageSize: CGFloat = 256.0 / 375.0 + static let trezorBleed: CGFloat = 84.0 / 375.0 + static let ledgerBleed: CGFloat = 53.0 / 375.0 + static let stagger: CGFloat = 12.0 / 375.0 + } + + var body: some View { + GeometryReader { geo in + let width = geo.size.width + let imageSize = width * Ratio.imageSize + let staggerY = width * Ratio.stagger + + ZStack { + Image("trezor") + .resizable() + .scaledToFit() + .frame(width: imageSize, height: imageSize) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) + .offset(x: -width * Ratio.trezorBleed, y: staggerY) + + Image("ledger") + .resizable() + .scaledToFit() + .frame(width: imageSize, height: imageSize) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing) + .offset(x: width * Ratio.ledgerBleed, y: -staggerY) + .blur(radius: 16) + } + } + .accessibilityHidden(true) + } +} + +#Preview { + HwDeviceIllustrations() + .frame(height: 300) + .background(Color.black) + .preferredColorScheme(.dark) +} diff --git a/Bitkit/Components/Widgets/Suggestions.swift b/Bitkit/Components/Widgets/Suggestions.swift index 81b48c2e7..9e910b44d 100644 --- a/Bitkit/Components/Widgets/Suggestions.swift +++ b/Bitkit/Components/Widgets/Suggestions.swift @@ -12,7 +12,7 @@ struct SuggestionCardData: Identifiable, Hashable { enum SuggestionAction: Hashable { case backup case buyBitcoin - // case hardware + case hardware case invite case notifications case profile @@ -34,8 +34,8 @@ enum WalletSuggestionState { /// Max 4 cards are shown; when one is dismissed or completed, the next in this list is shown. private let suggestionOrderByState: [WalletSuggestionState: [String]] = [ .empty: ["buyBitcoin", "transferToSpending", "support", "backupSeedPhrase", "pin", "profile", "invite"], - .onchain: ["backupSeedPhrase", "pin", "transferToSpending", "support", "profile", "invite", "buyBitcoin"], - .spending: ["quickpay", "notifications", "shop", "profile", "support", "invite", "buyBitcoin"], + .onchain: ["backupSeedPhrase", "pin", "transferToSpending", "hardware", "support", "profile", "invite", "buyBitcoin"], + .spending: ["quickpay", "notifications", "shop", "hardware", "profile", "support", "invite", "buyBitcoin"], ] let cards: [SuggestionCardData] = [ @@ -119,14 +119,14 @@ let cards: [SuggestionCardData] = [ color: .brand24, action: .profile ), - // SuggestionCardData( - // id: "hardware", - // title: t("cards__hardware__title"), - // description: t("cards__hardware__description"), - // imageName: "trezor-card", - // color: .blue24, - // action: .hardware - // ), + SuggestionCardData( + id: "hardware", + title: t("cards__hardware__title"), + description: t("cards__hardware__description"), + imageName: "trezor-card", + color: .blue24, + action: .hardware + ), ] private let cardsById: [String: SuggestionCardData] = Dictionary(uniqueKeysWithValues: cards.map { ($0.id, $0) }) @@ -138,8 +138,8 @@ extension SuggestionCardData { return "back_up" case .buyBitcoin: return "buy" - // case .hardware: - // return "hardware" + case .hardware: + return "hardware" case .invite: return "invite" case .notifications: @@ -179,6 +179,7 @@ struct Suggestions: View { @EnvironmentObject var suggestionsManager: SuggestionsManager @EnvironmentObject var wallet: WalletViewModel @EnvironmentObject var pubkyProfile: PubkyProfileManager + @Environment(HwWalletRepo.self) private var hwWalletRepo @AppStorage(PaykitFeatureFlags.uiEnabledKey) private var isPaykitUIEnabled = false @State private var showShareSheet = false @@ -196,6 +197,7 @@ struct Suggestions: View { settings: SettingsViewModel, suggestionsManager: SuggestionsManager, pubkyProfile: PubkyProfileManager? = nil, + hasHardwareWallet: Bool = false, isPaykitUIEnabled: Bool = PaykitFeatureFlags.isUIEnabled, isPreview: Bool = false, previewCardIds: [String]? = nil @@ -218,7 +220,7 @@ struct Suggestions: View { for id in orderedIds { guard let card = cardsById[id] else { continue } if !isPaykitUIEnabled, card.isPaykitCard { continue } - if isCardCompleted(card, app: app, settings: settings, pubkyProfile: pubkyProfile) { continue } + if isCardCompleted(card, app: app, settings: settings, pubkyProfile: pubkyProfile, hasHardwareWallet: hasHardwareWallet) { continue } if suggestionsManager.isDismissed(card.id) { continue } result.append(card) if result.count >= 4 { break } @@ -228,10 +230,11 @@ struct Suggestions: View { /// Whether the user has completed this suggestion (e.g. backup verified, pin enabled, notifications on). private static func isCardCompleted(_ card: SuggestionCardData, app: AppViewModel, settings: SettingsViewModel, - pubkyProfile: PubkyProfileManager? = nil) -> Bool + pubkyProfile: PubkyProfileManager? = nil, hasHardwareWallet: Bool = false) -> Bool { switch card.action { case .backup: return app.backupVerified + case .hardware: return hasHardwareWallet case .notifications: return settings.enableNotifications case .profile: return pubkyProfile?.isAuthenticated ?? false case .quickpay: return settings.enableQuickpay @@ -248,6 +251,7 @@ struct Suggestions: View { settings: settings, suggestionsManager: suggestionsManager, pubkyProfile: pubkyProfile, + hasHardwareWallet: isPreview ? false : !hwWalletRepo.wallets.isEmpty, isPaykitUIEnabled: isPaykitUIActive, isPreview: isPreview, previewCardIds: previewCardIds @@ -353,8 +357,8 @@ struct Suggestions: View { route = app.hasSeenShopIntro ? .shopDiscover : .shopIntro case .support: route = .support - // case .hardware: - // route = .support + case .hardware: + sheets.showSheet(.hardwareIntro) case .transferToSpending: route = app.hasSeenTransferIntro ? .fundingOptions : .transferIntro } @@ -398,5 +402,6 @@ struct SuggestionsPreviewTile: View { .environmentObject(SuggestionsManager()) .environmentObject(WalletViewModel()) .environmentObject(PubkyProfileManager()) + .environment(HwWalletRepo()) .preferredColorScheme(.dark) } diff --git a/Bitkit/MainNavView.swift b/Bitkit/MainNavView.swift index 90a46fa2b..c62bbe14b 100644 --- a/Bitkit/MainNavView.swift +++ b/Bitkit/MainNavView.swift @@ -13,6 +13,8 @@ struct MainNavView: View { @EnvironmentObject private var settings: SettingsViewModel @EnvironmentObject private var sheets: SheetViewModel @EnvironmentObject private var wallet: WalletViewModel + @Environment(TrezorViewModel.self) private var trezor + @Environment(HwWalletRepo.self) private var hwWalletRepo @Environment(\.scenePhase) var scenePhase @State private var showClipboardAlert = false @@ -195,6 +197,31 @@ struct MainNavView: View { ) { config in WidgetsSheet(config: config) } + .sheet( + item: $sheets.hardwareIntroSheetItem, + onDismiss: { + sheets.hideSheet() + } + ) { + config in HardwareIntroSheet(config: config) + } + .sheet( + item: $sheets.hardwarePairingSheetItem, + onDismiss: { + sheets.hideSheet() + } + ) { + config in HardwarePairingSheet(config: config) + } + .onChange(of: trezor.showPairingCode) { _, needsCode in + // A hardware device asked for its one-time pairing code (e.g. during reconnect); + // surface the app-wide Pair Device sheet. Hidden again once submitted/cancelled. + if needsCode { + sheets.showSheet(.hardwarePairing) + } else { + sheets.hideSheetIfActive(.hardwarePairing, reason: "Pairing code resolved") + } + } .accentColor(.white) .overlay { TabBar() diff --git a/Bitkit/ViewModels/SheetViewModel.swift b/Bitkit/ViewModels/SheetViewModel.swift index 838e7cd9b..f9e53c39c 100644 --- a/Bitkit/ViewModels/SheetViewModel.swift +++ b/Bitkit/ViewModels/SheetViewModel.swift @@ -24,6 +24,8 @@ enum SheetID: String, CaseIterable { case tagFilter case dateRangeSelector case widgets + case hardwareIntro + case hardwarePairing } struct SheetConfiguration { @@ -301,6 +303,30 @@ class SheetViewModel: ObservableObject { } } + var hardwareIntroSheetItem: HardwareIntroSheetItem? { + get { + guard let config = activeSheetConfiguration, config.id == .hardwareIntro else { return nil } + return HardwareIntroSheetItem() + } + set { + if newValue == nil { + activeSheetConfiguration = nil + } + } + } + + var hardwarePairingSheetItem: HardwarePairingSheetItem? { + get { + guard let config = activeSheetConfiguration, config.id == .hardwarePairing else { return nil } + return HardwarePairingSheetItem() + } + set { + if newValue == nil { + activeSheetConfiguration = nil + } + } + } + var scannerSheetItem: ScannerSheetItem? { get { guard let config = activeSheetConfiguration, config.id == .scanner else { return nil } diff --git a/Bitkit/Views/Sheets/HardwareIntroSheet.swift b/Bitkit/Views/Sheets/HardwareIntroSheet.swift new file mode 100644 index 000000000..12bf3efd3 --- /dev/null +++ b/Bitkit/Views/Sheets/HardwareIntroSheet.swift @@ -0,0 +1,47 @@ +import SwiftUI + +struct HardwareIntroSheetItem: SheetItem { + let id: SheetID = .hardwareIntro + let size: SheetSize = .large +} + +/// Intro sheet opened from the Hardware suggestion card. Mirrors bitkit-android's `HwIntroSheet`: +/// staggered device hero, accent title, copy, and Cancel + (disabled) Continue. Continue is +/// intentionally disabled — the connect flow ships in a later PR. +struct HardwareIntroSheet: View { + @EnvironmentObject private var sheets: SheetViewModel + let config: HardwareIntroSheetItem + + var body: some View { + Sheet(id: .hardwareIntro, data: config) { + VStack(spacing: 0) { + SheetHeader(title: t("hardware__intro_title")) + .padding(.horizontal, 16) + + HwDeviceIllustrations() + .frame(maxWidth: .infinity, maxHeight: .infinity) + + VStack(alignment: .leading, spacing: 0) { + DisplayText(t("hardware__intro_header"), accentColor: .blueAccent) + + BodyMText(t("hardware__intro_text")) + .padding(.top, 8) + + HStack(spacing: 16) { + CustomButton(title: t("common__cancel"), variant: .secondary, shouldExpand: true) { + sheets.hideSheet() + } + .accessibilityIdentifier("HwIntroCancel") + + CustomButton(title: t("common__continue"), isDisabled: true, shouldExpand: true) + .accessibilityIdentifier("HwIntroContinue") + } + .padding(.top, 32) + .padding(.bottom, 16) + } + .padding(.horizontal, 32) + } + .accessibilityIdentifier("HwIntroSheet") + } + } +} diff --git a/Bitkit/Views/Sheets/HardwarePairingSheet.swift b/Bitkit/Views/Sheets/HardwarePairingSheet.swift new file mode 100644 index 000000000..8dfa5fb3a --- /dev/null +++ b/Bitkit/Views/Sheets/HardwarePairingSheet.swift @@ -0,0 +1,72 @@ +import SwiftUI + +struct HardwarePairingSheetItem: SheetItem { + let id: SheetID = .hardwarePairing + let size: SheetSize = .large +} + +/// App-wide sheet for the one-time pairing code a hardware device shows during connect/reconnect. +/// Mirrors bitkit-android's `HwPairCodeSheet`: 6 fixed-width cells + an on-screen number pad. +/// Dismissing without entering the full code cancels the pending pairing request. +struct HardwarePairingSheet: View { + @Environment(HwWalletRepo.self) private var hwWalletRepo + let config: HardwarePairingSheetItem + + private let codeLength = 6 + private let cellWidth: CGFloat = 32 + + @State private var code = "" + @State private var submitted = false + + var body: some View { + Sheet(id: .hardwarePairing, data: config) { + VStack(spacing: 0) { + SheetHeader(title: t("hardware__pairing_title")) + .padding(.horizontal, 16) + + VStack(spacing: 0) { + BodyMText(t("hardware__pairing_text")) + .multilineTextAlignment(.center) + + Spacer() + + HStack(spacing: 8) { + ForEach(0 ..< codeLength, id: \.self) { index in + let digit = digit(at: index) + DisplayText(digit ?? "•", textColor: digit != nil ? .textPrimary : .white32) + .frame(width: cellWidth) + } + } + + Spacer() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding(.horizontal, 32) + + NumberPad(type: .simple, onPress: handleKey) + .frame(height: NumberPad.contentHeight) + } + .accessibilityIdentifier("HwPairSheet") + } + .onDisappear { + if !submitted { hwWalletRepo.cancelPairingCode() } + } + } + + private func digit(at index: Int) -> String? { + let characters = Array(code) + return index < characters.count ? String(characters[index]) : nil + } + + private func handleKey(_ key: String) { + if key == "delete" { + if !code.isEmpty { code.removeLast() } + } else if code.count < codeLength { + code += key + if code.count == codeLength { + submitted = true + hwWalletRepo.submitPairingCode(code) + } + } + } +} diff --git a/Bitkit/Views/Trezor/TrezorRootView.swift b/Bitkit/Views/Trezor/TrezorRootView.swift index 1f3dc7971..5d24cb627 100644 --- a/Bitkit/Views/Trezor/TrezorRootView.swift +++ b/Bitkit/Views/Trezor/TrezorRootView.swift @@ -123,9 +123,8 @@ private struct TrezorDialogsModifier: ViewModifier { .sheet(isPresented: $trezor.showPinEntry) { TrezorPinEntrySheet() } - .sheet(isPresented: $trezor.showPairingCode) { - TrezorPairingCodeSheet() - } + // Pairing code is presented app-wide via the SheetViewModel system (see MainNavView), + // so the home hardware feature shows it regardless of being on this dev screen. .sheet(isPresented: $trezor.showPassphraseEntry) { TrezorPassphraseSheet() } From 69d725cca2e9f5907e97b68e36ee661d2e69f4dd Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 15:00:18 -0300 Subject: [PATCH 06/52] feat: activity merge and sheet receive --- Bitkit/Extensions/Activity+Contact.swift | 16 ++++++++++++++++ Bitkit/MainNavView.swift | 4 ++++ Bitkit/Services/CoreService.swift | 12 ++++++++---- Bitkit/Styles/Colors.swift | 1 + Bitkit/Utilities/AppReset.swift | 5 +++++ Bitkit/ViewModels/ActivityItemViewModel.swift | 2 +- Bitkit/ViewModels/ActivityListViewModel.swift | 12 ++++++++---- Bitkit/Views/Wallets/Activity/ActivityIcon.swift | 7 ++++++- 8 files changed, 49 insertions(+), 10 deletions(-) diff --git a/Bitkit/Extensions/Activity+Contact.swift b/Bitkit/Extensions/Activity+Contact.swift index da84be98a..49197c895 100644 --- a/Bitkit/Extensions/Activity+Contact.swift +++ b/Bitkit/Extensions/Activity+Contact.swift @@ -1,6 +1,22 @@ import BitkitCore extension Activity { + /// bitkit-core wallet id scoping this activity (`"bitkit"` for the normal wallet, a derived + /// id for watch-only hardware wallets — see `HwWalletId`). + var walletId: String { + switch self { + case let .lightning(lightning): + return lightning.walletId + case let .onchain(onchain): + return onchain.walletId + } + } + + /// Whether this activity belongs to a watch-only hardware wallet (not the normal Bitkit wallet). + var isHardwareWallet: Bool { + walletId != WalletScope.default + } + func contact(in contacts: [PubkyContact]) -> PubkyContact? { guard let contactPublicKey else { return nil } return contacts.first(where: { PubkyPublicKeyFormat.matches($0.publicKey, contactPublicKey) }) diff --git a/Bitkit/MainNavView.swift b/Bitkit/MainNavView.swift index c62bbe14b..d7a9d0bae 100644 --- a/Bitkit/MainNavView.swift +++ b/Bitkit/MainNavView.swift @@ -222,6 +222,10 @@ struct MainNavView: View { sheets.hideSheetIfActive(.hardwarePairing, reason: "Pairing code resolved") } } + .onReceive(hwWalletRepo.receivedTxPublisher) { tx in + // New inbound transaction to a watched hardware wallet — show the received celebration. + sheets.showSheet(.receivedTx, data: ReceivedTxSheetDetails(type: .onchain, sats: tx.sats)) + } .accentColor(.white) .overlay { TabBar() diff --git a/Bitkit/Services/CoreService.swift b/Bitkit/Services/CoreService.swift index 2ef034d70..ea2dd927b 100644 --- a/Bitkit/Services/CoreService.swift +++ b/Bitkit/Services/CoreService.swift @@ -990,9 +990,9 @@ class ActivityService { return details.outputs.first?.scriptpubkeyAddress } - func getActivity(id: String) async throws -> Activity? { + func getActivity(id: String, walletId: String = WalletScope.default) async throws -> Activity? { try await ServiceQueue.background(.core) { - try getActivityById(walletId: WalletScope.default, activityId: id) + try getActivityById(walletId: walletId, activityId: id) } } @@ -1020,6 +1020,9 @@ class ActivityService { } } + /// Fetch activities. `walletId` defaults to the normal Bitkit wallet; pass `nil` to query + /// every wallet globally (Bitkit + watch-only hardware wallets) for the merged Home / All + /// Activity lists. func get( filter: ActivityFilter? = nil, txType: PaymentType? = nil, @@ -1028,11 +1031,12 @@ class ActivityService { minDate: UInt64? = nil, maxDate: UInt64? = nil, limit: UInt32? = nil, - sortDirection: SortDirection? = nil + sortDirection: SortDirection? = nil, + walletId: String? = WalletScope.default ) async throws -> [Activity] { try await ServiceQueue.background(.core) { try getActivities( - walletId: WalletScope.default, + walletId: walletId, filter: filter, txType: txType, tags: tags, diff --git a/Bitkit/Styles/Colors.swift b/Bitkit/Styles/Colors.swift index 389087b76..adb58e7d4 100644 --- a/Bitkit/Styles/Colors.swift +++ b/Bitkit/Styles/Colors.swift @@ -41,6 +41,7 @@ extension Color { static let white64 = Color.white.opacity(0.64) static let white80 = Color.white.opacity(0.80) + static let blue16 = Color.blueAccent.opacity(0.16) static let blue24 = Color.blueAccent.opacity(0.24) static let brand08 = Color.brandAccent.opacity(0.08) static let brand16 = Color.brandAccent.opacity(0.16) diff --git a/Bitkit/Utilities/AppReset.swift b/Bitkit/Utilities/AppReset.swift index 04d596a58..bcc9e9acb 100644 --- a/Bitkit/Utilities/AppReset.swift +++ b/Bitkit/Utilities/AppReset.swift @@ -23,6 +23,11 @@ enum AppReset { await VssBackupClient.shared.reset() VssStoreIdProvider.shared.clearCache() + // Stop any running watch-only hardware-wallet watchers. Their persisted xpubs/known + // devices and activities are cleared below by the UserDefaults/keychain/core-DB wipes; + // the app-lifetime HwWalletRepo is rebuilt by session.bump() at the end of this wipe. + TrezorService.shared.stopAllWatchers() + // Stop node and wipe LDK persistence via the wallet API. try await wallet.wipe() diff --git a/Bitkit/ViewModels/ActivityItemViewModel.swift b/Bitkit/ViewModels/ActivityItemViewModel.swift index a0e45515b..f9b8c9063 100644 --- a/Bitkit/ViewModels/ActivityItemViewModel.swift +++ b/Bitkit/ViewModels/ActivityItemViewModel.swift @@ -55,7 +55,7 @@ class ActivityItemViewModel: ObservableObject { func refreshActivity() async { do { - if let updatedActivity = try await coreService.activity.getActivity(id: activityId) { + if let updatedActivity = try await coreService.activity.getActivity(id: activityId, walletId: activity.walletId) { activity = updatedActivity } else { // Activity not found by ID - it might have been replaced by RBF diff --git a/Bitkit/ViewModels/ActivityListViewModel.swift b/Bitkit/ViewModels/ActivityListViewModel.swift index 0d95b2273..f9adec550 100644 --- a/Bitkit/ViewModels/ActivityListViewModel.swift +++ b/Bitkit/ViewModels/ActivityListViewModel.swift @@ -138,8 +138,9 @@ class ActivityListViewModel: ObservableObject { do { // Get latest activities first as that's displayed on the home view let limitLatest = UInt32(ActivityDisplayConstants.maxHomeActivityItems) - // Fetch extra to account for potential filtering of replaced transactions - let latest = try await coreService.activity.get(filter: .all, limit: limitLatest * 3) + // Fetch extra to account for potential filtering of replaced transactions. + // walletId nil → global: merges the Bitkit wallet with watch-only hardware wallets. + let latest = try await coreService.activity.get(filter: .all, limit: limitLatest * 3, walletId: nil) let filtered = await filterOutReplacedSentTransactions(latest) latestActivities = Array(filtered.prefix(Int(limitLatest))) @@ -188,13 +189,16 @@ class ActivityListViewModel: ObservableObject { return UInt64(nextDay.timeIntervalSince1970 - 1) } - // Apply base filtering + // Apply base filtering. walletId nil → global so the All Activity list merges the + // Bitkit wallet with watch-only hardware wallets (tag filters exclude hw items, which + // carry no tags, matching bitkit-android). let baseFilteredActivities = try await coreService.activity.get( filter: .all, tags: selectedTags.isEmpty ? nil : Array(selectedTags), search: searchText.isEmpty ? nil : searchText, minDate: minDate, - maxDate: maxDate + maxDate: maxDate, + walletId: nil ) // Filter out replaced sent transactions that appear in another transaction's boostTxIds diff --git a/Bitkit/Views/Wallets/Activity/ActivityIcon.swift b/Bitkit/Views/Wallets/Activity/ActivityIcon.swift index 13810c493..dcd97388b 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityIcon.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityIcon.swift @@ -17,11 +17,13 @@ struct ActivityIcon: View { let doesExist: Bool let isCpfpChild: Bool let context: Context + let isHwWallet: Bool init(activity: Activity, size: CGFloat = 32, isCpfpChild: Bool = false, context: Context = .detail) { self.size = size self.isCpfpChild = isCpfpChild self.context = context + isHwWallet = activity.isHardwareWallet switch activity { case let .lightning(ln): @@ -70,7 +72,10 @@ struct ActivityIcon: View { ) } else { let paymentIcon = txType == .sent ? "arrow-up" : "arrow-down" - let (iconColor, backgroundColor): (Color, Color) = if isTransfer { + let (iconColor, backgroundColor): (Color, Color) = if isHwWallet { + // Watch-only hardware-wallet activity reads blue. + (.blueAccent, .blue16) + } else if isTransfer { // From savings (to spending) = sent = orange, From spending (to savings) = received = purple txType == .sent ? (.brandAccent, .brand16) : (.purpleAccent, .purple16) } else { From befcb934e2a04f5cc729a1c269e7b33c41b37127 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 17:38:59 -0300 Subject: [PATCH 07/52] refactor: dependency decoupling --- Bitkit/AppScene.swift | 37 +- Bitkit/Components/Widgets/Suggestions.swift | 6 +- Bitkit/MainNavView.swift | 8 +- .../HwWalletManager.swift} | 94 +-- Bitkit/Managers/TrezorManager.swift | 667 +++++++++++++++++ Bitkit/Models/HwWallet.swift | 2 +- Bitkit/Services/Trezor/TrezorService.swift | 43 ++ Bitkit/Utilities/AppReset.swift | 2 +- .../ViewModels/Trezor/TrezorViewModel.swift | 708 ++---------------- Bitkit/Views/Home/HomeWalletView.swift | 8 +- .../Views/Sheets/HardwarePairingSheet.swift | 6 +- Bitkit/Views/Trezor/TrezorAddressView.swift | 9 +- .../Trezor/TrezorBalanceLookupView.swift | 3 +- Bitkit/Views/Trezor/TrezorConnectedView.swift | 21 +- .../Trezor/TrezorDeviceFeaturesView.swift | 12 +- .../Views/Trezor/TrezorDeviceListView.swift | 68 +- Bitkit/Views/Trezor/TrezorPublicKeyView.swift | 2 +- Bitkit/Views/Trezor/TrezorRootView.swift | 71 +- .../Views/Trezor/TrezorSignMessageView.swift | 2 +- .../Trezor/TrezorTransactionDetailView.swift | 2 +- .../Trezor/TrezorTransactionHistoryView.swift | 2 +- ...Tests.swift => HwWalletManagerTests.swift} | 9 +- BitkitTests/TrezorViewModelWatcherTests.swift | 45 +- 23 files changed, 968 insertions(+), 859 deletions(-) rename Bitkit/{Services/HwWalletRepo.swift => Managers/HwWalletManager.swift} (84%) create mode 100644 Bitkit/Managers/TrezorManager.swift rename BitkitTests/{HwWalletRepoTests.swift => HwWalletManagerTests.swift} (98%) diff --git a/Bitkit/AppScene.swift b/Bitkit/AppScene.swift index 646e4c67a..1c5dcffce 100644 --- a/Bitkit/AppScene.swift +++ b/Bitkit/AppScene.swift @@ -31,8 +31,9 @@ struct AppScene: View { @StateObject private var pubkyProfile = PubkyProfileManager() @StateObject private var contactsManager = ContactsManager() @State private var keyboardManager = KeyboardManager() + @State private var trezorManager: TrezorManager @State private var trezorViewModel: TrezorViewModel - @State private var hwWalletRepo: HwWalletRepo + @State private var hwWalletManager: HwWalletManager @State private var calculatorInputManager = CalculatorInputManager() @State private var hideSplash = false @@ -83,9 +84,11 @@ struct AppScene: View { _transferTracking = StateObject(wrappedValue: TransferTrackingManager(service: transferService)) - let trezor = TrezorViewModel() - _trezorViewModel = State(initialValue: trezor) - _hwWalletRepo = State(initialValue: HwWalletRepo(trezor: trezor)) + let trezorManager = TrezorManager() + let trezorViewModel = TrezorViewModel(connection: trezorManager) + _trezorManager = State(initialValue: trezorManager) + _trezorViewModel = State(initialValue: trezorViewModel) + _hwWalletManager = State(initialValue: HwWalletManager()) CoreService.shared.activity.setPrivatePaykitContactResolvers( invoice: { paymentHash in @@ -111,6 +114,9 @@ struct AppScene: View { .onChange(of: wallet.nodeLifecycleState) { _, newValue in handleNodeLifecycleChange(newValue) } .onChange(of: scenePhase, initial: true) { _, newValue in handleScenePhaseChange(newValue) } .onChange(of: network.isConnected) { _, isConnected in handleNetworkChange(isConnected) } + // Bridge Trezor device state into the watch-only manager without coupling the two: + // TrezorManager bumps devicesRevision on any device/connection change. + .onChange(of: trezorManager.devicesRevision) { _, _ in pushHardwareDevices() } .onChange(of: migrations.isShowingMigrationLoading) { _, isLoading in if !isLoading { SettingsViewModel.shared.updatePinEnabledState() @@ -153,8 +159,9 @@ struct AppScene: View { .environmentObject(pubkyProfile) .environmentObject(contactsManager) .environment(keyboardManager) + .environment(trezorManager) .environment(trezorViewModel) - .environment(hwWalletRepo) + .environment(hwWalletManager) .environment(calculatorInputManager) .onChange(of: pubkyProfile.authState, initial: true) { _, authState in if authState == .authenticated, let pk = pubkyProfile.publicKey { @@ -476,8 +483,11 @@ struct AppScene: View { await checkAndPerformRNMigration() try wallet.setWalletExistsState() - // Start watch-only hardware-wallet watchers (no-op until a device is paired). - hwWalletRepo.start() + // Load any paired hardware devices from storage and feed the watch-only manager so its + // watchers start at launch (no-op until a device is paired). loadKnownDevices() also + // bumps devicesRevision, but push explicitly so the initial state is delivered. + trezorManager.loadKnownDevices() + pushHardwareDevices() // Setup TimedSheetManager with all timed sheets TimedSheetManager.shared.setup( @@ -610,7 +620,9 @@ struct AppScene: View { } if newPhase == .active { - hwWalletRepo.onAppForegrounded() + // Reconnect a known hardware device so its connection indicator turns green again; + // watch-only balances stay live regardless. + Task { await trezorManager.autoReconnect() } if wallet.walletExists == true { Task { await clearDeliveredNotifications() @@ -644,6 +656,15 @@ struct AppScene: View { center.removeDeliveredNotifications(withIdentifiers: deliveredNotifications.map(\.request.identifier)) } + /// Feed the current Trezor device snapshot into the watch-only manager. This is the only link + /// between the two managers, kept in the composition root so neither type references the other. + private func pushHardwareDevices() { + hwWalletManager.updateDevices( + knownDevices: trezorManager.knownDevices, + connectedDeviceId: trezorManager.connectedDevice?.id + ) + } + private func handleNetworkChange(_ isConnected: Bool) { Logger.info("Network changed: \(isConnected ? "connected" : "disconnected")", context: "AppScene") diff --git a/Bitkit/Components/Widgets/Suggestions.swift b/Bitkit/Components/Widgets/Suggestions.swift index 9e910b44d..ac4195d1d 100644 --- a/Bitkit/Components/Widgets/Suggestions.swift +++ b/Bitkit/Components/Widgets/Suggestions.swift @@ -179,7 +179,7 @@ struct Suggestions: View { @EnvironmentObject var suggestionsManager: SuggestionsManager @EnvironmentObject var wallet: WalletViewModel @EnvironmentObject var pubkyProfile: PubkyProfileManager - @Environment(HwWalletRepo.self) private var hwWalletRepo + @Environment(HwWalletManager.self) private var hwWalletManager @AppStorage(PaykitFeatureFlags.uiEnabledKey) private var isPaykitUIEnabled = false @State private var showShareSheet = false @@ -251,7 +251,7 @@ struct Suggestions: View { settings: settings, suggestionsManager: suggestionsManager, pubkyProfile: pubkyProfile, - hasHardwareWallet: isPreview ? false : !hwWalletRepo.wallets.isEmpty, + hasHardwareWallet: isPreview ? false : !hwWalletManager.wallets.isEmpty, isPaykitUIEnabled: isPaykitUIActive, isPreview: isPreview, previewCardIds: previewCardIds @@ -402,6 +402,6 @@ struct SuggestionsPreviewTile: View { .environmentObject(SuggestionsManager()) .environmentObject(WalletViewModel()) .environmentObject(PubkyProfileManager()) - .environment(HwWalletRepo()) + .environment(HwWalletManager()) .preferredColorScheme(.dark) } diff --git a/Bitkit/MainNavView.swift b/Bitkit/MainNavView.swift index d7a9d0bae..311e8badd 100644 --- a/Bitkit/MainNavView.swift +++ b/Bitkit/MainNavView.swift @@ -13,8 +13,8 @@ struct MainNavView: View { @EnvironmentObject private var settings: SettingsViewModel @EnvironmentObject private var sheets: SheetViewModel @EnvironmentObject private var wallet: WalletViewModel - @Environment(TrezorViewModel.self) private var trezor - @Environment(HwWalletRepo.self) private var hwWalletRepo + @Environment(TrezorManager.self) private var trezorManager + @Environment(HwWalletManager.self) private var hwWalletManager @Environment(\.scenePhase) var scenePhase @State private var showClipboardAlert = false @@ -213,7 +213,7 @@ struct MainNavView: View { ) { config in HardwarePairingSheet(config: config) } - .onChange(of: trezor.showPairingCode) { _, needsCode in + .onChange(of: trezorManager.showPairingCode) { _, needsCode in // A hardware device asked for its one-time pairing code (e.g. during reconnect); // surface the app-wide Pair Device sheet. Hidden again once submitted/cancelled. if needsCode { @@ -222,7 +222,7 @@ struct MainNavView: View { sheets.hideSheetIfActive(.hardwarePairing, reason: "Pairing code resolved") } } - .onReceive(hwWalletRepo.receivedTxPublisher) { tx in + .onReceive(hwWalletManager.receivedTxPublisher) { tx in // New inbound transaction to a watched hardware wallet — show the received celebration. sheets.showSheet(.receivedTx, data: ReceivedTxSheetDetails(type: .onchain, sats: tx.sats)) } diff --git a/Bitkit/Services/HwWalletRepo.swift b/Bitkit/Managers/HwWalletManager.swift similarity index 84% rename from Bitkit/Services/HwWalletRepo.swift rename to Bitkit/Managers/HwWalletManager.swift index 6b62b26b1..ef240df1c 100644 --- a/Bitkit/Services/HwWalletRepo.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -7,13 +7,13 @@ import Foundation /// per-device balance in memory, and persisting each device's on-chain activity into /// bitkit-core scoped by a derived `walletId` (core 0.3.x wallet-scoped storage). /// -/// Built on top of `TrezorViewModel`, which owns the device list, connect orchestration and the -/// underlying watcher transport. Adapts bitkit-android's `HwWalletRepo`. iOS supports Bluetooth -/// only, so the cross-transport (BLE+USB) dedup is reduced to a plain xpub-based identity and -/// USB-specific reconnect handling is omitted. +/// Fully decoupled from `TrezorManager`: it receives the paired-device snapshot through +/// `updateDevices(...)`, fed by the composition root (`AppScene`). Adapts bitkit-android's +/// `HwWalletRepo`. iOS supports Bluetooth only, so the cross-transport (BLE+USB) dedup is reduced +/// to a plain xpub-based identity and USB-specific reconnect handling is omitted. @Observable @MainActor -final class HwWalletRepo { +final class HwWalletManager { private enum Constants { static let watcherIdSeparator = "|" static let watcherStartRetryDelay: Duration = .seconds(30) @@ -39,7 +39,6 @@ final class HwWalletRepo { // MARK: - Dependencies - private weak var trezor: TrezorViewModel? private let watcherService: TrezorWatcherServicing private let monitoredTypesProvider: () -> Set private let electrumUrlProvider: () -> String @@ -59,7 +58,6 @@ final class HwWalletRepo { private var listeners: [String: TrezorEventListener] = [:] init( - trezor: TrezorViewModel? = nil, watcherService: TrezorWatcherServicing = TrezorService.shared, monitoredTypes: (() -> Set)? = nil, electrumUrl: (() -> String)? = nil, @@ -67,13 +65,12 @@ final class HwWalletRepo { persistActivities: (([Activity]) -> Void)? = nil, deleteActivities: ((String) -> Void)? = nil ) { - self.trezor = trezor self.watcherService = watcherService - networkProvider = network ?? { TrezorViewModel.appDefaultCoinType } + networkProvider = network ?? { TrezorService.appDefaultCoinType } monitoredTypesProvider = monitoredTypes ?? { Set(SettingsViewModel.shared.addressTypesToMonitor.map(\.stringValue)) } - electrumUrlProvider = electrumUrl ?? { TrezorViewModel.getElectrumUrl() } + electrumUrlProvider = electrumUrl ?? { TrezorService.getElectrumUrl() } self.persistActivities = persistActivities ?? { activities in guard !activities.isEmpty else { return } Task { @@ -91,51 +88,11 @@ final class HwWalletRepo { } } - // MARK: - Lifecycle + // MARK: - Device input - /// Begin observing the Trezor device state and start the initial watcher sync. - func start() { - observeTrezorState() - refreshFromTrezor() - } - - /// Re-read device state and monitored settings, then reconcile watchers. - func refresh() { - refreshFromTrezor() - } - - /// On app foreground, ask the Trezor layer to reconnect a known device so the connection - /// indicator turns green again; watch-only balances stay live regardless. - func onAppForegrounded() { - guard let trezor else { return } - Task { await trezor.autoReconnect() } - } - - private func refreshFromTrezor() { - guard let trezor else { - syncWatchers() - recomputeDerivedState() - return - } - updateDevices(knownDevices: trezor.knownDevices, connectedDeviceId: trezor.connectedDevice?.id) - } - - private func observeTrezorState() { - guard let trezor else { return } - withObservationTracking { - _ = trezor.knownDevices.map { "\($0.id):\($0.xpubs.count)" } - _ = trezor.connectedDevice?.id - } onChange: { [weak self] in - Task { @MainActor in - guard let self else { return } - self.refreshFromTrezor() - self.observeTrezorState() - } - } - } - - /// Update the device snapshot and reconcile watchers. Exposed for tests so the engine can be - /// exercised without a live `TrezorViewModel`. + /// Update the device snapshot and reconcile watchers. This is the manager's sole input: the + /// composition root (`AppScene`) feeds it the current Trezor device list, so this type stays + /// fully decoupled from `TrezorManager`. Also the test seam — tests drive it directly. func updateDevices(knownDevices: [TrezorKnownDevice], connectedDeviceId: String?) { self.knownDevices = knownDevices self.connectedDeviceId = connectedDeviceId @@ -144,20 +101,6 @@ final class HwWalletRepo { recomputeDerivedState() } - // MARK: - Pairing passthroughs - - var needsPairingCode: Bool { - trezor?.showPairingCode ?? false - } - - func submitPairingCode(_ code: String) { - trezor?.submitPairingCode(code) - } - - func cancelPairingCode() { - trezor?.cancelPairingCode() - } - // MARK: - Control func resetState() { @@ -176,22 +119,17 @@ final class HwWalletRepo { recomputeDerivedState() } - /// Remove a paired hardware wallet: stop its watchers, delete its stored activities, and - /// forget every device entry that shares the same xpub-derived identity, so the tile doesn't - /// reappear through another entry. - func removeDevice(id deviceId: String) async { + /// Stop watching a paired hardware wallet and delete its stored activities. The caller is + /// responsible for forgetting the device entries (via `TrezorManager.forgetDevice`); the next + /// `updateDevices(...)` push then drops it from the tile list. + func removeDevice(id deviceId: String) { let group = deviceGroups().first { $0.ids.contains(deviceId) } let ids = group?.ids ?? [deviceId] for watcherId in activeWatchers where ids.contains(self.deviceId(fromWatcherId: watcherId)) { _ = stopActiveWatcher(watcherId) } if let group { deleteActivities(group.walletId) } - if let trezor { - for id in ids { - await trezor.forgetDevice(id: id) - } - } - refreshFromTrezor() + recomputeDerivedState() } // MARK: - Watcher orchestration diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift new file mode 100644 index 000000000..0543ff2b4 --- /dev/null +++ b/Bitkit/Managers/TrezorManager.swift @@ -0,0 +1,667 @@ +import BitkitCore +import Combine +import CoreBluetooth +import Foundation + +/// Device/connection orchestration and pairing/PIN/passphrase coordination for the Trezor +/// hardware wallet. Owns the device list, connect/disconnect lifecycle, known-device storage, +/// auto-reconnect, network selection, and the UI dialog state for PIN/passphrase/pairing flows. +/// +/// Split out of `TrezorViewModel` so production managers (e.g. `HwWalletManager`) depend on a +/// manager rather than a dev-screen ViewModel, keeping dependencies pointing Manager→Manager→Service. +@Observable +@MainActor +final class TrezorManager { + // MARK: - Network Configuration + + /// The network selected in the Trezor dashboard (independent of app's global network) + var selectedNetwork: TrezorCoinType + + /// BIP44 coin type component based on the dashboard's selected network: "0'" for mainnet, "1'" for test networks + var coinTypeComponent: String { + selectedNetwork == .bitcoin ? "0'" : "1'" + } + + // MARK: - Connection State + + /// Whether the Trezor manager is initialized + private var isInitialized: Bool = false + + /// Whether currently scanning for devices + var isScanning: Bool = false + + /// List of discovered devices + var devices: [TrezorDeviceInfo] = [] + + /// Currently connected device + var connectedDevice: TrezorDeviceInfo? { + didSet { devicesRevision &+= 1 } + } + + /// Bumped whenever the device list or connection state changes, so observers (e.g. the + /// composition root that feeds `HwWalletManager`) can react without those types coupling. + private(set) var devicesRevision: Int = 0 + + /// Features of the connected device + var deviceFeatures: TrezorFeatures? + + /// Device root fingerprint (hex string) + var deviceFingerprint: String? + + /// Last error message + var error: String? + + // MARK: - UI Dialog State + + /// Show PIN entry dialog + var showPinEntry: Bool = false + + /// Show passphrase entry dialog + var showPassphraseEntry: Bool = false + + /// Show BLE pairing code dialog + var showPairingCode: Bool = false + + /// Show "Confirm on device" overlay + var showConfirmOnDevice: Bool = false + + /// Message for confirm on device overlay + var confirmMessage: String = "" + + /// Show the "where to enter the passphrase" chooser (phone vs Trezor). + /// Only presented for devices that report on-device passphrase entry capability. + var showWalletModeChooser: Bool = false + + // MARK: - Wallet Mode State + + /// The currently selected wallet mode (standard / hidden-on-phone / hidden-on-device). + /// Drives the wallet-mode selector UI; the binding to the device session is applied + /// via setWalletMode (disconnect/reconnect). + var walletMode: TrezorWalletMode = .standard + + /// Whether the connected device supports entering the passphrase on the Trezor itself. + var passphraseEntryCapable: Bool { + deviceFeatures?.passphraseEntryCapable == true + } + + // MARK: - Known Devices & Auto-Reconnect + + /// Previously connected devices loaded from storage + var knownDevices: [TrezorKnownDevice] = [] { + didSet { devicesRevision &+= 1 } + } + + /// Whether auto-reconnect is in progress + var isAutoReconnecting: Bool = false + + /// Status text during auto-reconnect + var autoReconnectStatus: String? + + /// Prevents a user-initiated disconnect from immediately reconnecting + /// when the disconnected device list appears. + private var suppressNextAutoReconnect = false + + // MARK: - Bluetooth State + + /// Current Bluetooth state — reads directly from BLEManager (@Observable chaining) + var bluetoothState: CBManagerState { + TrezorBLEManager.shared.bluetoothState + } + + var isBridgeModeEnabled: Bool { + transport.isBridgeEnabled + } + + // MARK: - Private Properties + + private let trezorService = TrezorService.shared + private let transport = TrezorTransport.shared + private let uiHandler = TrezorUiHandler.shared + private var cancellables = Set() + private var hasSetupSubscriptions = false + + // MARK: - Initialization + + init() { + selectedNetwork = TrezorService.appDefaultCoinType + // Callback subscriptions are deferred to setup() to avoid + // triggering BLE stack and Combine overhead at app launch. + } + + /// Subscribe to callback publishers for UI notifications + private func setupCallbackSubscriptions() { + // Pairing code request + transport.needsPairingCodePublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.showPairingCode = true + } + .store(in: &cancellables) + + // PIN request from device + uiHandler.needsPinPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.showPinEntry = true + } + .store(in: &cancellables) + + // Passphrase entry is now driven proactively by the wallet-mode selector + // (see setWalletMode / requestPassphraseWallet). The device callback + // `onPassphraseRequest` is answered silently from the selected mode, so there + // is no reactive passphrase prompt to subscribe to here. + } + + // MARK: - Debug Log Helper + + /// Log to both Logger and TrezorDebugLog + private func trezorLog(_ message: String, level: String = "info") { + switch level { + case "error": + Logger.error(message, context: "TrezorManager") + case "warn": + Logger.warn(message, context: "TrezorManager") + default: + Logger.info(message, context: "TrezorManager") + } + TrezorDebugLog.shared.log(message) + } + + // MARK: - State Reset Helpers + + func clearWalletDerivedState() { + deviceFingerprint = nil + } + + func clearDisconnectedDeviceState(errorMessage: String? = nil) { + connectedDevice = nil + deviceFeatures = nil + clearWalletDerivedState() + error = errorMessage + showPinEntry = false + showPassphraseEntry = false + showConfirmOnDevice = false + showWalletModeChooser = false + uiHandler.setWalletMode(.standard) + walletMode = .standard + } + + // MARK: - Manager Setup + + /// Set up subscriptions and start BLE stack (synchronous, non-blocking). + /// Called from TrezorRootView's .task to prepare the UI layer. + func setup() { + guard !hasSetupSubscriptions else { return } + if !transport.isBridgeEnabled { + // Start BLE stack early so bluetoothState is updated by the time + // TrezorDeviceListView renders (the delegate callback fires async). + TrezorBLEManager.shared.ensureStarted() + } + setupCallbackSubscriptions() + hasSetupSubscriptions = true + } + + /// Initialize the Trezor FFI manager (async, may be slow). + /// Called lazily before first scan/connect. + func initialize() async { + setup() + + guard !isInitialized else { return } + + do { + try await trezorService.initialize() + isInitialized = true + error = nil + trezorLog("TrezorManager initialized") + } catch { + self.error = errorMessage(from: error) + trezorLog("Failed to initialize Trezor: \(error)", level: "error") + } + } + + // MARK: - Device Scanning + + /// Start scanning for Trezor devices + /// - Parameter clearExisting: Whether to clear existing device list before scanning + func startScan(clearExisting: Bool = true) async { + if !isInitialized { + await initialize() + } + + isScanning = true + error = nil + + if clearExisting { + devices = [] + } + + if !transport.isBridgeEnabled { + // Start BLE scanning + transport.startBLEScanning() + + // Wait for BLE to discover devices (like Android's 3-second scan) + // This ensures devices are found before we call the FFI enumerate + try? await Task.sleep(nanoseconds: 3_000_000_000) // 3 seconds + + // Stop BLE scanning before calling FFI to prevent race conditions + transport.stopBLEScanning() + } + + do { + // Trigger FFI scan which will use our transport callbacks + let foundDevices = try await trezorService.scan() + + // Deduplicate by path (in case of duplicate scan results) + var seenPaths = Set() + let uniqueDevices = foundDevices.filter { device in + if seenPaths.contains(device.path) { + return false + } + seenPaths.insert(device.path) + return true + } + + devices = uniqueDevices + trezorLog("Found \(uniqueDevices.count) Trezor devices (filtered from \(foundDevices.count))") + } catch { + self.error = errorMessage(from: error) + trezorLog("Scan failed: \(error)", level: "error") + } + + isScanning = false + } + + /// Stop scanning for devices + func stopScan() { + transport.stopBLEScanning() + isScanning = false + } + + // MARK: - Connection + + /// Connect to a device + func connect(device: TrezorDeviceInfo) async { + error = nil + suppressNextAutoReconnect = false + + // Explicit user-initiated connect always opens the standard wallet — a + // passphrase/on-device selection left over from a previously connected device + // must not silently apply to a newly selected one. + uiHandler.setWalletMode(.standard) + walletMode = .standard + + trezorLog("=== Connecting to device: \(device.path) ===") + + do { + let features = try await trezorService.connect(deviceId: device.path, selection: uiHandler.currentSelection()) + connectedDevice = device + deviceFeatures = features + showConfirmOnDevice = false + + await saveCurrentDeviceAsKnown() + trezorLog("Connected to Trezor: \(device.path)") + } catch { + let errorMsg = errorMessage(from: error) + self.error = errorMsg + showConfirmOnDevice = false + trezorLog("Connection failed: \(error)", level: "error") + } + } + + /// Disconnect from current device + func disconnect() async { + guard connectedDevice != nil else { return } + suppressNextAutoReconnect = true + + // NOTE: the event watcher is intentionally NOT stopped here. It subscribes to + // Electrum directly and does not require a connected device, so it survives a + // disconnect and remains controllable from the device-list screen. It is only + // torn down on a network switch (different Electrum server) or via stopWatcher(). + + do { + try await trezorService.disconnect() + // Clear connection state but preserve device list for quick reconnection + clearDisconnectedDeviceState() + + trezorLog("Disconnected from Trezor") + } catch { + // Even if disconnect fails, clear local state + clearDisconnectedDeviceState(errorMessage: errorMessage(from: error)) + trezorLog("Disconnect failed: \(error)", level: "error") + } + } + + /// Check if currently connected + var isConnected: Bool { + connectedDevice != nil + } + + // MARK: - UI Callbacks + + /// Submit PIN from UI + func submitPin(_ pin: String) { + showPinEntry = false + uiHandler.submitPin(pin) + } + + /// Cancel PIN entry + func cancelPin() { + showPinEntry = false + uiHandler.cancelPin() + } + + /// Submit a host-entered passphrase from the UI — opens the corresponding hidden + /// wallet (or the standard wallet when empty) by resetting the session. + func submitPassphrase(_ passphrase: String) async { + showPassphraseEntry = false + showConfirmOnDevice = false + await setWalletMode(passphrase.isEmpty ? .standard : .passphraseHost, passphrase: passphrase) + } + + /// Cancel passphrase entry + func cancelPassphrase() { + showPassphraseEntry = false + showConfirmOnDevice = false + showWalletModeChooser = false + } + + // MARK: - Wallet Mode Selection + + /// User tapped the "Standard" wallet option in the selector. + func selectStandardWallet() async { + guard walletMode != .standard else { return } + await setWalletMode(.standard) + } + + /// User tapped the "Passphrase" wallet option. On a capable device this offers a + /// choice of where to enter the passphrase; otherwise it goes straight to host entry. + func requestPassphraseWallet() { + if passphraseEntryCapable { + showWalletModeChooser = true + } else { + showPassphraseEntry = true + } + } + + /// Wallet-mode chooser: user chose to enter the passphrase on this phone. + func choosePhonePassphraseEntry() { + showWalletModeChooser = false + showPassphraseEntry = true + } + + /// Wallet-mode chooser: user chose to enter the passphrase on the Trezor. + func chooseDevicePassphraseEntry() async { + showWalletModeChooser = false + await setWalletMode(.passphraseDevice) + } + + /// Switch between wallet modes. The Trezor caches the passphrase for the whole + /// session, so switching requires a fresh session: this records the desired mode, + /// then disconnects and reconnects by path. Mirrors bitkit-android's setWalletMode. + func setWalletMode(_ mode: TrezorWalletMode, passphrase: String = "") async { + guard let device = connectedDevice else { + error = "Not connected to a Trezor" + return + } + + error = nil + trezorLog("=== Switching wallet mode to \(mode); resetting session ===") + + // Reset the session. We call the service directly (not the manager's disconnect()) + // so connectedDevice/deviceFeatures stay populated for the reconnect. + do { + try await trezorService.disconnect() + } catch { + trezorLog("Disconnect before wallet-mode switch failed: \(error)", level: "warn") + } + + // Results derived from the previous wallet are no longer valid once the + // session has been reset for a different wallet mode. + clearWalletDerivedState() + + // Brief settle delay before reconnecting (matches Android's reconnect delay). + try? await Task.sleep(nanoseconds: 300_000_000) + + // Record the selection AFTER the disconnect so it survives into the new session. + // THP reads it via currentSelection() to bind the passphrase at session creation; + // non-THP devices re-request it mid-operation and are answered from the same value. + uiHandler.setWalletMode(mode, hostPassphrase: passphrase) + walletMode = mode + + do { + let features = try await trezorService.connect(deviceId: device.path, selection: uiHandler.currentSelection()) + connectedDevice = device + deviceFeatures = features + showConfirmOnDevice = false + trezorLog("Reconnected with wallet mode \(mode)") + } catch { + clearDisconnectedDeviceState(errorMessage: errorMessage(from: error)) + trezorLog("Reconnect after wallet-mode switch failed: \(error)", level: "error") + } + } + + /// Submit pairing code from UI + func submitPairingCode(_ code: String) { + showPairingCode = false + transport.submitPairingCode(code) + } + + /// Cancel pairing code entry + func cancelPairingCode() { + showPairingCode = false + transport.cancelPairingCode() + } + + /// Dismiss confirm on device overlay + func dismissConfirmOnDevice() { + showConfirmOnDevice = false + confirmMessage = "" + } + + // MARK: - Known Devices + + /// Load known devices from storage + func loadKnownDevices() { + knownDevices = TrezorKnownDeviceStorage.loadAll() + } + + /// Save the currently connected device as a known device, capturing its account + /// xpubs so watch-only balances/activity stay available while disconnected. + func saveCurrentDeviceAsKnown() async { + guard let device = connectedDevice else { return } + let previous = TrezorKnownDeviceStorage.loadAll().first { $0.id == device.id } + let fetched = await fetchAccountXpubs() + let mergedXpubs = (previous?.xpubs ?? [:]).merging(fetched) { _, new in new } + let known = TrezorKnownDevice( + id: device.id, + name: device.name ?? "Trezor", + path: device.path, + transportType: device.transportType == .bluetooth ? "bluetooth" : "usb", + label: device.label ?? deviceFeatures?.label, + model: device.model ?? deviceFeatures?.model, + lastConnectedAt: Date(), + xpubs: mergedXpubs + ) + TrezorKnownDeviceStorage.save(known) + loadKnownDevices() + trezorLog("Saved known device: \(known.name) with \(mergedXpubs.count) xpubs") + } + + /// Read the account-level xpub for every address type from the connected device. + /// Per-type failures are swallowed so a single missing type doesn't block the rest. + func fetchAccountXpubs() async -> [String: String] { + var result: [String: String] = [:] + for addressType in HwAddressType.allCases { + do { + let params = TrezorGetPublicKeyParams( + path: addressType.accountDerivationPath(network: selectedNetwork), + coin: selectedNetwork, + showOnTrezor: false + ) + let response = try await trezorService.getPublicKey(params: params) + result[addressType.settingsString] = response.xpub + } catch { + trezorLog("Could not read xpub for '\(addressType.settingsString)': \(error)", level: "warn") + } + } + return result + } + + /// Forget a known device — removes from storage and clears credentials + func forgetDevice(id: String) async { + // Find the device to get its path for credential clearing + if let device = knownDevices.first(where: { $0.id == id }) { + do { + try await trezorService.clearCredentials(deviceId: device.path) + } catch { + trezorLog("Failed to clear credentials for forgotten device: \(error)", level: "warn") + } + TrezorCredentialStorage.delete(deviceId: device.path) + } + TrezorKnownDeviceStorage.remove(id: id) + loadKnownDevices() + trezorLog("Forgot device: \(id)") + } + + // MARK: - Auto-Reconnect + + /// Automatically scan and reconnect to the first matching known device + func autoReconnect() async { + guard !knownDevices.isEmpty else { return } + guard !isAutoReconnecting else { return } + if suppressNextAutoReconnect { + suppressNextAutoReconnect = false + trezorLog("Auto-reconnect: skipped after manual disconnect") + return + } + + isAutoReconnecting = true + autoReconnectStatus = "Scanning for known devices..." + trezorLog("Auto-reconnect: starting scan") + + await startScan(clearExisting: true) + + // Find the first scanned device that matches a known device + let knownIds = Set(knownDevices.map(\.id)) + if let match = devices.first(where: { knownIds.contains($0.id) }) { + autoReconnectStatus = "Connecting to \(match.label ?? match.name ?? "Trezor")..." + trezorLog("Auto-reconnect: found known device \(match.path)") + await connect(device: match) + } else { + autoReconnectStatus = nil + trezorLog("Auto-reconnect: no known devices found nearby") + } + + isAutoReconnecting = false + autoReconnectStatus = nil + } + + // MARK: - Electrum URL Helpers + + // MARK: - Network Switching + + /// Switch the dashboard's network independently of the app's global network + func setSelectedNetwork(_ network: TrezorCoinType) { + guard network != selectedNetwork else { return } + selectedNetwork = network + error = nil + trezorLog("Switched dashboard network to \(network)") + } + + // MARK: - Credential Management + + /// Clear stored credentials for current device + func clearCredentials() async { + guard let device = connectedDevice else { + error = "No device connected" + return + } + + do { + try await trezorService.clearCredentials(deviceId: device.path) + trezorLog("Cleared credentials for \(device.path)") + } catch { + self.error = errorMessage(from: error) + trezorLog("Failed to clear credentials: \(error)", level: "error") + } + } + + // MARK: - Error Handling + + /// Extract a user-friendly error message from a Trezor error + private func errorMessage(from error: Error) -> String { + // ServiceQueue wraps all errors in AppError, so extract the original message + if let appError = error as? AppError { + // debugMessage contains the original error's localizedDescription + if let debugMessage = appError.debugMessage, !debugMessage.isEmpty { + // Check for common Trezor error patterns in the debug message + return formatTrezorErrorMessage(debugMessage) + } + // Fall through to show the app error message if no debug info + return appError.message + } + + // Handle TrezorError directly (if not wrapped) + if let trezorError = error as? TrezorError { + return trezorError.localizedDescription + } + + // Handle TrezorBLEError from BLE layer + if let bleError = error as? TrezorBLEError { + return bleError.localizedDescription + } + + // Handle TrezorTransportError from transport layer + if let transportError = error as? TrezorTransportError { + return transportError.localizedDescription + } + + // For any other error, try to get a meaningful description + let description = error.localizedDescription + if description == "The operation couldn't be completed." || description.isEmpty { + return "Connection failed. Please ensure your Trezor is in pairing mode and try again." + } + return description + } + + /// Format Trezor error messages for user display + private func formatTrezorErrorMessage(_ message: String) -> String { + // Clean up common Trezor error prefixes for better readability + let cleanedMessage = message + .replacingOccurrences(of: "Transport error: ", with: "") + .replacingOccurrences(of: "Connection error: ", with: "") + .replacingOccurrences(of: "Protocol error: ", with: "") + .replacingOccurrences(of: "Device error: ", with: "") + .replacingOccurrences(of: "Session error: ", with: "") + .replacingOccurrences(of: "IO error: ", with: "") + + // Map technical messages to user-friendly ones + if message.contains("Stale Bluetooth pairing") || message.contains("Peer removed pairing") { + return "Stale Bluetooth pairing detected. Go to iOS Settings → Bluetooth, forget your Trezor device, then put it back in pairing mode and try again." + } + if message.contains("Unable to open device") || message.contains("Failed to connect") { + return "Failed to connect to Trezor. Please ensure it's in pairing mode and try again." + } + if message.contains("Pairing required") { + return "Bluetooth pairing required. Please put your Trezor in pairing mode." + } + if message.contains("Pairing failed") || message.contains("Invalid credentials") { + return "Pairing failed. Please try putting your Trezor back in pairing mode." + } + if message.contains("THP handshake failed") { + return "Connection handshake failed. Please disconnect and try again." + } + if message.contains("timed out") || message.contains("Timeout") { + return "Connection timed out. Please try again." + } + if message.contains("Device disconnected") { + return "Trezor disconnected. Please reconnect and try again." + } + if message.contains("Action cancelled") { + return "Action was cancelled on the device." + } + + // Return the cleaned message if no specific mapping + return cleanedMessage + } +} diff --git a/Bitkit/Models/HwWallet.swift b/Bitkit/Models/HwWallet.swift index 62b078cee..4fe3dba4d 100644 --- a/Bitkit/Models/HwWallet.swift +++ b/Bitkit/Models/HwWallet.swift @@ -4,7 +4,7 @@ import Foundation /// A paired hardware wallet tracked as a watch-only balance. /// /// Activities are NOT held here — they are persisted in bitkit-core scoped by `walletId` -/// and read back through the normal activity pipeline (see `HwWalletRepo`). +/// and read back through the normal activity pipeline (see `HwWalletManager`). struct HwWallet: Identifiable { let id: String /// bitkit-core wallet id scoping this device's activities (see `HwWalletId`). diff --git a/Bitkit/Services/Trezor/TrezorService.swift b/Bitkit/Services/Trezor/TrezorService.swift index a31d4052f..ba45668b9 100644 --- a/Bitkit/Services/Trezor/TrezorService.swift +++ b/Bitkit/Services/Trezor/TrezorService.swift @@ -327,3 +327,46 @@ class TrezorService { Logger.info("Cleared credentials for device: \(deviceId)", context: "TrezorService") } } + +// MARK: - Network / Electrum helpers + +/// Network- and Electrum-derivation helpers shared by all Trezor consumers (`TrezorManager`, +/// `TrezorViewModel`, `HwWalletManager`). They live on the service layer so feature managers +/// don't reference each other for plain network/electrum configuration. +extension TrezorService { + /// The app's global network mapped to a `TrezorCoinType`. + static var appDefaultCoinType: TrezorCoinType { + switch Env.network { + case .bitcoin: .bitcoin + case .testnet: .testnet + case .signet: .signet + case .regtest: .regtest + } + } + + /// BIP44 coin-type component for the app's global network: "0'" mainnet, "1'" test networks. + static var defaultCoinTypeComponent: String { + Env.network == .bitcoin ? "0'" : "1'" + } + + /// Hardcoded Electrum server URL per network (with the regtest dev override). + static func electrumUrlForNetwork(_ network: TrezorCoinType) -> String { + if network == .regtest, let trezorElectrumUrl = Env.trezorElectrumUrl { + return trezorElectrumUrl + } + switch network { + case .bitcoin: + return "ssl://bitkit.to:9999" + case .testnet, .signet: + return "ssl://electrum.blockstream.info:60002" + case .regtest: + return "ssl://electrs.bitkit.stag0.blocktank.to:9999" + } + } + + /// The app's configured Electrum server (falls back to the default). + static func getElectrumUrl() -> String { + let server = ElectrumConfigService().getCurrentServer() + return server.fullUrl.isEmpty ? Env.electrumServerUrl : server.fullUrl + } +} diff --git a/Bitkit/Utilities/AppReset.swift b/Bitkit/Utilities/AppReset.swift index bcc9e9acb..25f8faa97 100644 --- a/Bitkit/Utilities/AppReset.swift +++ b/Bitkit/Utilities/AppReset.swift @@ -25,7 +25,7 @@ enum AppReset { // Stop any running watch-only hardware-wallet watchers. Their persisted xpubs/known // devices and activities are cleared below by the UserDefaults/keychain/core-DB wipes; - // the app-lifetime HwWalletRepo is rebuilt by session.bump() at the end of this wipe. + // the app-lifetime HwWalletManager is rebuilt by session.bump() at the end of this wipe. TrezorService.shared.stopAllWatchers() // Stop node and wipe LDK persistence via the wallet API. diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index 7c4b04dae..98368d8d5 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -1,6 +1,5 @@ import BitkitCore import Combine -import CoreBluetooth import Foundation /// Represents the current step in the send transaction flow @@ -59,98 +58,30 @@ enum TrezorAccountTypeSelection: String, CaseIterable, Identifiable, CustomStrin } } -/// ViewModel for Trezor hardware wallet integration +/// ViewModel for the Trezor hardware-wallet dev/dashboard screens. Owns only the dev-screen +/// tools (address generation, signing, lookups, the single dev watcher, etc.); device/connection +/// orchestration and pairing/PIN/passphrase coordination live in `TrezorManager`, injected here +/// as `connection`. @Observable @MainActor class TrezorViewModel { - // MARK: - Network Configuration + // MARK: - Connection Manager - /// The network selected in the Trezor dashboard (independent of app's global network) - var selectedNetwork: TrezorCoinType + /// Device/connection orchestration and pairing/PIN/passphrase coordination. + let connection: TrezorManager - /// Map the app's current network to the corresponding TrezorCoinType (used for default initialization) - static var appDefaultCoinType: TrezorCoinType { - switch Env.network { - case .bitcoin: .bitcoin - case .testnet: .testnet - case .signet: .signet - case .regtest: .regtest - } - } - - /// BIP44 coin type component based on the dashboard's selected network: "0'" for mainnet, "1'" for test networks - var coinTypeComponent: String { - selectedNetwork == .bitcoin ? "0'" : "1'" - } - - /// BIP44 coin type component based on the app's global network (used for initial default values) - private static var defaultCoinTypeComponent: String { - Env.network == .bitcoin ? "0'" : "1'" - } - - // MARK: - Connection State - - /// Whether the Trezor manager is initialized - private var isInitialized: Bool = false - - /// Whether currently scanning for devices - var isScanning: Bool = false + // MARK: - Operation State /// Whether currently performing an operation (address, signing, etc.) var isOperating: Bool = false - /// List of discovered devices - var devices: [TrezorDeviceInfo] = [] - - /// Currently connected device - var connectedDevice: TrezorDeviceInfo? - - /// Features of the connected device - var deviceFeatures: TrezorFeatures? - - /// Device root fingerprint (hex string) - var deviceFingerprint: String? - - /// Last error message + /// Last error message from a dev operation var error: String? - // MARK: - UI Dialog State - - /// Show PIN entry dialog - var showPinEntry: Bool = false - - /// Show passphrase entry dialog - var showPassphraseEntry: Bool = false - - /// Show BLE pairing code dialog - var showPairingCode: Bool = false - - /// Show "Confirm on device" overlay - var showConfirmOnDevice: Bool = false - - /// Message for confirm on device overlay - var confirmMessage: String = "" - - /// Show the "where to enter the passphrase" chooser (phone vs Trezor). - /// Only presented for devices that report on-device passphrase entry capability. - var showWalletModeChooser: Bool = false - - // MARK: - Wallet Mode State - - /// The currently selected wallet mode (standard / hidden-on-phone / hidden-on-device). - /// Drives the wallet-mode selector UI; the binding to the device session is applied - /// via setWalletMode (disconnect/reconnect). - var walletMode: TrezorWalletMode = .standard - - /// Whether the connected device supports entering the passphrase on the Trezor itself. - var passphraseEntryCapable: Bool { - deviceFeatures?.passphraseEntryCapable == true - } - // MARK: - Address Generation State /// Current derivation path - var derivationPath: String = "m/84'/\(defaultCoinTypeComponent)/0'/0/0" + var derivationPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'/0/0" /// Current script type for address generation var selectedScriptType: TrezorScriptType = .spendWitness @@ -167,26 +98,11 @@ class TrezorViewModel { var messageToSign: String = "Hello, Trezor!" /// Path for message signing - var messageSigningPath: String = "m/84'/\(defaultCoinTypeComponent)/0'/0/0" + var messageSigningPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'/0/0" /// Signed message result var signedMessage: TrezorSignedMessageResponse? - // MARK: - Known Devices & Auto-Reconnect - - /// Previously connected devices loaded from storage - var knownDevices: [TrezorKnownDevice] = [] - - /// Whether auto-reconnect is in progress - var isAutoReconnecting: Bool = false - - /// Status text during auto-reconnect - var autoReconnectStatus: String? - - /// Prevents a user-initiated disconnect from immediately reconnecting - /// when the disconnected device list appears. - private var suppressNextAutoReconnect = false - // MARK: - Address Index /// Current address index (last path component) @@ -195,7 +111,7 @@ class TrezorViewModel { // MARK: - Public Key State /// Account-level derivation path for public key - var publicKeyPath: String = "m/84'/\(defaultCoinTypeComponent)/0'" + var publicKeyPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'" /// Retrieved xpub string var xpub: String? @@ -356,57 +272,16 @@ class TrezorViewModel { !watcherEvents.isEmpty } - // MARK: - Bluetooth State - - /// Current Bluetooth state — reads directly from BLEManager (@Observable chaining) - var bluetoothState: CBManagerState { - TrezorBLEManager.shared.bluetoothState - } - - var isBridgeModeEnabled: Bool { - transport.isBridgeEnabled - } - // MARK: - Private Properties private let trezorService = TrezorService.shared private let watcherService: TrezorWatcherServicing - private let transport = TrezorTransport.shared - private let uiHandler = TrezorUiHandler.shared - private var cancellables = Set() - private var hasSetupSubscriptions = false // MARK: - Initialization - init(watcherService: TrezorWatcherServicing = TrezorService.shared) { + init(connection: TrezorManager, watcherService: TrezorWatcherServicing = TrezorService.shared) { + self.connection = connection self.watcherService = watcherService - selectedNetwork = Self.appDefaultCoinType - // Callback subscriptions are deferred to initialize() to avoid - // triggering BLE stack and Combine overhead at app launch. - } - - /// Subscribe to callback publishers for UI notifications - private func setupCallbackSubscriptions() { - // Pairing code request - transport.needsPairingCodePublisher - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.showPairingCode = true - } - .store(in: &cancellables) - - // PIN request from device - uiHandler.needsPinPublisher - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.showPinEntry = true - } - .store(in: &cancellables) - - // Passphrase entry is now driven proactively by the wallet-mode selector - // (see setWalletMode / requestPassphraseWallet). The device callback - // `onPassphraseRequest` is answered silently from the selected mode, so there - // is no reactive passphrase prompt to subscribe to here. } // MARK: - Debug Log Helper @@ -424,185 +299,12 @@ class TrezorViewModel { TrezorDebugLog.shared.log(message) } - // MARK: - State Reset Helpers - - func clearWalletDerivedState() { - deviceFingerprint = nil - generatedAddress = nil - signedMessage = nil - xpub = nil - publicKeyHex = nil - } - - func clearDisconnectedDeviceState(errorMessage: String? = nil) { - connectedDevice = nil - deviceFeatures = nil - clearWalletDerivedState() - error = errorMessage - showPinEntry = false - showPassphraseEntry = false - showConfirmOnDevice = false - showWalletModeChooser = false - uiHandler.setWalletMode(.standard) - walletMode = .standard - } - - // MARK: - Manager Setup - - /// Set up subscriptions and start BLE stack (synchronous, non-blocking). - /// Called from TrezorRootView's .task to prepare the UI layer. - func setup() { - guard !hasSetupSubscriptions else { return } - if !transport.isBridgeEnabled { - // Start BLE stack early so bluetoothState is updated by the time - // TrezorDeviceListView renders (the delegate callback fires async). - TrezorBLEManager.shared.ensureStarted() - } - setupCallbackSubscriptions() - hasSetupSubscriptions = true - } - - /// Initialize the Trezor FFI manager (async, may be slow). - /// Called lazily before first scan/connect. - func initialize() async { - setup() - - guard !isInitialized else { return } - - do { - try await trezorService.initialize() - isInitialized = true - error = nil - trezorLog("TrezorViewModel initialized") - } catch { - self.error = errorMessage(from: error) - trezorLog("Failed to initialize Trezor: \(error)", level: "error") - } - } - - // MARK: - Device Scanning - - /// Start scanning for Trezor devices - /// - Parameter clearExisting: Whether to clear existing device list before scanning - func startScan(clearExisting: Bool = true) async { - if !isInitialized { - await initialize() - } - - isScanning = true - error = nil - - if clearExisting { - devices = [] - } - - if !transport.isBridgeEnabled { - // Start BLE scanning - transport.startBLEScanning() - - // Wait for BLE to discover devices (like Android's 3-second scan) - // This ensures devices are found before we call the FFI enumerate - try? await Task.sleep(nanoseconds: 3_000_000_000) // 3 seconds - - // Stop BLE scanning before calling FFI to prevent race conditions - transport.stopBLEScanning() - } - - do { - // Trigger FFI scan which will use our transport callbacks - let foundDevices = try await trezorService.scan() - - // Deduplicate by path (in case of duplicate scan results) - var seenPaths = Set() - let uniqueDevices = foundDevices.filter { device in - if seenPaths.contains(device.path) { - return false - } - seenPaths.insert(device.path) - return true - } - - devices = uniqueDevices - trezorLog("Found \(uniqueDevices.count) Trezor devices (filtered from \(foundDevices.count))") - } catch { - self.error = errorMessage(from: error) - trezorLog("Scan failed: \(error)", level: "error") - } - - isScanning = false - } - - /// Stop scanning for devices - func stopScan() { - transport.stopBLEScanning() - isScanning = false - } - - // MARK: - Connection - - /// Connect to a device - func connect(device: TrezorDeviceInfo) async { - error = nil - suppressNextAutoReconnect = false - - // Explicit user-initiated connect always opens the standard wallet — a - // passphrase/on-device selection left over from a previously connected device - // must not silently apply to a newly selected one. - uiHandler.setWalletMode(.standard) - walletMode = .standard - - trezorLog("=== Connecting to device: \(device.path) ===") - - do { - let features = try await trezorService.connect(deviceId: device.path, selection: uiHandler.currentSelection()) - connectedDevice = device - deviceFeatures = features - showConfirmOnDevice = false - - await saveCurrentDeviceAsKnown() - trezorLog("Connected to Trezor: \(device.path)") - } catch { - let errorMsg = errorMessage(from: error) - self.error = errorMsg - showConfirmOnDevice = false - trezorLog("Connection failed: \(error)", level: "error") - } - } - - /// Disconnect from current device - func disconnect() async { - guard connectedDevice != nil else { return } - suppressNextAutoReconnect = true - - // NOTE: the event watcher is intentionally NOT stopped here. It subscribes to - // Electrum directly and does not require a connected device, so it survives a - // disconnect and remains controllable from the device-list screen. It is only - // torn down on a network switch (different Electrum server) or via stopWatcher(). - - do { - try await trezorService.disconnect() - // Clear connection state but preserve device list for quick reconnection - clearDisconnectedDeviceState() - - trezorLog("Disconnected from Trezor") - } catch { - // Even if disconnect fails, clear local state - clearDisconnectedDeviceState(errorMessage: errorMessage(from: error)) - trezorLog("Disconnect failed: \(error)", level: "error") - } - } - - /// Check if currently connected - var isConnected: Bool { - connectedDevice != nil - } - // MARK: - Address Operations /// Get address from connected device /// - Parameter showOnDevice: Whether to display address on Trezor screen func getAddress(showOnDevice: Bool = true) async { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return } @@ -613,19 +315,19 @@ class TrezorViewModel { do { let params = TrezorGetAddressParams( path: derivationPath, - coin: selectedNetwork, + coin: connection.selectedNetwork, showOnTrezor: showOnDevice, scriptType: selectedScriptType ) let response = try await trezorService.getAddress(params: params) generatedAddress = response.address - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Generated address: \(response.address)") } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Get address failed: \(error)", level: "error") } @@ -636,7 +338,7 @@ class TrezorViewModel { /// Sign a message with the connected device func signMessage() async { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return } @@ -653,17 +355,17 @@ class TrezorViewModel { let params = TrezorSignMessageParams( path: messageSigningPath, message: messageToSign, - coin: selectedNetwork + coin: connection.selectedNetwork ) let response = try await trezorService.signMessage(params: params) signedMessage = response - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Message signed successfully") } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Sign message failed: \(error)", level: "error") } @@ -672,7 +374,7 @@ class TrezorViewModel { /// Verify a signed message func verifyMessage(address: String, signature: String, message: String) async -> Bool { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return false } @@ -685,11 +387,11 @@ class TrezorViewModel { address: address, signature: signature, message: message, - coin: selectedNetwork + coin: connection.selectedNetwork ) let isValid = try await trezorService.verifyMessage(params: params) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Message verification result: \(isValid)") @@ -697,7 +399,7 @@ class TrezorViewModel { return isValid } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Verify message failed: \(error)", level: "error") isOperating = false @@ -705,229 +407,6 @@ class TrezorViewModel { } } - // MARK: - UI Callbacks - - /// Submit PIN from UI - func submitPin(_ pin: String) { - showPinEntry = false - uiHandler.submitPin(pin) - } - - /// Cancel PIN entry - func cancelPin() { - showPinEntry = false - uiHandler.cancelPin() - } - - /// Submit a host-entered passphrase from the UI — opens the corresponding hidden - /// wallet (or the standard wallet when empty) by resetting the session. - func submitPassphrase(_ passphrase: String) async { - showPassphraseEntry = false - showConfirmOnDevice = false - await setWalletMode(passphrase.isEmpty ? .standard : .passphraseHost, passphrase: passphrase) - } - - /// Cancel passphrase entry - func cancelPassphrase() { - showPassphraseEntry = false - showConfirmOnDevice = false - showWalletModeChooser = false - } - - // MARK: - Wallet Mode Selection - - /// User tapped the "Standard" wallet option in the selector. - func selectStandardWallet() async { - guard walletMode != .standard else { return } - await setWalletMode(.standard) - } - - /// User tapped the "Passphrase" wallet option. On a capable device this offers a - /// choice of where to enter the passphrase; otherwise it goes straight to host entry. - func requestPassphraseWallet() { - if passphraseEntryCapable { - showWalletModeChooser = true - } else { - showPassphraseEntry = true - } - } - - /// Wallet-mode chooser: user chose to enter the passphrase on this phone. - func choosePhonePassphraseEntry() { - showWalletModeChooser = false - showPassphraseEntry = true - } - - /// Wallet-mode chooser: user chose to enter the passphrase on the Trezor. - func chooseDevicePassphraseEntry() async { - showWalletModeChooser = false - await setWalletMode(.passphraseDevice) - } - - /// Switch between wallet modes. The Trezor caches the passphrase for the whole - /// session, so switching requires a fresh session: this records the desired mode, - /// then disconnects and reconnects by path. Mirrors bitkit-android's setWalletMode. - func setWalletMode(_ mode: TrezorWalletMode, passphrase: String = "") async { - guard let device = connectedDevice else { - error = "Not connected to a Trezor" - return - } - - isOperating = true - error = nil - trezorLog("=== Switching wallet mode to \(mode); resetting session ===") - - // Reset the session. We call the service directly (not the VM's disconnect()) - // so connectedDevice/deviceFeatures stay populated for the reconnect. - do { - try await trezorService.disconnect() - } catch { - trezorLog("Disconnect before wallet-mode switch failed: \(error)", level: "warn") - } - - // Results derived from the previous wallet are no longer valid once the - // session has been reset for a different wallet mode. - clearWalletDerivedState() - - // Brief settle delay before reconnecting (matches Android's reconnect delay). - try? await Task.sleep(nanoseconds: 300_000_000) - - // Record the selection AFTER the disconnect so it survives into the new session. - // THP reads it via currentSelection() to bind the passphrase at session creation; - // non-THP devices re-request it mid-operation and are answered from the same value. - uiHandler.setWalletMode(mode, hostPassphrase: passphrase) - walletMode = mode - - do { - let features = try await trezorService.connect(deviceId: device.path, selection: uiHandler.currentSelection()) - connectedDevice = device - deviceFeatures = features - showConfirmOnDevice = false - trezorLog("Reconnected with wallet mode \(mode)") - } catch { - clearDisconnectedDeviceState(errorMessage: errorMessage(from: error)) - trezorLog("Reconnect after wallet-mode switch failed: \(error)", level: "error") - } - - isOperating = false - } - - /// Submit pairing code from UI - func submitPairingCode(_ code: String) { - showPairingCode = false - transport.submitPairingCode(code) - } - - /// Cancel pairing code entry - func cancelPairingCode() { - showPairingCode = false - transport.cancelPairingCode() - } - - /// Dismiss confirm on device overlay - func dismissConfirmOnDevice() { - showConfirmOnDevice = false - confirmMessage = "" - } - - // MARK: - Known Devices - - /// Load known devices from storage - func loadKnownDevices() { - knownDevices = TrezorKnownDeviceStorage.loadAll() - } - - /// Save the currently connected device as a known device, capturing its account - /// xpubs so watch-only balances/activity stay available while disconnected. - func saveCurrentDeviceAsKnown() async { - guard let device = connectedDevice else { return } - let previous = TrezorKnownDeviceStorage.loadAll().first { $0.id == device.id } - let fetched = await fetchAccountXpubs() - let mergedXpubs = (previous?.xpubs ?? [:]).merging(fetched) { _, new in new } - let known = TrezorKnownDevice( - id: device.id, - name: device.name ?? "Trezor", - path: device.path, - transportType: device.transportType == .bluetooth ? "bluetooth" : "usb", - label: device.label ?? deviceFeatures?.label, - model: device.model ?? deviceFeatures?.model, - lastConnectedAt: Date(), - xpubs: mergedXpubs - ) - TrezorKnownDeviceStorage.save(known) - loadKnownDevices() - trezorLog("Saved known device: \(known.name) with \(mergedXpubs.count) xpubs") - } - - /// Read the account-level xpub for every address type from the connected device. - /// Per-type failures are swallowed so a single missing type doesn't block the rest. - func fetchAccountXpubs() async -> [String: String] { - var result: [String: String] = [:] - for addressType in HwAddressType.allCases { - do { - let params = TrezorGetPublicKeyParams( - path: addressType.accountDerivationPath(network: selectedNetwork), - coin: selectedNetwork, - showOnTrezor: false - ) - let response = try await trezorService.getPublicKey(params: params) - result[addressType.settingsString] = response.xpub - } catch { - trezorLog("Could not read xpub for '\(addressType.settingsString)': \(error)", level: "warn") - } - } - return result - } - - /// Forget a known device — removes from storage and clears credentials - func forgetDevice(id: String) async { - // Find the device to get its path for credential clearing - if let device = knownDevices.first(where: { $0.id == id }) { - do { - try await trezorService.clearCredentials(deviceId: device.path) - } catch { - trezorLog("Failed to clear credentials for forgotten device: \(error)", level: "warn") - } - TrezorCredentialStorage.delete(deviceId: device.path) - } - TrezorKnownDeviceStorage.remove(id: id) - loadKnownDevices() - trezorLog("Forgot device: \(id)") - } - - // MARK: - Auto-Reconnect - - /// Automatically scan and reconnect to the first matching known device - func autoReconnect() async { - guard !knownDevices.isEmpty else { return } - guard !isAutoReconnecting else { return } - if suppressNextAutoReconnect { - suppressNextAutoReconnect = false - trezorLog("Auto-reconnect: skipped after manual disconnect") - return - } - - isAutoReconnecting = true - autoReconnectStatus = "Scanning for known devices..." - trezorLog("Auto-reconnect: starting scan") - - await startScan(clearExisting: true) - - // Find the first scanned device that matches a known device - let knownIds = Set(knownDevices.map(\.id)) - if let match = devices.first(where: { knownIds.contains($0.id) }) { - autoReconnectStatus = "Connecting to \(match.label ?? match.name ?? "Trezor")..." - trezorLog("Auto-reconnect: found known device \(match.path)") - await connect(device: match) - } else { - autoReconnectStatus = nil - trezorLog("Auto-reconnect: no known devices found nearby") - } - - isAutoReconnecting = false - autoReconnectStatus = nil - } - // MARK: - Address Index /// Increment the address index and update derivation path @@ -955,7 +434,7 @@ class TrezorViewModel { /// Get public key (xpub) from connected device func getPublicKey(showOnDevice: Bool = false) async { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return } @@ -966,19 +445,19 @@ class TrezorViewModel { do { let params = TrezorGetPublicKeyParams( path: publicKeyPath, - coin: selectedNetwork, + coin: connection.selectedNetwork, showOnTrezor: showOnDevice ) let response = try await trezorService.getPublicKey(params: params) xpub = response.xpub publicKeyHex = response.publicKey - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Got public key for path: \(publicKeyPath)") } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Get public key failed: \(error)", level: "error") } @@ -989,7 +468,7 @@ class TrezorViewModel { /// Sign a Bitcoin transaction func signTx(params: TrezorSignTxParams) async -> TrezorSignedTx? { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return nil } @@ -999,13 +478,13 @@ class TrezorViewModel { do { let result = try await trezorService.signTx(params: params) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Transaction signed successfully") isOperating = false return result } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Sign tx failed: \(error)", level: "error") isOperating = false return nil @@ -1018,7 +497,7 @@ class TrezorViewModel { /// - Parameter psbtBase64: Base64-encoded PSBT data /// - Returns: The signed transaction, or nil on failure func signTxFromPsbt(psbtBase64: String) async -> TrezorSignedTx? { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return nil } @@ -1029,15 +508,15 @@ class TrezorViewModel { do { let result = try await trezorService.signTxFromPsbt( psbtBase64: psbtBase64, - network: selectedNetwork + network: connection.selectedNetwork ) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("PSBT signed successfully") isOperating = false return result } catch { self.error = errorMessage(from: error) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("Sign PSBT failed: \(error)", level: "error") isOperating = false return nil @@ -1048,7 +527,7 @@ class TrezorViewModel { /// Get the device's master root fingerprint func getDeviceFingerprint() async { - guard isConnected else { + guard connection.isConnected else { error = "Not connected to a Trezor" return } @@ -1058,7 +537,7 @@ class TrezorViewModel { do { let fingerprint = try await trezorService.getDeviceFingerprint() - deviceFingerprint = fingerprint + connection.deviceFingerprint = fingerprint trezorLog("Device fingerprint: \(fingerprint)") } catch { self.error = errorMessage(from: error) @@ -1068,45 +547,18 @@ class TrezorViewModel { isOperating = false } - // MARK: - Electrum URL Helpers - - /// Get the Electrum server URL for a specific network (hardcoded per-network URLs) - static func electrumUrlForNetwork(_ network: TrezorCoinType) -> String { - if network == .regtest, let trezorElectrumUrl = Env.trezorElectrumUrl { - return trezorElectrumUrl - } - - switch network { - case .bitcoin: - return "ssl://bitkit.to:9999" - case .testnet, .signet: - return "ssl://electrum.blockstream.info:60002" - case .regtest: - return "ssl://electrs.bitkit.stag0.blocktank.to:9999" - } - } - - /// Get the current Electrum server URL from configuration (uses app's configured server) - static func getElectrumUrl() -> String { - let configService = ElectrumConfigService() - let server = configService.getCurrentServer() - return server.fullUrl.isEmpty ? Env.electrumServerUrl : server.fullUrl - } - // MARK: - Network Switching - /// Switch the dashboard's network independently of the app's global network - func setSelectedNetwork(_ network: TrezorCoinType) { - guard network != selectedNetwork else { return } - selectedNetwork = network - + /// React to a dashboard network switch by resetting the dev-tool derivation paths, + /// results and the dev watcher. The network change itself is owned by `TrezorManager`. + func handleNetworkChange() { // A running watcher is bound to the previous network's Electrum server. stopWatcher() // Reset derivation paths with the new coin type - derivationPath = "m/84'/\(coinTypeComponent)/0'/0/0" - publicKeyPath = "m/84'/\(coinTypeComponent)/0'" - messageSigningPath = "m/84'/\(coinTypeComponent)/0'/0/0" + derivationPath = "m/84'/\(connection.coinTypeComponent)/0'/0/0" + publicKeyPath = "m/84'/\(connection.coinTypeComponent)/0'" + messageSigningPath = "m/84'/\(connection.coinTypeComponent)/0'/0/0" addressIndex = 0 // Clear results from previous network @@ -1119,8 +571,6 @@ class TrezorViewModel { addressResult = nil lookupError = nil resetSendFlow() - - trezorLog("Switched dashboard network to \(network)") } // MARK: - Balance Lookup Operations @@ -1161,7 +611,7 @@ class TrezorViewModel { addressResult = nil resetSendFlow() - let electrumUrl = Self.electrumUrlForNetwork(selectedNetwork) + let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) do { switch Self.detectInputType(trimmedInput) { @@ -1169,14 +619,14 @@ class TrezorViewModel { accountResult = try await trezorService.getAccountInfo( extendedKey: trimmedInput, electrumUrl: electrumUrl, - network: selectedNetwork, + network: connection.selectedNetwork, scriptType: onchainAccountTypeSelection.accountType ) case .address: addressResult = try await trezorService.getAddressInfo( address: trimmedInput, electrumUrl: electrumUrl, - network: selectedNetwork + network: connection.selectedNetwork ) case .unknown: lookupError = "Unrecognized input. Enter a Bitcoin address or extended public key (xpub/ypub/zpub/tpub/upub/vpub)." @@ -1233,13 +683,13 @@ class TrezorViewModel { txHistoryError = nil txHistoryResult = nil - let electrumUrl = Self.electrumUrlForNetwork(selectedNetwork) + let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) do { txHistoryResult = try await trezorService.getTransactionHistory( extendedKey: trimmedKey, electrumUrl: electrumUrl, - network: selectedNetwork, + network: connection.selectedNetwork, scriptType: onchainAccountTypeSelection.accountType ) } catch { @@ -1261,14 +711,14 @@ class TrezorViewModel { txDetailError = nil txDetailResult = nil - let electrumUrl = Self.electrumUrlForNetwork(selectedNetwork) + let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) do { txDetailResult = try await trezorService.getTransactionDetail( extendedKey: trimmedKey, electrumUrl: electrumUrl, txid: trimmedTxid, - network: selectedNetwork, + network: connection.selectedNetwork, scriptType: onchainAccountTypeSelection.accountType ) } catch { @@ -1318,9 +768,9 @@ class TrezorViewModel { // Ensure we have the device fingerprint for proper PSBT derivation paths. // Without it, BDK produces relative paths (e.g. m/0/0) that the Trezor // rejects as "Forbidden key path". - if deviceFingerprint == nil { + if connection.deviceFingerprint == nil { do { - deviceFingerprint = try await trezorService.getDeviceFingerprint() + connection.deviceFingerprint = try await trezorService.getDeviceFingerprint() } catch { trezorLog("Failed to get device fingerprint: \(error)", level: "error") sendError = "Failed to get device fingerprint" @@ -1338,13 +788,13 @@ class TrezorViewModel { ? .sendMax(address: address) : .payment(address: address, amountSats: UInt64(sendAmountSats) ?? 0) - let electrumUrl = Self.electrumUrlForNetwork(selectedNetwork) - let network = toNetwork(selectedNetwork) + let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let network = toNetwork(connection.selectedNetwork) let wallet = WalletParams( extendedKey: extendedKey, electrumUrl: electrumUrl, - fingerprint: deviceFingerprint, + fingerprint: connection.deviceFingerprint, network: network, accountType: accountInfo.accountType ) @@ -1413,7 +863,7 @@ class TrezorViewModel { return } - guard isConnected else { + guard connection.isConnected else { sendError = "Not connected to a Trezor" return } @@ -1429,9 +879,9 @@ class TrezorViewModel { trezorLog("Calling trezor signTxFromPsbt...") let signedTx = try await trezorService.signTxFromPsbt( psbtBase64: psbt, - network: selectedNetwork + network: connection.selectedNetwork ) - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("=== signComposedTx SUCCESS ===") trezorLog("signatures=\(signedTx.signatures.count), txid=\(signedTx.txid ?? "nil"), rawTxLen=\(signedTx.serializedTx.count)") @@ -1439,7 +889,7 @@ class TrezorViewModel { signedTxResult = signedTx sendStep = .signed } catch { - showConfirmOnDevice = false + connection.showConfirmOnDevice = false trezorLog("signComposedTx FAILED: \(error)", level: "error") sendError = errorMessage(from: error) } @@ -1454,7 +904,7 @@ class TrezorViewModel { isBroadcasting = true sendError = nil - let electrumUrl = Self.electrumUrlForNetwork(selectedNetwork) + let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) do { let txid = try await trezorService.broadcastRawTx(serializedTx: rawTx, electrumUrl: electrumUrl) @@ -1583,24 +1033,6 @@ class TrezorViewModel { return cleanedMessage } - // MARK: - Credential Management - - /// Clear stored credentials for current device - func clearCredentials() async { - guard let device = connectedDevice else { - error = "No device connected" - return - } - - do { - try await trezorService.clearCredentials(deviceId: device.path) - trezorLog("Cleared credentials for \(device.path)") - } catch { - self.error = errorMessage(from: error) - trezorLog("Failed to clear credentials: \(error)", level: "error") - } - } - // MARK: - Event Watcher Operations /// Copy the most recently retrieved xpub into the watcher's extended-key field. @@ -1625,13 +1057,13 @@ class TrezorViewModel { } let watcherId = UUID().uuidString - let network = selectedNetwork + let network = connection.selectedNetwork let accountType = onchainAccountTypeSelection.accountType let params = WatcherParams( watcherId: watcherId, extendedKey: key, - electrumUrl: Self.electrumUrlForNetwork(network), + electrumUrl: TrezorService.electrumUrlForNetwork(network), network: toNetwork(network), accountType: accountType, gapLimit: gapLimit @@ -1662,7 +1094,7 @@ class TrezorViewModel { return } - if selectedNetwork != network { + if connection.selectedNetwork != network { try? watcherService.stopWatcher(watcherId: watcherId) finishStoppedWatcherStartup(watcherId: watcherId) return @@ -1852,22 +1284,22 @@ class TrezorViewModel { func testShowPinPrompt() { guard Env.isTrezorEmulatorTesting else { return } - showPinEntry = true + connection.showPinEntry = true } func testShowPassphrasePrompt() { guard Env.isTrezorEmulatorTesting else { return } - showPassphraseEntry = true + connection.showPassphraseEntry = true } func testShowPairingCodePrompt() { guard Env.isTrezorEmulatorTesting else { return } - showPairingCode = true + connection.showPairingCode = true } func testShowConfirmOnDevicePrompt() { guard Env.isTrezorEmulatorTesting else { return } - confirmMessage = "Confirm test action on your Trezor" - showConfirmOnDevice = true + connection.confirmMessage = "Confirm test action on your Trezor" + connection.showConfirmOnDevice = true } } diff --git a/Bitkit/Views/Home/HomeWalletView.swift b/Bitkit/Views/Home/HomeWalletView.swift index 36cbcdf46..149de8811 100644 --- a/Bitkit/Views/Home/HomeWalletView.swift +++ b/Bitkit/Views/Home/HomeWalletView.swift @@ -5,7 +5,7 @@ struct HomeWalletView: View { @EnvironmentObject var app: AppViewModel @EnvironmentObject var settings: SettingsViewModel @EnvironmentObject var wallet: WalletViewModel - @Environment(HwWalletRepo.self) private var hwWalletRepo + @Environment(HwWalletManager.self) private var hwWalletManager var hasActivity: Bool { return activity.latestActivities?.isEmpty == false @@ -14,7 +14,7 @@ struct HomeWalletView: View { /// Headline total including watch-only hardware-wallet balances (keeps `totalBalanceSats` /// semantics unchanged for send/transfer logic; only the headline folds hardware in). private var headlineSats: Int { - wallet.totalBalanceSats + Int(clamping: hwWalletRepo.totalSats) + wallet.totalBalanceSats + Int(clamping: hwWalletManager.totalSats) } var body: some View { @@ -50,8 +50,8 @@ struct HomeWalletView: View { .frame(height: 50) .padding(.bottom, 32) - if !hwWalletRepo.wallets.isEmpty { - HardwareWalletsGrid(wallets: hwWalletRepo.wallets) { _ in + if !hwWalletManager.wallets.isEmpty { + HardwareWalletsGrid(wallets: hwWalletManager.wallets) { _ in app.toast(type: .info, title: t("coming_soon__nav_title")) } .padding(.bottom, 32) diff --git a/Bitkit/Views/Sheets/HardwarePairingSheet.swift b/Bitkit/Views/Sheets/HardwarePairingSheet.swift index 8dfa5fb3a..9ba6e992a 100644 --- a/Bitkit/Views/Sheets/HardwarePairingSheet.swift +++ b/Bitkit/Views/Sheets/HardwarePairingSheet.swift @@ -9,7 +9,7 @@ struct HardwarePairingSheetItem: SheetItem { /// Mirrors bitkit-android's `HwPairCodeSheet`: 6 fixed-width cells + an on-screen number pad. /// Dismissing without entering the full code cancels the pending pairing request. struct HardwarePairingSheet: View { - @Environment(HwWalletRepo.self) private var hwWalletRepo + @Environment(TrezorManager.self) private var trezorManager let config: HardwarePairingSheetItem private let codeLength = 6 @@ -49,7 +49,7 @@ struct HardwarePairingSheet: View { .accessibilityIdentifier("HwPairSheet") } .onDisappear { - if !submitted { hwWalletRepo.cancelPairingCode() } + if !submitted { trezorManager.cancelPairingCode() } } } @@ -65,7 +65,7 @@ struct HardwarePairingSheet: View { code += key if code.count == codeLength { submitted = true - hwWalletRepo.submitPairingCode(code) + trezorManager.submitPairingCode(code) } } } diff --git a/Bitkit/Views/Trezor/TrezorAddressView.swift b/Bitkit/Views/Trezor/TrezorAddressView.swift index 95537e0e7..c53b254b5 100644 --- a/Bitkit/Views/Trezor/TrezorAddressView.swift +++ b/Bitkit/Views/Trezor/TrezorAddressView.swift @@ -39,6 +39,7 @@ enum TrezorAddressScriptType: String, CaseIterable { /// Inline content for address generation, used by expandable section. struct TrezorAddressContent: View { + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor @State private var selectedScriptType: TrezorAddressScriptType = .segwit @@ -51,7 +52,7 @@ struct TrezorAddressContent: View { AddressResultSection() } .onChange(of: selectedScriptType) { newValue in - trezor.derivationPath = newValue.defaultPath(coinType: trezor.coinTypeComponent) + trezor.derivationPath = newValue.defaultPath(coinType: trezorManager.coinTypeComponent) trezor.selectedScriptType = newValue.trezorScriptType trezor.addressIndex = 0 } @@ -104,6 +105,7 @@ private struct AddressTypeSection: View { // MARK: - Derivation Path Section private struct DerivationPathSection: View { + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor let selectedScriptType: TrezorAddressScriptType @FocusState private var isFieldFocused: Bool @@ -157,7 +159,7 @@ private struct DerivationPathSection: View { .trezorAccessibilityAnchor("TrezorAddressIndex") Button(action: { - trezor.derivationPath = selectedScriptType.defaultPath(coinType: trezor.coinTypeComponent) + trezor.derivationPath = selectedScriptType.defaultPath(coinType: trezorManager.coinTypeComponent) trezor.addressIndex = 0 }) { Text("Use default path") @@ -404,7 +406,8 @@ private struct CopyButton: View { NavigationStack { TrezorAddressView() } - .environment(TrezorViewModel()) + .environment(TrezorManager()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorBalanceLookupView.swift b/Bitkit/Views/Trezor/TrezorBalanceLookupView.swift index af533557c..83d1e268f 100644 --- a/Bitkit/Views/Trezor/TrezorBalanceLookupView.swift +++ b/Bitkit/Views/Trezor/TrezorBalanceLookupView.swift @@ -56,6 +56,7 @@ private struct LookupButtonWrapper: View { /// keeping the parent body free of ViewModel property accesses. private struct BalanceLookupResultsSection: View { let input: String + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor private var hasResults: Bool { @@ -89,7 +90,7 @@ private struct BalanceLookupResultsSection: View { isComposing: trezor.isComposing, isOperating: trezor.isOperating, isBroadcasting: trezor.isBroadcasting, - isDeviceConnected: trezor.isConnected, + isDeviceConnected: trezorManager.isConnected, composeResult: trezor.composeResult, signedTxResult: trezor.signedTxResult, broadcastTxid: trezor.broadcastTxid, diff --git a/Bitkit/Views/Trezor/TrezorConnectedView.swift b/Bitkit/Views/Trezor/TrezorConnectedView.swift index ace5faab2..35426a3d4 100644 --- a/Bitkit/Views/Trezor/TrezorConnectedView.swift +++ b/Bitkit/Views/Trezor/TrezorConnectedView.swift @@ -4,7 +4,7 @@ import SwiftUI /// View displayed when connected to a Trezor device. /// Uses expandable sections instead of navigation to separate screens. struct TrezorConnectedView: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager @State private var isAddressExpanded = false @State private var isSignMessageExpanded = false @State private var isPublicKeyExpanded = false @@ -19,8 +19,8 @@ struct TrezorConnectedView: View { VStack(spacing: 24) { // Device card DeviceInfoCard( - device: trezor.connectedDevice, - features: trezor.deviceFeatures + device: trezorManager.connectedDevice, + features: trezorManager.deviceFeatures ) // Wallet mode selector (standard vs hidden/passphrase wallet) @@ -112,7 +112,7 @@ struct TrezorConnectedView: View { // Disconnect button Button(action: { Task { - await trezor.disconnect() + await trezorManager.disconnect() } }) { HStack(spacing: 8) { @@ -142,8 +142,8 @@ struct TrezorConnectedView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { TrezorStatusBadge( - isConnected: trezor.isConnected, - deviceName: trezor.deviceFeatures?.label + isConnected: trezorManager.isConnected, + deviceName: trezorManager.deviceFeatures?.label ) .allowsHitTesting(false) } @@ -156,6 +156,7 @@ struct TrezorConnectedView: View { /// Lets the user switch between the standard wallet and a hidden (passphrase) wallet. /// Switching resets the device session (handled by the ViewModel). private struct WalletModeSelectorRow: View { + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor private enum WalletModeTab: CaseIterable, CustomStringConvertible { @@ -175,13 +176,13 @@ private struct WalletModeSelectorRow: View { /// passphrase flow completes). private var selectedTab: Binding { Binding( - get: { trezor.walletMode == .standard ? .standard : .passphrase }, + get: { trezorManager.walletMode == .standard ? .standard : .passphrase }, set: { newValue in switch newValue { case .standard: - Task { await trezor.selectStandardWallet() } + Task { await trezorManager.selectStandardWallet() } case .passphrase: - trezor.requestPassphraseWallet() + trezorManager.requestPassphraseWallet() } } ) @@ -253,7 +254,7 @@ private struct DeviceInfoCard: View { NavigationStack { TrezorConnectedView() } - .environment(TrezorViewModel()) + .environment(TrezorManager()) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorDeviceFeaturesView.swift b/Bitkit/Views/Trezor/TrezorDeviceFeaturesView.swift index 322f4ef93..9dc216e9b 100644 --- a/Bitkit/Views/Trezor/TrezorDeviceFeaturesView.swift +++ b/Bitkit/Views/Trezor/TrezorDeviceFeaturesView.swift @@ -3,14 +3,14 @@ import SwiftUI /// Inline content for device features, used by expandable section. struct TrezorDeviceFeaturesContent: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager var body: some View { VStack(spacing: 24) { - if let features = trezor.deviceFeatures { + if let features = trezorManager.deviceFeatures { FirmwareSection(features: features) SecuritySection(features: features) - IdentifiersSection(features: features, device: trezor.connectedDevice) + IdentifiersSection(features: features, device: trezorManager.connectedDevice) ActionsSection() } else { NoFeaturesView() @@ -140,13 +140,13 @@ private struct IdentifiersSection: View { // MARK: - Actions Section private struct ActionsSection: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager var body: some View { VStack(spacing: 12) { Button(action: { Task { - await trezor.clearCredentials() + await trezorManager.clearCredentials() } }) { HStack(spacing: 8) { @@ -272,7 +272,7 @@ private struct TrezorStatusRow: View { NavigationStack { TrezorDeviceFeaturesView() } - .environment(TrezorViewModel()) + .environment(TrezorManager()) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorDeviceListView.swift b/Bitkit/Views/Trezor/TrezorDeviceListView.swift index 358560798..56eb2833b 100644 --- a/Bitkit/Views/Trezor/TrezorDeviceListView.swift +++ b/Bitkit/Views/Trezor/TrezorDeviceListView.swift @@ -4,14 +4,14 @@ import SwiftUI /// View displaying discovered Trezor devices struct TrezorDeviceListView: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager @State private var connectingDevicePath: String? @State private var isWatcherExpanded = false /// Scanned devices that are NOT already in the known devices list private var nearbyDevices: [TrezorDeviceInfo] { - let knownIds = Set(trezor.knownDevices.map(\.id)) - return trezor.devices.filter { !knownIds.contains($0.id) } + let knownIds = Set(trezorManager.knownDevices.map(\.id)) + return trezorManager.devices.filter { !knownIds.contains($0.id) } } var body: some View { @@ -20,28 +20,28 @@ struct TrezorDeviceListView: View { ScrollView { VStack(spacing: 24) { // Bluetooth status (don't show during initial .unknown state) - if !trezor.isBridgeModeEnabled, trezor.bluetoothState != .poweredOn, trezor.bluetoothState != .unknown { - BluetoothStatusCard(state: trezor.bluetoothState) + if !trezorManager.isBridgeModeEnabled, trezorManager.bluetoothState != .poweredOn, trezorManager.bluetoothState != .unknown { + BluetoothStatusCard(state: trezorManager.bluetoothState) } // Auto-reconnect indicator - if trezor.isAutoReconnecting, let status = trezor.autoReconnectStatus { + if trezorManager.isAutoReconnecting, let status = trezorManager.autoReconnectStatus { AutoReconnectIndicator(status: status) } // Scanning indicator - if trezor.isScanning, !trezor.isAutoReconnecting { + if trezorManager.isScanning, !trezorManager.isAutoReconnecting { ScanningIndicator() } // Known devices section - if !trezor.knownDevices.isEmpty { + if !trezorManager.knownDevices.isEmpty { VStack(alignment: .leading, spacing: 12) { Text("My Devices") .font(.system(size: 14, weight: .medium)) .foregroundColor(.white.opacity(0.6)) - ForEach(trezor.knownDevices) { device in + ForEach(trezorManager.knownDevices) { device in KnownDeviceRow( device: device, isConnecting: connectingDevicePath == device.path @@ -49,7 +49,7 @@ struct TrezorDeviceListView: View { connectToKnownDevice(device) } onForget: { Task { - await trezor.forgetDevice(id: device.id) + await trezorManager.forgetDevice(id: device.id) } } } @@ -75,14 +75,14 @@ struct TrezorDeviceListView: View { } // Empty state - if !trezor.isScanning, !trezor.isAutoReconnecting, - trezor.knownDevices.isEmpty, trezor.devices.isEmpty + if !trezorManager.isScanning, !trezorManager.isAutoReconnecting, + trezorManager.knownDevices.isEmpty, trezorManager.devices.isEmpty { TrezorEmptyStateView() } // Error display - if let error = trezor.error { + if let error = trezorManager.error { ErrorCard(message: error) } @@ -103,17 +103,17 @@ struct TrezorDeviceListView: View { } // Bottom action button - if !trezor.isScanning, !trezor.isAutoReconnecting, - trezor.isBridgeModeEnabled || trezor.bluetoothState == .poweredOn || trezor.bluetoothState == .unknown + if !trezorManager.isScanning, !trezorManager.isAutoReconnecting, + trezorManager.isBridgeModeEnabled || trezorManager.bluetoothState == .poweredOn || trezorManager.bluetoothState == .unknown { Button(action: { Task { - await trezor.startScan() + await trezorManager.startScan() } }) { HStack(spacing: 8) { Image(systemName: "antenna.radiowaves.left.and.right") - Text(trezor.devices.isEmpty ? "Scan for Devices" : "Scan Again") + Text(trezorManager.devices.isEmpty ? "Scan for Devices" : "Scan Again") } .font(.system(size: 16, weight: .semibold)) .foregroundColor(.black) @@ -131,27 +131,27 @@ struct TrezorDeviceListView: View { .navigationBarTitleDisplayMode(.inline) .trezorAccessibilityAnchor("TrezorDeviceList") .task { - trezor.loadKnownDevices() + trezorManager.loadKnownDevices() // Wait briefly for BLE state to settle if still unknown // (CBCentralManager fires centralManagerDidUpdateState async after creation) - if trezor.bluetoothState == .unknown { + if trezorManager.bluetoothState == .unknown { for _ in 0 ..< 10 { try? await Task.sleep(nanoseconds: 100_000_000) // 100ms - if trezor.bluetoothState != .unknown { break } + if trezorManager.bluetoothState != .unknown { break } } } - guard trezor.isBridgeModeEnabled || trezor.bluetoothState == .poweredOn else { return } + guard trezorManager.isBridgeModeEnabled || trezorManager.bluetoothState == .poweredOn else { return } - if !trezor.knownDevices.isEmpty { - await trezor.autoReconnect() - } else if trezor.devices.isEmpty { - await trezor.startScan() + if !trezorManager.knownDevices.isEmpty { + await trezorManager.autoReconnect() + } else if trezorManager.devices.isEmpty { + await trezorManager.startScan() } } .onDisappear { - trezor.stopScan() + trezorManager.stopScan() } } @@ -159,7 +159,7 @@ struct TrezorDeviceListView: View { connectingDevicePath = device.path Task { - await trezor.connect(device: device) + await trezorManager.connect(device: device) connectingDevicePath = nil } } @@ -169,15 +169,15 @@ struct TrezorDeviceListView: View { Task { // Check if this device was found in the last scan - if let scanned = trezor.devices.first(where: { $0.id == knownDevice.id }) { - await trezor.connect(device: scanned) + if let scanned = trezorManager.devices.first(where: { $0.id == knownDevice.id }) { + await trezorManager.connect(device: scanned) } else { // Need to scan first to find the device - await trezor.startScan(clearExisting: false) - if let scanned = trezor.devices.first(where: { $0.id == knownDevice.id }) { - await trezor.connect(device: scanned) + await trezorManager.startScan(clearExisting: false) + if let scanned = trezorManager.devices.first(where: { $0.id == knownDevice.id }) { + await trezorManager.connect(device: scanned) } else { - trezor.error = "Device not found nearby. Make sure your Trezor is turned on." + trezorManager.error = "Device not found nearby. Make sure your Trezor is turned on." } } connectingDevicePath = nil @@ -329,7 +329,7 @@ private struct ErrorCard: View { NavigationStack { TrezorDeviceListView() } - .environment(TrezorViewModel()) + .environment(TrezorManager()) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorPublicKeyView.swift b/Bitkit/Views/Trezor/TrezorPublicKeyView.swift index cb51ae12e..ffa956681 100644 --- a/Bitkit/Views/Trezor/TrezorPublicKeyView.swift +++ b/Bitkit/Views/Trezor/TrezorPublicKeyView.swift @@ -155,7 +155,7 @@ private struct CopyableField: View { NavigationStack { TrezorPublicKeyView() } - .environment(TrezorViewModel()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorRootView.swift b/Bitkit/Views/Trezor/TrezorRootView.swift index 5d24cb627..01ec132ba 100644 --- a/Bitkit/Views/Trezor/TrezorRootView.swift +++ b/Bitkit/Views/Trezor/TrezorRootView.swift @@ -57,17 +57,17 @@ extension View { /// Isolates the connected/disconnected toggle so only this view /// re-renders when connection state changes. private struct TrezorContentSwitcher: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager var body: some View { Group { - if trezor.isConnected { + if trezorManager.isConnected { TrezorConnectedView() } else { TrezorDeviceListView() } } - .animation(.easeInOut(duration: 0.25), value: trezor.isConnected) + .animation(.easeInOut(duration: 0.25), value: trezorManager.isConnected) } } @@ -80,12 +80,13 @@ private struct TrezorContentSwitcher: View { /// The ViewModel is only accessed inside closures, so the root body still /// establishes no observation dependencies. private struct TrezorLifecycleModifier: ViewModifier { + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor func body(content: Content) -> some View { content .task { - trezor.setup() + trezorManager.setup() } .onDisappear { // The ViewModel outlives this screen (app-lifetime), so watchers and @@ -115,46 +116,46 @@ private struct TrezorDebugLogWrapper: View { /// Groups all sheet and overlay presentations that depend on ViewModel state, /// keeping TrezorRootView's body free of @Environment access. private struct TrezorDialogsModifier: ViewModifier { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager func body(content: Content) -> some View { - @Bindable var trezor = trezor + @Bindable var trezorManager = trezorManager content - .sheet(isPresented: $trezor.showPinEntry) { + .sheet(isPresented: $trezorManager.showPinEntry) { TrezorPinEntrySheet() } // Pairing code is presented app-wide via the SheetViewModel system (see MainNavView), // so the home hardware feature shows it regardless of being on this dev screen. - .sheet(isPresented: $trezor.showPassphraseEntry) { + .sheet(isPresented: $trezorManager.showPassphraseEntry) { TrezorPassphraseSheet() } .confirmationDialog( "Passphrase Entry", - isPresented: $trezor.showWalletModeChooser, + isPresented: $trezorManager.showWalletModeChooser, titleVisibility: .visible ) { Button("On this phone") { - trezor.choosePhonePassphraseEntry() + trezorManager.choosePhonePassphraseEntry() } .accessibilityIdentifier("TrezorWalletModeOnPhone") Button("On the Trezor") { - Task { await trezor.chooseDevicePassphraseEntry() } + Task { await trezorManager.chooseDevicePassphraseEntry() } } .accessibilityIdentifier("TrezorWalletModeOnTrezor") Button("Cancel", role: .cancel) { - trezor.showWalletModeChooser = false + trezorManager.showWalletModeChooser = false } } message: { Text("Where do you want to enter the passphrase for your hidden wallet?") } .overlay { - if trezor.showConfirmOnDevice { + if trezorManager.showConfirmOnDevice { TrezorConfirmOnDeviceOverlay( - message: trezor.confirmMessage, + message: trezorManager.confirmMessage, onCancel: { - trezor.dismissConfirmOnDevice() + trezorManager.dismissConfirmOnDevice() } ) } @@ -165,6 +166,7 @@ private struct TrezorDialogsModifier: ViewModifier { // MARK: - Network Selector private struct NetworkSelectorRow: View { + @Environment(TrezorManager.self) private var trezorManager @Environment(TrezorViewModel.self) private var trezor private let networks: [(TrezorCoinType, String)] = [ @@ -182,13 +184,13 @@ private struct NetworkSelectorRow: View { HStack(spacing: 8) { ForEach(Array(networks.enumerated()), id: \.offset) { _, item in let (network, label) = item - Button(action: { trezor.setSelectedNetwork(network) }) { + Button(action: { selectNetwork(network) }) { Text(label) .font(.system(size: 12, weight: .semibold)) - .foregroundColor(trezor.selectedNetwork == network ? .white : .white.opacity(0.5)) + .foregroundColor(trezorManager.selectedNetwork == network ? .white : .white.opacity(0.5)) .padding(.horizontal, 14) .padding(.vertical, 6) - .background(trezor.selectedNetwork == network ? Color.white.opacity(0.2) : Color.white.opacity(0.05)) + .background(trezorManager.selectedNetwork == network ? Color.white.opacity(0.2) : Color.white.opacity(0.05)) .clipShape(Capsule()) } .accessibilityIdentifier("TrezorNetwork-\(label)") @@ -199,12 +201,18 @@ private struct NetworkSelectorRow: View { .frame(maxWidth: .infinity) .background(Color.white.opacity(0.02)) } + + private func selectNetwork(_ network: TrezorCoinType) { + guard network != trezorManager.selectedNetwork else { return } + trezorManager.setSelectedNetwork(network) + trezor.handleNetworkChange() + } } // MARK: - PIN Entry Sheet struct TrezorPinEntrySheet: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager @Environment(\.dismiss) private var dismiss @State private var pin: String = "" @@ -233,7 +241,7 @@ struct TrezorPinEntrySheet: View { // Buttons HStack(spacing: 16) { Button(action: { - trezor.cancelPin() + trezorManager.cancelPin() dismiss() }) { Text("Cancel") @@ -247,7 +255,7 @@ struct TrezorPinEntrySheet: View { .accessibilityIdentifier("TrezorPinCancel") Button(action: { - trezor.submitPin(pin) + trezorManager.submitPin(pin) dismiss() }) { Text("Confirm") @@ -275,7 +283,7 @@ struct TrezorPinEntrySheet: View { // MARK: - Pairing Code Sheet struct TrezorPairingCodeSheet: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager @Environment(\.dismiss) private var dismiss @State private var code: String = "" @State private var hasSubmitted = false @@ -307,7 +315,7 @@ struct TrezorPairingCodeSheet: View { // Buttons HStack(spacing: 16) { Button(action: { - trezor.cancelPairingCode() + trezorManager.cancelPairingCode() dismiss() }) { Text("Cancel") @@ -323,7 +331,7 @@ struct TrezorPairingCodeSheet: View { Button(action: { guard !hasSubmitted else { return } hasSubmitted = true - trezor.submitPairingCode(code) + trezorManager.submitPairingCode(code) dismiss() }) { Text("Confirm") @@ -349,7 +357,7 @@ struct TrezorPairingCodeSheet: View { if newValue.count == digitCount { guard !hasSubmitted else { return } hasSubmitted = true - trezor.submitPairingCode(newValue) + trezorManager.submitPairingCode(newValue) dismiss() } } @@ -359,7 +367,7 @@ struct TrezorPairingCodeSheet: View { // MARK: - Passphrase Sheet struct TrezorPassphraseSheet: View { - @Environment(TrezorViewModel.self) private var trezor + @Environment(TrezorManager.self) private var trezorManager @Environment(\.dismiss) private var dismiss @State private var passphrase: String = "" @State private var confirmPassphrase: String = "" @@ -426,10 +434,10 @@ struct TrezorPassphraseSheet: View { } // Offer on-device entry when the connected Trezor supports it - if trezor.passphraseEntryCapable { + if trezorManager.passphraseEntryCapable { CustomButton(title: "Enter on Trezor instead", variant: .tertiary) { dismiss() - await trezor.chooseDevicePassphraseEntry() + await trezorManager.chooseDevicePassphraseEntry() } .padding(.top, 4) .accessibilityIdentifier("TrezorPassphraseUseDevice") @@ -442,7 +450,7 @@ struct TrezorPassphraseSheet: View { // Buttons HStack(spacing: 16) { Button(action: { - trezor.cancelPassphrase() + trezorManager.cancelPassphrase() dismiss() }) { Text("Cancel") @@ -458,7 +466,7 @@ struct TrezorPassphraseSheet: View { Button(action: { let entered = passphrase dismiss() - Task { await trezor.submitPassphrase(entered) } + Task { await trezorManager.submitPassphrase(entered) } }) { Text("Confirm") .font(.system(size: 16, weight: .semibold)) @@ -652,7 +660,8 @@ struct TrezorDebugLogPanel: View { struct TrezorRootView_Previews: PreviewProvider { static var previews: some View { TrezorRootView() - .environment(TrezorViewModel()) + .environment(TrezorManager()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorSignMessageView.swift b/Bitkit/Views/Trezor/TrezorSignMessageView.swift index 01b600383..b3e2e2b37 100644 --- a/Bitkit/Views/Trezor/TrezorSignMessageView.swift +++ b/Bitkit/Views/Trezor/TrezorSignMessageView.swift @@ -369,7 +369,7 @@ private struct VerificationResultBanner: View { NavigationStack { TrezorSignMessageView() } - .environment(TrezorViewModel()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorTransactionDetailView.swift b/Bitkit/Views/Trezor/TrezorTransactionDetailView.swift index 937cb9be0..ffea197d5 100644 --- a/Bitkit/Views/Trezor/TrezorTransactionDetailView.swift +++ b/Bitkit/Views/Trezor/TrezorTransactionDetailView.swift @@ -528,7 +528,7 @@ private struct ResultRow: View { NavigationStack { TrezorTransactionDetailView() } - .environment(TrezorViewModel()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/Bitkit/Views/Trezor/TrezorTransactionHistoryView.swift b/Bitkit/Views/Trezor/TrezorTransactionHistoryView.swift index 9be5933f7..970cc7f7f 100644 --- a/Bitkit/Views/Trezor/TrezorTransactionHistoryView.swift +++ b/Bitkit/Views/Trezor/TrezorTransactionHistoryView.swift @@ -411,7 +411,7 @@ private struct ResultRow: View { NavigationStack { TrezorTransactionHistoryView() } - .environment(TrezorViewModel()) + .environment(TrezorViewModel(connection: TrezorManager())) } } #endif diff --git a/BitkitTests/HwWalletRepoTests.swift b/BitkitTests/HwWalletManagerTests.swift similarity index 98% rename from BitkitTests/HwWalletRepoTests.swift rename to BitkitTests/HwWalletManagerTests.swift index 3d23d718a..53582896f 100644 --- a/BitkitTests/HwWalletRepoTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -3,11 +3,11 @@ import BitkitCore import Combine import XCTest -/// Engine tests for `HwWalletRepo`, adapting bitkit-android's `HwWalletRepoTest`. +/// Engine tests for `HwWalletManager`, adapting bitkit-android's `HwWalletRepoTest`. /// The engine is driven directly (no live `TrezorViewModel`) via `updateDevices` and /// `handleWatcherEvent`, with spies for the bitkit-core persistence side. @MainActor -final class HwWalletRepoTests: XCTestCase { +final class HwWalletManagerTests: XCTestCase { // MARK: - Mocks & spies private final class MockWatcherService: TrezorWatcherServicing, @unchecked Sendable { @@ -43,9 +43,8 @@ final class HwWalletRepoTests: XCTestCase { private func makeViewModel( watcherService: TrezorWatcherServicing = MockWatcherService(), monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"] - ) -> HwWalletRepo { - let vm = HwWalletRepo( - trezor: nil, + ) -> HwWalletManager { + let vm = HwWalletManager( watcherService: watcherService, monitoredTypes: { monitored }, electrumUrl: { "ssl://test:1" }, diff --git a/BitkitTests/TrezorViewModelWatcherTests.swift b/BitkitTests/TrezorViewModelWatcherTests.swift index 1abda22b3..8582ed83d 100644 --- a/BitkitTests/TrezorViewModelWatcherTests.swift +++ b/BitkitTests/TrezorViewModelWatcherTests.swift @@ -130,7 +130,7 @@ final class TrezorViewModelWatcherTests: XCTestCase { @MainActor private func makeViewModel(service: MockWatcherService) -> TrezorViewModel { - let viewModel = TrezorViewModel(watcherService: service) + let viewModel = TrezorViewModel(connection: TrezorManager(), watcherService: service) viewModel.watcherExtendedKey = "xpub6test123" return viewModel } @@ -184,32 +184,27 @@ final class TrezorViewModelWatcherTests: XCTestCase { @MainActor func testDisconnectedStateResetClearsSensitiveWalletState() { - let service = MockWatcherService() - let viewModel = makeViewModel(service: service) + let connection = TrezorManager() TrezorUiHandler.shared.setWalletMode(.passphraseHost, hostPassphrase: "secret") - viewModel.walletMode = .passphraseHost - viewModel.deviceFingerprint = "73c5da0a" - viewModel.generatedAddress = "bcrt1qexample" - viewModel.xpub = "xpub6previous" - viewModel.publicKeyHex = "02abcdef" - viewModel.showPinEntry = true - viewModel.showPassphraseEntry = true - viewModel.showConfirmOnDevice = true - viewModel.showWalletModeChooser = true - - viewModel.clearDisconnectedDeviceState(errorMessage: "disconnect failed") - - XCTAssertNil(viewModel.deviceFingerprint) - XCTAssertNil(viewModel.generatedAddress) - XCTAssertNil(viewModel.xpub) - XCTAssertNil(viewModel.publicKeyHex) - XCTAssertEqual(viewModel.error, "disconnect failed") - XCTAssertFalse(viewModel.showPinEntry) - XCTAssertFalse(viewModel.showPassphraseEntry) - XCTAssertFalse(viewModel.showConfirmOnDevice) - XCTAssertFalse(viewModel.showWalletModeChooser) - XCTAssertEqual(viewModel.walletMode, .standard) + connection.walletMode = .passphraseHost + connection.deviceFingerprint = "73c5da0a" + connection.showPinEntry = true + connection.showPassphraseEntry = true + connection.showConfirmOnDevice = true + connection.showWalletModeChooser = true + + connection.clearDisconnectedDeviceState(errorMessage: "disconnect failed") + + XCTAssertNil(connection.deviceFingerprint) + XCTAssertNil(connection.connectedDevice) + XCTAssertNil(connection.deviceFeatures) + XCTAssertEqual(connection.error, "disconnect failed") + XCTAssertFalse(connection.showPinEntry) + XCTAssertFalse(connection.showPassphraseEntry) + XCTAssertFalse(connection.showConfirmOnDevice) + XCTAssertFalse(connection.showWalletModeChooser) + XCTAssertEqual(connection.walletMode, .standard) switch TrezorUiHandler.shared.currentSelection() { case .standard: From 571dfed004dd02f5e7ea321f309edec497da4a02 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 18:00:29 -0300 Subject: [PATCH 08/52] test: test parity --- BitkitTests/ActivityHardwareTests.swift | 63 ++++++++ BitkitTests/HwAddressTypeTests.swift | 43 ++++++ BitkitTests/HwWalletIdTests.swift | 30 ++++ BitkitTests/HwWalletManagerTests.swift | 196 ++++++++++++++++++++++++ 4 files changed, 332 insertions(+) create mode 100644 BitkitTests/ActivityHardwareTests.swift create mode 100644 BitkitTests/HwAddressTypeTests.swift create mode 100644 BitkitTests/HwWalletIdTests.swift diff --git a/BitkitTests/ActivityHardwareTests.swift b/BitkitTests/ActivityHardwareTests.swift new file mode 100644 index 000000000..b4a41ba46 --- /dev/null +++ b/BitkitTests/ActivityHardwareTests.swift @@ -0,0 +1,63 @@ +@testable import Bitkit +import BitkitCore +import XCTest + +/// Covers the `Activity` walletId helpers that drive the merged activity list + the blue +/// hardware-wallet icon variant. +final class ActivityHardwareTests: XCTestCase { + private func onchain(walletId: String) -> Activity { + .onchain(OnchainActivity( + walletId: walletId, + id: "tx1", + txType: .received, + txId: "tx1", + value: 1000, + fee: 0, + feeRate: 1, + address: "", + confirmed: true, + timestamp: 1, + isBoosted: false, + boostTxIds: [], + isTransfer: false, + doesExist: true, + confirmTimestamp: nil, + channelId: nil, + transferTxId: nil, + contact: nil, + createdAt: nil, + updatedAt: nil, + seenAt: nil + )) + } + + private func lightning(walletId: String) -> Activity { + .lightning(LightningActivity( + walletId: walletId, + id: "ln1", + txType: .received, + status: .succeeded, + value: 1000, + fee: nil, + invoice: "lnbc1", + message: "", + timestamp: 1, + preimage: nil, + contact: nil, + createdAt: nil, + updatedAt: nil, + seenAt: nil + )) + } + + func testWalletIdExtractedFromBothCases() { + XCTAssertEqual(onchain(walletId: "trezor:abc").walletId, "trezor:abc") + XCTAssertEqual(lightning(walletId: WalletScope.default).walletId, WalletScope.default) + } + + func testIsHardwareWallet() { + XCTAssertTrue(onchain(walletId: "trezor:abc").isHardwareWallet) + XCTAssertFalse(onchain(walletId: WalletScope.default).isHardwareWallet) + XCTAssertFalse(lightning(walletId: WalletScope.default).isHardwareWallet) + } +} diff --git a/BitkitTests/HwAddressTypeTests.swift b/BitkitTests/HwAddressTypeTests.swift new file mode 100644 index 000000000..ff9b184d6 --- /dev/null +++ b/BitkitTests/HwAddressTypeTests.swift @@ -0,0 +1,43 @@ +@testable import Bitkit +import BitkitCore +import XCTest + +final class HwAddressTypeTests: XCTestCase { + func testAllCasesOrderMatchesAndroid() { + XCTAssertEqual(HwAddressType.allCases, [.legacy, .nestedSegwit, .nativeSegwit, .taproot]) + } + + func testSettingsStrings() { + XCTAssertEqual(HwAddressType.legacy.settingsString, "legacy") + XCTAssertEqual(HwAddressType.nestedSegwit.settingsString, "nestedSegwit") + XCTAssertEqual(HwAddressType.nativeSegwit.settingsString, "nativeSegwit") + XCTAssertEqual(HwAddressType.taproot.settingsString, "taproot") + } + + func testAccountTypeMapping() { + XCTAssertEqual(HwAddressType.legacy.accountType, .legacy) + XCTAssertEqual(HwAddressType.nestedSegwit.accountType, .wrappedSegwit) + XCTAssertEqual(HwAddressType.nativeSegwit.accountType, .nativeSegwit) + XCTAssertEqual(HwAddressType.taproot.accountType, .taproot) + } + + func testAccountDerivationPathMainnet() { + XCTAssertEqual(HwAddressType.legacy.accountDerivationPath(network: .bitcoin), "m/44'/0'/0'") + XCTAssertEqual(HwAddressType.nestedSegwit.accountDerivationPath(network: .bitcoin), "m/49'/0'/0'") + XCTAssertEqual(HwAddressType.nativeSegwit.accountDerivationPath(network: .bitcoin), "m/84'/0'/0'") + XCTAssertEqual(HwAddressType.taproot.accountDerivationPath(network: .bitcoin), "m/86'/0'/0'") + } + + func testAccountDerivationPathUsesCoinType1ForTestNetworks() { + XCTAssertEqual(HwAddressType.nativeSegwit.accountDerivationPath(network: .regtest), "m/84'/1'/0'") + XCTAssertEqual(HwAddressType.taproot.accountDerivationPath(network: .testnet), "m/86'/1'/0'") + } + + func testInitFromSettingsStringRoundTrips() { + for type in HwAddressType.allCases { + XCTAssertEqual(HwAddressType(settingsString: type.settingsString), type) + } + XCTAssertNil(HwAddressType(settingsString: "p2wpkh")) + XCTAssertNil(HwAddressType(settingsString: "")) + } +} diff --git a/BitkitTests/HwWalletIdTests.swift b/BitkitTests/HwWalletIdTests.swift new file mode 100644 index 000000000..7a9242bba --- /dev/null +++ b/BitkitTests/HwWalletIdTests.swift @@ -0,0 +1,30 @@ +@testable import Bitkit +import XCTest + +final class HwWalletIdTests: XCTestCase { + func testDeterministicForSameXpubs() { + let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "x") + let b = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "y") + XCTAssertEqual(a, b, "id derives from xpubs, independent of the fallback id") + } + + func testOrderIndependent() { + let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "x") + let b = HwWalletId.derive(xpubs: ["taproot": "zTR", "nativeSegwit": "zNS"], fallbackId: "x") + XCTAssertEqual(a, b, "values are sorted before hashing") + } + + func testDifferentXpubsProduceDifferentIds() { + let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS"], fallbackId: "x") + let b = HwWalletId.derive(xpubs: ["nativeSegwit": "DIFFERENT"], fallbackId: "x") + XCTAssertNotEqual(a, b) + } + + func testPrefix() { + XCTAssertTrue(HwWalletId.derive(xpubs: ["nativeSegwit": "z"], fallbackId: "x").hasPrefix("trezor:")) + } + + func testFallsBackToDeviceIdWhenNoXpubs() { + XCTAssertEqual(HwWalletId.derive(xpubs: [:], fallbackId: "device-123"), "trezor:device-123") + } +} diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 53582896f..10751e1ec 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -13,6 +13,9 @@ final class HwWalletManagerTests: XCTestCase { private final class MockWatcherService: TrezorWatcherServicing, @unchecked Sendable { private(set) var startedParams: [WatcherParams] = [] private(set) var stoppedWatcherIds: [String] = [] + var stopShouldFail = false + + struct StopError: Error {} func startWatcher(params: WatcherParams, listener _: EventListener) async throws { startedParams.append(params) @@ -20,6 +23,7 @@ final class HwWalletManagerTests: XCTestCase { func stopWatcher(watcherId: String) throws { stoppedWatcherIds.append(watcherId) + if stopShouldFail { throw StopError() } } func stopAllWatchers() {} @@ -254,6 +258,198 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(vm.totalSats, 0) } + func testZeroBalanceBeforeAnyWatcherEvent() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + XCTAssertEqual(vm.wallets.count, 1) + XCTAssertEqual(vm.wallets[0].balanceSats, 0) + XCTAssertEqual(vm.totalSats, 0) + XCTAssertTrue(vm.walletsLoaded) + } + + func testNoWalletWithoutCapturedXpubs() { + let device = makeDevice(id: "dev1", xpubs: [:]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + XCTAssertTrue(vm.wallets.isEmpty) + XCTAssertTrue(vm.hwWalletIds.isEmpty) + } + + func testDisplayNameUsesDeviceLabelWhenSet() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "x"], label: "My Trezor", model: "Safe 5") + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + XCTAssertEqual(vm.wallets.first?.name, "My Trezor") + } + + func testDisplayNameUsesVendorPrefixedModelWhenLabelMissing() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "x"], label: nil, model: "Safe 7") + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + XCTAssertEqual(vm.wallets.first?.name, "Trezor Safe 7") + } + + func testDisplayNameUsesVendorPrefixWhenLabelIsFactoryDefault() { + // Factory label mirrors the model — fall back to the vendor-prefixed model. + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "x"], label: "Safe 7", model: "Safe 7") + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + XCTAssertEqual(vm.wallets.first?.name, "Trezor Safe 7") + } + + func testDisplayNameKeepsModelAlreadyPrefixed() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "x"], label: nil, model: "Trezor Model T") + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + XCTAssertEqual(vm.wallets.first?.name, "Trezor Model T") + } + + func testDisplayNameDefaultsToTrezorWhenNoModel() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "x"], label: nil, model: nil) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + XCTAssertEqual(vm.wallets.first?.name, "Trezor") + } + + func testMergesDuplicateTxAcrossAddressTypes() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + // Same txid reported by two address-type watchers — merged into one activity, amounts summed. + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "shared", received: 30000, sent: 0, direction: .received)], total: 30000 + )) + vm.handleWatcherEvent(watcherId: watcherId("dev1", "taproot"), event: makeEvent( + [makeTx(txid: "shared", received: 20000, sent: 0, direction: .received)], total: 20000 + )) + + let lastPersisted = persisted.last ?? [] + XCTAssertEqual(lastPersisted.count, 1) + guard case let .onchain(onchain) = lastPersisted[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.txId, "shared") + XCTAssertEqual(onchain.value, 50000) + } + + func testSentTxValueExcludesFee() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "spend", received: 0, sent: 20000, fee: 500, direction: .sent)], total: 0 + )) + guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.txType, .sent) + XCTAssertEqual(onchain.value, 19500) // sent - received - fee + XCTAssertEqual(onchain.fee, 500) + } + + func testWatcherStartedOnConfiguredElectrumAndNetwork() async { + let mock = MockWatcherService() + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + await waitUntil { mock.startedParams.count == 1 } + let params = mock.startedParams.first + XCTAssertEqual(params?.electrumUrl, "ssl://test:1") + XCTAssertEqual(params?.network, .regtest) + XCTAssertEqual(params?.extendedKey, "z") + XCTAssertEqual(params?.accountType, .nativeSegwit) + } + + func testReceivedTxEmittedOnceAcrossMultipleWatchers() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + let ns = watcherId("dev1", "nativeSegwit") + let tr = watcherId("dev1", "taproot") + + // Baselines for both watchers. + vm.handleWatcherEvent(watcherId: ns, event: makeEvent([], total: 0)) + vm.handleWatcherEvent(watcherId: tr, event: makeEvent([], total: 0)) + + // Both watchers report the same new inbound tx — emit only once. + let tx = makeTx(txid: "new", received: 10000, sent: 0, direction: .received) + vm.handleWatcherEvent(watcherId: ns, event: makeEvent([tx], total: 10000)) + vm.handleWatcherEvent(watcherId: tr, event: makeEvent([tx], total: 10000)) + + XCTAssertEqual(receivedTxs.map(\.txid), ["new"]) + } + + func testConnectedEntryWinsRepresentativeIdentity() { + // Same xpub over two entries; the more recent is `ble1`, but `usb1` is connected. + let xpubs = ["nativeSegwit": "shared"] + let ble = makeDevice(id: "ble1", xpubs: xpubs, lastConnectedAt: Date(timeIntervalSince1970: 2000)) + let usb = makeDevice(id: "usb1", xpubs: xpubs, lastConnectedAt: Date(timeIntervalSince1970: 1000)) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [ble, usb], connectedDeviceId: "usb1") + + XCTAssertEqual(vm.wallets.count, 1) + XCTAssertEqual(vm.wallets[0].id, "usb1") + XCTAssertTrue(vm.wallets[0].isConnected) + } + + func testTotalSatsSaturatesInsteadOfOverflowing() { + let d1 = makeDevice(id: "d1", xpubs: ["nativeSegwit": "a"]) + let d2 = makeDevice(id: "d2", xpubs: ["nativeSegwit": "b"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [d1, d2], connectedDeviceId: nil) + + // Per-device balance comes from the watcher's reported total; d1 maxes it out. + vm.handleWatcherEvent(watcherId: watcherId("d1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: .max + )) + vm.handleWatcherEvent(watcherId: watcherId("d2", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "t2", received: 1000, sent: 0, direction: .received)], total: 1000 + )) + + XCTAssertEqual(vm.totalSats, .max) + } + + func testStaleWatcherKeptUntilStopSucceeds() async { + let mock = MockWatcherService() + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "t1", received: 40000, sent: 0, direction: .received)], total: 40000 + )) + XCTAssertEqual(vm.wallets.first?.balanceSats, 40000) + + // Stop fails → the watcher must stay active and keep feeding its balance. + mock.stopShouldFail = true + vm.updateDevices(knownDevices: [makeDevice(id: "dev1", xpubs: [:])], connectedDeviceId: nil) + XCTAssertTrue(mock.stoppedWatcherIds.contains(watcherId("dev1", "nativeSegwit"))) + + // Stop now succeeds → next sync removes it. + mock.stopShouldFail = false + vm.updateDevices(knownDevices: [makeDevice(id: "dev1", xpubs: [:])], connectedDeviceId: nil) + XCTAssertTrue(vm.wallets.isEmpty) + } + + func testRemoveDeviceStopsWatchersAndDeletesActivities() async { + let mock = MockWatcherService() + let xpubs = ["nativeSegwit": "z"] + let device = makeDevice(id: "dev1", xpubs: xpubs) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: 1000 + )) + + vm.removeDevice(id: "dev1") + + XCTAssertTrue(mock.stoppedWatcherIds.contains(watcherId("dev1", "nativeSegwit"))) + XCTAssertEqual(deleted, [HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1")]) + } + // MARK: - Helpers private func waitUntil(timeout: TimeInterval = 2, _ condition: () -> Bool) async { From fad790d2ec7e0009e5d6f8fb956784e2ed290ccf Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 22 Jun 2026 18:07:17 -0300 Subject: [PATCH 09/52] doc: changelog --- changelog.d/next/{hw-wallet-home.added.md => 605.added.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/next/{hw-wallet-home.added.md => 605.added.md} (100%) diff --git a/changelog.d/next/hw-wallet-home.added.md b/changelog.d/next/605.added.md similarity index 100% rename from changelog.d/next/hw-wallet-home.added.md rename to changelog.d/next/605.added.md From 5510a4d094b7aefc7045b82785ca75f45bf1b09d Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 23 Jun 2026 07:55:13 -0300 Subject: [PATCH 10/52] fix: reimport device ilustrations --- .../ledger.imageset/Contents.json | 14 ++++++++-- .../Illustrations/ledger.imageset/ledger.png | Bin 0 -> 48034 bytes .../Illustrations/ledger.imageset/ledger.webp | Bin 97258 -> 0 bytes .../ledger.imageset/ledger@2x.png | Bin 0 -> 162298 bytes .../trezor.imageset/Contents.json | 14 ++++++++-- .../Illustrations/trezor.imageset/trezor.png | Bin 0 -> 41942 bytes .../Illustrations/trezor.imageset/trezor.webp | Bin 129882 -> 0 bytes .../trezor.imageset/trezor@2x.png | Bin 0 -> 152362 bytes .../Trezor/HwDeviceIllustrations.swift | 24 ++++++++++-------- 9 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.png delete mode 100644 Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.webp create mode 100644 Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger@2x.png create mode 100644 Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.png delete mode 100644 Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.webp create mode 100644 Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor@2x.png diff --git a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json index abc1d8499..e1bd58d29 100644 --- a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json +++ b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/Contents.json @@ -1,8 +1,18 @@ { "images" : [ { - "filename" : "ledger.webp", - "idiom" : "universal" + "filename" : "ledger.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ledger@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" } ], "info" : { diff --git a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.png b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger.png new file mode 100644 index 0000000000000000000000000000000000000000..ea544f7b4163027b2e3941457c699ace3c84c3df GIT binary patch literal 48034 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 XTglU$_!bouYcqo6^1d_x00000h}lT7 diff --git a/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger@2x.png b/Bitkit/Assets.xcassets/Illustrations/ledger.imageset/ledger@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b1cb6b57977f7d3cac1aa06b9a7fdebf6f2e9560 GIT binary patch literal 162298 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%0DcYiV+9651XBle1-8#_^$XW0`v6XttiV@ zGpmy)?|rB#0(?pY79iB767fjTqs1A4tn^hT+(rUxG*|`#g~aPduuTz}=Kzmavu%b< zqFVcpkzxhE!I|{NzJ&$YoKbTru0sGuL*ert)~0w%fn``KTY`!v@mh)dGSO3zFyU}= zpAvC*UqaF^+<;FpRm9UeRx#E-=$jH!vsIMVR?dGHtLlB?I`sjO_E)ZBWg`}_sENR0 zP2^*Op>?!Ps&z6Pkmo1>sv@85wSWrW&wW+!Yd`auzJbW84uz^q(tchRVaJ-maWOF_ z(DZ-1L*rrvW}EY)m>kFT;7}0y9%~B=FiStYXDZ%4(ySN}M#9Vf%{SkK^Ej3D!L2|9 z1}}Sn3QderXlaXW&{Z*%V*CC|%bmRB(6jW$wEyy7{tLhbh`g9i ze*NoT4=bP!DACzra@;=@^Om#ogo!Yp0dOHfgE1M#Vfwak1{Njkg8>HP+DQN#)&o>H z^S)^=c3;9z)OHSbekS`nVuuCy(PnVT)nH%-o2=BoeoiaAoS(;E$bMS8Y4qWE zjz(qe=*WazQO}6;b-R@qq0QN20F4ki=A6BeGt6&+HFK)W94ce`N$O5UM$R^VH^~&~ zsXNKvH}N&%!rUv&#lrkIHAzTNX=VykZi}VZCNA0lWo#dTObT|kt(Sd1ITNx=`^^0W zpzaGZU-jU9a%~rNy{r$vRn|wpm;2;4eR~!`=#qo*RZO-Jtea$lZ08A-NvW}?zj;0n z`FvR0?|HGk1GP?O7agLn)?RxIyJZX-4Qe0}XrZ8Itt zXMYyb9*D&L+kg9S%lG_slvjaciPBa!wj3ri30Uj{$Y2d!%fIO;|t?I%fa!^7WGc~2r+ei-5-W}`x57HeSwCJND(i|EDZ^OFRJ%6(dN zRWdFU&g7Vh(ll9@niID+Q$CY(F;gOqbDQWpXg19Gz)1aU+~;#foVpb8a7o=wni`!& zX5*~t;xJ`qC*nQXPznO>i=vx^9tYcalIg*^ZXZJ*vD7np4+R~wQ#h8^b`~W2aNERc zdO?nnMYN~Sm+Pt?mU1lKPw&5jjnpOnnr-1py!g@pkm!`@OqlmvMPKuG`Gz$K;bPO2 zzMPP06~^D5t_UHW*u3k_Oug%ksnLDUXu(~n1L{?kNR&| zhJpAaQzT+lht*gvK&RNw^|Q1Ti{Cgut;L>ju`x@I+4wPX-`{eZnIvo0d>n_&0FO** z-zwpf376v$<@~7Glqkrn^QVX{*66INH_7dap4z5`%aO^14to095Mg=Fng&YT1%n&g zsWXZ1V?(S`R#t<_3y~k&BDjp($o^PXUM(%Yd}jAVdon{OvUfg_?@(4_Ex4Fg7I-Z! z!U*6dStMOVkS2NWg&->j&^7{J;w)X4F2?BwQ+egp%1Xsht%(Rr*0%M3J| zpSV@nRu&N#)*4d3FO89pdBGq5@gK)F{aTo>1y&LaPKn7d*v4aIYm47#ShWOMoM|3K5l5`-XrBrpWHZ8bf$-s?u4CaR|0z}5K>S#X9 z6~kH4#dOiq%By8sQy#;Dd*d41GtXhL$q%`fNm_vLRU-XhsvfQc`+0hQikId4DTHUN<8=AU)OuHr9>mJ}El&Y|v8YK%#wef3pQ zj?`I?HfQ)dXzbOwI^MQ}e0GVndYj{`6!utlOE3+K z&vv2G{tC>09p#k*mTailhJuOPR6H?P3kyt-JKI;k;f>$*Es+pRvrMAlq0~>sa>*~5 zuf-+$=p8yp2bE*waUr1W39#-H3<^v@lodE^W?hU-ivlD?@b$OB6Mh~mqA%wb7s!o>#>seCt*8PR^N-q^jxz?bw=|RynYoz4(VZr4w8EFBP===JL_F`P$AKW$T@N% z4VSHl^0L3JVem`*jB_+Iqz%RWL&X7m()Ya>4w3Sl8ed!^q*Y6WJ)I$$YX#g2-&=fE zqJXBl|JpGn$}1%bWARlvSo^z3>;|p{07H= `n3<~I>Ttfl!eL|w25g9xl$IZZ-T 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�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 Hu0mjfr14n& literal 0 HcmV?d00001 diff --git a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json index 6f23bace6..012c311e7 100644 --- a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json +++ b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/Contents.json @@ -1,8 +1,18 @@ { "images" : [ { - "filename" : "trezor.webp", - "idiom" : "universal" + "filename" : "trezor.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "trezor@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" } ], "info" : { diff --git a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.png b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor.png new file mode 100644 index 0000000000000000000000000000000000000000..4c48b6f214c33a127ee772a1a5eb4505f99b3433 GIT binary patch literal 41942 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�`1g4` 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ªQePc6050^zpS3u+rC&JmWt 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 An*aa+ diff --git a/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor@2x.png b/Bitkit/Assets.xcassets/Illustrations/trezor.imageset/trezor@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..71f7e62930051e4b8ec5b2d121795ef5a59599e6 GIT binary patch literal 152362 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%0DEK=f$MlXl7p-^I|i$f0CUue zR62@W^E^Y^1+4Y<%7+t}6GK;VE~}R$QYySz&IExDC+;}vwr$&F{e|moVq$sQVx5_t zvAmit=O<&iEY&qd$`Jb+-@*=pyc`IjA%70Z0Yb2;IN@DVxM5-gEgaAwN1_e6m0{Vm zK#ITtM!On*mbiyNJSLn*l^sDtjpm^CAlD8(4MGVK? zNpd0^5|$J-@Hp=Is)XJeFZ;mjB7e}rU!z?q4Pdm#Z=>qNNSDbkBoOWTJ-Dj86sz(V50O6_*=Pk^J3fvHMW?Ju4Le7TuY-tK8Q=lyVus0Gg~kYff*`SqQD*uLEu_& zKEaA*cHPSZ6B84*YtQbZ$B!R3Sv)?}1IxZ$16`w#B#_8mBwS*opBw@z-n@kV}@ zbG*1_UAF+!j3L7s9O0413=HoO;h>7V!A&^BsL*2NKJ$-~@t!#kmw)%okacH$Y}16-_XdJ!0mNp@MLhU*DLIP$?(my*^m<{`>Fi zJ)gKcZ`IvC6PsU{FO6L2f98J1)l5)}zjlo@N&)7v2CZ|V=bSkJ8VYm~1g)wz;Z7SJ zcHSP&0%1>rQmLP%i;e`E8(&b4FkjQDV%$P45HAHx#J`SYR`HJrZOvl_KvQ#+p%k+c zhwTm6l%XC$^H#*)N=~;mY_krXV9({Yle8`qD{Hom5gKov0}e)k%A%w8AtYEfU^F+De<(^E70*kh0FmBr&jJ<7HM zSRqm#UoQ>l4}S2xuI<5fdh(3jbNAhmo-fT{U06U8vxi+UEnD%wQdQwnB;_WE=6W9q zke^5z9^$i^OsDldHTaV9QjQ0}YYaLii>_=^g7b7l=Z;gxyvTxvL}7KZ8enIsTmzMGE_le$@e z;W^-WD!;1rF|yByFJU~1KfxrWH8{RP>geGkGCF>CkT&quJSD;(2`pnS+k@l)@?S2<;_;y##rx^7A9f)sI*_k_{cCwDy0Glz? zQgXkTmr6{lGXy)*xHeGdoFk$;eM(+Z*N`ighR8%}@K5>pf<0+$ zSH;iMYfW#X6Hlu4zh&YY3&fB!jM)(2azyz&aU`kHI_c}@;@!55H%1MU>!Pnr3#G6|7_L=sSE zxo~npW~+0E0ky7JWz(cL-fcLhhxU~xN zRvEO=Xu$s!-bOVGPOwcH2o_N&Q&*Ko*Y={XlXj#T|d5S;Knc&5b>CozN2}PRLI`^Gtae-{BC~1ux5? z!tFQ3)Y=FrK*kc&7WwT8rPTE>+?dK~Qu(dbiR2vHMCwGw^kDI2l24UN1iUpC>_Igm zydBg6w+W$fBx&$nx-dR|x-N8$xBz)~y{gv&6oOdrBdPt9@9C|#-pU2fW$oJYt?66q zS*(takC$n<&@F%vB8>_pCIucKCqSACPw}IQ#@zn3VypAR1&HLzjQOsKIMO{};TZ7m zz!Dqk++uMXMYPJK!s0X}W+s)liNsC?G!(V&86H0#d9A#KFVezToGE{DY;>dtmyyW8 z5+bs9qF~c&-k?9Ah@J|EU)E5Q3HOj_GB|*H9Ez|$RUS97TJ$i#2g+cf4Y1Tz3SZ10 zRp*0+vUkYn5_@#jo>9=1j$@A7tM`HEyogIjN5<^HfrE1=Po6v^i^qq4P>7P&*5?QN z(#tP($Bv)qnZRke<(3V$cI~<(;dFvGEp(ncAYzS=<3}B-pnu>3N-7~D;Xrd-BKNv- zGiw2PXlZBW4ZzRMFpnCLnK;All`t0F3tJ{75K1P39xP8f@(V8D0kAs


(Cf> z>k{0h?Dlhu%XZMfLo>HS?kZFvM zyhu05tB!1Cb&jrOxn%z!GlM;LlN&n`op! zNsICxpn^{YMuF{Aq%tB2@eg2AM>PqRHm3(9kS%#!SqaEy?VaMjB4rEjDejSA-A}^= z-PccCiYMg=`@8RN(Hn2Pq1OyoL<90EvP>{CGFpD-bg7OI3y^S;&9B|Hh+l51REppn z^*iv>D&10ZHg7-$+P)?YQ(IWejmKpSg%Ua#r!G#8rvRjkS0uWg*%sm9aBl+%Xhp7H zW8R<~GzO#qc3v-?Bjuvimf@MFLCSTFIq+!N-9D%?gH?PVw7liKFG;o5uvYzwH^=+K zm`Ysc2HM}bR9jJ$#G|yl>!@v8V6-Z_#3T%&MR$RiGL_h%1eBrGv1_x|l<>0he`UZ9 z1~~^d9XoO2opqz@PRio(p&x~ncEU9vRh-OqB!BPsen;1=St}<`9G81P{s~K%h&=L8 z@a?9JIeg`Hx1w%%U8~ZTIk`lX#jIGim3Ts@0U_861;_Hq6f1kx;HXo@tH56deB>%o z*T9sBKzlQL0m4uBXi7?AvSOmq$q5KRiP@-Wz7z-(LSf#RMtw|H*om6aD(j7Z? z=6uEO(n~H01j(P7nx2*wD_4}+l~*QZkoAH)XcdUD_^Qb0V%J&J!zIda6}(Ic(!)I< z^&SvNBSS^YeZo3Jr5zKku_g%t!A(_#DbO#C{D4j>x22;&G~&%`qenSlQwd0v!_}=9 z%MTG@{hv;!XQpL#W>)itlS&)mqlLp&O0b;@t;Hs3Lp@{Q#ApinwulUI@hX`J$Ue0y ztIm!N6e|mLh^R#0cMZK|Y8|Y9SHPPxUWW`aH~1Kk%7<8LyOd?JT{pil-yJ!6bnfSN zZag82$A^9})E)ws4{jf}2M->yH{N`sy!?qz+?x}YY0YB@W+x>FYn*^|6-ZGrr39xM z?SK%RXIx!>K7JV%jH?<=y$ymZ@Oc=cM>|-+f2#zWZ)Y?{bp)xw$f< zdZ{1>yEN9}hUS7B0wkgrlS{qPjZyGHX?u*~VLi}8tL0~0n0Tip3(&|A-b78UZvGE+>aT&|UISaqI^PHj` zmGoDN0nI=(Ryru09S#kDjuty%3W};(Fi?&vB}FAcN9RW@ly=gGuMg0LsJaXS(G?M; z+ykqedF$~_o({DQ)EBGh-0WnnL<3l>QNJU`Y!z(IB|Kr*3epgnlTqSu^ z#K#|hoP-FDkq^ku^Sr#oX3HdSK8*p0h?LKLiOG(YN&@2P95a{)1PqjYm2lR{5t>ov z-)`~T6}bjTM9Ebw0>MO4sbTHr;|d(;EWAVCu)|kPvBY;rFMxGx75ZWbY7B2cH85wE zmaER&>#x6=wQiZ{1B=p3hLfjG$;9#r%}ZzJ=NFs+cE+8{-Sh9D`5}TFDB74Oo)6Z~ zB1Mf+Fuyxg=V}e2VL5C(_Id$eap0N<_V{#JqoHaIb%&3D|D-6#iE2s`5>QsV-+UzhUh-FcX{Y*JDRyyU<4 z?cLY2*};}Ybp7!hDU$BZ^Bp^}h~Q?0Y2%x3mTbpEhY#u#pZ>HgUAiO`Bb*~o{tD9k zSy#Yv^x;A(C?D%HkO?ozf=(i60*L_LZQwx&U_z8NOkIx)gIk~-;Eon42j)oNDCfw{ zf$QJw0%$NfgDyH4B~NiJfutz?C$&E`NTfsoS#NjjmH>3s&U0Mz=T4nGAzQa@m78z5 zndd5(%-elWj4!n;+04z&=FAPx{a1mTU{EAuEv(a~=ptrZDdp4B869dnAvoxflIFS6 z1Q@$b8{E%VPW;8Si1HK>SgU+egH{6vy&F}frtAgx&R^@e(G-Yza#P@7YVd>6xrNY@ zaiVTRB5z#2az!7Y{iD6&EE~X>3pDz!K~VGD{H_z)@A_~{8B9a{FZWRrMmnOc#CQ!; zWJZ-32C4Kc#&>?6{jY;u=tVjKpc)RJI$<5P(&JDlghQ}+gauq-*lp>OC35)aQR}6N zO)87WkK^beV!=%;()1D-D$(W8;Y0Gm3opn>Z}HdmdhFHLUIUG?96o2WA?1qB&Xvaw z(~j036O94E%`~5>;2pB$JUr6r#!Z{-!Tawk z`LFEX{JrV<*_^Ufw7|}d8KOL0^SeM{Bro+v4Fn(+AZzveh0x!DG#c*CI~PxY>CD>L z(9)IF%$3g28b%A2#V1s$y+T736wdJ^C<7;puNFfFXhH%W)bV%Wc0lkUmPa&_MzGgaYHkiB+2BWoK@J;<;YW_moaV}d`N=RE80ZVYBoV?`NXU0>TcS_JODty6ys$?AW5~53-l@lIa1ZxtVkFR$^uvgw`m|;an3d)@* zhMB^eDQuIA1a5vh;cAIufm9ao?XvK`mZXg2u>d5$-o%OtIehqF^N3i-Qgn1=6rM_q zg`mX*RL%+2sQxIyLjiPF?J35m@nM$8M3LwVwU&~?25Zf+?-S3+k}W!4Xr3r`vCAb@ zD(&VF1K2${4F|!WQ%*%Yboj`j{_n+&4u4EX;y~h)^6`Z&V9c%J=6ANp(WA$5pha%D z{)TkHg?ZOmZ9&Fev>;DnO)is!gDn8t#?>*73skxnj-|jYXACUroZs%c#;bQUcj{)C z1j!b>2Xy5@hJUwDW*lTzi zy$D16O1#}_b^-NLWhe{nLN?Pi6I*wYqY}D&KXM)7lRo-wV`H zh4$RvN#U8&{UR)AAOXM%<5d|BYfzj)q*e>a3r>-@>1o%<=BFl0qiz*yLkRXvdQbed zB4P?e!(`E>h-F|Jf(Q!OGCL{AoK}wEbTKF+^tgs2T8B6gjapC5-`ccMZ@%efS-W;E z@4NVhCr_NTb?eraYvzFCLI<7|n1I-z!BAR!9rM{+*ND^1UdGHsE^UoU)2YBI!+eT0 z484T6@xT)LP6M0cu~(bo?5=5GX;bprXBLu%1=5+z6tOV^nk?l>4MnQryo1`u#FE4j74@mGV z*e}gT;jzMxhp7O$7p|yaRutNpMTkR(j@ZtfJM_~}Jl-pMD1D{Ap3t48Sa;%hT84awSS@0!Ndc?Mjp^dB@C1xA zBz~iPiBPIfWJD{=qw4?2DQc6wwlqCEyHOU8AKMWNDkZ`Q{%q+gCQ!}Or%uZcUid-T ze&WIlE^wW&HUHvuILiW1tW?Fic>|(hQV1NZpf-++AR3&kEpzquaG9*pK|(G)D(TVH zBFbo2xuUtN7laZ7I^l{&Z&~8%*rO3sn)8Y?+sHml!WOwMsKkE|;?hd9hJFZc80cDN zDlo6CBkzT?uYdiUa{KLf$oc258!}+~_wTd*HOYo-9(zh*>+t3&#FKR~pfr*J5q`uk z-O4H8jF`Zk2n8c|45*fLs&q}%5HqZtvq_agZx!TB}J{Q>=rIKqLi+IvH?NPIV0MUxs?(mWt&JiKf(PcwlhSK}pdX z9UZfsd-e>LEnD`I(6THZANmnXs6f$b@KdXIlV8c2;5WYc&BDBn96hAJ^h>`aO)^k9 z@-Mwch9Lb@k7?j9l$BrD4ty{O{ zg$F!EIq~V!XLRY(B{H#enamZLpd*)&(C=_+39^c=5&}Oy=r<3V=8Y{33*xe`Wbff4 ziD-m)gxMvASuY}OXvZY*-g`hjUp~Z{qV6k#d!>=sfJJ~=;DV+@CL#au^!if3%TRwB zNa&7|UpxO;x@@BNwoXd7V6f&I(3Rz`6!lds3}60aEtuJ1F^l=u*k;WxG1TQ=0oE4 zLEhTz{4#IKY{e|~+)R`3j*6KhwEgn|Vfj1J_v=bw{D z9(hD3ycTa92lgM3ywgNBO=bBkSyRljVTk90tJ=8V}U_*oJ5w6FVUP{ zICNEfWxQv0S);_6X=7PaF_{lD#?Jtz^{L@{#d#n&V`#&ESJEm~>oDwvBeWr~ZZ3$S zqPmx=kl`4m2o?UYl0;P0)Gjw?;q~RHeIQ+8Z-1_2bR@UP=id00ghbIl)Ni~sRhmP?-3-sIIU>R zV}%eQq$1?Y3aHVhX~BfhVy!}4|IePX&TV;>D3AmCM^_u$2MAmU?ij3*1(ILuE%x~MSl2UHwzFE&{`Zlw(b6ne zAbit71V;VIyBgx-iwJ6P!O?bjG+N;kcNSkLX#}B$lZbL)R72;ekM+3LC?>#7F;*|^ zAnFvIh9lEc)^cubX|us}W*P7J@#8ueq_++qK72|Rk00BS)~;ErL$4T|E|G?11ap*E zUwgf0QTxl*vUlBem#kQ^lIRoXaogPa;sv9Aiv8k@GrfFGgM&&WD!Sz5+F_Qxx*(#W zRT!n6FXFyW)ieb3-grcO1-K$CSML)Ex#rdQ`w~=4FQ=*65KYgw@%Q{Tlnlcs9Li1k z@Q=xe2#8wSPYPNK3}-o1@4%9}^xf}0TWUb8T)9%3{lG|OadxAn z)knnhvseq|)tX~5v3l)kt#eZ<=Arq@$zDK7VRBPfQQIG@V!uHOyQE!aK_4~vGT!DD zfhOn|9~Me-R-a`f8iT}jkRQnhEbEVD^UglL!;{fOl%s#&ll%qs*G;PE%Ev-u0&>tK z{6^1~5#m5iG}mQ*R8p#%ZGWSm8*jED|5r#&NL13UWR$HW<~IQCe9? z-t6(@$1~;KF>zd=`ONl@+;|uEWluHEVI49YLQc`WFN+f`)TixL3ddKa0eMn}J(=59yea z7={X-=fM+;lAcCCo6v*X!gNFajs_c4RaAaq+yq*7Qie!0+J|!WK`SdkYy5mC^D2Ay z?vwoo_UmJx`c&(u>X9QyblH++a^Zy++FT#V$x;FECD6f5i0_(}2ntF93Xif%qry(Y z($XExvl=>s{Qr)IP56`Trpc6GUY&E(ZS8wks;xx;oWSU+p?g(o}|!0 z@-Qz$IM&Mp2l`;(TsOz>wM2NUtp0?@`IWj2{eW>41e!}jr9O~;NZdO z-rT$=i^q@kNWCWI3`uJcgOgLjRj0_6UFc-5Z`^1H4jjIb zlWPp~@=`M2g+>iaBt5-MNf#t?vSK}2g-)w8s@d#rp%L^n=2#8Z#Wd?DSFSzq?03E+ z_uYH1TzSQnO&^$SeCsW}<(8XeY;?2_c+K{*%v^ah(e?M8tPC_60T?8biF=gMDL`a_ z9rC;NgaMYFtbJA=w4L?j*o`6D#}x#K7~ctF>iQv~j2MFw+W=LzPf(V6R+?LF^ajgI zy7wPAIPg1W9ZYX>E1?& zmfU>P&03iZ7b!|3AWAsCUTdJ!zyA;ZzN|fey`?} zoM=IXw2O0#lT2#*7x}0EZuD-QkA+32!l%V;^Vob6RAi|#a9$o6sxRU!nBx-uZxgTZ z7Jz*_ell7O9TWG`@GOpdHog_zgaIb^vWypna_MCr``nJ zoSmJKw>G^kx7>77>F>F@`HmItK)#bu%k=6Wp#fX0?~jK2%A<}qZ+wbU8814jVr+BM zU~by{1tef@s`rXFrj-MN>;mtG9(jN%>{G1TKo{kNm4bJ<;B=2G+UorBWJXX)9#V8YM(H-5alBv)Y zcIx-y|B)Swu)9E&{iF({Cq>saL7Fy`iGztso1PRru)V?ENoeS2*6>Qyo^ zv5etQiAVx?LYX>s@l7F#FTVJqZQ8U^PMkbpf95~?&+yHm|75{4%t;G^t@-XC`G1I; zy1Ql)^9gxN-bTN04x)4rHia;$K{$MlqHq9IWK3^HgmdDHaSFKJRjj^Ge&2ywDIA*! zW4z_#NEahXBYNUw-C5n*<{(JmJHCcQbg0Q1%>hFSPqQeby-RB^zx1-MS+hp3x%#Ra zr0%<7@BY2AblFn5=)#Mv*J1}VGqb5Hxn&6sa1B3WhAIeh!hdi^{lzZ0Y`_Td#qW@u z&}{|r*=TblkdP$aZ=FjC9KPI&D0-=KGv(J1xD2aD+GcLFotb7(GTKn_-cBPUdE0rL z@+Go%)KiyC_SCaP=`>K6oYN7(r9bl!xq)O8 z|C7_;JjpwDR1-hKdF(8P8*)n^HRTg)8d9#To@kQgd*q{*!c)0OO8;V6)9+8vqO)6q zoBtdc8OY(INA#@6RgRw7X_gO)Ma8$viIlfe!g?%V#Jhl}lE7~9{8eKuwnznksuh)= zl)D_5qo@n@EIh$cPtyy0hPN-wM$2QsQ(GzTShUbti)-8odk&9}j@zLlhjS|0vp>`c zi^qq4q%;`V_HEnc^2;v`=IV@v?umFQKckW^F{_^c!SlLv`wlyP;-vh^U-~6mwrnZv zso*@l=9qUxRSf8mJVAPDR2@9jfCkuah|WFEn4C!#K&9VBhU!^X+K8woRZLZh`dx;A zg^MDfF#={pH<9erhG`ICLfpF!SC@XKRqi36AO1C?e@t)|sgTRKxCTpdL@JpS*(c3X z!Amc`l$K8{*M}Z>(0KiPf~m<#dHe0R?ScF6FP3n&2iUwLtuxaO`<@Byk}!OtRR9jO z@xFHFL8~kfj~oP;db4L#EEB@KL_J&U!YM~+UfUAy)k zhR$>yjl_%O!RfJ*Lewc^F(;X^>+vK^Kb*m0#>8I*)VrWopsx;M-b*umAnPk%{vG-B zXFjd#FT6kv^e0cRty{O|6;p#dZo9qg*)=melXs$p7z~0Gwi3Ge8!1T9|3)^-+CEs$zK*h6)Qp(8rLv01lTN8y(B_ z8hQgWXYKeCf6RTrXS{sRLOhDG2#hUhAM74wFf3_(pH1S%NOAFO3K#NxaBbUH0CIC1 zGlmZ76XhO49wMb&R7Au=-!SBS92gMM^MV0VoUH=>*&3A{6S{?k$*IYA*R5MO)%L;S z@#8rLBZI-O<>xp(JtH^WbfawBzP*`;$rq9{&?`;u4T{?xJ$ghgzTiT={PHX8x@)i1 zuYc=Xd5PZeRjgFxitI~apxQ!1azxB8Bpouh9Iy4d(A^4Ld zkv^DIlcDv#%2!mZ?q$wu1v>PNdSfc7rGm}Lg;%pGKWYT?*qAcUQ_S*W@FIM|BqPQB z+p*(Eb=8Vhy&SVaHog6pma>Jo_RgI<^@ba-*YQ4(bLh~a0-dRMnG-H+_0|FCYz}%# zm^<%XVhN;_JS!}RcY2EL+}z%@Y`;8!f&`xKr>rf75MShr_*K|vDns-%3}cPODL8iN zCijPOVV6O#J7z6<&z`+`b4WfevUcskSC&mo0KpX7&zB0dNS@)WIqj-<@t0ZN5=P>|7)YOQHY5!aF>0C_!N2^i ze^uVT;DQU}Q;$3n!X5w1pUHJhCG2sL0yOwYf$t8X7SnnW=UA92R=J>Sx}LhPkpDX& zPJvj}`5sLM<81DpH;Pvf5ZLW_b&&*8cg6SY% zY_^gTm8NLDA8G&&D#6($o`{BRLwL%X%uQvyQsIPn_DJq!M8|tDT}W__B9!la#z3h?|jFedFE+Zv3y0|s8ai&m(6$c zhRvj`vPZXNT~|~0t*Xl6=%SRfanBat^diy{o5dnA)WGhDIn?6b z_#m1NDP0ua412u%TXqNRgI75(8#;GYbHPlP^zs2yTUDv|pv(mbK=~?SSr~$@U%L`s z2dnRP1bgphLRd)6>cmmF`x;s^?3}t?(iGppV?pXloChw03k*IxEYy1i%EyrI%}g(Y zEXm%>bPu&}$Rfa=69=@PlyeAm_ujp-cI|3iv0{07(}J;7eSkDJ?6pa$vj3$oe_4(n zJE7~(zrdb(@+qnG)K8TM!9t<203l8z^T`9OjQD->D%hUn5^zU{P1{g%8D~+xtyQm5 zaPXM(xCZiO)#ti9kEBiFa2m{6LIf5}0HKVbjFS19;JkuV{C*gUD6K;HU4)#5B*-U{ zpSbhwP>8r7jZ9wxKKATnpj)?ZldpZ_8}euW?4QkBsmH_2-#u~il>F}R{l5L`fBY-5 zbm>yd0k2;EDf(d6%@OnRr|b3f>HO2A!jMF+EZ>zn=bKScUOfQfP0Rh9>`_$YlGA%7>f=JxQL=x8sQq@LLY2M-gA zGVm5KDd->1&nk^^^N}F2jjbCP4Rf9>nHw?UUH1!TiCAuGk zLhCPe_>0?yW^zmIi&`s60=l#z%+b+Qs^LENjIC!Y@4x@9+;HQKvSGt5wrSH_(n|uk zOOw;5PwSpN`{c8qeMYu!+bYvj)7r;AtQXuFPRS0XcMUr&ij6`ISF2_$HBC2u3N&9m zP>OyFy6#%0x7UQxo45wteiwpST1Bgp5zn-CWh^maSC<0iqa!17^vE&o?YbsdTodU{_TDH_ATbXo&!hHATB=s z4j(=u7hQCr_EAWmB_3yvbXazg@6L`Hja`h_oiF;_LpyR`GuT+J$! z{*YhdndnOQhe<%?kMh5|A6LFyN6JAlQKiPqg%x4EM$-67+j@NQBUM?|n5Q&xj-<>kr$z!=SOj8I%j9^Wg;HXhe--{Z+z=y(lC#!_T5&t~!N8+Zxk!c0%+5&O z?V)x#eGRv~W8>q-y#ld4k|+4nDZ+`}paenoCyc>O?*|a4TJ?Q|?L>omR%`1gY$Okt zeGQ$B>quS8Lf?SMh;8o7Uo*if-7F^$G)A{qni%OLT~lW!)56@sbFaMe%A717=fu&= zS0lgHN%hzBTIK@>4qIM0(6iY58K9B0hS?_$=nsiUp1=nW9h65Oeat2%mfOx9JJbGy z2dpfwjRO;T5S+%8St@utB>#wQl|Lf-<-;(7!MPns5U&EG;18vY3WRFj5{(-GFHpo$ z{C`v{MB(xSyC|202;%e-w9Ol=jqNGGs*yJk49~xus_N*m9-JmxtTho7J(SOvb2@Xj z#*Upk_0dNjE#*RX?AR_Oy}7NqK=+y6b^h#A&)AM#JN0z$Wt5z#!N8XiQx*U_!)y=Z z2Ap%Z+x3)S{DqtOW2=~Hwc){8)iVzKi9+P8rTr<;$k3zJ+WRhLhouX2%bYRS7C3U` zh|SK;>9Akp17u`mpv#snV?&e?Q%XNF^OAM=4u8`hMkxTm^%!@C* zBzXc@R8tN8_3LQ*4kJ&c4)9Ar7uq!4-h61mOyO?B<{Yw7+H30%9v-trf`&>LUA& zcU89Y!iik5M@T~aWz$$hqS@4U0cMhBz+{nXUdAz3`miNo_? zolAsImN!(N?g#J3uKSqv3@LvOSk(?ywV(y+!=B@A>-!(*z4zZIYuBvJfdkw8&SsFI zAeg{puuy#0L8L$_QO)QY8-D^F{U3$zCgis&m3e|=1iWH4F{Gkpkb*muT%q`iU>Jk& zL~qrCv+ORFs!-AqCASSyhD&p41N+af#ZHZFx;0K*KWTBo4tce14T>Y6Cr_TT6UUFr zFaOG~$hNK9GOL5WSWeyLAlL5QyW}&UdD8YD*eAJY_d@n6`u-mfV~i=Y>>b=y%WmVP zFn@2%{ zx#Z=uN?22Zn&TpWt(GC3WuB!qCh_z*Uz+LQYq>qmg?p?ipBtYu9=0_-tU_Pt@^9IQ9UaWeew8l9fOh4(O+}Tk^I!- z8+p>+bkj|G{P+p&S#16+hLk^O)9O--Hlfn~-I=)=J9_k(KJv*&e*Tb~#Vi zNCo61ngEs<_LxNY1W707hl3s!TmisyK4{Q91qhR7DFBttMOawj66-Laf>RjhICp+b zhLyTf8(>w2X`st^8 zusx=G_wBQ`IeCZGUA;{3*rSi;RbJ`v;lnxbm2)ObyA!QaJfL9wS|3TJb+|JN4(HKq zcDn(514H8BVJI~NGnK^Mc*YV2Ck;JTyyIgo#bgn|;;vFOn;%lK;lb}$ zP8G@(X5XtqdE?0FNG@ViR_?w3!3S?X_Sj?pFfW~!#p9ef2BT^47tJ9g2nwXM zk{NK_^*2aw87&er>!{;oX<@9qnoqWO|6aZJ+Kmg zvsEo{m4mT5Yc0)fiH=12sn3|^#Oe!(6nrJojfBPlM?6)O%lDiJ{h0hJ!lZa2qtuBt zL~VQ(88SPK3~Y!J;!3gCNt_M#%|B{q&C-hBg7*WU9OOz*^|$cSBJ3E*C# z9kf%+YWLC<2)vv^O0<7mmXj+p$SzsBq~rk~JAVA1ZQQu=8?tzuGe`Ci|3n%|Yw9v= ziAcrCQz!NE%PzHAO>SWtNz8;Uw=)0_H&=trAwCBR6n`j+xi~T z2;%Ueod$*^nZRpGeME1LWahdk2eFY03D=FIF&*bQry){bK~}{@Mi$`rIgjKp1jZn1 zkU0|DjqqpuYS;*VIpoXAeH=*9L+pbF%qqU>5CM|-wT*lPYxX9)a+0_F?gJfq;=~F4 zQ@`>ndE>vdch4UGJUhJq=(}6q)2pw%+Ag`|;yx&OsDHk*CBi-^SdwQtO(GNHuR41~lblr`n>W8B&wTb7 zx$NRgoBWt^&0mTb|nCyf|*GR5^f8sxuA`P;Zs+p4B$#s1O^w1opsj{Iey}}^h~_o zJ5H9_>e6M)${uCQd+jwZKqx9d6GJ$%v<8dH$-5xV)qr_^Gasw42^!H^K0yhOtSlwO z;K3cojdI-y2N!w`+^{rn@giCSrL-D3MXhMCJ;1J9vC_7@`|i=cEq}N7NcPL( zan2lr@$vD)a|`pI?#1#oc$Cc-f!0`0g(kp_1dFAG7g5@nDwGP-=X`k3>O`=xw3mP?%wCC}fbmgn%|{WzGhj|l zozYVzYannv3|L-$m={#^dSqEL8vR>tqi%=|oKrdyxJSAj(MNclBN-s{n@s8bd&prR` z_U+pj7Z{vF$6#S$;b{N(az&7*OZ3$$GQlm=!~I0O@4owV$Bv!3T2Xm7MTI2DWeF}( zr7z%=sdq`=(Yx-vOZy0?Tz&Ob_R4FoW}PetS)w84)Cmls0x8B;!F^2)f@=j8tC|%C zJ@HHtc1KyK%CV*LEK}vuE~Qx!W&WZgScNjm%SdmlET>7jq>F2B7x&^ky zXkrFe6DGiO5iG10U+cwMh&!(0)5n2L9wGL1wSJ3ooGYRs5=pcMGqu5QdDpulY z7GZn6Id5<{uCw#Aws-fQ-@fC{JHNab;5xSsBtqKee%O4XpG;SxMiseJ8CJROYc7qq z;g(xu>$Yu9FDKa{t{yNL4Ugi0e?PT-1hQ#5( z$Hl|d5|G`Xtytbw6P2q(sg0GCDuPhTRmK`KiOvfuvaWjc=#f(MLRG3ga?74U)sCMy zQA!eykBzc>ITrKJE)ZP3Z5oMj)V8au0n(XDXta?bc;`ME$upC0V;5Akno;%j)WgHm zup%7BT0Qj`i)~^=qB{$5vGADil45hik-?}gTed__pE_d)4ObX)Vm z?~nx`ejO;ARI7JSWNiA-&gxg-gf+Cwr-D0%LJ2nzkUiNj2SDCL%+at$2z6C3VE{6W20Lyd70lQ@Q?vU&%Y zW5-Wq>B1Uxjz_X??b=e7F@JsO(q*8R+6c$VLSA(iOVG8(&Kj4|nQy|awZR(8uIoSi zHMLe0?-e;*Q|(sF5W@&CoKP_=D#zAft1-Dkflsbah=)o_4cJ`VMV2jF-tFAAqw52e zf4lcCKaj=aoI2`$+h*H(*Xok~Y2IFnW5>j)(|!NGefq=`PxLPTyTyIXOu!jNm6Ht4 z80%CB=Ue|{$BrFk-S{Uz`EUknees1C3Qe7znIngVLkvq@S{6ivI7#GJ3mzbWDY%-2 z57@qnX-x>ya5$TJ8}4ghkEujfx=E0UKo}5@nDfy4#25lsprZkK<7@sx?y6LAIQ&yT zEhPh$c7;*2qI@#(u1MCS-@yt?H+Q`kk$Ra&|J0xQRk`A_%jLcI-;&Z2+CSFZVPMA`_c zO19eIDsKUFmq3nU$x0nU8H^Ni0!S9TY2g?QTW_&aM-gp^i~~i+0)Fk~k3p6rdVQeR zV0$Atq3^x--pRfv|7PD$M`ZChr;b7M`$DeQ+bziFdZ1k@U?7E9m?ygD9Lt=@oeRP2 zJ8&SzNfz9VWNhdFJ#o^|OA1N1e(*s*X)my=uez$c{>B^R`RAYS2TMv>3k>?=6`IRr ziBV<%)avTFOAMURCO*_iXl#U!UH>Z&YSJ1ZTtPNupo;4mG~gJV5c#u+TZmP;0Z^C- z1PsDsixLMvr#DRvm!wrN5KcD26)YPqPO!STE1C==3qpfR3KVY<+{r!7V@HnY#-7dI zbn`88#~pXd?p?d|)ag^ksZ38jA163yeOP#V4e*-<#U@{t4$bZV2 zA+l-XCS5+U)c*9J{y&!Ici`Z`K1ehJ?j5pdsqcF7?OU^#5Ld*=429Le}t? zE?HU(zoD{)&^Q{Gp?cRa_Q?StJhwj@uc<&tMU`O`A_DY9%8bQ{hK!@cZV+h*y%}!{ zbkz_Lq(0<$P9iaq#rG@Y4z}f^BRNpg2ZZzPBa>5;+Rw>vZQQu=U&!Kd&K-lZUs$$m z**m@ae}4~rmrAqx9_~;1=~)Gzuy@~opJmv~14rsm(FjB57p%dr!Q(PWzW4p_mdg8= zUV4dc>w_x`{Un{5%(hW|!r2QV zT&FVcwoYmiA)kIov=?+wZd+G!DN++^qM{~Y95j9h{??QS_OnEoUZU-)4MS4j#Uwhy z+Am{ieGSevW&-Fo_*+lQ2<``wJ#X2)PTQUzaF6H1FI;z16wb~2BTnl2C-^y7m-Ga&S6UVxq zEhm$+oe@9s)mAFG0UHEFrQo+@ZTKBab8L{HmJ z49Q31`INxi5GcdAh?^^#8yTj?9EgZ5=USLv-mTSY%i3bQ5~J^P3C6?{Vzy3rT~)GCJt-l&{8b4GXW*q!eA_`Q1DZMW*nFTRv(nwCl2bshJo$3g_D0O)|?jn$Yi zIBQT;%qS3~itOc-r8$Yty#>ibC51oI{%>gzVPm@`*XuITg9Wcm{BM zUwI9W!`wyEY+$9AD{>(kp=jN@EcwTI=dJE~&qsId-lY>umKHZzqhrE&2E#``SP*I8 zDy*uT%R-%5m6uP$@eUuVqk%(7>LR^-k4>Nycg8kXo38P2!-!%lkCH*-Z7PJtauuIu zn=_s!Uu;m)8Ak>KomjrY_UzfyYinbFb!KL2uPh$t+%fp0UNl?S-h=B^{ixZ%tdVAE zV0H()oI9CwD|5NL-hvh;n^%@Niu%|z$E9QyceJ=XNSEEScX!E3_{1mfvs-W5ps&65 zYMC3khAF>L+9PCQMG&q5dQK|>Zmd0|e^>daYLH!4pVeSDfzzT$)U2prD(#k0CGHUv zhQ({No+QKpOm!oBBBp`eK!B}v!PHABt4R%u)s!uEND5c-Eb~&mZi~)QOm>NA7hFzH zdGl>ftkjbIpbvPx^2%#vmxRxK{-dw1E>ODkGv)0XUQ$mG;id0x3b!06am zA9Pw)vJmFy<}E+l*}`lWie|e|r1f01%oG0&QhP52*s0Se^R-y>IyKx~_zZj9zWld& z%a)XPiX9yvbLOj3Ydm^15C*b#5d{gk6{Vl%Yrg`BBg3r94lW@iUrCTkBD7Lg zKsV!wRhtRVp_=-#98MM-Pz?qL16N1{nk!?lmBCYLG4v8aPew+2_P%uCy?5W+x$3+X zf3*)DFBaK82am!3!t3)R6Ql1g%q@JXA580VVF_y5qj&K^ZyAQY$s5;EG9IBQePKZ2cAehQA{fEs;VSzQa%jo)2cUcM}6rq1XqJ)7ON zW4Au_^wav}Q$J-R{U>(s*{!80OoMn*33G|#J6+I@Emr(;}k}U_3_kd}o;W=u7c!zp2?uy%_hpCvi7ly~aJuG{}2Rvu=oWEal@C zGkMJCVV~0%dru)R8P1i$`Z+RXhYlWm;n?xx|5z4}bMp9K0$5p?T{zTFuF0NcJT<`T zbd1`FYR=8h=e5vw`Q?|%?%jKW<_rcSsqDxZj+xb95{7g5%Kh=mE3evRmtWB{;@c%x zpnvntH#KkAcgD*k3ch97v%~``(y+Yh#nqU+k_c*r6^6N^G;1{+2Cm9|n$$O4R7!@N zuW+=@OLf%K;HFA~s7TCsarkrbk9h@tM*;n2${POwCX*;{7WEETilzqYVGz(X9Acb@5|vyHL)IqvsWeDuTmb3gIMr_F#R7f>y_j!xN9UvO0>Yj zy-R^!(((~ZDTe8#-QP1LiGo#d7h^_i#eBimFxBUiq4-I-rR9>TimPY`xfGXG2pw7Q zZQnp!V`UvrTbi1J^ZK-PwS#wxx>gk`p(jet7_paLd{Oh_gC{@p8T;j5{*!ro65YLP zm(BH(K;8<7EV6dHRy;4)F;CuiBoE-N`b*dmZT>4KI)B~ynggNpJu80h`RB8Dq~oJw zu5>bEAh;`yP6!%AGx!54mHn3nGUOP_5?v6Lnxj|mgnQ>G_pWUsUS&t!WSz!%G7K*_ zYkbr=k{4vKM(;@;6DS!SrrcTwmq*jNf-7(IxP19?d;k5d*`xbA{T$gOi^n;6{96IG zXEF;b$Hq2I&(D9pe~>E^i?=dcve+i0Y_w@3f$v*VZ!@BT`5d9r$xY7 zVT7o@Qs-1S&LFu(U=w_-azfM>tp`|P5D}c(sjm~%GBr#ZV6PL0h=AE>5c}$nKn=Fh zQNv8?wlyN`9x|ZjMf?>tSTtyt*7YP6>P?1R@2r{b+rMAF|J-xBdGi*1@PP;9KmR}f zS-bhho8-X3{d)T3=`JroXboIF0(hyJoDHb*!`~4b@3q`t`o&+;d++;%Jp1f-b<^8# zmwl%)uxLWz2=u;)Mv@>+Rh$rhlQqEFpl11CLQz3>i8K}vELX9Tpm-Xk-+c__ZPt5V zsB1(ai!-G5?wa^Tj1UDotwnW2nkHyCVt9Gr%_w_tjf~2Y@g=tJz=4_m@4qoUJ$*nH zk8|=E{I7jrW?|v@$jHdig@uLB<%jF;tkp?sWwXmt@b`&NKOyhDv!$#V&!cv9bgXPi z8UlfT!N~aBMFpO9mU8s?*=N7q>$(ri^*7v5sl zMS1@F-;)(9R_V|G{1@f(Kl}Ndld1>y@3$FWfDn8fJ%m%lMJwRqZh@AzcI{ey_@RgN z&-|G`qg&tKD*x9PvqBZf0)6JXcXDql&Ap)|m40-$(d6J?vB!#qH zp0ThNt|2z5N`r`UPmzwu0~o660UAU-lTxwA!8*b!2ooNR7tIbVO*|bG!BSyHVuh$x zxlvf`rY>a#WAB+%F24Tu+i%J9&;OtliMgo{PX62%z964^^pQRob+e5x9oNY-lLZOq z7Zy}v4M%`U&%{P#bZo?yFQ1T`ZoW~z_=PX(Pd)L3oSHl%|LmXtGkJ64M(HEvJ#!tQ zmk|#LJriaOrURBHcp$dg@>?_I?q9{Z;0-yxYKpO*g2lat!aMfzBr9NPl=G9?Iqx_Lm;YJ37Qe?Xi6zZYFhhIN&;>6#P#p9ek z^xyS^H{X2o*yhcf-|5-xWmpGH zg)ANT$cw0we_xUR7q8iQtIkXR<$v{Gc6Z%zmwfqmz9RqNAN>8)v!nUm9Zj)wJa8gU z);y4*>2a4+k%)m=&6`rpFtbQHtsw{tR^7Ut$Tu^vVT(B)(}|}sK(NCX=f8-=ssb5S zguAZgT2|G%hJ(9PDls)PSt@HN3HH`9pXeFY;RlVokS6xj^da9!ipo<~s%r<}5|+i4 z6GU{Zq+n%zKGzHG$B5ql-~)30nl*C%`RmH&iziNho61TbtkNHTRA3#v5;1-qxn~l#I)-sewy$xk~FMG;0}5A_qgE?m}R}xI#w5 z(7sy&qvAS&(R^AMR@!FzT`r{$A!Ho|DH1y3b$0bf_ZD{`!)oOZ7xvpfEEho8NgyPM$oKy`Ai(PS2i zf@l|Y%0V;Z27Gq%26)z{Ez<8KeDoXvOjVX`e;9aW@l$YT*B5TZoIA15tk-4Z&4#F zSDk0S_Lu*vUUu2V@~{5qf2F_mZ+=VWa?*MavS!`To#ZV=)c5CeG60aZII~#8Dw=eD z2UH*x$ZtgD!TtOnDx-!o#HP3~4o%*adR|$cHgWM%$VP(-Id1Z+oTB0mDfkwVxA9JS zI#ON79vepUSOFFIBLw|;;Vj_gm+19o&?FuU9utiq#g*tt+5$(JVsY}$6@3>h%y*?$ zK>xdDLz`Le=*YnGiX>o`wR>tB!txqW<6V^+6+TRvhx^EEiM`U)Kl3bXM6!xi>EMgh zTmhbfT?0xP4Z@oqg78!sKAlQq0lopNv;<))eRSchrSrN{kFm6)ESE4=->l<&p?t3Tu-d;D%uAEUPp3R8lHC+7-Z(vNB_&u%ust_X)rRdR4E?M zXKjOc^9qJa10xznBl;hEDnQ|skP~uG72Uq`dVz+uS+uWOFD7BW;z9UbrIHJ)zKSY# zoE>_4&6tI$itfFjlY+7+Y=ydV}71op$Vwo44rBZqV*MdtP6^e*NFi znLe_3oU_OOW`OOF*@@eyK0stNdU2k<(SAg(`t043;{N`tAiArim`3!who{Hk2-R*|o=W;ggTFcoy5nKh!cyU;h4;vt?&18ttMd0@)HZ``x(@@|iKALD-0r;UUVJS0>G6rG) z@sW|df^E!BpFU+rjvoESfddDAOBRoF`uO(&Sec!jJ+p4zx^K=*P5)dErz_HkLjx>* zacA<1lLPw?$*L90<-YswlTDl6D#I_YJ72PNne=QX&xr&a^4&p_?*dx*Z1VDmJ>w~W zl1t+~_xy8m;e{8fHuFS_0F|P%rbzNgVG6!KsP+qR=oqV@mvF1V_KH|87#bJnpm9*hlTv%Czyl7MsI2A+-7@yvnHtE!8SH zM@zKjg8=!=P>T%VH<|$2Ow+eWSOJa!jiv1uf~_a|qYVO?!5>L{rkYh9)>U{P2ujs{ zY>>NV1!z25ioM(sIBKNTVaYF~vP5=}_fE5ehYolBeE5fbJme)=JkIIk-wR;#F*!MT zdijdw-<@Ar_=O%6$MV90%v=ir9Q6N}yz$O;*%f#Kl_3~5 zN0katBgZtrBUyxZ8lqkMAp4o+EmmQTXgOL=pLFSv{CV4NMmXb{xRWmgYSS&RQs1%Lu=0IJ(JfMnV7+HIsaquQ+i zH}ggx-yz|bJUVlTk8GGWJyJ%|n!fR`#hzNq zGhvVR>SQ-7?L|X$cKvY}GyG!Q5itO@UNbq3D}S;)H#noa+JYr(?(!S1qEJ4At1Dnt zu<4MrUP<<15*{&_a^<3Y^bNF{HrA>ETRbAGwgkCyuvZE#K;ZxIBHs6=Tt*wFjkju$ z?iH~)?+X7?Dm)~oXq6RQS%%raf8XSiB}@L&)YQ}oSv=0^<9`>x=A*Zw@9W6esowc~ zVr*<|AiilztS8L_JLjox+qPZqy6cXds*{TZ=LGbu$=ZrlD>JAjfNNeFn;B_Is?IJ^ zj+$o6o!RVIPCD-g?@SM}J#&?AzO!HWg2_7Il}1f5@!#br1*^i3AW<{?f+x0TdPl8K6|A zpvFn0f$7qItTqzg1)AsfJ4^wUL_$%z|31f45LhN-WVi1?59!!%cKDECIh=`$_NsWr#}x; zeQ8A2PWiaX^Yq8(rjI9Z+lmYWF)q!+7!tI&J}zFW2*=)LaBwuY^j!g0m)r9E$W`X@ z&z`|Pcf$=g{GEOK_I0v&oYTkuZh-9%yWzTzy>ax|;jw;fJ798wUUiRbb9g4OI|?sNC3D#Zr8_lf*?n zSj8qxYUmF>nW;-UFD?I25d>>B<#t)UkKnF#Z9^ZNGNo8`!{Bl;(P=}&Z5 zUwxIn`r4~yF#@vS!xa>A2t$e(p`e0AMPq4QXJw%je4e0L8EEBk@hSXU-NkaS=yQvH zIg>~{LCv>8wP=xgP|7(b*tON>K^`FelBPjo4XK3#s*p6WxK_dAN_w4zbP!lBp>0}w z*C4(@z}lO&3ZsU?Kz=F|ALJ4-qA&DdanD#PEj4Zb0Ju`r)qrhAvuNuG$9R~U;$c)v zB^CVqr@~6o{nrLn#aFw9+W~>W^-0IX37PILDka+h+%g4?L>37<)~u>TfhemwCl>D`!$+_%C^Tc2>gbGCfGStAgcUDW#V4sUMX7&EP8F*xk<%=f9-3n{o7%Ubw`S_>?)C0}| zz119fV50obQe%JWF!C01K)BqZc@bBZ%4EDB^V_#=KQkus-_6X=AD6}BoIn0U0<83+ z`^<`w70>sa^oH^Av8ywvB2QLI3f7BQUw!EWhUP`-u-TCe{ zm!MY;a+P3L|J^}e#gcr*}?f@fO zV1!74LWu~D00D`6R>4t~L{zkCCFxlCS+_#4KzLuJ=J!xlRf1cvG-dJWLt`7t-;KL?@p*SjVe=w=D z1o0{2p=S#;+r60k#sR;WA`vk2y=CERR#JxmcQ7Q-Cl8+F6DFxzYUI5}kVJehDEy|> z2dv`Ykeg{kw_4E#OwUXjpr#cNM@5M}aCid-K&6QRa5%9eww4l-rF}>RbHfvYDK=do zxfinYN)I(j3WCl5LWO`!fe5=rgM3+TeY<(kzJwu#Z*BpGO>7H!0p=2pKc@a>5=s~~ zZK#wS7?~P>M=GM0WRX+}skUZAIF8T_HjJxqT#(;fPS%h4vS_E*U+vh5lV3k_~ zz4OkyWO8aU3-~%UJz4TsFIazm5%;rHkb_(qsBq?w&*dW@B8Y!w)*`u?FxQ+>7ha39fY`8YSFG6f$AhiIdh#cxy0JZte{17i9*6 zRGulrsv_96GA&K`VP=#GAOIg^49Tna3xKq+Q(rw*JC>&+uw+*Ow++-*Xf63_CHI*^ ztpmEUzhOD7@h%+nl4( zGm=Kc+3TRhPO|9lnFcN)KP6FOBj?dIq+P1b-x(OE4D7e7?4Ue{-5TS^-fo z8ADXiKp}x@s@4J<;J9W7l^tsf6=sIN-zc)u+KD(MA}ACR4yX|H*}b=E-RlKyeO}VU``Attnr|^eOBJjJvF~QX<8; zK5=QbZ-ICb(o0;xh@~mMBoueq8g6tW^&O6=7>*>uz9UyZ`t|F-GCMPKNAK2OIWjUj!0N2Bs34D{LD?a6Jm>c51NYxw z2-)6!`|@|S*JkyC3)YtkOao8T>IYliwz%ZSmZgK4y%t?I7ZmCLTfO?cLbXnuIH51T z@PbTDPs=k;Kdl>XzS;8b2xlhG0FEeoaaVCG%Wn%OjC!5Uv<$&s5zZCN{>Iza79gtI z>6iu&wGHjJKdO)*O-2*cTEY^(VFXhWI1NA8le5D{V z0M%fq3;QVO?E_Dq z_NB3dL79ak{oi?8klnlX=*>6XqB)^@-`>622hHT*p+j=bRaceD_IcG;mI`u!OLI0s zFB9Z6uz`bZkqUZ{wbiTF6j07Pp>Eu`Q9tX4v zA)clY#}a~?25f4D7j0bMb~UG)fnG}Kx=Q0g2y&A#Vgq2|wiKb4~v@r`qC@=AQ zqG=;S!hBiumk9%7^-SpSW~)okcMl47%+wtYya_Rws;`JPSr%?W6Z$-{3}tAG=87D={1Cwg=A}%VL63AUoy!*i=?;si$xqJ#s`gY}lYVC1uyH z-C1+$gJFl{qKhulm8({jiIu$YZ~@c)d>Fl5(PvnE^g|D6z*_w5sYGWp~n&59+JCB-Ti&%Md6i(`K@YaEI@Lui52q zwn&j+qeU~8c+1aC#AAxYgnfQsCHFKW%!S1 ztSxm{@Li#$^1H`1XqA%Dcop(i$_5J4+k_Pj9X&f-&Zu5{+Y?U^*G^S^R^KJtBvvy+ z6_y$c3=S$%Grb)D;87&4$rTdmzZTJ~3htDkovM0%gOK)0q@;v^fcNMx6&{@iWqE9# z6T5crk)_L*{5Nwmi~8$F>G;q9HXnJ#*TKVwes9%z=j~a#WZ9EhyjQqFC4Fnq^Ra=i zxjuF3v@Bn?TyMPb2K!*^2We(z+P3f5sp~ITZx>yBQI1M^uq$h?IhAFkRP)L?vSqz? z&cV&-w|vENyYPYwHEXf^_wBPUf91=1`DK^%lEKf~nqIHnv}qH_T0Xk))yaya?moi# z9J3@(cTeTPUWS~FLAJ`Yho*p<`~tt1Vk@a){OSi6k15D!naXva*`b&_+QjkvTq8fW=`44<3AN-I_J~mo1xkcrY@$BoEa=S%lzgt}~MKnycgm1k08#ElX?j z&Iog}v$nH$m2#HB9k<`6^WD6Tlt9-=+0q!rVJww;1|zI(AbA&ri!Zq(ZzPpLUcdLf z@7u!sygdEPXZ5OUuCdK;y)C&EVlD_S5zqD+!@|(M2Va9BF}I0r8rVWVk?XJko?wI0 z0#iil#b1^L+S#mzmsrmwq;wu(!N!LrH_RH5BjY_{LW;uI8d+k_yGc3mmXb~h^Gu~w zpi(SiLz@E!w29bhvqlyUx`F;`>I5K<4S1aJjP@=zRtiynR5Tw}KVSN5o$$^hjS-!_NE!G>@P`YcAQ!K*D za}u$wzUd=Ac5`{c?$DuwIyp7H{h6P6=Ks-qbS8_(N9Oo(0Bkw-?ce|EvWbZu%a$#B zVk}3eGRTg2{Z}s!>&0Diplg11PCotVCv@kootm=)Je})|TzmD^n7lb)mh)>pohxg) zSt8J~k5R6rIZ~F^UUcC_l4XNq$ByZ1uf49jckZ-b{*_?4>ZTcNq zJU&v#j}2h+(KFe%F1zfq-|DB&FD%VeRW$Njlh?u2k-=yga7T|G)qC¯W#A2iec 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 literal 0 HcmV?d00001 diff --git a/Bitkit/Components/Trezor/HwDeviceIllustrations.swift b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift index d192f6db1..f4ada6b9d 100644 --- a/Bitkit/Components/Trezor/HwDeviceIllustrations.swift +++ b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift @@ -3,34 +3,36 @@ import SwiftUI /// Staggered hardware-device hero used by the hardware intro sheet: a Trezor bleeding off the /// left and a blurred Ledger bleeding off the right. Ports bitkit-android's `HwDeviceIllustrations`. struct HwDeviceIllustrations: View { + /// Ratios of the 375pt-wide Figma frame. Each device is positioned by its exact top-leading + /// x and rendered at its natural (non-square) aspect ratio so it bleeds off the correct edge. private enum Ratio { - static let imageSize: CGFloat = 256.0 / 375.0 - static let trezorBleed: CGFloat = 84.0 / 375.0 - static let ledgerBleed: CGFloat = 53.0 / 375.0 - static let stagger: CGFloat = 12.0 / 375.0 + static let imageHeight: CGFloat = 256.0 / 375.0 + static let trezorWidth: CGFloat = 172.0 / 375.0 + static let ledgerWidth: CGFloat = 203.0 / 375.0 + static let ledgerX: CGFloat = 172.0 / 375.0 + static let stagger: CGFloat = 11.6 / 375.0 } var body: some View { GeometryReader { geo in let width = geo.size.width - let imageSize = width * Ratio.imageSize + let imageHeight = width * Ratio.imageHeight let staggerY = width * Ratio.stagger ZStack { Image("trezor") .resizable() .scaledToFit() - .frame(width: imageSize, height: imageSize) + .frame(width: width * Ratio.trezorWidth, height: imageHeight) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) - .offset(x: -width * Ratio.trezorBleed, y: staggerY) + .offset(y: staggerY) Image("ledger") .resizable() .scaledToFit() - .frame(width: imageSize, height: imageSize) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing) - .offset(x: width * Ratio.ledgerBleed, y: -staggerY) - .blur(radius: 16) + .frame(width: width * Ratio.ledgerWidth, height: imageHeight) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) + .offset(x: width * Ratio.ledgerX, y: -staggerY) } } .accessibilityHidden(true) From 95406769d9d37c673b6b1a10f3685cbbea5bdade Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 23 Jun 2026 08:22:05 -0300 Subject: [PATCH 11/52] refactor: extract magic numbers and use better constant naming --- .../Trezor/HwDeviceIllustrations.swift | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Bitkit/Components/Trezor/HwDeviceIllustrations.swift b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift index f4ada6b9d..513fc381d 100644 --- a/Bitkit/Components/Trezor/HwDeviceIllustrations.swift +++ b/Bitkit/Components/Trezor/HwDeviceIllustrations.swift @@ -1,38 +1,42 @@ import SwiftUI -/// Staggered hardware-device hero used by the hardware intro sheet: a Trezor bleeding off the -/// left and a blurred Ledger bleeding off the right. Ports bitkit-android's `HwDeviceIllustrations`. +/// Staggered hardware-device hero used by the hardware intro sheet: a Trezor on the left and a +/// blurred Ledger bleeding off the right. Ports bitkit-android's `HwDeviceIllustrations`. struct HwDeviceIllustrations: View { - /// Ratios of the 375pt-wide Figma frame. Each device is positioned by its exact top-leading - /// x and rendered at its natural (non-square) aspect ratio so it bleeds off the correct edge. - private enum Ratio { - static let imageHeight: CGFloat = 256.0 / 375.0 - static let trezorWidth: CGFloat = 172.0 / 375.0 - static let ledgerWidth: CGFloat = 203.0 / 375.0 - static let ledgerX: CGFloat = 172.0 / 375.0 - static let stagger: CGFloat = 11.6 / 375.0 + /// All measurements are expressed as fractions of the Figma design frame's width, so the hero + /// scales proportionally to whatever width it's given. Each device is rendered at its natural + /// (non-square) aspect ratio; the Trezor's left bleed is baked into the exported asset, while + /// the Ledger is offset to bleed off the right edge. + private enum Layout { + static let referenceWidth: CGFloat = 375 + + static let proportionalHeight: CGFloat = 256 / referenceWidth + static let trezorProportionalWidth: CGFloat = 172 / referenceWidth + static let ledgerProportionalWidth: CGFloat = 203 / referenceWidth + static let ledgerProportionalX: CGFloat = 172 / referenceWidth + static let proportionalStagger: CGFloat = 11.6 / referenceWidth } var body: some View { GeometryReader { geo in let width = geo.size.width - let imageHeight = width * Ratio.imageHeight - let staggerY = width * Ratio.stagger + let imageHeight = width * Layout.proportionalHeight + let staggerY = width * Layout.proportionalStagger ZStack { Image("trezor") .resizable() .scaledToFit() - .frame(width: width * Ratio.trezorWidth, height: imageHeight) + .frame(width: width * Layout.trezorProportionalWidth, height: imageHeight) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) .offset(y: staggerY) Image("ledger") .resizable() .scaledToFit() - .frame(width: width * Ratio.ledgerWidth, height: imageHeight) + .frame(width: width * Layout.ledgerProportionalWidth, height: imageHeight) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) - .offset(x: width * Ratio.ledgerX, y: -staggerY) + .offset(x: width * Layout.ledgerProportionalX, y: -staggerY) } } .accessibilityHidden(true) From 097b08c0f814f21540acc6782d59621865abc988 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 23 Jun 2026 10:52:12 -0300 Subject: [PATCH 12/52] refactor: extract HW onChain methods to a vendor agnostic protocol --- Bitkit/Managers/HwWalletManager.swift | 8 +- Bitkit/Managers/TrezorManager.swift | 2 +- Bitkit/Services/OnChainHwService.swift | 201 ++++++++++++++++++ Bitkit/Services/Trezor/TrezorService.swift | 187 ---------------- Bitkit/Utilities/AppReset.swift | 2 +- .../ViewModels/Trezor/TrezorViewModel.swift | 35 +-- BitkitTests/HwWalletManagerTests.swift | 4 +- BitkitTests/TrezorViewModelWatcherTests.swift | 2 +- 8 files changed, 228 insertions(+), 213 deletions(-) create mode 100644 Bitkit/Services/OnChainHwService.swift diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index ef240df1c..f531bd281 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -39,7 +39,7 @@ final class HwWalletManager { // MARK: - Dependencies - private let watcherService: TrezorWatcherServicing + private let watcherService: OnChainWatcherServicing private let monitoredTypesProvider: () -> Set private let electrumUrlProvider: () -> String private let networkProvider: () -> TrezorCoinType @@ -58,7 +58,7 @@ final class HwWalletManager { private var listeners: [String: TrezorEventListener] = [:] init( - watcherService: TrezorWatcherServicing = TrezorService.shared, + watcherService: OnChainWatcherServicing = OnChainHwService.shared, monitoredTypes: (() -> Set)? = nil, electrumUrl: (() -> String)? = nil, network: (() -> TrezorCoinType)? = nil, @@ -66,11 +66,11 @@ final class HwWalletManager { deleteActivities: ((String) -> Void)? = nil ) { self.watcherService = watcherService - networkProvider = network ?? { TrezorService.appDefaultCoinType } + networkProvider = network ?? { OnChainHwService.appDefaultCoinType } monitoredTypesProvider = monitoredTypes ?? { Set(SettingsViewModel.shared.addressTypesToMonitor.map(\.stringValue)) } - electrumUrlProvider = electrumUrl ?? { TrezorService.getElectrumUrl() } + electrumUrlProvider = electrumUrl ?? { OnChainHwService.getElectrumUrl() } self.persistActivities = persistActivities ?? { activities in guard !activities.isEmpty else { return } Task { diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index 0543ff2b4..82ba06755 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -123,7 +123,7 @@ final class TrezorManager { // MARK: - Initialization init() { - selectedNetwork = TrezorService.appDefaultCoinType + selectedNetwork = OnChainHwService.appDefaultCoinType // Callback subscriptions are deferred to setup() to avoid // triggering BLE stack and Combine overhead at app launch. } diff --git a/Bitkit/Services/OnChainHwService.swift b/Bitkit/Services/OnChainHwService.swift new file mode 100644 index 000000000..111fc934f --- /dev/null +++ b/Bitkit/Services/OnChainHwService.swift @@ -0,0 +1,201 @@ +import BitkitCore +import Foundation + +/// Watcher-related service calls, extracted as a protocol so unit tests can +/// substitute a mock. +protocol OnChainWatcherServicing { + func startWatcher(params: WatcherParams, listener: EventListener) async throws + func stopWatcher(watcherId: String) throws + func stopAllWatchers() +} + +extension OnChainHwService: OnChainWatcherServicing {} + +/// Vendor-neutral on-chain service layer. Wraps the device-less `onchain*` BitkitCore FFI +/// functions — account/address info, transaction history/detail, transaction composition and +/// broadcasting, and the Electrum event watcher. None of these require a connected hardware +/// device; they query Electrum directly. Shared by all consumers (`HwWalletManager`, +/// `TrezorViewModel`, …) so the watch-only layer depends on this rather than `TrezorService`. +/// All operations run on ServiceQueue.background(.core) to ensure thread safety. +class OnChainHwService { + static let shared = OnChainHwService() + + private init() {} + + // MARK: - Account/Address Info (No Device Required) + + /// Get account info (balance, UTXOs) for an extended public key (xpub/ypub/zpub/tpub/upub/vpub). + /// This does NOT require a connected Trezor device — it queries the Electrum server directly. + func getAccountInfo( + extendedKey: String, + electrumUrl: String, + network: TrezorCoinType? = nil, + gapLimit: UInt32? = nil, + scriptType: AccountType? = nil + ) async throws -> AccountInfoResult { + let networkParam = toNetwork(network) + return try await ServiceQueue.background(.core) { + try await onchainGetAccountInfo( + extendedKey: extendedKey, + electrumUrl: electrumUrl, + network: networkParam, + gapLimit: gapLimit, + scriptType: scriptType + ) + } + } + + /// Get address info (balance, UTXOs) for a single Bitcoin address. + /// This does NOT require a connected Trezor device — it queries the Electrum server directly. + func getAddressInfo( + address: String, + electrumUrl: String, + network: TrezorCoinType? = nil + ) async throws -> SingleAddressInfoResult { + let networkParam = toNetwork(network) + return try await ServiceQueue.background(.core) { + try await onchainGetAddressInfo( + address: address, + electrumUrl: electrumUrl, + network: networkParam + ) + } + } + + // MARK: - Transaction History & Detail (No Device Required) + + /// Get transaction history for an extended public key (xpub/ypub/zpub/tpub/upub/vpub). + /// This does NOT require a connected Trezor device — it queries the Electrum server directly. + func getTransactionHistory( + extendedKey: String, + electrumUrl: String, + network: TrezorCoinType? = nil, + scriptType: AccountType? = nil + ) async throws -> TransactionHistoryResult { + let networkParam = toNetwork(network) + return try await ServiceQueue.background(.core) { + try await onchainGetTransactionHistory( + extendedKey: extendedKey, + electrumUrl: electrumUrl, + network: networkParam, + scriptType: scriptType + ) + } + } + + /// Get detailed information for a specific transaction by its ID. + /// This does NOT require a connected Trezor device — it queries the Electrum server directly. + func getTransactionDetail( + extendedKey: String, + electrumUrl: String, + txid: String, + network: TrezorCoinType? = nil, + scriptType: AccountType? = nil + ) async throws -> TransactionDetail { + let networkParam = toNetwork(network) + return try await ServiceQueue.background(.core) { + try await onchainGetTransactionDetail( + extendedKey: extendedKey, + electrumUrl: electrumUrl, + txid: txid, + network: networkParam, + scriptType: scriptType + ) + } + } + + // MARK: - Transaction Composition & Broadcasting + + /// Compose a transaction using BDK-based PSBT generation (signer-agnostic). + /// Does NOT require a connected Trezor device. + func composeTransaction(params: ComposeParams) async throws -> [ComposeResult] { + try await ServiceQueue.background(.core) { + await onchainComposeTransaction(params: params) + } + } + + /// Broadcast a signed raw transaction via Electrum. + /// - Returns: The transaction ID (txid) + func broadcastRawTx(serializedTx: String, electrumUrl: String) async throws -> String { + try await ServiceQueue.background(.core) { + try await onchainBroadcastRawTx(serializedTx: serializedTx, electrumUrl: electrumUrl) + } + } + + // MARK: - Event Watcher (No Device Required) + + /// Start watching an extended public key for on-chain transaction activity. + /// Events are delivered to `listener` until the watcher is stopped. + /// Does NOT require a connected Trezor device — it subscribes to Electrum directly. + func startWatcher(params: WatcherParams, listener: EventListener) async throws { + try await ServiceQueue.background(.core) { + try await onchainStartWatcher(params: params, listener: listener) + } + } + + /// Stop a specific watcher by its id. + func stopWatcher(watcherId: String) throws { + try onchainStopWatcher(watcherId: watcherId) + } + + /// Stop all active watchers. + func stopAllWatchers() { + onchainStopAllWatchers() + } + + // MARK: - Helpers + + /// Convert TrezorCoinType to the Network enum used by onchain FFI functions + private func toNetwork(_ coin: TrezorCoinType?) -> Network? { + guard let coin else { return nil } + switch coin { + case .bitcoin: return .bitcoin + case .testnet: return .testnet + case .signet: return .signet + case .regtest: return .regtest + } + } +} + +// MARK: - Network / Electrum helpers + +/// Network- and Electrum-derivation helpers shared by all on-chain consumers (`TrezorManager`, +/// `TrezorViewModel`, `HwWalletManager`). They live on the service layer so feature managers +/// don't reference each other for plain network/electrum configuration. +extension OnChainHwService { + /// The app's global network mapped to a `TrezorCoinType`. + static var appDefaultCoinType: TrezorCoinType { + switch Env.network { + case .bitcoin: .bitcoin + case .testnet: .testnet + case .signet: .signet + case .regtest: .regtest + } + } + + /// BIP44 coin-type component for the app's global network: "0'" mainnet, "1'" test networks. + static var defaultCoinTypeComponent: String { + Env.network == .bitcoin ? "0'" : "1'" + } + + /// Hardcoded Electrum server URL per network (with the regtest dev override). + static func electrumUrlForNetwork(_ network: TrezorCoinType) -> String { + if network == .regtest, let trezorElectrumUrl = Env.trezorElectrumUrl { + return trezorElectrumUrl + } + switch network { + case .bitcoin: + return "ssl://bitkit.to:9999" + case .testnet, .signet: + return "ssl://electrum.blockstream.info:60002" + case .regtest: + return "ssl://electrs.bitkit.stag0.blocktank.to:9999" + } + } + + /// The app's configured Electrum server (falls back to the default). + static func getElectrumUrl() -> String { + let server = ElectrumConfigService().getCurrentServer() + return server.fullUrl.isEmpty ? Env.electrumServerUrl : server.fullUrl + } +} diff --git a/Bitkit/Services/Trezor/TrezorService.swift b/Bitkit/Services/Trezor/TrezorService.swift index ba45668b9..1736fb0be 100644 --- a/Bitkit/Services/Trezor/TrezorService.swift +++ b/Bitkit/Services/Trezor/TrezorService.swift @@ -1,16 +1,6 @@ import BitkitCore import Foundation -/// Watcher-related service calls, extracted as a protocol so unit tests can -/// substitute a mock (mirrors bitkit-android's mocked TrezorRepo in TrezorViewModelTest). -protocol TrezorWatcherServicing { - func startWatcher(params: WatcherParams, listener: EventListener) async throws - func stopWatcher(watcherId: String) throws - func stopAllWatchers() -} - -extension TrezorService: TrezorWatcherServicing {} - /// Service layer wrapper for Trezor FFI functions /// All operations run on ServiceQueue.background(.core) to ensure thread safety class TrezorService { @@ -182,140 +172,6 @@ class TrezorService { } } - // MARK: - Account/Address Info (No Device Required) - - /// Get account info (balance, UTXOs) for an extended public key (xpub/ypub/zpub/tpub/upub/vpub). - /// This does NOT require a connected Trezor device — it queries the Electrum server directly. - func getAccountInfo( - extendedKey: String, - electrumUrl: String, - network: TrezorCoinType? = nil, - gapLimit: UInt32? = nil, - scriptType: AccountType? = nil - ) async throws -> AccountInfoResult { - let networkParam = toNetwork(network) - return try await ServiceQueue.background(.core) { - try await onchainGetAccountInfo( - extendedKey: extendedKey, - electrumUrl: electrumUrl, - network: networkParam, - gapLimit: gapLimit, - scriptType: scriptType - ) - } - } - - /// Get address info (balance, UTXOs) for a single Bitcoin address. - /// This does NOT require a connected Trezor device — it queries the Electrum server directly. - func getAddressInfo( - address: String, - electrumUrl: String, - network: TrezorCoinType? = nil - ) async throws -> SingleAddressInfoResult { - let networkParam = toNetwork(network) - return try await ServiceQueue.background(.core) { - try await onchainGetAddressInfo( - address: address, - electrumUrl: electrumUrl, - network: networkParam - ) - } - } - - // MARK: - Transaction History & Detail (No Device Required) - - /// Get transaction history for an extended public key (xpub/ypub/zpub/tpub/upub/vpub). - /// This does NOT require a connected Trezor device — it queries the Electrum server directly. - func getTransactionHistory( - extendedKey: String, - electrumUrl: String, - network: TrezorCoinType? = nil, - scriptType: AccountType? = nil - ) async throws -> TransactionHistoryResult { - let networkParam = toNetwork(network) - return try await ServiceQueue.background(.core) { - try await onchainGetTransactionHistory( - extendedKey: extendedKey, - electrumUrl: electrumUrl, - network: networkParam, - scriptType: scriptType - ) - } - } - - /// Get detailed information for a specific transaction by its ID. - /// This does NOT require a connected Trezor device — it queries the Electrum server directly. - func getTransactionDetail( - extendedKey: String, - electrumUrl: String, - txid: String, - network: TrezorCoinType? = nil, - scriptType: AccountType? = nil - ) async throws -> TransactionDetail { - let networkParam = toNetwork(network) - return try await ServiceQueue.background(.core) { - try await onchainGetTransactionDetail( - extendedKey: extendedKey, - electrumUrl: electrumUrl, - txid: txid, - network: networkParam, - scriptType: scriptType - ) - } - } - - // MARK: - Transaction Composition & Broadcasting - - /// Compose a transaction using BDK-based PSBT generation (signer-agnostic). - /// Does NOT require a connected Trezor device. - func composeTransaction(params: ComposeParams) async throws -> [ComposeResult] { - try await ServiceQueue.background(.core) { - await onchainComposeTransaction(params: params) - } - } - - /// Broadcast a signed raw transaction via Electrum. - /// - Returns: The transaction ID (txid) - func broadcastRawTx(serializedTx: String, electrumUrl: String) async throws -> String { - try await ServiceQueue.background(.core) { - try await onchainBroadcastRawTx(serializedTx: serializedTx, electrumUrl: electrumUrl) - } - } - - // MARK: - Event Watcher (No Device Required) - - /// Start watching an extended public key for on-chain transaction activity. - /// Events are delivered to `listener` until the watcher is stopped. - /// Does NOT require a connected Trezor device — it subscribes to Electrum directly. - func startWatcher(params: WatcherParams, listener: EventListener) async throws { - try await ServiceQueue.background(.core) { - try await onchainStartWatcher(params: params, listener: listener) - } - } - - /// Stop a specific watcher by its id. - func stopWatcher(watcherId: String) throws { - try onchainStopWatcher(watcherId: watcherId) - } - - /// Stop all active watchers. - func stopAllWatchers() { - onchainStopAllWatchers() - } - - // MARK: - Helpers - - /// Convert TrezorCoinType to the Network enum used by onchain FFI functions - private func toNetwork(_ coin: TrezorCoinType?) -> Network? { - guard let coin else { return nil } - switch coin { - case .bitcoin: return .bitcoin - case .testnet: return .testnet - case .signet: return .signet - case .regtest: return .regtest - } - } - // MARK: - Credential Management /// Clear stored Bluetooth pairing credentials for a specific device @@ -327,46 +183,3 @@ class TrezorService { Logger.info("Cleared credentials for device: \(deviceId)", context: "TrezorService") } } - -// MARK: - Network / Electrum helpers - -/// Network- and Electrum-derivation helpers shared by all Trezor consumers (`TrezorManager`, -/// `TrezorViewModel`, `HwWalletManager`). They live on the service layer so feature managers -/// don't reference each other for plain network/electrum configuration. -extension TrezorService { - /// The app's global network mapped to a `TrezorCoinType`. - static var appDefaultCoinType: TrezorCoinType { - switch Env.network { - case .bitcoin: .bitcoin - case .testnet: .testnet - case .signet: .signet - case .regtest: .regtest - } - } - - /// BIP44 coin-type component for the app's global network: "0'" mainnet, "1'" test networks. - static var defaultCoinTypeComponent: String { - Env.network == .bitcoin ? "0'" : "1'" - } - - /// Hardcoded Electrum server URL per network (with the regtest dev override). - static func electrumUrlForNetwork(_ network: TrezorCoinType) -> String { - if network == .regtest, let trezorElectrumUrl = Env.trezorElectrumUrl { - return trezorElectrumUrl - } - switch network { - case .bitcoin: - return "ssl://bitkit.to:9999" - case .testnet, .signet: - return "ssl://electrum.blockstream.info:60002" - case .regtest: - return "ssl://electrs.bitkit.stag0.blocktank.to:9999" - } - } - - /// The app's configured Electrum server (falls back to the default). - static func getElectrumUrl() -> String { - let server = ElectrumConfigService().getCurrentServer() - return server.fullUrl.isEmpty ? Env.electrumServerUrl : server.fullUrl - } -} diff --git a/Bitkit/Utilities/AppReset.swift b/Bitkit/Utilities/AppReset.swift index 25f8faa97..967877389 100644 --- a/Bitkit/Utilities/AppReset.swift +++ b/Bitkit/Utilities/AppReset.swift @@ -26,7 +26,7 @@ enum AppReset { // Stop any running watch-only hardware-wallet watchers. Their persisted xpubs/known // devices and activities are cleared below by the UserDefaults/keychain/core-DB wipes; // the app-lifetime HwWalletManager is rebuilt by session.bump() at the end of this wipe. - TrezorService.shared.stopAllWatchers() + OnChainHwService.shared.stopAllWatchers() // Stop node and wipe LDK persistence via the wallet API. try await wallet.wipe() diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index 98368d8d5..c7ce821d6 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -81,7 +81,7 @@ class TrezorViewModel { // MARK: - Address Generation State /// Current derivation path - var derivationPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'/0/0" + var derivationPath: String = "m/84'/\(OnChainHwService.defaultCoinTypeComponent)/0'/0/0" /// Current script type for address generation var selectedScriptType: TrezorScriptType = .spendWitness @@ -98,7 +98,7 @@ class TrezorViewModel { var messageToSign: String = "Hello, Trezor!" /// Path for message signing - var messageSigningPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'/0/0" + var messageSigningPath: String = "m/84'/\(OnChainHwService.defaultCoinTypeComponent)/0'/0/0" /// Signed message result var signedMessage: TrezorSignedMessageResponse? @@ -111,7 +111,7 @@ class TrezorViewModel { // MARK: - Public Key State /// Account-level derivation path for public key - var publicKeyPath: String = "m/84'/\(TrezorService.defaultCoinTypeComponent)/0'" + var publicKeyPath: String = "m/84'/\(OnChainHwService.defaultCoinTypeComponent)/0'" /// Retrieved xpub string var xpub: String? @@ -275,11 +275,12 @@ class TrezorViewModel { // MARK: - Private Properties private let trezorService = TrezorService.shared - private let watcherService: TrezorWatcherServicing + private let onChainService = OnChainHwService.shared + private let watcherService: OnChainWatcherServicing // MARK: - Initialization - init(connection: TrezorManager, watcherService: TrezorWatcherServicing = TrezorService.shared) { + init(connection: TrezorManager, watcherService: OnChainWatcherServicing = OnChainHwService.shared) { self.connection = connection self.watcherService = watcherService } @@ -611,19 +612,19 @@ class TrezorViewModel { addressResult = nil resetSendFlow() - let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) do { switch Self.detectInputType(trimmedInput) { case .extendedKey: - accountResult = try await trezorService.getAccountInfo( + accountResult = try await onChainService.getAccountInfo( extendedKey: trimmedInput, electrumUrl: electrumUrl, network: connection.selectedNetwork, scriptType: onchainAccountTypeSelection.accountType ) case .address: - addressResult = try await trezorService.getAddressInfo( + addressResult = try await onChainService.getAddressInfo( address: trimmedInput, electrumUrl: electrumUrl, network: connection.selectedNetwork @@ -683,10 +684,10 @@ class TrezorViewModel { txHistoryError = nil txHistoryResult = nil - let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) do { - txHistoryResult = try await trezorService.getTransactionHistory( + txHistoryResult = try await onChainService.getTransactionHistory( extendedKey: trimmedKey, electrumUrl: electrumUrl, network: connection.selectedNetwork, @@ -711,10 +712,10 @@ class TrezorViewModel { txDetailError = nil txDetailResult = nil - let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) do { - txDetailResult = try await trezorService.getTransactionDetail( + txDetailResult = try await onChainService.getTransactionDetail( extendedKey: trimmedKey, electrumUrl: electrumUrl, txid: trimmedTxid, @@ -788,7 +789,7 @@ class TrezorViewModel { ? .sendMax(address: address) : .payment(address: address, amountSats: UInt64(sendAmountSats) ?? 0) - let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) let network = toNetwork(connection.selectedNetwork) let wallet = WalletParams( @@ -807,7 +808,7 @@ class TrezorViewModel { ) do { - let results = try await trezorService.composeTransaction(params: params) + let results = try await onChainService.composeTransaction(params: params) handleComposeResults(results) } catch { trezorLog("composeTx FAILED: \(error)", level: "error") @@ -904,10 +905,10 @@ class TrezorViewModel { isBroadcasting = true sendError = nil - let electrumUrl = TrezorService.electrumUrlForNetwork(connection.selectedNetwork) + let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) do { - let txid = try await trezorService.broadcastRawTx(serializedTx: rawTx, electrumUrl: electrumUrl) + let txid = try await onChainService.broadcastRawTx(serializedTx: rawTx, electrumUrl: electrumUrl) trezorLog("BROADCAST SUCCESS txid=\(txid)") broadcastTxid = txid } catch { @@ -1063,7 +1064,7 @@ class TrezorViewModel { let params = WatcherParams( watcherId: watcherId, extendedKey: key, - electrumUrl: TrezorService.electrumUrlForNetwork(network), + electrumUrl: OnChainHwService.electrumUrlForNetwork(network), network: toNetwork(network), accountType: accountType, gapLimit: gapLimit diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 10751e1ec..3c661a64a 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -10,7 +10,7 @@ import XCTest final class HwWalletManagerTests: XCTestCase { // MARK: - Mocks & spies - private final class MockWatcherService: TrezorWatcherServicing, @unchecked Sendable { + private final class MockWatcherService: OnChainWatcherServicing, @unchecked Sendable { private(set) var startedParams: [WatcherParams] = [] private(set) var stoppedWatcherIds: [String] = [] var stopShouldFail = false @@ -45,7 +45,7 @@ final class HwWalletManagerTests: XCTestCase { // MARK: - Factories private func makeViewModel( - watcherService: TrezorWatcherServicing = MockWatcherService(), + watcherService: OnChainWatcherServicing = MockWatcherService(), monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"] ) -> HwWalletManager { let vm = HwWalletManager( diff --git a/BitkitTests/TrezorViewModelWatcherTests.swift b/BitkitTests/TrezorViewModelWatcherTests.swift index 8582ed83d..7b23d35f0 100644 --- a/BitkitTests/TrezorViewModelWatcherTests.swift +++ b/BitkitTests/TrezorViewModelWatcherTests.swift @@ -9,7 +9,7 @@ final class TrezorViewModelWatcherTests: XCTestCase { /// Mock watcher service, standing in for Android's mocked `TrezorRepo`. /// `holdStart` mirrors the `CompletableDeferred`-backed mock used to keep /// the native start call in flight until the test resolves it. - private final class MockWatcherService: TrezorWatcherServicing, @unchecked Sendable { + private final class MockWatcherService: OnChainWatcherServicing, @unchecked Sendable { private let lock = NSLock() private(set) var startedParams: [WatcherParams] = [] From 7c8fb7922d7c87ae2d5901da36466defa0c4a093 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 23 Jun 2026 14:00:18 -0300 Subject: [PATCH 13/52] refactor: make chunck code more readable --- Bitkit/Components/HardwareWalletsGrid.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Bitkit/Components/HardwareWalletsGrid.swift b/Bitkit/Components/HardwareWalletsGrid.swift index b0da4cdb6..04b2eab52 100644 --- a/Bitkit/Components/HardwareWalletsGrid.swift +++ b/Bitkit/Components/HardwareWalletsGrid.swift @@ -7,7 +7,14 @@ struct HardwareWalletsGrid: View { let onTap: (HwWallet) -> Void private var rows: [[HwWallet]] { - stride(from: 0, to: wallets.count, by: 2).map { Array(wallets[$0 ..< min($0 + 2, wallets.count)]) } + chunked(wallets, into: 2) + } + + private func chunked(_ wallets: [HwWallet], into size: Int) -> [[HwWallet]] { + stride(from: 0, to: wallets.count, by: size).map { start in + let end = min(start + size, wallets.count) + return Array(wallets[start ..< end]) + } } var body: some View { From 763d0a4a0eb19cbc195e8ed059a0a49d71c96b05 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 23 Jun 2026 14:37:27 -0300 Subject: [PATCH 14/52] refactor: remove redundant comments --- Bitkit/Managers/TrezorManager.swift | 94 +++++------------------------ 1 file changed, 16 insertions(+), 78 deletions(-) diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index 82ba06755..0ca4c421c 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -14,7 +14,7 @@ import Foundation final class TrezorManager { // MARK: - Network Configuration - /// The network selected in the Trezor dashboard (independent of app's global network) + /// Independent of the app's global network — scoped to the Trezor dashboard. var selectedNetwork: TrezorCoinType /// BIP44 coin type component based on the dashboard's selected network: "0'" for mainnet, "1'" for test networks @@ -24,16 +24,12 @@ final class TrezorManager { // MARK: - Connection State - /// Whether the Trezor manager is initialized private var isInitialized: Bool = false - /// Whether currently scanning for devices var isScanning: Bool = false - /// List of discovered devices var devices: [TrezorDeviceInfo] = [] - /// Currently connected device var connectedDevice: TrezorDeviceInfo? { didSet { devicesRevision &+= 1 } } @@ -42,59 +38,45 @@ final class TrezorManager { /// composition root that feeds `HwWalletManager`) can react without those types coupling. private(set) var devicesRevision: Int = 0 - /// Features of the connected device var deviceFeatures: TrezorFeatures? - /// Device root fingerprint (hex string) var deviceFingerprint: String? - /// Last error message var error: String? // MARK: - UI Dialog State - /// Show PIN entry dialog var showPinEntry: Bool = false - /// Show passphrase entry dialog var showPassphraseEntry: Bool = false - /// Show BLE pairing code dialog var showPairingCode: Bool = false - /// Show "Confirm on device" overlay var showConfirmOnDevice: Bool = false - /// Message for confirm on device overlay var confirmMessage: String = "" - /// Show the "where to enter the passphrase" chooser (phone vs Trezor). /// Only presented for devices that report on-device passphrase entry capability. var showWalletModeChooser: Bool = false // MARK: - Wallet Mode State - /// The currently selected wallet mode (standard / hidden-on-phone / hidden-on-device). - /// Drives the wallet-mode selector UI; the binding to the device session is applied - /// via setWalletMode (disconnect/reconnect). + /// The binding to the device session is applied via setWalletMode (disconnect/reconnect), + /// not by mutating this property directly. var walletMode: TrezorWalletMode = .standard - /// Whether the connected device supports entering the passphrase on the Trezor itself. var passphraseEntryCapable: Bool { deviceFeatures?.passphraseEntryCapable == true } // MARK: - Known Devices & Auto-Reconnect - /// Previously connected devices loaded from storage var knownDevices: [TrezorKnownDevice] = [] { didSet { devicesRevision &+= 1 } } - /// Whether auto-reconnect is in progress var isAutoReconnecting: Bool = false - /// Status text during auto-reconnect var autoReconnectStatus: String? /// Prevents a user-initiated disconnect from immediately reconnecting @@ -103,7 +85,7 @@ final class TrezorManager { // MARK: - Bluetooth State - /// Current Bluetooth state — reads directly from BLEManager (@Observable chaining) + /// Reads directly from BLEManager (@Observable chaining). var bluetoothState: CBManagerState { TrezorBLEManager.shared.bluetoothState } @@ -128,9 +110,7 @@ final class TrezorManager { // triggering BLE stack and Combine overhead at app launch. } - /// Subscribe to callback publishers for UI notifications private func setupCallbackSubscriptions() { - // Pairing code request transport.needsPairingCodePublisher .receive(on: DispatchQueue.main) .sink { [weak self] in @@ -138,7 +118,6 @@ final class TrezorManager { } .store(in: &cancellables) - // PIN request from device uiHandler.needsPinPublisher .receive(on: DispatchQueue.main) .sink { [weak self] in @@ -154,7 +133,6 @@ final class TrezorManager { // MARK: - Debug Log Helper - /// Log to both Logger and TrezorDebugLog private func trezorLog(_ message: String, level: String = "info") { switch level { case "error": @@ -188,8 +166,7 @@ final class TrezorManager { // MARK: - Manager Setup - /// Set up subscriptions and start BLE stack (synchronous, non-blocking). - /// Called from TrezorRootView's .task to prepare the UI layer. + /// Synchronous, non-blocking. Called from TrezorRootView's .task to prepare the UI layer. func setup() { guard !hasSetupSubscriptions else { return } if !transport.isBridgeEnabled { @@ -201,8 +178,7 @@ final class TrezorManager { hasSetupSubscriptions = true } - /// Initialize the Trezor FFI manager (async, may be slow). - /// Called lazily before first scan/connect. + /// Async and potentially slow. Called lazily before first scan/connect. func initialize() async { setup() @@ -221,8 +197,6 @@ final class TrezorManager { // MARK: - Device Scanning - /// Start scanning for Trezor devices - /// - Parameter clearExisting: Whether to clear existing device list before scanning func startScan(clearExisting: Bool = true) async { if !isInitialized { await initialize() @@ -236,19 +210,16 @@ final class TrezorManager { } if !transport.isBridgeEnabled { - // Start BLE scanning transport.startBLEScanning() - // Wait for BLE to discover devices (like Android's 3-second scan) - // This ensures devices are found before we call the FFI enumerate - try? await Task.sleep(nanoseconds: 3_000_000_000) // 3 seconds + // Wait for BLE to discover devices (like Android's 3-second scan) before + // calling the FFI enumerate, then stop scanning to prevent race conditions. + try? await Task.sleep(nanoseconds: 3_000_000_000) - // Stop BLE scanning before calling FFI to prevent race conditions transport.stopBLEScanning() } do { - // Trigger FFI scan which will use our transport callbacks let foundDevices = try await trezorService.scan() // Deduplicate by path (in case of duplicate scan results) @@ -271,7 +242,6 @@ final class TrezorManager { isScanning = false } - /// Stop scanning for devices func stopScan() { transport.stopBLEScanning() isScanning = false @@ -279,7 +249,6 @@ final class TrezorManager { // MARK: - Connection - /// Connect to a device func connect(device: TrezorDeviceInfo) async { error = nil suppressNextAutoReconnect = false @@ -308,7 +277,6 @@ final class TrezorManager { } } - /// Disconnect from current device func disconnect() async { guard connectedDevice != nil else { return } suppressNextAutoReconnect = true @@ -331,34 +299,29 @@ final class TrezorManager { } } - /// Check if currently connected var isConnected: Bool { connectedDevice != nil } // MARK: - UI Callbacks - /// Submit PIN from UI func submitPin(_ pin: String) { showPinEntry = false uiHandler.submitPin(pin) } - /// Cancel PIN entry func cancelPin() { showPinEntry = false uiHandler.cancelPin() } - /// Submit a host-entered passphrase from the UI — opens the corresponding hidden - /// wallet (or the standard wallet when empty) by resetting the session. + /// Opens the corresponding hidden wallet (or the standard wallet when empty) by resetting the session. func submitPassphrase(_ passphrase: String) async { showPassphraseEntry = false showConfirmOnDevice = false await setWalletMode(passphrase.isEmpty ? .standard : .passphraseHost, passphrase: passphrase) } - /// Cancel passphrase entry func cancelPassphrase() { showPassphraseEntry = false showConfirmOnDevice = false @@ -367,14 +330,13 @@ final class TrezorManager { // MARK: - Wallet Mode Selection - /// User tapped the "Standard" wallet option in the selector. func selectStandardWallet() async { guard walletMode != .standard else { return } await setWalletMode(.standard) } - /// User tapped the "Passphrase" wallet option. On a capable device this offers a - /// choice of where to enter the passphrase; otherwise it goes straight to host entry. + /// On a capable device this offers a choice of where to enter the passphrase; + /// otherwise it goes straight to host entry. func requestPassphraseWallet() { if passphraseEntryCapable { showWalletModeChooser = true @@ -383,13 +345,11 @@ final class TrezorManager { } } - /// Wallet-mode chooser: user chose to enter the passphrase on this phone. func choosePhonePassphraseEntry() { showWalletModeChooser = false showPassphraseEntry = true } - /// Wallet-mode chooser: user chose to enter the passphrase on the Trezor. func chooseDevicePassphraseEntry() async { showWalletModeChooser = false await setWalletMode(.passphraseDevice) @@ -440,19 +400,16 @@ final class TrezorManager { } } - /// Submit pairing code from UI func submitPairingCode(_ code: String) { showPairingCode = false transport.submitPairingCode(code) } - /// Cancel pairing code entry func cancelPairingCode() { showPairingCode = false transport.cancelPairingCode() } - /// Dismiss confirm on device overlay func dismissConfirmOnDevice() { showConfirmOnDevice = false confirmMessage = "" @@ -460,13 +417,12 @@ final class TrezorManager { // MARK: - Known Devices - /// Load known devices from storage func loadKnownDevices() { knownDevices = TrezorKnownDeviceStorage.loadAll() } - /// Save the currently connected device as a known device, capturing its account - /// xpubs so watch-only balances/activity stay available while disconnected. + /// Captures the connected device's account xpubs so watch-only balances/activity + /// stay available while disconnected. func saveCurrentDeviceAsKnown() async { guard let device = connectedDevice else { return } let previous = TrezorKnownDeviceStorage.loadAll().first { $0.id == device.id } @@ -487,7 +443,6 @@ final class TrezorManager { trezorLog("Saved known device: \(known.name) with \(mergedXpubs.count) xpubs") } - /// Read the account-level xpub for every address type from the connected device. /// Per-type failures are swallowed so a single missing type doesn't block the rest. func fetchAccountXpubs() async -> [String: String] { var result: [String: String] = [:] @@ -507,9 +462,7 @@ final class TrezorManager { return result } - /// Forget a known device — removes from storage and clears credentials func forgetDevice(id: String) async { - // Find the device to get its path for credential clearing if let device = knownDevices.first(where: { $0.id == id }) { do { try await trezorService.clearCredentials(deviceId: device.path) @@ -525,7 +478,6 @@ final class TrezorManager { // MARK: - Auto-Reconnect - /// Automatically scan and reconnect to the first matching known device func autoReconnect() async { guard !knownDevices.isEmpty else { return } guard !isAutoReconnecting else { return } @@ -541,7 +493,6 @@ final class TrezorManager { await startScan(clearExisting: true) - // Find the first scanned device that matches a known device let knownIds = Set(knownDevices.map(\.id)) if let match = devices.first(where: { knownIds.contains($0.id) }) { autoReconnectStatus = "Connecting to \(match.label ?? match.name ?? "Trezor")..." @@ -556,11 +507,9 @@ final class TrezorManager { autoReconnectStatus = nil } - // MARK: - Electrum URL Helpers - // MARK: - Network Switching - /// Switch the dashboard's network independently of the app's global network + /// Switches the dashboard's network independently of the app's global network. func setSelectedNetwork(_ network: TrezorCoinType) { guard network != selectedNetwork else { return } selectedNetwork = network @@ -570,7 +519,6 @@ final class TrezorManager { // MARK: - Credential Management - /// Clear stored credentials for current device func clearCredentials() async { guard let device = connectedDevice else { error = "No device connected" @@ -588,35 +536,29 @@ final class TrezorManager { // MARK: - Error Handling - /// Extract a user-friendly error message from a Trezor error private func errorMessage(from error: Error) -> String { // ServiceQueue wraps all errors in AppError, so extract the original message if let appError = error as? AppError { // debugMessage contains the original error's localizedDescription if let debugMessage = appError.debugMessage, !debugMessage.isEmpty { - // Check for common Trezor error patterns in the debug message return formatTrezorErrorMessage(debugMessage) } - // Fall through to show the app error message if no debug info + // Fall through to the app error message if no debug info return appError.message } - // Handle TrezorError directly (if not wrapped) if let trezorError = error as? TrezorError { return trezorError.localizedDescription } - // Handle TrezorBLEError from BLE layer if let bleError = error as? TrezorBLEError { return bleError.localizedDescription } - // Handle TrezorTransportError from transport layer if let transportError = error as? TrezorTransportError { return transportError.localizedDescription } - // For any other error, try to get a meaningful description let description = error.localizedDescription if description == "The operation couldn't be completed." || description.isEmpty { return "Connection failed. Please ensure your Trezor is in pairing mode and try again." @@ -624,9 +566,7 @@ final class TrezorManager { return description } - /// Format Trezor error messages for user display private func formatTrezorErrorMessage(_ message: String) -> String { - // Clean up common Trezor error prefixes for better readability let cleanedMessage = message .replacingOccurrences(of: "Transport error: ", with: "") .replacingOccurrences(of: "Connection error: ", with: "") @@ -635,7 +575,6 @@ final class TrezorManager { .replacingOccurrences(of: "Session error: ", with: "") .replacingOccurrences(of: "IO error: ", with: "") - // Map technical messages to user-friendly ones if message.contains("Stale Bluetooth pairing") || message.contains("Peer removed pairing") { return "Stale Bluetooth pairing detected. Go to iOS Settings → Bluetooth, forget your Trezor device, then put it back in pairing mode and try again." } @@ -661,7 +600,6 @@ final class TrezorManager { return "Action was cancelled on the device." } - // Return the cleaned message if no specific mapping return cleanedMessage } } From 1b03abfb93e9e3a991d825effaeb682826559977 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 06:37:12 -0300 Subject: [PATCH 15/52] refactor: remove redundant comment --- Bitkit/Utilities/AppReset.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Bitkit/Utilities/AppReset.swift b/Bitkit/Utilities/AppReset.swift index 967877389..ddc12ddfe 100644 --- a/Bitkit/Utilities/AppReset.swift +++ b/Bitkit/Utilities/AppReset.swift @@ -23,9 +23,6 @@ enum AppReset { await VssBackupClient.shared.reset() VssStoreIdProvider.shared.clearCache() - // Stop any running watch-only hardware-wallet watchers. Their persisted xpubs/known - // devices and activities are cleared below by the UserDefaults/keychain/core-DB wipes; - // the app-lifetime HwWalletManager is rebuilt by session.bump() at the end of this wipe. OnChainHwService.shared.stopAllWatchers() // Stop node and wipe LDK persistence via the wallet API. From 9a92952d5e0e8b768f83fe0efc5d9326a7ad7ce1 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 07:27:40 -0300 Subject: [PATCH 16/52] chore: add preview --- Bitkit/Views/Sheets/HardwarePairingSheet.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Bitkit/Views/Sheets/HardwarePairingSheet.swift b/Bitkit/Views/Sheets/HardwarePairingSheet.swift index 9ba6e992a..9615dc4e6 100644 --- a/Bitkit/Views/Sheets/HardwarePairingSheet.swift +++ b/Bitkit/Views/Sheets/HardwarePairingSheet.swift @@ -6,7 +6,6 @@ struct HardwarePairingSheetItem: SheetItem { } /// App-wide sheet for the one-time pairing code a hardware device shows during connect/reconnect. -/// Mirrors bitkit-android's `HwPairCodeSheet`: 6 fixed-width cells + an on-screen number pad. /// Dismissing without entering the full code cancels the pending pairing request. struct HardwarePairingSheet: View { @Environment(TrezorManager.self) private var trezorManager @@ -70,3 +69,10 @@ struct HardwarePairingSheet: View { } } } + +#Preview { + HardwarePairingSheet(config: HardwarePairingSheetItem()) + .environmentObject(SheetViewModel()) + .environment(TrezorManager()) + .preferredColorScheme(.dark) +} From a6b48e713b372e8866244743b604b55533fe7bbc Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 13:34:00 -0300 Subject: [PATCH 17/52] fix: disable RBF, contact and tag features for HW activity detail --- .../Wallets/Activity/ActivityItemView.swift | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift index cba5f657f..23698b8c8 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift @@ -135,7 +135,15 @@ struct ActivityItemView: View { return DateFormatterHelpers.formatActivityDetail(activity.timestamp) } + private var isHardwareActivity: Bool { + viewModel.activity.isHardwareWallet + } + private var shouldDisableBoostButton: Bool { + // Watch-only hardware wallets have no signing keys, so RBF is impossible. + if isHardwareActivity { + return true + } switch viewModel.activity { case .lightning: return true @@ -514,42 +522,45 @@ struct ActivityItemView: View { private var buttons: some View { VStack(spacing: 16) { - HStack(spacing: 16) { - if isPaykitUIActive { + // Contact and tag actions are hidden for watch-only hardware wallets. + if !isHardwareActivity { + HStack(spacing: 16) { + if isPaykitUIActive { + CustomButton( + title: assignedContact == nil ? t("wallet__activity_assign") : t("wallet__activity_detach"), size: .small, + icon: Image(assignedContact == nil ? "user-plus" : "user-minus") + .foregroundColor(accentColor), + shouldExpand: true + ) { + if assignedContact == nil { + navigation.navigate(.assignActivityContact(activityId: viewModel.activityId)) + } else { + Task { + await detachContact() + } + } + } + .accessibilityIdentifier(assignedContact == nil ? "ActivityAssignContact" : "ActivityDetachContact") + } + CustomButton( - title: assignedContact == nil ? t("wallet__activity_assign") : t("wallet__activity_detach"), size: .small, - icon: Image(assignedContact == nil ? "user-plus" : "user-minus") + title: t("wallet__activity_tag"), size: .small, + icon: Image("tag") .foregroundColor(accentColor), shouldExpand: true ) { - if assignedContact == nil { - navigation.navigate(.assignActivityContact(activityId: viewModel.activityId)) - } else { - Task { - await detachContact() - } + let activityId: String = switch viewModel.activity { + case let .lightning(activity): + activity.id + case let .onchain(activity): + activity.id } + sheets.showSheet(.addTag, data: AddTagConfig(activityId: activityId)) } - .accessibilityIdentifier(assignedContact == nil ? "ActivityAssignContact" : "ActivityDetachContact") + .accessibilityIdentifier("ActivityTag") } - - CustomButton( - title: t("wallet__activity_tag"), size: .small, - icon: Image("tag") - .foregroundColor(accentColor), - shouldExpand: true - ) { - let activityId: String = switch viewModel.activity { - case let .lightning(activity): - activity.id - case let .onchain(activity): - activity.id - } - sheets.showSheet(.addTag, data: AddTagConfig(activityId: activityId)) - } - .accessibilityIdentifier("ActivityTag") + .frame(maxWidth: .infinity) } - .frame(maxWidth: .infinity) HStack(spacing: 16) { CustomButton( From e3364671391b366b033e412525dce7b1c69755d3 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 13:40:54 -0300 Subject: [PATCH 18/52] fix: set wallet scope for tag methods --- Bitkit/Services/CoreService.swift | 12 ++++++------ Bitkit/ViewModels/ActivityItemViewModel.swift | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Bitkit/Services/CoreService.swift b/Bitkit/Services/CoreService.swift index ea2dd927b..01e280d2c 100644 --- a/Bitkit/Services/CoreService.swift +++ b/Bitkit/Services/CoreService.swift @@ -1213,23 +1213,23 @@ class ActivityService { // MARK: - Tag Methods - func appendTags(toActivity id: String, _ tags: [String]) async throws { + func appendTags(toActivity id: String, _ tags: [String], walletId: String = WalletScope.default) async throws { try await ServiceQueue.background(.core) { - try addTags(walletId: WalletScope.default, activityId: id, tags: tags) + try addTags(walletId: walletId, activityId: id, tags: tags) self.activitiesChangedSubject.send() } } - func dropTags(fromActivity id: String, _ tags: [String]) async throws { + func dropTags(fromActivity id: String, _ tags: [String], walletId: String = WalletScope.default) async throws { try await ServiceQueue.background(.core) { - try removeTags(walletId: WalletScope.default, activityId: id, tags: tags) + try removeTags(walletId: walletId, activityId: id, tags: tags) self.activitiesChangedSubject.send() } } - func tags(forActivity id: String) async throws -> [String] { + func tags(forActivity id: String, walletId: String = WalletScope.default) async throws -> [String] { try await ServiceQueue.background(.core) { - try getTags(walletId: WalletScope.default, activityId: id) + try getTags(walletId: walletId, activityId: id) } } diff --git a/Bitkit/ViewModels/ActivityItemViewModel.swift b/Bitkit/ViewModels/ActivityItemViewModel.swift index f9b8c9063..993ca68c4 100644 --- a/Bitkit/ViewModels/ActivityItemViewModel.swift +++ b/Bitkit/ViewModels/ActivityItemViewModel.swift @@ -37,7 +37,7 @@ class ActivityItemViewModel: ObservableObject { func loadTags() async { do { - tags = try await coreService.activity.tags(forActivity: activityId) + tags = try await coreService.activity.tags(forActivity: activityId, walletId: activity.walletId) } catch { Logger.error(error, context: "Failed to load tags for activity \(activityId)") tags = [] @@ -46,7 +46,7 @@ class ActivityItemViewModel: ObservableObject { func removeTag(_ tag: String) async { do { - try await coreService.activity.dropTags(fromActivity: activityId, [tag]) + try await coreService.activity.dropTags(fromActivity: activityId, [tag], walletId: activity.walletId) await loadTags() // Reload tags after removal } catch { Logger.error(error, context: "Failed to remove tag \(tag) from activity \(activityId)") From d239df292a55d5fa8ab1d26ab1a23853b82a6a0e Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 13:48:28 -0300 Subject: [PATCH 19/52] fix: set wallet id for refresh method in explore --- Bitkit/Services/CoreService.swift | 4 ++-- .../Views/Wallets/Activity/ActivityExplorerView.swift | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Bitkit/Services/CoreService.swift b/Bitkit/Services/CoreService.swift index 01e280d2c..bf8bbb677 100644 --- a/Bitkit/Services/CoreService.swift +++ b/Bitkit/Services/CoreService.swift @@ -139,9 +139,9 @@ class ActivityService { } } - func getTransactionDetails(txid: String) async throws -> BitkitCore.TransactionDetails? { + func getTransactionDetails(txid: String, walletId: String = WalletScope.default) async throws -> BitkitCore.TransactionDetails? { try await ServiceQueue.background(.core) { - try BitkitCore.getTransactionDetails(walletId: WalletScope.default, txId: txid) + try BitkitCore.getTransactionDetails(walletId: walletId, txId: txid) } } diff --git a/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift b/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift index 9f5653d24..3a8f0bffb 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityExplorerView.swift @@ -48,7 +48,10 @@ struct ActivityExplorerView: View { guard let onchain else { return } do { - let details = try await CoreService.shared.activity.getTransactionDetails(txid: onchain.txId) + let details = try await CoreService.shared.activity.getTransactionDetails( + txid: onchain.txId, + walletId: item.walletId + ) await MainActor.run { txDetails = details } @@ -68,7 +71,10 @@ struct ActivityExplorerView: View { private func refreshActivity() async { do { - if let updatedActivity = try await CoreService.shared.activity.getActivity(id: activityId) { + if let updatedActivity = try await CoreService.shared.activity.getActivity( + id: activityId, + walletId: item.walletId + ) { await MainActor.run { item = updatedActivity } From 384e62f347a875a9db29a4264dc2fe17c5187d29 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 13:59:43 -0300 Subject: [PATCH 20/52] fix: set fallback timestamp for unconfirmed HW transactions --- Bitkit/Managers/HwWalletManager.swift | 30 ++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index f531bd281..530872a90 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -45,6 +45,7 @@ final class HwWalletManager { private let networkProvider: () -> TrezorCoinType private let persistActivities: ([Activity]) -> Void private let deleteActivities: (String) -> Void + private let nowProvider: () -> UInt64 // MARK: - Internal state @@ -57,13 +58,18 @@ final class HwWalletManager { private var emittedReceivedTxIds: Set = [] private var listeners: [String: TrezorEventListener] = [:] + /// First-seen wall-clock timestamp per unconfirmed txid, kept so a mempool tx stays at a + /// stable position in the (timestamp-sorted) activity list across watcher events. + private var assignedTimestamps: [String: UInt64] = [:] + init( watcherService: OnChainWatcherServicing = OnChainHwService.shared, monitoredTypes: (() -> Set)? = nil, electrumUrl: (() -> String)? = nil, network: (() -> TrezorCoinType)? = nil, persistActivities: (([Activity]) -> Void)? = nil, - deleteActivities: ((String) -> Void)? = nil + deleteActivities: ((String) -> Void)? = nil, + now: (() -> UInt64)? = nil ) { self.watcherService = watcherService networkProvider = network ?? { OnChainHwService.appDefaultCoinType } @@ -86,6 +92,7 @@ final class HwWalletManager { } } } + nowProvider = now ?? { UInt64(Date().timeIntervalSince1970) } } // MARK: - Device input @@ -116,6 +123,7 @@ final class HwWalletManager { emittedReceivedTxIds.removeAll() listeners.removeAll() watcherData.removeAll() + assignedTimestamps.removeAll() recomputeDerivedState() } @@ -252,12 +260,28 @@ final class HwWalletManager { private func mergedActivities(for group: DeviceGroup) -> [Activity] { let watchers = watcherData.values.filter { group.ids.contains($0.deviceId) } let grouped = Dictionary(grouping: watchers.flatMap(\.transactions), by: \.txid) - return grouped.values.map { transactions in - let timestamp = transactions.compactMap(\.timestamp).min() ?? 0 + return grouped.map { txid, transactions in + let timestamp = resolveTimestamp(txid: txid, transactions: transactions) return onchainActivity(walletId: group.walletId, from: transactions, timestamp: timestamp) } } + /// Confirmed txs carry a block timestamp; mempool txs report `nil`. Falling back to `0` + /// would bury a fresh receive at the bottom of the timestamp-sorted activity list, so use + /// the first-seen wall-clock time instead and remember it per txid until the tx confirms. + private func resolveTimestamp(txid: String, transactions: [HistoryTransaction]) -> UInt64 { + if let confirmed = transactions.compactMap(\.timestamp).min() { + assignedTimestamps[txid] = nil + return confirmed + } + if let assigned = assignedTimestamps[txid] { + return assigned + } + let now = nowProvider() + assignedTimestamps[txid] = now + return now + } + // MARK: - Aggregation private func recomputeDerivedState() { From 4f62696c2e61cca68ccf9443576f948b1a962398 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:09:05 -0300 Subject: [PATCH 21/52] fix: get tx direction from core --- Bitkit/Managers/HwWalletManager.swift | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 530872a90..ad50f8797 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -327,14 +327,24 @@ final class HwWalletManager { let received = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.received) } let sent = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.sent) } let fee = transactions.compactMap(\.fee).max() ?? 0 - let txType: PaymentType = received > sent ? .received : .sent + + // Classify by core's TxDirection (core 0.3.x): received-vs-sent arithmetic alone cannot + // tell a self-transfer/consolidation apart from a normal send (both have sent > received, + // since sent == received + fee), so without this a consolidation would show value 0 + // instead of the fee paid. + let txType: PaymentType let value: UInt64 - switch txType { + switch first.direction { case .received: + txType = .received value = received >= sent ? received - sent : 0 case .sent: + txType = .sent let net = sent >= received ? sent - received : 0 value = net >= fee ? net - fee : 0 + case .selfTransfer: + txType = .sent + value = fee } let confirmations = transactions.map(\.confirmations).max() ?? 0 let confirmed = confirmations > 0 From 893a53ed50da724ed216934689f70c102de18701 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:14:03 -0300 Subject: [PATCH 22/52] fix: clean orphaned activities from deleted devices --- Bitkit/Managers/HwWalletManager.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index ad50f8797..bb9a72b1a 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -101,11 +101,20 @@ final class HwWalletManager { /// composition root (`AppScene`) feeds it the current Trezor device list, so this type stays /// fully decoupled from `TrezorManager`. Also the test seam — tests drive it directly. func updateDevices(knownDevices: [TrezorKnownDevice], connectedDeviceId: String?) { + let previousWalletIds = hwWalletIds self.knownDevices = knownDevices self.connectedDeviceId = connectedDeviceId walletsLoaded = true syncWatchers() recomputeDerivedState() + + // A device that dropped out of the snapshot (e.g. the user forgot it) would otherwise + // leave its watch-only activities orphaned in the merged activity list, which queries + // every wallet id. syncWatchers already stopped its watcher above; delete its persisted + // activities too. Cleans up on any removal path, keeping us decoupled from TrezorManager. + for walletId in previousWalletIds.subtracting(hwWalletIds) { + deleteActivities(walletId) + } } // MARK: - Control From ca789695f4c402b76b7e6fffdac4b4f8b7c5d028 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:19:45 -0300 Subject: [PATCH 23/52] fix: watch idenpotency --- Bitkit/Managers/HwWalletManager.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index bb9a72b1a..eda68f993 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -55,6 +55,11 @@ final class HwWalletManager { private var activeWatchers: Set = [] private var activeWatcherElectrumUrls: [String: String] = [:] private var retryingWatcherStarts: Set = [] + + /// Watchers whose async start is dispatched but not yet confirmed in `activeWatchers`. + /// Guards against a second `syncWatchers()` double-starting the same watcher in that window. + private var pendingWatcherStarts: Set = [] + private var emittedReceivedTxIds: Set = [] private var listeners: [String: TrezorEventListener] = [:] @@ -129,6 +134,7 @@ final class HwWalletManager { activeWatchers.removeAll() activeWatcherElectrumUrls.removeAll() retryingWatcherStarts.removeAll() + pendingWatcherStarts.removeAll() emittedReceivedTxIds.removeAll() listeners.removeAll() watcherData.removeAll() @@ -166,6 +172,9 @@ final class HwWalletManager { let desiredIds = Set(specs.map(\.watcherId)) for spec in specs { + // A start is already in flight for this watcher; skip so we don't launch a duplicate. + // The next sync after it completes reconciles any electrum-url change. + if pendingWatcherStarts.contains(spec.watcherId) { continue } let isActive = activeWatchers.contains(spec.watcherId) if isActive, activeWatcherElectrumUrls[spec.watcherId] == spec.electrumUrl { continue } if isActive, !stopActiveWatcher(spec.watcherId) { continue } @@ -194,14 +203,17 @@ final class HwWalletManager { self?.handleWatcherEvent(watcherId: id, event: event) } listeners[spec.watcherId] = listener + pendingWatcherStarts.insert(spec.watcherId) Task { @MainActor in do { try await watcherService.startWatcher(params: params, listener: listener) + pendingWatcherStarts.remove(spec.watcherId) activeWatchers.insert(spec.watcherId) activeWatcherElectrumUrls[spec.watcherId] = spec.electrumUrl retryingWatcherStarts.remove(spec.watcherId) } catch { + pendingWatcherStarts.remove(spec.watcherId) listeners[spec.watcherId] = nil Logger.warn("Retrying hardware watcher '\(spec.watcherId)' after start failure: \(error)") scheduleWatcherStartRetry(spec.watcherId) From 79ae836d7a193947bee081586af56c5da3889219 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:27:07 -0300 Subject: [PATCH 24/52] fix: dont cancel pairing when bracgrouding the device --- Bitkit/Views/Sheets/HardwarePairingSheet.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Bitkit/Views/Sheets/HardwarePairingSheet.swift b/Bitkit/Views/Sheets/HardwarePairingSheet.swift index 9615dc4e6..6efb4fbad 100644 --- a/Bitkit/Views/Sheets/HardwarePairingSheet.swift +++ b/Bitkit/Views/Sheets/HardwarePairingSheet.swift @@ -9,6 +9,7 @@ struct HardwarePairingSheetItem: SheetItem { /// Dismissing without entering the full code cancels the pending pairing request. struct HardwarePairingSheet: View { @Environment(TrezorManager.self) private var trezorManager + @Environment(\.scenePhase) private var scenePhase let config: HardwarePairingSheetItem private let codeLength = 6 @@ -48,7 +49,11 @@ struct HardwarePairingSheet: View { .accessibilityIdentifier("HwPairSheet") } .onDisappear { - if !submitted { trezorManager.cancelPairingCode() } + // Treat this as a user cancel only when it's a genuine foreground dismissal with the + // request still pending. Backgrounding (scenePhase != .active) or the request already + // being resolved/submitted (showPairingCode == false) must not abort the pairing. + guard !submitted, scenePhase == .active, trezorManager.showPairingCode else { return } + trezorManager.cancelPairingCode() } } From 914acafcda1aaf455382e86dd48d101da672770c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:30:55 -0300 Subject: [PATCH 25/52] fix: clear dev dashboard results on wallet disconnect --- Bitkit/ViewModels/Trezor/TrezorViewModel.swift | 8 +++++++- Bitkit/Views/Trezor/TrezorRootView.swift | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index c7ce821d6..f27ebae4b 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -562,7 +562,13 @@ class TrezorViewModel { messageSigningPath = "m/84'/\(connection.coinTypeComponent)/0'/0/0" addressIndex = 0 - // Clear results from previous network + clearWalletResults() + } + + /// Clear dev-tool results derived from the connected wallet (generated address, xpub, public + /// key, signed message and lookup results). Called on network switch, disconnect and + /// wallet-mode change so a previous wallet's data is never shown for a different/absent wallet. + func clearWalletResults() { generatedAddress = nil xpub = nil publicKeyHex = nil diff --git a/Bitkit/Views/Trezor/TrezorRootView.swift b/Bitkit/Views/Trezor/TrezorRootView.swift index 01ec132ba..844157edf 100644 --- a/Bitkit/Views/Trezor/TrezorRootView.swift +++ b/Bitkit/Views/Trezor/TrezorRootView.swift @@ -58,6 +58,7 @@ extension View { /// re-renders when connection state changes. private struct TrezorContentSwitcher: View { @Environment(TrezorManager.self) private var trezorManager + @Environment(TrezorViewModel.self) private var trezor var body: some View { Group { @@ -68,6 +69,18 @@ private struct TrezorContentSwitcher: View { } } .animation(.easeInOut(duration: 0.25), value: trezorManager.isConnected) + .onChange(of: trezorManager.isConnected) { _, isConnected in + // Drop the previous wallet's dev-tool results on disconnect so a different/absent + // wallet never shows stale xpub/address/public-key data. + if !isConnected { + trezor.clearWalletResults() + } + } + .onChange(of: trezorManager.walletMode) { _, _ in + // A wallet-mode switch rebinds the session to a different wallet but keeps the device + // connected, so the disconnect path above doesn't fire — clear results here too. + trezor.clearWalletResults() + } } } From c22f68296853f5b38960cd2a4d0dc9ae43127f2c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:35:22 -0300 Subject: [PATCH 26/52] refactor: consolidate network conversion --- Bitkit/Managers/HwWalletManager.swift | 11 +------ Bitkit/Services/OnChainHwService.swift | 33 +++++++++---------- .../ViewModels/Trezor/TrezorViewModel.swift | 14 ++------ 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index eda68f993..74e017b0d 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -195,7 +195,7 @@ final class HwWalletManager { watcherId: spec.watcherId, extendedKey: spec.xpub, electrumUrl: spec.electrumUrl, - network: toNetwork(network), + network: network.coreNetwork, accountType: addressType.accountType, gapLimit: Constants.defaultGapLimit ) @@ -411,15 +411,6 @@ final class HwWalletManager { return String(watcherId[.. BitkitCore.Network { - switch coin { - case .bitcoin: .bitcoin - case .testnet: .testnet - case .signet: .signet - case .regtest: .regtest - } - } - private func saturatingAdd(_ a: UInt64, _ b: UInt64) -> UInt64 { let (sum, overflow) = a.addingReportingOverflow(b) return overflow ? .max : sum diff --git a/Bitkit/Services/OnChainHwService.swift b/Bitkit/Services/OnChainHwService.swift index 111fc934f..619489809 100644 --- a/Bitkit/Services/OnChainHwService.swift +++ b/Bitkit/Services/OnChainHwService.swift @@ -33,7 +33,7 @@ class OnChainHwService { gapLimit: UInt32? = nil, scriptType: AccountType? = nil ) async throws -> AccountInfoResult { - let networkParam = toNetwork(network) + let networkParam = network?.coreNetwork return try await ServiceQueue.background(.core) { try await onchainGetAccountInfo( extendedKey: extendedKey, @@ -52,7 +52,7 @@ class OnChainHwService { electrumUrl: String, network: TrezorCoinType? = nil ) async throws -> SingleAddressInfoResult { - let networkParam = toNetwork(network) + let networkParam = network?.coreNetwork return try await ServiceQueue.background(.core) { try await onchainGetAddressInfo( address: address, @@ -72,7 +72,7 @@ class OnChainHwService { network: TrezorCoinType? = nil, scriptType: AccountType? = nil ) async throws -> TransactionHistoryResult { - let networkParam = toNetwork(network) + let networkParam = network?.coreNetwork return try await ServiceQueue.background(.core) { try await onchainGetTransactionHistory( extendedKey: extendedKey, @@ -92,7 +92,7 @@ class OnChainHwService { network: TrezorCoinType? = nil, scriptType: AccountType? = nil ) async throws -> TransactionDetail { - let networkParam = toNetwork(network) + let networkParam = network?.coreNetwork return try await ServiceQueue.background(.core) { try await onchainGetTransactionDetail( extendedKey: extendedKey, @@ -142,19 +142,6 @@ class OnChainHwService { func stopAllWatchers() { onchainStopAllWatchers() } - - // MARK: - Helpers - - /// Convert TrezorCoinType to the Network enum used by onchain FFI functions - private func toNetwork(_ coin: TrezorCoinType?) -> Network? { - guard let coin else { return nil } - switch coin { - case .bitcoin: return .bitcoin - case .testnet: return .testnet - case .signet: return .signet - case .regtest: return .regtest - } - } } // MARK: - Network / Electrum helpers @@ -199,3 +186,15 @@ extension OnChainHwService { return server.fullUrl.isEmpty ? Env.electrumServerUrl : server.fullUrl } } + +extension TrezorCoinType { + /// The BitkitCore `Network` this coin type maps to, used by the onchain FFI functions. + var coreNetwork: BitkitCore.Network { + switch self { + case .bitcoin: .bitcoin + case .testnet: .testnet + case .signet: .signet + case .regtest: .regtest + } + } +} diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index f27ebae4b..80bcfe13c 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -796,7 +796,7 @@ class TrezorViewModel { : .payment(address: address, amountSats: UInt64(sendAmountSats) ?? 0) let electrumUrl = OnChainHwService.electrumUrlForNetwork(connection.selectedNetwork) - let network = toNetwork(connection.selectedNetwork) + let network = connection.selectedNetwork.coreNetwork let wallet = WalletParams( extendedKey: extendedKey, @@ -951,15 +951,7 @@ class TrezorViewModel { // MARK: - Helpers - /// Convert TrezorCoinType to the Network enum used by onchain FFI functions - private func toNetwork(_ coin: TrezorCoinType) -> Network? { - switch coin { - case .bitcoin: return .bitcoin - case .testnet: return .testnet - case .signet: return .signet - case .regtest: return .regtest - } - } + // Convert TrezorCoinType to the Network enum used by onchain FFI functions // MARK: - Error Handling @@ -1071,7 +1063,7 @@ class TrezorViewModel { watcherId: watcherId, extendedKey: key, electrumUrl: OnChainHwService.electrumUrlForNetwork(network), - network: toNetwork(network), + network: network.coreNetwork, accountType: accountType, gapLimit: gapLimit ) From b940159e5e4df743443a65a0ac8b6393d0bf956e Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Wed, 24 Jun 2026 14:51:57 -0300 Subject: [PATCH 27/52] test: regression tests --- BitkitTests/HwWalletManagerTests.swift | 130 ++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 3c661a64a..f097a3309 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -46,7 +46,8 @@ final class HwWalletManagerTests: XCTestCase { private func makeViewModel( watcherService: OnChainWatcherServicing = MockWatcherService(), - monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"] + monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"], + now: @escaping () -> UInt64 = { 1_700_000_000 } ) -> HwWalletManager { let vm = HwWalletManager( watcherService: watcherService, @@ -54,7 +55,8 @@ final class HwWalletManagerTests: XCTestCase { electrumUrl: { "ssl://test:1" }, network: { .regtest }, persistActivities: { [weak self] in self?.persisted.append($0) }, - deleteActivities: { [weak self] in self?.deleted.append($0) } + deleteActivities: { [weak self] in self?.deleted.append($0) }, + now: now ) vm.receivedTxPublisher .sink { [weak self] in self?.receivedTxs.append($0) } @@ -450,6 +452,130 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(deleted, [HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1")]) } + // MARK: - Fix 4: unconfirmed timestamp + + func testUnconfirmedTxUsesNowTimestampNotZero() { + let fixedNow: UInt64 = 1_650_000_000 + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(now: { fixedNow }) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 + )) + + guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.timestamp, fixedNow) + XCTAssertEqual(onchain.createdAt, fixedNow) + XCTAssertFalse(onchain.confirmed) + } + + func testUnconfirmedTxTimestampStableAcrossEvents() { + var nowValue: UInt64 = 1_650_000_000 + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(now: { nowValue }) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + let wid = watcherId("dev1", "nativeSegwit") + + vm.handleWatcherEvent(watcherId: wid, event: makeEvent( + [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 + )) + + // Clock advances, but a later event for the still-unconfirmed tx must keep the first timestamp. + nowValue = 1_650_009_999 + vm.handleWatcherEvent(watcherId: wid, event: makeEvent( + [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 + )) + + guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.timestamp, 1_650_000_000) + } + + func testConfirmedTxUsesBlockTimestamp() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(now: { 1_650_000_000 }) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "confirmed", received: 5000, sent: 0, direction: .received, confirmations: 3, timestamp: 1_699_999_000)], total: 5000 + )) + + guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.timestamp, 1_699_999_000) + XCTAssertTrue(onchain.confirmed) + } + + // MARK: - Fix 5: self-transfer value + + func testSelfTransferValueIsFee() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + // Consolidation: everything comes back to the wallet minus the fee (sent == received + fee). + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "consolidate", received: 19500, sent: 20000, fee: 500, direction: .selfTransfer)], total: 19500 + )) + + guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } + XCTAssertEqual(onchain.txType, .sent) + XCTAssertEqual(onchain.value, 500) // the fee paid, not 0 + XCTAssertEqual(onchain.fee, 500) + } + + // MARK: - Fix 6: forget device deletes activities + + func testForgettingDeviceViaUpdateDeletesActivities() async { + let mock = MockWatcherService() + let xpubs = ["nativeSegwit": "z"] + let device = makeDevice(id: "dev1", xpubs: xpubs) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: 1000 + )) + let walletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + + // Device forgotten → the next snapshot no longer includes it. + vm.updateDevices(knownDevices: [], connectedDeviceId: nil) + + XCTAssertEqual(deleted, [walletId]) + XCTAssertTrue(vm.wallets.isEmpty) + XCTAssertTrue(mock.stoppedWatcherIds.contains(watcherId("dev1", "nativeSegwit"))) + } + + func testUpdateKeepingDeviceDoesNotDeleteActivities() async { + let mock = MockWatcherService() + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + + // Same device pushed again (e.g. connection toggled) → no deletion. + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + + XCTAssertTrue(deleted.isEmpty) + XCTAssertEqual(vm.wallets.count, 1) + } + + // MARK: - Fix 7: watcher start-race guard + + func testDoubleSyncDoesNotDoubleStartWatcher() async { + let mock = MockWatcherService() + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + + // Two pushes back-to-back, before the first start's async Task can complete. + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + + await waitUntil { mock.startedParams.count >= 1 } + // Give any erroneous second start a chance to land before asserting. + try? await Task.sleep(nanoseconds: 50_000_000) + XCTAssertEqual(mock.startedParams.count, 1) + } + // MARK: - Helpers private func waitUntil(timeout: TimeInterval = 2, _ condition: () -> Bool) async { From 32d491504f2d40bb38698d8f7db3753fb7c91e95 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 06:58:47 -0300 Subject: [PATCH 28/52] refactor: implement core 0.3.2 wallet id derivation and adopt the redesigned watcher api with persistent-ready activity instead of HistoryTransaction --- Bitkit.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- Bitkit/Managers/HwWalletManager.swift | 139 ++++------- Bitkit/Models/HwWalletId.swift | 26 +- .../ViewModels/Trezor/TrezorViewModel.swift | 17 +- Bitkit/Views/Trezor/TrezorWatcherView.swift | 42 +++- BitkitTests/HwWalletIdTests.swift | 28 +-- BitkitTests/HwWalletManagerTests.swift | 223 ++++++------------ BitkitTests/TrezorViewModelWatcherTests.swift | 72 +++--- 9 files changed, 223 insertions(+), 330 deletions(-) diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index 503b87cce..9d20fc9c4 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -1201,7 +1201,7 @@ repositoryURL = "https://github.com/synonymdev/bitkit-core"; requirement = { kind = exactVersion; - version = 0.3.2; + version = 0.3.4; }; }; 96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = { diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3882def7e..f21c062d4 100644 --- a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/synonymdev/bitkit-core", "state" : { - "revision" : "d95a061cb0062e89fa0107743989c3dc62d8f1b1", - "version" : "0.3.2" + "revision" : "c098b41d961594ead9dfd474b8508e289f6be2de", + "version" : "0.3.4" } }, { diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 74e017b0d..ca32848e6 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -45,7 +45,6 @@ final class HwWalletManager { private let networkProvider: () -> TrezorCoinType private let persistActivities: ([Activity]) -> Void private let deleteActivities: (String) -> Void - private let nowProvider: () -> UInt64 // MARK: - Internal state @@ -63,18 +62,13 @@ final class HwWalletManager { private var emittedReceivedTxIds: Set = [] private var listeners: [String: TrezorEventListener] = [:] - /// First-seen wall-clock timestamp per unconfirmed txid, kept so a mempool tx stays at a - /// stable position in the (timestamp-sorted) activity list across watcher events. - private var assignedTimestamps: [String: UInt64] = [:] - init( watcherService: OnChainWatcherServicing = OnChainHwService.shared, monitoredTypes: (() -> Set)? = nil, electrumUrl: (() -> String)? = nil, network: (() -> TrezorCoinType)? = nil, persistActivities: (([Activity]) -> Void)? = nil, - deleteActivities: ((String) -> Void)? = nil, - now: (() -> UInt64)? = nil + deleteActivities: ((String) -> Void)? = nil ) { self.watcherService = watcherService networkProvider = network ?? { OnChainHwService.appDefaultCoinType } @@ -97,7 +91,6 @@ final class HwWalletManager { } } } - nowProvider = now ?? { UInt64(Date().timeIntervalSince1970) } } // MARK: - Device input @@ -138,7 +131,6 @@ final class HwWalletManager { emittedReceivedTxIds.removeAll() listeners.removeAll() watcherData.removeAll() - assignedTimestamps.removeAll() recomputeDerivedState() } @@ -164,9 +156,11 @@ final class HwWalletManager { var seen = Set() var specs: [WatcherSpec] = [] for device in knownDevices { + // Scope a device's watchers under its derived wallet id (skips devices without xpubs). + guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } for (addressType, xpub) in device.xpubs where monitored.contains(addressType) { guard seen.insert("\(addressType)\u{1}\(xpub)").inserted else { continue } - specs.append(WatcherSpec(deviceId: device.id, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) + specs.append(WatcherSpec(deviceId: device.id, walletId: walletId, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) } } let desiredIds = Set(specs.map(\.watcherId)) @@ -193,6 +187,7 @@ final class HwWalletManager { let network = networkProvider() let params = WatcherParams( watcherId: spec.watcherId, + walletId: spec.walletId, extendedKey: spec.xpub, electrumUrl: spec.electrumUrl, network: network.coreNetwork, @@ -248,29 +243,39 @@ final class HwWalletManager { /// Update aggregated state from a watcher event. The first event after a watcher starts /// delivers the full history (baseline); only later inbound txs are surfaced as received. + /// Core builds the persistence-ready activities (core 0.3.4 watch-only watcher); the manager + /// stores, aggregates, and scopes them to the device. func handleWatcherEvent(watcherId: String, event: WatcherEvent) { - guard case let .transactionsChanged(transactions, balance, _, _, _) = event else { return } + guard case let .transactionsChanged(activities, _, balance, _, _, _) = event else { return } let previous = watcherData[watcherId] watcherData[watcherId] = HwWatcherData( deviceId: deviceId(fromWatcherId: watcherId), balanceSats: balance.total, - transactions: transactions + activities: activities ) recomputeDerivedState() persistGroupActivities(forDevice: deviceId(fromWatcherId: watcherId)) - emitReceivedTxs(previous: previous, transactions: transactions) + emitReceivedTxs(previous: previous, activities: activities) } - private func emitReceivedTxs(previous: HwWatcherData?, transactions: [HistoryTransaction]) { + private func emitReceivedTxs(previous: HwWatcherData?, activities: [Activity]) { guard let previous else { return } - let knownTxIds = Set(previous.transactions.map(\.txid)) - for tx in transactions where tx.direction == .received { - guard !knownTxIds.contains(tx.txid) else { continue } - guard emittedReceivedTxIds.insert(tx.txid).inserted else { continue } - receivedTxPublisher.send(HwWalletReceivedTx(txid: tx.txid, sats: tx.amount)) + let knownTxIds = onchainTxIds(in: previous.activities) + for activity in activities { + guard case let .onchain(onchain) = activity, onchain.txType == .received else { continue } + guard !knownTxIds.contains(onchain.txId) else { continue } + guard emittedReceivedTxIds.insert(onchain.txId).inserted else { continue } + receivedTxPublisher.send(HwWalletReceivedTx(txid: onchain.txId, sats: onchain.value)) } } + private func onchainTxIds(in activities: [Activity]) -> Set { + Set(activities.compactMap { activity in + guard case let .onchain(onchain) = activity else { return nil } + return onchain.txId + }) + } + // MARK: - Persistence private func persistGroupActivities(forDevice deviceId: String) { @@ -278,29 +283,35 @@ final class HwWalletManager { persistActivities(mergedActivities(for: group)) } + /// Aggregate the activities core emitted across a device-group's watchers, scoping each to the + /// group's wallet id and deduping by activity id (so the same tx seen by two address-type + /// watchers persists once). private func mergedActivities(for group: DeviceGroup) -> [Activity] { let watchers = watcherData.values.filter { group.ids.contains($0.deviceId) } - let grouped = Dictionary(grouping: watchers.flatMap(\.transactions), by: \.txid) - return grouped.map { txid, transactions in - let timestamp = resolveTimestamp(txid: txid, transactions: transactions) - return onchainActivity(walletId: group.walletId, from: transactions, timestamp: timestamp) + var byId: [String: Activity] = [:] + for activity in watchers.flatMap(\.activities) { + let scoped = scopedToWallet(activity, walletId: group.walletId) + byId[activityId(of: scoped)] = scoped } + return Array(byId.values) } - /// Confirmed txs carry a block timestamp; mempool txs report `nil`. Falling back to `0` - /// would bury a fresh receive at the bottom of the timestamp-sorted activity list, so use - /// the first-seen wall-clock time instead and remember it per txid until the tx confirms. - private func resolveTimestamp(txid: String, transactions: [HistoryTransaction]) -> UInt64 { - if let confirmed = transactions.compactMap(\.timestamp).min() { - assignedTimestamps[txid] = nil - return confirmed + private func scopedToWallet(_ activity: Activity, walletId: String) -> Activity { + switch activity { + case var .onchain(onchain): + onchain.walletId = walletId + return .onchain(onchain) + case var .lightning(lightning): + lightning.walletId = walletId + return .lightning(lightning) } - if let assigned = assignedTimestamps[txid] { - return assigned + } + + private func activityId(of activity: Activity) -> String { + switch activity { + case let .onchain(onchain): return onchain.id + case let .lightning(lightning): return lightning.id } - let now = nowProvider() - assignedTimestamps[txid] = now - return now } // MARK: - Aggregation @@ -333,7 +344,7 @@ final class HwWalletManager { var order: [String] = [] var grouped: [String: [TrezorKnownDevice]] = [:] for device in knownDevices where !device.xpubs.isEmpty { - let walletId = HwWalletId.derive(xpubs: device.xpubs, fallbackId: device.id) + guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } if grouped[walletId] == nil { order.append(walletId) } grouped[walletId, default: []].append(device) } @@ -343,59 +354,6 @@ final class HwWalletManager { } } - private func onchainActivity(walletId: String, from transactions: [HistoryTransaction], timestamp: UInt64) -> Activity { - let first = transactions[0] - let received = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.received) } - let sent = transactions.reduce(UInt64(0)) { saturatingAdd($0, $1.sent) } - let fee = transactions.compactMap(\.fee).max() ?? 0 - - // Classify by core's TxDirection (core 0.3.x): received-vs-sent arithmetic alone cannot - // tell a self-transfer/consolidation apart from a normal send (both have sent > received, - // since sent == received + fee), so without this a consolidation would show value 0 - // instead of the fee paid. - let txType: PaymentType - let value: UInt64 - switch first.direction { - case .received: - txType = .received - value = received >= sent ? received - sent : 0 - case .sent: - txType = .sent - let net = sent >= received ? sent - received : 0 - value = net >= fee ? net - fee : 0 - case .selfTransfer: - txType = .sent - value = fee - } - let confirmations = transactions.map(\.confirmations).max() ?? 0 - let confirmed = confirmations > 0 - return .onchain( - OnchainActivity( - walletId: walletId, - id: first.txid, - txType: txType, - txId: first.txid, - value: value, - fee: fee, - feeRate: 1, - address: "", - confirmed: confirmed, - timestamp: timestamp, - isBoosted: false, - boostTxIds: [], - isTransfer: false, - doesExist: true, - confirmTimestamp: confirmed ? timestamp : nil, - channelId: nil, - transferTxId: nil, - contact: nil, - createdAt: timestamp, - updatedAt: timestamp, - seenAt: nil - ) - ) - } - // MARK: - Helpers /// The label is the user-set name stored on the device; without one (or with the factory @@ -420,6 +378,7 @@ final class HwWalletManager { private struct WatcherSpec { let deviceId: String + let walletId: String let addressType: String let xpub: String let electrumUrl: String @@ -445,6 +404,6 @@ final class HwWalletManager { private struct HwWatcherData { let deviceId: String let balanceSats: UInt64 - let transactions: [HistoryTransaction] + let activities: [Activity] } } diff --git a/Bitkit/Models/HwWalletId.swift b/Bitkit/Models/HwWalletId.swift index 40ffbd2d3..0f1c45cf8 100644 --- a/Bitkit/Models/HwWalletId.swift +++ b/Bitkit/Models/HwWalletId.swift @@ -1,24 +1,14 @@ -import CryptoKit +import BitkitCore import Foundation -/// Derives a stable, app-level wallet id for a paired hardware wallet, used to scope its -/// activities in bitkit-core's wallet-scoped storage (core 0.3.x). -/// -/// ⚠️ INTERIM / PROVISIONAL. bitkit-core does not derive this — it only ships the default -/// `"bitkit"` id (`getDefaultWalletId()`), and the Android app has not yet adopted -/// wallet-scoped hardware storage. The exact format MUST be agreed cross-platform before -/// release so iOS and Android produce identical ids for the same device. This is the single -/// source of the derivation: swap it here when the shared scheme is finalized. +/// Derives a stable, cross-platform wallet id for a paired hardware wallet, used to scope +/// its activities in bitkit-core's wallet-scoped storage. Delegates to bitkit-core's +/// `deriveWalletId` (the canonical cross-platform derivation, finalized in core 0.3.4) so +/// iOS and Android produce identical ids for the same device. enum HwWalletId { - private static let prefix = "trezor:" - /// Deterministic id derived from the device's account xpubs (transport-independent: the - /// same physical device paired over different transports shares its xpubs, hence its id). - /// Falls back to the device id when no xpubs were captured. - static func derive(xpubs: [String: String], fallbackId: String) -> String { - let sorted = xpubs.values.sorted() - guard !sorted.isEmpty else { return prefix + fallbackId } - let digest = SHA256.hash(data: Data(sorted.joined(separator: "\n").utf8)) - return prefix + Data(digest).hex + /// same physical device shares its xpubs, hence its id). Throws if `xpubs` is empty. + static func derive(xpubs: [String: String], deviceType: String = "trezor") throws -> String { + try deriveWalletId(deviceType: deviceType, xpubs: Array(xpubs.values)) } } diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index 80bcfe13c..ccc4251cd 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -245,8 +245,8 @@ class TrezorViewModel { /// Transaction count reported by the watcher var watcherTransactionCount: UInt32 = 0 - /// Latest transactions reported by the watcher - var watcherTransactions: [HistoryTransaction] = [] + /// Latest activities reported by the watcher (core builds these in 0.3.4). + var watcherActivities: [Activity] = [] /// Rolling event log (most recent last, capped) var watcherEvents: [String] = [] @@ -1059,8 +1059,11 @@ class TrezorViewModel { let network = connection.selectedNetwork let accountType = onchainAccountTypeSelection.accountType + // Dev watcher: scope its emitted activities under an id derived from the watched key. + let walletId = (try? HwWalletId.derive(xpubs: ["watcher": key])) ?? "trezor:watcher" let params = WatcherParams( watcherId: watcherId, + walletId: walletId, extendedKey: key, electrumUrl: OnChainHwService.electrumUrlForNetwork(network), network: network.coreNetwork, @@ -1076,7 +1079,7 @@ class TrezorViewModel { isStartingWatcher = true startingWatcherId = watcherId watcherConnectionStatus = .starting - watcherTransactions = [] + watcherActivities = [] watcherEvents = ["starting: \(watcherId)"] watcherBalance = nil watcherTransactionCount = 0 @@ -1162,7 +1165,7 @@ class TrezorViewModel { watcherConnectionStatus = .idle watcherListener = nil watcherBalance = nil - watcherTransactions = [] + watcherActivities = [] watcherTransactionCount = 0 watcherBlockHeight = 0 watcherAccountType = nil @@ -1213,10 +1216,10 @@ class TrezorViewModel { guard watcherId == activeWatcherId || watcherId == startingWatcherId else { return } switch event { - case let .transactionsChanged(transactions, balance, txCount, blockHeight, accountType): + case let .transactionsChanged(activities, _, balance, txCount, blockHeight, accountType): watcherConnectionStatus = .connected watcherError = nil - watcherTransactions = transactions + watcherActivities = activities watcherBalance = balance watcherTransactionCount = txCount watcherBlockHeight = blockHeight @@ -1270,7 +1273,7 @@ class TrezorViewModel { watcherConnectionStatus = .idle watcherListener = nil watcherBalance = nil - watcherTransactions = [] + watcherActivities = [] watcherTransactionCount = 0 watcherBlockHeight = 0 watcherAccountType = nil diff --git a/Bitkit/Views/Trezor/TrezorWatcherView.swift b/Bitkit/Views/Trezor/TrezorWatcherView.swift index bac2a939c..b35a9ba13 100644 --- a/Bitkit/Views/Trezor/TrezorWatcherView.swift +++ b/Bitkit/Views/Trezor/TrezorWatcherView.swift @@ -139,12 +139,12 @@ private struct WatcherStatusView: View { } // Transactions - if !trezor.watcherTransactions.isEmpty { - CaptionMText("Transactions (\(trezor.watcherTransactions.count))") + if !trezor.watcherActivities.isEmpty { + CaptionMText("Transactions (\(trezor.watcherActivities.count))") VStack(spacing: 4) { - ForEach(trezor.watcherTransactions, id: \.txid) { tx in - WatcherTransactionRow(tx: tx) + ForEach(trezor.watcherActivities, id: \.watcherRowId) { activity in + WatcherActivityRow(activity: activity) } } } @@ -181,33 +181,39 @@ private struct WatcherStatusView: View { } } -private struct WatcherTransactionRow: View { - let tx: HistoryTransaction +private struct WatcherActivityRow: View { + let activity: Activity + + private var onchain: OnchainActivity? { + guard case let .onchain(onchain) = activity else { return nil } + return onchain + } private var directionLabel: String { - switch tx.direction { + switch onchain?.txType { case .sent: return "Sent" case .received: return "Recv" - case .selfTransfer: return "Self" + case .none: return "-" } } private var directionColor: Color { - switch tx.direction { + switch onchain?.txType { case .sent: return .redAccent case .received: return .greenAccent - case .selfTransfer: return .white64 + case .none: return .white64 } } private var shortTxid: String { - guard tx.txid.count > 16 else { return tx.txid } - return "\(tx.txid.prefix(8))...\(tx.txid.suffix(8))" + let txid = onchain?.txId ?? "" + guard txid.count > 16 else { return txid } + return "\(txid.prefix(8))...\(txid.suffix(8))" } var body: some View { HStack { - CaptionText("\(directionLabel) \(tx.amount) sats", textColor: directionColor) + CaptionText("\(directionLabel) \(onchain?.value ?? 0) sats", textColor: directionColor) Spacer() Text(shortTxid) .font(.system(size: 12, design: .monospaced)) @@ -217,6 +223,16 @@ private struct WatcherTransactionRow: View { } } +private extension Activity { + /// Stable identifier for list rendering. + var watcherRowId: String { + switch self { + case let .onchain(onchain): return onchain.id + case let .lightning(lightning): return lightning.id + } + } +} + private struct InfoRow: View { let label: String let value: String diff --git a/BitkitTests/HwWalletIdTests.swift b/BitkitTests/HwWalletIdTests.swift index 7a9242bba..2ba2632ec 100644 --- a/BitkitTests/HwWalletIdTests.swift +++ b/BitkitTests/HwWalletIdTests.swift @@ -2,29 +2,29 @@ import XCTest final class HwWalletIdTests: XCTestCase { - func testDeterministicForSameXpubs() { - let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "x") - let b = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "y") - XCTAssertEqual(a, b, "id derives from xpubs, independent of the fallback id") + func testDeterministicForSameXpubs() throws { + let a = try HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + let b = try HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + XCTAssertEqual(a, b, "id derives deterministically from xpubs") } - func testOrderIndependent() { - let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"], fallbackId: "x") - let b = HwWalletId.derive(xpubs: ["taproot": "zTR", "nativeSegwit": "zNS"], fallbackId: "x") + func testOrderIndependent() throws { + let a = try HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + let b = try HwWalletId.derive(xpubs: ["taproot": "zTR", "nativeSegwit": "zNS"]) XCTAssertEqual(a, b, "values are sorted before hashing") } - func testDifferentXpubsProduceDifferentIds() { - let a = HwWalletId.derive(xpubs: ["nativeSegwit": "zNS"], fallbackId: "x") - let b = HwWalletId.derive(xpubs: ["nativeSegwit": "DIFFERENT"], fallbackId: "x") + func testDifferentXpubsProduceDifferentIds() throws { + let a = try HwWalletId.derive(xpubs: ["nativeSegwit": "zNS"]) + let b = try HwWalletId.derive(xpubs: ["nativeSegwit": "DIFFERENT"]) XCTAssertNotEqual(a, b) } - func testPrefix() { - XCTAssertTrue(HwWalletId.derive(xpubs: ["nativeSegwit": "z"], fallbackId: "x").hasPrefix("trezor:")) + func testPrefix() throws { + XCTAssertTrue(try HwWalletId.derive(xpubs: ["nativeSegwit": "z"]).hasPrefix("trezor:")) } - func testFallsBackToDeviceIdWhenNoXpubs() { - XCTAssertEqual(HwWalletId.derive(xpubs: [:], fallbackId: "device-123"), "trezor:device-123") + func testThrowsWhenNoXpubs() { + XCTAssertThrowsError(try HwWalletId.derive(xpubs: [:])) } } diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index f097a3309..b3535aed7 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -46,8 +46,7 @@ final class HwWalletManagerTests: XCTestCase { private func makeViewModel( watcherService: OnChainWatcherServicing = MockWatcherService(), - monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"], - now: @escaping () -> UInt64 = { 1_700_000_000 } + monitored: Set = ["legacy", "nestedSegwit", "nativeSegwit", "taproot"] ) -> HwWalletManager { let vm = HwWalletManager( watcherService: watcherService, @@ -55,8 +54,7 @@ final class HwWalletManagerTests: XCTestCase { electrumUrl: { "ssl://test:1" }, network: { .regtest }, persistActivities: { [weak self] in self?.persisted.append($0) }, - deleteActivities: { [weak self] in self?.deleted.append($0) }, - now: now + deleteActivities: { [weak self] in self?.deleted.append($0) } ) vm.receivedTxPublisher .sink { [weak self] in self?.receivedTxs.append($0) } @@ -83,36 +81,51 @@ final class HwWalletManagerTests: XCTestCase { ) } - private func makeTx( - txid: String, - received: UInt64, - sent: UInt64, - fee: UInt64? = nil, - direction: TxDirection, - confirmations: UInt32 = 1, - timestamp: UInt64? = 1_700_000_000 - ) -> HistoryTransaction { - let amount: UInt64 = direction == .received ? received : (sent >= received ? sent - received : 0) - return HistoryTransaction( - txid: txid, - received: received, - sent: sent, - net: Int64(received) - Int64(sent), - fee: fee, - amount: amount, - direction: direction, - blockHeight: confirmations > 0 ? 100 : nil, - timestamp: timestamp, - confirmations: confirmations - ) + /// Build a persistence-ready onchain activity, mirroring what core's watch-only watcher + /// emits in 0.3.4. `walletId` defaults to empty because the manager re-scopes activities to + /// the device's derived wallet id before persisting. + private func makeActivity( + txId: String, + value: UInt64, + txType: PaymentType, + walletId: String = "" + ) -> Activity { + .onchain(OnchainActivity( + walletId: walletId, + id: txId, + txType: txType, + txId: txId, + value: value, + fee: 0, + feeRate: 1, + address: "", + confirmed: true, + timestamp: 1_700_000_000, + isBoosted: false, + boostTxIds: [], + isTransfer: false, + doesExist: true, + confirmTimestamp: 1_700_000_000, + channelId: nil, + transferTxId: nil, + contact: nil, + createdAt: 1_700_000_000, + updatedAt: 1_700_000_000, + seenAt: nil + )) } - private func makeEvent(_ transactions: [HistoryTransaction], total: UInt64) -> WatcherEvent { + private func makeEvent(_ activities: [Activity], total: UInt64) -> WatcherEvent { let balance = WalletBalance( confirmed: total, immature: 0, trustedPending: 0, untrustedPending: 0, spendable: total, total: total ) return .transactionsChanged( - transactions: transactions, balance: balance, txCount: UInt32(transactions.count), blockHeight: 100, accountType: .nativeSegwit + activities: activities, + transactionDetails: [], + balance: balance, + txCount: UInt32(activities.count), + blockHeight: 100, + accountType: .nativeSegwit ) } @@ -122,14 +135,14 @@ final class HwWalletManagerTests: XCTestCase { // MARK: - Tests - func testPairedDeviceProducesWalletWithBalanceAndWalletId() { + func testPairedDeviceProducesWalletWithBalanceAndWalletId() throws { let xpubs = ["nativeSegwit": "zpubNS"] let device = makeDevice(id: "dev1", xpubs: xpubs, model: "Safe 5") let vm = makeViewModel() vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "tx1", received: 50000, sent: 0, direction: .received)], total: 50000 + [makeActivity(txId: "tx1", value: 50000, txType: .received)], total: 50000 )) XCTAssertEqual(vm.wallets.count, 1) @@ -139,7 +152,7 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(wallet.name, "Trezor Safe 5") XCTAssertTrue(wallet.isConnected) XCTAssertEqual(vm.totalSats, 50000) - XCTAssertEqual(wallet.walletId, HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1")) + XCTAssertEqual(wallet.walletId, try HwWalletId.derive(xpubs: xpubs)) XCTAssertEqual(vm.hwWalletIds, [wallet.walletId]) } @@ -149,10 +162,10 @@ final class HwWalletManagerTests: XCTestCase { vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "txNS", received: 30000, sent: 0, direction: .received)], total: 30000 + [makeActivity(txId: "txNS", value: 30000, txType: .received)], total: 30000 )) vm.handleWatcherEvent(watcherId: watcherId("dev1", "taproot"), event: makeEvent( - [makeTx(txid: "txTR", received: 20000, sent: 0, direction: .received)], total: 20000 + [makeActivity(txId: "txTR", value: 20000, txType: .received)], total: 20000 )) XCTAssertEqual(vm.wallets.count, 1) @@ -169,7 +182,7 @@ final class HwWalletManagerTests: XCTestCase { vm.updateDevices(knownDevices: [ble, usb], connectedDeviceId: nil) vm.handleWatcherEvent(watcherId: watcherId("ble1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "tx1", received: 70000, sent: 0, direction: .received)], total: 70000 + [makeActivity(txId: "tx1", value: 70000, txType: .received)], total: 70000 )) XCTAssertEqual(vm.wallets.count, 1) @@ -179,17 +192,18 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(vm.hwWalletIds.count, 1) } - func testActivityPersistedWithDeviceWalletId() { + func testActivityPersistedWithDeviceWalletId() throws { let xpubs = ["nativeSegwit": "zpubNS"] let device = makeDevice(id: "dev1", xpubs: xpubs) let vm = makeViewModel() vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "txABC", received: 40000, sent: 0, direction: .received)], total: 40000 + [makeActivity(txId: "txABC", value: 40000, txType: .received)], total: 40000 )) - let expectedWalletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + // The manager re-scopes core's emitted activity to the device's derived wallet id. + let expectedWalletId = try HwWalletId.derive(xpubs: xpubs) XCTAssertEqual(persisted.count, 1) let activities = persisted[0] XCTAssertEqual(activities.count, 1) @@ -208,15 +222,15 @@ final class HwWalletManagerTests: XCTestCase { // Baseline (first event) — must NOT emit, even for received txs. vm.handleWatcherEvent(watcherId: wid, event: makeEvent( - [makeTx(txid: "old", received: 10000, sent: 0, direction: .received)], total: 10000 + [makeActivity(txId: "old", value: 10000, txType: .received)], total: 10000 )) XCTAssertTrue(receivedTxs.isEmpty) // New inbound tx after baseline — emits once. vm.handleWatcherEvent(watcherId: wid, event: makeEvent( [ - makeTx(txid: "old", received: 10000, sent: 0, direction: .received), - makeTx(txid: "new", received: 25000, sent: 0, direction: .received), + makeActivity(txId: "old", value: 10000, txType: .received), + makeActivity(txId: "new", value: 25000, txType: .received), ], total: 35000 )) XCTAssertEqual(receivedTxs.map(\.txid), ["new"]) @@ -225,9 +239,9 @@ final class HwWalletManagerTests: XCTestCase { // Outbound tx is ignored, and the same inbound is not re-emitted. vm.handleWatcherEvent(watcherId: wid, event: makeEvent( [ - makeTx(txid: "old", received: 10000, sent: 0, direction: .received), - makeTx(txid: "new", received: 25000, sent: 0, direction: .received), - makeTx(txid: "spend", received: 0, sent: 5000, fee: 200, direction: .sent), + makeActivity(txId: "old", value: 10000, txType: .received), + makeActivity(txId: "new", value: 25000, txType: .received), + makeActivity(txId: "spend", value: 5000, txType: .sent), ], total: 30000 )) XCTAssertEqual(receivedTxs.map(\.txid), ["new"]) @@ -244,16 +258,16 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(mock.startedParams.first?.watcherId, watcherId("dev1", "nativeSegwit")) } - func testResetStateDeletesStoredActivitiesAndClears() { + func testResetStateDeletesStoredActivitiesAndClears() throws { let xpubs = ["nativeSegwit": "zpubNS"] let device = makeDevice(id: "dev1", xpubs: xpubs) let vm = makeViewModel() vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "tx1", received: 40000, sent: 0, direction: .received)], total: 40000 + [makeActivity(txId: "tx1", value: 40000, txType: .received)], total: 40000 )) - let walletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + let walletId = try HwWalletId.derive(xpubs: xpubs) vm.resetState() XCTAssertEqual(deleted, [walletId]) @@ -316,37 +330,25 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(vm.wallets.first?.name, "Trezor") } - func testMergesDuplicateTxAcrossAddressTypes() { + /// The same tx seen by two address-type watchers persists once (deduped by activity id). + /// Value composition is core's job now (core 0.3.4 watch-only watcher), so this only checks + /// dedup, not summing. + func testDuplicateTxAcrossAddressTypesPersistsOnce() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) let vm = makeViewModel() vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - // Same txid reported by two address-type watchers — merged into one activity, amounts summed. vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "shared", received: 30000, sent: 0, direction: .received)], total: 30000 + [makeActivity(txId: "shared", value: 30000, txType: .received)], total: 30000 )) vm.handleWatcherEvent(watcherId: watcherId("dev1", "taproot"), event: makeEvent( - [makeTx(txid: "shared", received: 20000, sent: 0, direction: .received)], total: 20000 + [makeActivity(txId: "shared", value: 30000, txType: .received)], total: 30000 )) let lastPersisted = persisted.last ?? [] XCTAssertEqual(lastPersisted.count, 1) guard case let .onchain(onchain) = lastPersisted[0] else { return XCTFail("expected onchain") } XCTAssertEqual(onchain.txId, "shared") - XCTAssertEqual(onchain.value, 50000) - } - - func testSentTxValueExcludesFee() { - let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) - let vm = makeViewModel() - vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "spend", received: 0, sent: 20000, fee: 500, direction: .sent)], total: 0 - )) - guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } - XCTAssertEqual(onchain.txType, .sent) - XCTAssertEqual(onchain.value, 19500) // sent - received - fee - XCTAssertEqual(onchain.fee, 500) } func testWatcherStartedOnConfiguredElectrumAndNetwork() async { @@ -375,7 +377,7 @@ final class HwWalletManagerTests: XCTestCase { vm.handleWatcherEvent(watcherId: tr, event: makeEvent([], total: 0)) // Both watchers report the same new inbound tx — emit only once. - let tx = makeTx(txid: "new", received: 10000, sent: 0, direction: .received) + let tx = makeActivity(txId: "new", value: 10000, txType: .received) vm.handleWatcherEvent(watcherId: ns, event: makeEvent([tx], total: 10000)) vm.handleWatcherEvent(watcherId: tr, event: makeEvent([tx], total: 10000)) @@ -403,10 +405,10 @@ final class HwWalletManagerTests: XCTestCase { // Per-device balance comes from the watcher's reported total; d1 maxes it out. vm.handleWatcherEvent(watcherId: watcherId("d1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: .max + [makeActivity(txId: "t1", value: 1000, txType: .received)], total: .max )) vm.handleWatcherEvent(watcherId: watcherId("d2", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "t2", received: 1000, sent: 0, direction: .received)], total: 1000 + [makeActivity(txId: "t2", value: 1000, txType: .received)], total: 1000 )) XCTAssertEqual(vm.totalSats, .max) @@ -420,7 +422,7 @@ final class HwWalletManagerTests: XCTestCase { await waitUntil { mock.startedParams.count == 1 } vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "t1", received: 40000, sent: 0, direction: .received)], total: 40000 + [makeActivity(txId: "t1", value: 40000, txType: .received)], total: 40000 )) XCTAssertEqual(vm.wallets.first?.balanceSats, 40000) @@ -435,7 +437,7 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertTrue(vm.wallets.isEmpty) } - func testRemoveDeviceStopsWatchersAndDeletesActivities() async { + func testRemoveDeviceStopsWatchersAndDeletesActivities() async throws { let mock = MockWatcherService() let xpubs = ["nativeSegwit": "z"] let device = makeDevice(id: "dev1", xpubs: xpubs) @@ -443,89 +445,18 @@ final class HwWalletManagerTests: XCTestCase { vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) await waitUntil { mock.startedParams.count == 1 } vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: 1000 + [makeActivity(txId: "t1", value: 1000, txType: .received)], total: 1000 )) vm.removeDevice(id: "dev1") XCTAssertTrue(mock.stoppedWatcherIds.contains(watcherId("dev1", "nativeSegwit"))) - XCTAssertEqual(deleted, [HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1")]) - } - - // MARK: - Fix 4: unconfirmed timestamp - - func testUnconfirmedTxUsesNowTimestampNotZero() { - let fixedNow: UInt64 = 1_650_000_000 - let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) - let vm = makeViewModel(now: { fixedNow }) - vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - - vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 - )) - - guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } - XCTAssertEqual(onchain.timestamp, fixedNow) - XCTAssertEqual(onchain.createdAt, fixedNow) - XCTAssertFalse(onchain.confirmed) - } - - func testUnconfirmedTxTimestampStableAcrossEvents() { - var nowValue: UInt64 = 1_650_000_000 - let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) - let vm = makeViewModel(now: { nowValue }) - vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - let wid = watcherId("dev1", "nativeSegwit") - - vm.handleWatcherEvent(watcherId: wid, event: makeEvent( - [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 - )) - - // Clock advances, but a later event for the still-unconfirmed tx must keep the first timestamp. - nowValue = 1_650_009_999 - vm.handleWatcherEvent(watcherId: wid, event: makeEvent( - [makeTx(txid: "mempool", received: 5000, sent: 0, direction: .received, confirmations: 0, timestamp: nil)], total: 5000 - )) - - guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } - XCTAssertEqual(onchain.timestamp, 1_650_000_000) - } - - func testConfirmedTxUsesBlockTimestamp() { - let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) - let vm = makeViewModel(now: { 1_650_000_000 }) - vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - - vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "confirmed", received: 5000, sent: 0, direction: .received, confirmations: 3, timestamp: 1_699_999_000)], total: 5000 - )) - - guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } - XCTAssertEqual(onchain.timestamp, 1_699_999_000) - XCTAssertTrue(onchain.confirmed) - } - - // MARK: - Fix 5: self-transfer value - - func testSelfTransferValueIsFee() { - let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) - let vm = makeViewModel() - vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) - - // Consolidation: everything comes back to the wallet minus the fee (sent == received + fee). - vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "consolidate", received: 19500, sent: 20000, fee: 500, direction: .selfTransfer)], total: 19500 - )) - - guard case let .onchain(onchain) = (persisted.last ?? [])[0] else { return XCTFail("expected onchain") } - XCTAssertEqual(onchain.txType, .sent) - XCTAssertEqual(onchain.value, 500) // the fee paid, not 0 - XCTAssertEqual(onchain.fee, 500) + XCTAssertEqual(deleted, try [HwWalletId.derive(xpubs: xpubs)]) } - // MARK: - Fix 6: forget device deletes activities + // MARK: - Forget device deletes activities - func testForgettingDeviceViaUpdateDeletesActivities() async { + func testForgettingDeviceViaUpdateDeletesActivities() async throws { let mock = MockWatcherService() let xpubs = ["nativeSegwit": "z"] let device = makeDevice(id: "dev1", xpubs: xpubs) @@ -533,9 +464,9 @@ final class HwWalletManagerTests: XCTestCase { vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) await waitUntil { mock.startedParams.count == 1 } vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeTx(txid: "t1", received: 1000, sent: 0, direction: .received)], total: 1000 + [makeActivity(txId: "t1", value: 1000, txType: .received)], total: 1000 )) - let walletId = HwWalletId.derive(xpubs: xpubs, fallbackId: "dev1") + let walletId = try HwWalletId.derive(xpubs: xpubs) // Device forgotten → the next snapshot no longer includes it. vm.updateDevices(knownDevices: [], connectedDeviceId: nil) diff --git a/BitkitTests/TrezorViewModelWatcherTests.swift b/BitkitTests/TrezorViewModelWatcherTests.swift index 7b23d35f0..cd66a15fa 100644 --- a/BitkitTests/TrezorViewModelWatcherTests.swift +++ b/BitkitTests/TrezorViewModelWatcherTests.swift @@ -77,48 +77,42 @@ final class TrezorViewModelWatcherTests: XCTestCase { total: 156_000 ) - private static let sampleTransactions: [HistoryTransaction] = [ - HistoryTransaction( - txid: "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", - received: 50000, - sent: 0, - net: 50000, - fee: nil, - amount: 50000, - direction: .received, - blockHeight: 849_990, + private static func onchainActivity(txId: String, value: UInt64, txType: PaymentType) -> Activity { + .onchain(OnchainActivity( + walletId: "trezor:watcher", + id: txId, + txType: txType, + txId: txId, + value: value, + fee: 0, + feeRate: 1, + address: "", + confirmed: true, timestamp: 1_700_000_000, - confirmations: 11 - ), - HistoryTransaction( - txid: "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", - received: 0, - sent: 20000, - net: -20000, - fee: 500, - amount: 19500, - direction: .sent, - blockHeight: 849_995, - timestamp: 1_700_001_000, - confirmations: 6 - ), - HistoryTransaction( - txid: "6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516", - received: 10000, - sent: 10500, - net: -500, - fee: 500, - amount: 500, - direction: .selfTransfer, - blockHeight: nil, - timestamp: nil, - confirmations: 0 - ), + isBoosted: false, + boostTxIds: [], + isTransfer: false, + doesExist: true, + confirmTimestamp: 1_700_000_000, + channelId: nil, + transferTxId: nil, + contact: nil, + createdAt: 1_700_000_000, + updatedAt: 1_700_000_000, + seenAt: nil + )) + } + + private static let sampleActivities: [Activity] = [ + onchainActivity(txId: "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", value: 50000, txType: .received), + onchainActivity(txId: "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", value: 19500, txType: .sent), + onchainActivity(txId: "6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516", value: 500, txType: .sent), ] private static func sampleTransactionsChangedEvent() -> WatcherEvent { .transactionsChanged( - transactions: sampleTransactions, + activities: sampleActivities, + transactionDetails: [], balance: sampleBalance, txCount: 3, blockHeight: 850_000, @@ -274,7 +268,7 @@ final class TrezorViewModelWatcherTests: XCTestCase { XCTAssertNil(viewModel.activeWatcherId) XCTAssertEqual(viewModel.watcherConnectionStatus, .idle) XCTAssertNil(viewModel.watcherBalance) - XCTAssertTrue(viewModel.watcherTransactions.isEmpty) + XCTAssertTrue(viewModel.watcherActivities.isEmpty) } /// iOS-specific: stopping while the native start call is still in flight @@ -302,7 +296,7 @@ final class TrezorViewModelWatcherTests: XCTestCase { await waitUntil(timeout: 0.2) { viewModel.watcherBalance != nil } XCTAssertNil(viewModel.watcherBalance) - XCTAssertTrue(viewModel.watcherTransactions.isEmpty) + XCTAssertTrue(viewModel.watcherActivities.isEmpty) XCTAssertEqual(viewModel.watcherConnectionStatus, .idle) // The held native call returning success must not activate the watcher. From 57292793948537ed12a130ba5dc4c471bc80c8db Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 07:48:58 -0300 Subject: [PATCH 29/52] fix: trigger activitiesChangedSubject after persist and delet HW activities --- Bitkit/Managers/HwWalletManager.swift | 2 ++ Bitkit/Services/CoreService.swift | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index ca32848e6..bad2adbbf 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -81,6 +81,7 @@ final class HwWalletManager { Task { try? await ServiceQueue.background(.core) { try BitkitCore.upsertActivities(activities: activities) + CoreService.shared.activity.notifyActivitiesChanged() } } } @@ -88,6 +89,7 @@ final class HwWalletManager { Task { try? await ServiceQueue.background(.core) { _ = try BitkitCore.deleteActivitiesByWalletId(walletId: walletId) + CoreService.shared.activity.notifyActivitiesChanged() } } } diff --git a/Bitkit/Services/CoreService.swift b/Bitkit/Services/CoreService.swift index bf8bbb677..6cb6e9994 100644 --- a/Bitkit/Services/CoreService.swift +++ b/Bitkit/Services/CoreService.swift @@ -42,6 +42,12 @@ class ActivityService { activitiesChangedSubject.eraseToAnyPublisher() } + /// Notify observers that activities changed after a write made directly through BitkitCore + /// (bypassing this service), e.g. hardware-wallet watcher persistence. + func notifyActivitiesChanged() { + activitiesChangedSubject.send() + } + private let metadataChangedSubject = PassthroughSubject() var metadataChangedPublisher: AnyPublisher { @@ -370,6 +376,7 @@ class ActivityService { try await ServiceQueue.background(.core) { try upsertActivities(activities: activities) await self.refreshBoostTxIdsCache() + self.activitiesChangedSubject.send() } } From 6dc21048bfc7970e28d36896969f5ff8df56ca25 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 07:53:46 -0300 Subject: [PATCH 30/52] fix: guard reconnect under connectedDevice --- Bitkit/Managers/TrezorManager.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index 0ca4c421c..e878da40d 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -481,6 +481,10 @@ final class TrezorManager { func autoReconnect() async { guard !knownDevices.isEmpty else { return } guard !isAutoReconnecting else { return } + guard connectedDevice == nil else { + trezorLog("Auto-reconnect: skipped, device already connected") + return + } if suppressNextAutoReconnect { suppressNextAutoReconnect = false trezorLog("Auto-reconnect: skipped after manual disconnect") From a8c451ec70923f56eab63a8e82881fb7a68975d6 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:03:09 -0300 Subject: [PATCH 31/52] fix: protect headlineSats from overflow --- Bitkit/Views/Home/HomeWalletView.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Bitkit/Views/Home/HomeWalletView.swift b/Bitkit/Views/Home/HomeWalletView.swift index 149de8811..990f8f5ee 100644 --- a/Bitkit/Views/Home/HomeWalletView.swift +++ b/Bitkit/Views/Home/HomeWalletView.swift @@ -14,7 +14,9 @@ struct HomeWalletView: View { /// Headline total including watch-only hardware-wallet balances (keeps `totalBalanceSats` /// semantics unchanged for send/transfer logic; only the headline folds hardware in). private var headlineSats: Int { - wallet.totalBalanceSats + Int(clamping: hwWalletManager.totalSats) + let hw = Int(clamping: hwWalletManager.totalSats) + let (result, overflow) = wallet.totalBalanceSats.addingReportingOverflow(hw) + return overflow ? .max : result } var body: some View { From a26a474826ef65ab92de14f9eff2e9ca296bf957 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:06:45 -0300 Subject: [PATCH 32/52] refactor: remove unused method --- Bitkit/Managers/HwWalletManager.swift | 17 ----------------- BitkitTests/HwWalletManagerTests.swift | 16 ---------------- 2 files changed, 33 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index bad2adbbf..9e2947255 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -119,23 +119,6 @@ final class HwWalletManager { // MARK: - Control - func resetState() { - for watcherId in activeWatchers { - try? watcherService.stopWatcher(watcherId: watcherId) - } - for walletId in hwWalletIds { - deleteActivities(walletId) - } - activeWatchers.removeAll() - activeWatcherElectrumUrls.removeAll() - retryingWatcherStarts.removeAll() - pendingWatcherStarts.removeAll() - emittedReceivedTxIds.removeAll() - listeners.removeAll() - watcherData.removeAll() - recomputeDerivedState() - } - /// Stop watching a paired hardware wallet and delete its stored activities. The caller is /// responsible for forgetting the device entries (via `TrezorManager.forgetDevice`); the next /// `updateDevices(...)` push then drops it from the tile list. diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index b3535aed7..aa7726e70 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -258,22 +258,6 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(mock.startedParams.first?.watcherId, watcherId("dev1", "nativeSegwit")) } - func testResetStateDeletesStoredActivitiesAndClears() throws { - let xpubs = ["nativeSegwit": "zpubNS"] - let device = makeDevice(id: "dev1", xpubs: xpubs) - let vm = makeViewModel() - vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") - vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( - [makeActivity(txId: "tx1", value: 40000, txType: .received)], total: 40000 - )) - - let walletId = try HwWalletId.derive(xpubs: xpubs) - vm.resetState() - - XCTAssertEqual(deleted, [walletId]) - XCTAssertEqual(vm.totalSats, 0) - } - func testZeroBalanceBeforeAnyWatcherEvent() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) let vm = makeViewModel() From a3a67c6154067be68fb4696247565b79a2e8a671 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:15:34 -0300 Subject: [PATCH 33/52] fix: stop only dahboard watcher on dashboard dismiss --- .../ViewModels/Trezor/TrezorViewModel.swift | 17 +++++------- BitkitTests/TrezorViewModelWatcherTests.swift | 26 ++++--------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index ccc4251cd..b8e4e580d 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -1174,18 +1174,13 @@ class TrezorViewModel { trezorLog("Watcher stopped: \(watcherId)") } - /// Tear down all watchers when the Trezor dashboard is dismissed. On Android this - /// happens in the ViewModel's onCleared, but this ViewModel is app-lifetime, so the - /// root view calls it from onDisappear. - func stopAllWatchers() { - stopWatcher() - watcherService.stopAllWatchers() - } - - /// Full teardown when the Trezor dashboard is dismissed: stop all watchers and - /// reset the watcher input state so the next visit starts fresh. + /// Full teardown when the Trezor dashboard is dismissed: stop only this dashboard's dev + /// watcher and reset the watcher input state so the next visit starts fresh. The global + /// `watcherService.stopAllWatchers()` is intentionally NOT called here — production + /// hardware watchers owned by `HwWalletManager` share the same service and must stay live; + /// the global stop is reserved for app reset/wipe (`AppReset`). func handleDashboardDismiss() { - stopAllWatchers() + stopWatcher() watcherExtendedKey = "" watcherGapLimit = "20" onchainAccountTypeSelection = .automatic diff --git a/BitkitTests/TrezorViewModelWatcherTests.swift b/BitkitTests/TrezorViewModelWatcherTests.swift index cd66a15fa..35b80e813 100644 --- a/BitkitTests/TrezorViewModelWatcherTests.swift +++ b/BitkitTests/TrezorViewModelWatcherTests.swift @@ -308,27 +308,11 @@ final class TrezorViewModelWatcherTests: XCTestCase { XCTAssertEqual(viewModel.watcherConnectionStatus, .idle) } - /// iOS-specific: the root view calls stopAllWatchers from onDisappear since the - /// ViewModel is app-lifetime (no onCleared equivalent). + /// iOS-specific: dashboard dismissal stops only this dashboard's dev watcher and resets + /// the watcher input fields. It must NOT call the global stop, since production hardware + /// watchers owned by HwWalletManager share the same service and have to stay live. @MainActor - func testStopAllWatchersStopsActiveWatcherAndService() async throws { - let service = MockWatcherService() - let viewModel = makeViewModel(service: service) - - await viewModel.startWatcher() - let watcherId = try XCTUnwrap(viewModel.activeWatcherId) - - viewModel.stopAllWatchers() - - XCTAssertEqual(service.stoppedWatcherIds, [watcherId]) - XCTAssertEqual(service.stopAllWatchersCallCount, 1) - XCTAssertNil(viewModel.activeWatcherId) - XCTAssertEqual(viewModel.watcherConnectionStatus, .idle) - } - - /// iOS-specific: dashboard dismissal also resets the watcher input fields. - @MainActor - func testHandleDashboardDismissStopsWatchersAndClearsInputState() async throws { + func testHandleDashboardDismissStopsDevWatcherAndClearsInputState() async throws { let service = MockWatcherService() let viewModel = makeViewModel(service: service) viewModel.watcherGapLimit = "30" @@ -340,7 +324,7 @@ final class TrezorViewModelWatcherTests: XCTestCase { viewModel.handleDashboardDismiss() XCTAssertEqual(service.stoppedWatcherIds, [watcherId]) - XCTAssertEqual(service.stopAllWatchersCallCount, 1) + XCTAssertEqual(service.stopAllWatchersCallCount, 0) XCTAssertNil(viewModel.activeWatcherId) XCTAssertEqual(viewModel.watcherExtendedKey, "") XCTAssertEqual(viewModel.watcherGapLimit, "20") From 8685359e2e71dcdc4ff98f63c093294017e6db5f Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:39:28 -0300 Subject: [PATCH 34/52] fix: re-check watcher ids after the async watcher start --- Bitkit/Managers/HwWalletManager.swift | 52 +++++++++++++++++------ BitkitTests/HwWalletManagerTests.swift | 58 ++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 9e2947255..3f9a2b03c 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -135,19 +135,7 @@ final class HwWalletManager { // MARK: - Watcher orchestration func syncWatchers() { - let monitored = monitoredTypesProvider() - let electrumUrl = electrumUrlProvider() - - var seen = Set() - var specs: [WatcherSpec] = [] - for device in knownDevices { - // Scope a device's watchers under its derived wallet id (skips devices without xpubs). - guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } - for (addressType, xpub) in device.xpubs where monitored.contains(addressType) { - guard seen.insert("\(addressType)\u{1}\(xpub)").inserted else { continue } - specs.append(WatcherSpec(deviceId: device.id, walletId: walletId, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) - } - } + let specs = desiredWatcherSpecs() let desiredIds = Set(specs.map(\.watcherId)) for spec in specs { @@ -167,6 +155,35 @@ final class HwWalletManager { } } + /// Build the watcher specs the current device/settings snapshot wants running: one per + /// (device, monitored address type), deduped by (addressType, xpub) and scoped to the + /// device's derived wallet id (devices without xpubs are skipped). + private func desiredWatcherSpecs() -> [WatcherSpec] { + let monitored = monitoredTypesProvider() + let electrumUrl = electrumUrlProvider() + + var seen = Set() + var specs: [WatcherSpec] = [] + for device in knownDevices { + guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } + for (addressType, xpub) in device.xpubs where monitored.contains(addressType) { + guard seen.insert(dedupKey(addressType: addressType, xpub: xpub)).inserted else { continue } + specs.append(WatcherSpec(deviceId: device.id, walletId: walletId, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) + } + } + return specs + } + + /// Identity for deduping watchers across devices that share an (addressType, xpub). Uses a + /// control-character separator that can't appear in either component. + private func dedupKey(addressType: String, xpub: String) -> String { + "\(addressType)\u{1}\(xpub)" + } + + private func desiredWatcherIds() -> Set { + Set(desiredWatcherSpecs().map(\.watcherId)) + } + private func startWatcher(_ spec: WatcherSpec) { guard let addressType = HwAddressType(settingsString: spec.addressType) else { return } let network = networkProvider() @@ -189,6 +206,15 @@ final class HwWalletManager { do { try await watcherService.startWatcher(params: params, listener: listener) pendingWatcherStarts.remove(spec.watcherId) + // The device may have been forgotten or its address type disabled while the start + // was in flight; if this watcher is no longer desired, tear it down instead of + // resurrecting a forgotten wallet or a stale address type. + guard desiredWatcherIds().contains(spec.watcherId) else { + try? watcherService.stopWatcher(watcherId: spec.watcherId) + listeners[spec.watcherId] = nil + retryingWatcherStarts.remove(spec.watcherId) + return + } activeWatchers.insert(spec.watcherId) activeWatcherElectrumUrls[spec.watcherId] = spec.electrumUrl retryingWatcherStarts.remove(spec.watcherId) diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index aa7726e70..bbd2ab370 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -11,17 +11,53 @@ final class HwWalletManagerTests: XCTestCase { // MARK: - Mocks & spies private final class MockWatcherService: OnChainWatcherServicing, @unchecked Sendable { + private let lock = NSLock() + private(set) var startedParams: [WatcherParams] = [] private(set) var stoppedWatcherIds: [String] = [] var stopShouldFail = false + /// When set, keeps the native start call in flight until `completeStart()` resolves it, + /// mirroring the gate used in `TrezorViewModelWatcherTests`. + var holdStart = false + private var startContinuation: CheckedContinuation? + private var pendingStartResult: Result? + struct StopError: Error {} func startWatcher(params: WatcherParams, listener _: EventListener) async throws { + lock.lock() startedParams.append(params) + let shouldHold = holdStart + lock.unlock() + + guard shouldHold else { return } + try await withCheckedThrowingContinuation { continuation in + lock.lock() + defer { lock.unlock() } + if let result = pendingStartResult { + pendingStartResult = nil + continuation.resume(with: result) + } else { + startContinuation = continuation + } + } + } + + func completeStart(with result: Result = .success(())) { + lock.lock() + defer { lock.unlock() } + if let continuation = startContinuation { + startContinuation = nil + continuation.resume(with: result) + } else { + pendingStartResult = result + } } func stopWatcher(watcherId: String) throws { + lock.lock() + defer { lock.unlock() } stoppedWatcherIds.append(watcherId) if stopShouldFail { throw StopError() } } @@ -258,6 +294,28 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(mock.startedParams.first?.watcherId, watcherId("dev1", "nativeSegwit")) } + func testForgottenDeviceDuringInFlightStartIsTornDownNotActivated() async { + let mock = MockWatcherService() + mock.holdStart = true + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + let wid = watcherId("dev1", "nativeSegwit") + + vm.updateDevices(knownDevices: [device], connectedDeviceId: "dev1") + await waitUntil { mock.startedParams.count == 1 } + + // Forget the device while its watcher start is still in flight. + vm.updateDevices(knownDevices: [], connectedDeviceId: nil) + + // Resolving the now-undesired start must tear the watcher down, not activate it. + mock.completeStart() + await waitUntil { mock.stoppedWatcherIds.contains(wid) } + + XCTAssertTrue(mock.stoppedWatcherIds.contains(wid)) + XCTAssertTrue(vm.wallets.isEmpty) + XCTAssertEqual(vm.totalSats, 0) + } + func testZeroBalanceBeforeAnyWatcherEvent() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) let vm = makeViewModel() From d2aa3f87c0b305a4dc9abdb55cd66edf48670c4c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:44:23 -0300 Subject: [PATCH 35/52] fix: reconcile hardware watchers when the Electrum server or monitored address types change --- Bitkit/AppScene.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Bitkit/AppScene.swift b/Bitkit/AppScene.swift index 1c5dcffce..c08dc64e4 100644 --- a/Bitkit/AppScene.swift +++ b/Bitkit/AppScene.swift @@ -117,6 +117,7 @@ struct AppScene: View { // Bridge Trezor device state into the watch-only manager without coupling the two: // TrezorManager bumps devicesRevision on any device/connection change. .onChange(of: trezorManager.devicesRevision) { _, _ in pushHardwareDevices() } + .onReceive(settings.settingsPublisher) { _ in hwWalletManager.syncWatchers() } .onChange(of: migrations.isShowingMigrationLoading) { _, isLoading in if !isLoading { SettingsViewModel.shared.updatePinEnabledState() From a039796916b1eb83065e64b0fdc2b43572b32315 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 08:51:09 -0300 Subject: [PATCH 36/52] fix: set hasHardwareWallet for home widgets and widgets preview --- Bitkit/Views/Home/HomeWidgetsView.swift | 2 ++ Bitkit/Views/Widgets/WidgetPreviewSheetView.swift | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Bitkit/Views/Home/HomeWidgetsView.swift b/Bitkit/Views/Home/HomeWidgetsView.swift index 7ab55c9f0..97ea293a0 100644 --- a/Bitkit/Views/Home/HomeWidgetsView.swift +++ b/Bitkit/Views/Home/HomeWidgetsView.swift @@ -2,6 +2,7 @@ import SwiftUI struct HomeWidgetsView: View { @Environment(CalculatorInputManager.self) private var calculatorInput + @Environment(HwWalletManager.self) private var hwWalletManager @EnvironmentObject var app: AppViewModel @Environment(KeyboardManager.self) private var keyboard @EnvironmentObject var navigation: NavigationViewModel @@ -49,6 +50,7 @@ struct HomeWidgetsView: View { app: app, settings: settings, suggestionsManager: suggestionsManager, + hasHardwareWallet: !hwWalletManager.wallets.isEmpty, isPaykitUIEnabled: isPaykitUIActive ).isEmpty } diff --git a/Bitkit/Views/Widgets/WidgetPreviewSheetView.swift b/Bitkit/Views/Widgets/WidgetPreviewSheetView.swift index 9ef333299..6b3da1812 100644 --- a/Bitkit/Views/Widgets/WidgetPreviewSheetView.swift +++ b/Bitkit/Views/Widgets/WidgetPreviewSheetView.swift @@ -6,6 +6,7 @@ struct WidgetPreviewSheetView: View { let type: WidgetType @Binding var navigationPath: [WidgetsRoute] + @Environment(HwWalletManager.self) private var hwWalletManager @EnvironmentObject private var app: AppViewModel @EnvironmentObject private var currency: CurrencyViewModel @EnvironmentObject private var navigation: NavigationViewModel @@ -74,6 +75,7 @@ struct WidgetPreviewSheetView: View { settings: settings, suggestionsManager: suggestionsManager, pubkyProfile: pubkyProfile, + hasHardwareWallet: !hwWalletManager.wallets.isEmpty, isPaykitUIEnabled: isPaykitUIActive ).isEmpty } From bae69fd746ea4046143f7c21102afd4c9ab5df1d Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 09:09:18 -0300 Subject: [PATCH 37/52] fix: sort watches for a deterministic merge --- Bitkit/Managers/HwWalletManager.swift | 12 ++++++--- BitkitTests/HwWalletManagerTests.swift | 35 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 3f9a2b03c..c3f58af25 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -296,15 +296,21 @@ final class HwWalletManager { /// Aggregate the activities core emitted across a device-group's watchers, scoping each to the /// group's wallet id and deduping by activity id (so the same tx seen by two address-type - /// watchers persists once). + /// watchers persists once). Watchers are walked in sorted `watcherId` order and the result is + /// sorted by activity id, so a tx observed by multiple address-type watchers (which can carry + /// different wallet-perspective directions) resolves to a deterministic winner — the + /// highest-ordered watcherId — rather than depending on dictionary iteration order. private func mergedActivities(for group: DeviceGroup) -> [Activity] { - let watchers = watcherData.values.filter { group.ids.contains($0.deviceId) } + let watchers = watcherData + .filter { group.ids.contains($0.value.deviceId) } + .sorted { $0.key < $1.key } + .map(\.value) var byId: [String: Activity] = [:] for activity in watchers.flatMap(\.activities) { let scoped = scopedToWallet(activity, walletId: group.walletId) byId[activityId(of: scoped)] = scoped } - return Array(byId.values) + return byId.values.sorted { activityId(of: $0) < activityId(of: $1) } } private func scopedToWallet(_ activity: Activity, walletId: String) -> Activity { diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index bbd2ab370..7945be39c 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -393,6 +393,41 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(onchain.txId, "shared") } + func testMixedDirectionDuplicateResolvesDeterministically() { + /// The same txid seen by two address-type watchers can carry different wallet-perspective + /// directions; the merge must resolve to the same winner regardless of arrival order. + func mergedTxType(nativeSegwitFirst: Bool) -> PaymentType? { + persisted = [] + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + let ns = watcherId("dev1", "nativeSegwit") + let tr = watcherId("dev1", "taproot") + let nsEvent = makeEvent([makeActivity(txId: "shared", value: 5000, txType: .sent)], total: 5000) + let trEvent = makeEvent([makeActivity(txId: "shared", value: 30000, txType: .received)], total: 30000) + if nativeSegwitFirst { + vm.handleWatcherEvent(watcherId: ns, event: nsEvent) + vm.handleWatcherEvent(watcherId: tr, event: trEvent) + } else { + vm.handleWatcherEvent(watcherId: tr, event: trEvent) + vm.handleWatcherEvent(watcherId: ns, event: nsEvent) + } + let shared = (persisted.last ?? []).first { + if case let .onchain(onchain) = $0 { return onchain.txId == "shared" } + return false + } + guard case let .onchain(onchain) = shared else { return nil } + return onchain.txType + } + + let nsFirst = mergedTxType(nativeSegwitFirst: true) + let trFirst = mergedTxType(nativeSegwitFirst: false) + + XCTAssertEqual(nsFirst, trFirst) + // 'dev1|taproot' sorts after 'dev1|nativeSegwit', so the taproot perspective wins. + XCTAssertEqual(nsFirst, .received) + } + func testWatcherStartedOnConfiguredElectrumAndNetwork() async { let mock = MockWatcherService() let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"]) From 39bbf3e907c0a9ce2a0881b846497cdb89ac24c0 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 10:09:50 -0300 Subject: [PATCH 38/52] chore: add TODO for next iterations --- Bitkit/Extensions/Activity+Contact.swift | 3 +++ Bitkit/Views/Wallets/Activity/ActivityItemView.swift | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/Bitkit/Extensions/Activity+Contact.swift b/Bitkit/Extensions/Activity+Contact.swift index 49197c895..ba94c2148 100644 --- a/Bitkit/Extensions/Activity+Contact.swift +++ b/Bitkit/Extensions/Activity+Contact.swift @@ -13,6 +13,9 @@ extension Activity { } /// Whether this activity belongs to a watch-only hardware wallet (not the normal Bitkit wallet). + // TODO: Used as an interim feature gate (see ActivityItemView.isHardwareActivity). The + // wallet-id shorthand holds only while CoreService activity mutations are default-scoped; + // replace with a real capability check when wallet_id mutation support lands. var isHardwareWallet: Bool { walletId != WalletScope.default } diff --git a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift index 23698b8c8..5de9a1084 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift @@ -135,6 +135,11 @@ struct ActivityItemView: View { return DateFormatterHelpers.formatActivityDetail(activity.timestamp) } + // TODO: Interim feature-gating. Tag/contact/boost are hidden for hardware activities + // because CoreService's activity-mutation methods (markActivityAsSeen, setContact, delete, + // tag, boost) still hardcode WalletScope.default and can't address a non-default wallet id. + // Revisit once those methods are wallet_id-scoped (and wallet_id / hardware activities ship + // to production) so this becomes a real capability check rather than a wallet-id shorthand. private var isHardwareActivity: Bool { viewModel.activity.isHardwareWallet } From 5632064f1028bd20c55fae275e6fcde357416302 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 10:12:12 -0300 Subject: [PATCH 39/52] chore: lint --- Bitkit/Managers/TrezorManager.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index e878da40d..1632a7f98 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -580,7 +580,8 @@ final class TrezorManager { .replacingOccurrences(of: "IO error: ", with: "") if message.contains("Stale Bluetooth pairing") || message.contains("Peer removed pairing") { - return "Stale Bluetooth pairing detected. Go to iOS Settings → Bluetooth, forget your Trezor device, then put it back in pairing mode and try again." + return "Stale Bluetooth pairing detected. Go to iOS Settings → Bluetooth, forget your Trezor device, " + + "then put it back in pairing mode and try again." } if message.contains("Unable to open device") || message.contains("Failed to connect") { return "Failed to connect to Trezor. Please ensure it's in pairing mode and try again." From 6b76cc32b98821ce95b0bd4040ae53a8cbf33d85 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 10:21:59 -0300 Subject: [PATCH 40/52] fix: narrow settings watcher trigger --- Bitkit/AppScene.swift | 2 +- Bitkit/Managers/HwWalletManager.swift | 18 ++++++++++++++ BitkitTests/HwWalletManagerTests.swift | 34 ++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Bitkit/AppScene.swift b/Bitkit/AppScene.swift index c08dc64e4..0ac425c24 100644 --- a/Bitkit/AppScene.swift +++ b/Bitkit/AppScene.swift @@ -117,7 +117,7 @@ struct AppScene: View { // Bridge Trezor device state into the watch-only manager without coupling the two: // TrezorManager bumps devicesRevision on any device/connection change. .onChange(of: trezorManager.devicesRevision) { _, _ in pushHardwareDevices() } - .onReceive(settings.settingsPublisher) { _ in hwWalletManager.syncWatchers() } + .onReceive(settings.settingsPublisher) { _ in hwWalletManager.reconcileForSettingsChange() } .onChange(of: migrations.isShowingMigrationLoading) { _, isLoading in if !isLoading { SettingsViewModel.shared.updatePinEnabledState() diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index c3f58af25..8e46a13b0 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -59,6 +59,11 @@ final class HwWalletManager { /// Guards against a second `syncWatchers()` double-starting the same watcher in that window. private var pendingWatcherStarts: Set = [] + /// Last watcher-relevant settings seen by `reconcileForSettingsChange()`, so an unrelated + /// settings change (theme, currency, …) doesn't trigger a needless watcher reconcile. + private var lastSyncedMonitored: Set? + private var lastSyncedElectrumUrl: String? + private var emittedReceivedTxIds: Set = [] private var listeners: [String: TrezorEventListener] = [:] @@ -134,6 +139,19 @@ final class HwWalletManager { // MARK: - Watcher orchestration + /// Reconcile watchers in response to a settings change, but only when the monitored address + /// types or the Electrum URL actually changed — `settingsPublisher` fires for every setting + /// (theme, currency, …), and a full `syncWatchers()` re-derives each device's wallet id over + /// the FFI, so we skip the work when nothing watcher-relevant moved. + func reconcileForSettingsChange() { + let monitored = monitoredTypesProvider() + let electrumUrl = electrumUrlProvider() + guard monitored != lastSyncedMonitored || electrumUrl != lastSyncedElectrumUrl else { return } + lastSyncedMonitored = monitored + lastSyncedElectrumUrl = electrumUrl + syncWatchers() + } + func syncWatchers() { let specs = desiredWatcherSpecs() let desiredIds = Set(specs.map(\.watcherId)) diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 7945be39c..6fcca9fc8 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -442,6 +442,40 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(params?.accountType, .nativeSegwit) } + func testReconcileForSettingsChangeSkipsUnchangedAndActsOnChange() async { + let mock = MockWatcherService() + var monitored: Set = ["nativeSegwit"] + let electrum = "ssl://a:1" + var electrumCalls = 0 + let vm = HwWalletManager( + watcherService: mock, + monitoredTypes: { monitored }, + electrumUrl: { electrumCalls += 1; return electrum }, + network: { .regtest }, + persistActivities: { _ in }, + deleteActivities: { _ in } + ) + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + + // Prime the last-synced snapshot. + vm.reconcileForSettingsChange() + + // Unchanged settings: the guard short-circuits before syncWatchers, so the Electrum + // provider is read exactly once (the guard) and no watcher work happens. + electrumCalls = 0 + vm.reconcileForSettingsChange() + XCTAssertEqual(electrumCalls, 1) + XCTAssertEqual(mock.startedParams.count, 1) + + // A monitored-types change does reconcile: the taproot watcher starts. + monitored = ["nativeSegwit", "taproot"] + vm.reconcileForSettingsChange() + await waitUntil { mock.startedParams.count == 2 } + XCTAssertEqual(mock.startedParams.count, 2) + } + func testReceivedTxEmittedOnceAcrossMultipleWatchers() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) let vm = makeViewModel() From 6e0248f8209af03012dfb7c1d4b3cb4f58410044 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 11:04:50 -0300 Subject: [PATCH 41/52] fix: every watch event was performing a full activity reload and FFi calls. improved eficiency caching wallet Ids and comparing merged activities before notify activity changes --- Bitkit/Managers/HwWalletManager.swift | 69 ++++++++++++++++++++++---- BitkitTests/HwWalletManagerTests.swift | 23 +++++++++ 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 8e46a13b0..1014d4f06 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -64,6 +64,15 @@ final class HwWalletManager { private var lastSyncedMonitored: Set? private var lastSyncedElectrumUrl: String? + /// Memoized `HwWalletId.derive` results keyed by an xpubs signature. The mapping is + /// deterministic and immutable, so caching avoids repeated FFI derivations on every watcher + /// event and sync. Pruned to the live device set on `updateDevices`/`removeDevice`. + private var walletIdCache: [String: String] = [:] + + /// Last activity set persisted per group wallet id, so an unchanged watcher event doesn't + /// re-upsert the whole history to core and fire a redundant activity-list reload. + private var lastPersisted: [String: [Activity]] = [:] + private var emittedReceivedTxIds: Set = [] private var listeners: [String: TrezorEventListener] = [:] @@ -120,6 +129,7 @@ final class HwWalletManager { for walletId in previousWalletIds.subtracting(hwWalletIds) { deleteActivities(walletId) } + pruneCaches() } // MARK: - Control @@ -133,7 +143,13 @@ final class HwWalletManager { for watcherId in activeWatchers where ids.contains(self.deviceId(fromWatcherId: watcherId)) { _ = stopActiveWatcher(watcherId) } - if let group { deleteActivities(group.walletId) } + if let group { + deleteActivities(group.walletId) + lastPersisted[group.walletId] = nil + } + if let device = knownDevices.first(where: { $0.id == deviceId }) { + walletIdCache[xpubsSignature(device.xpubs)] = nil + } recomputeDerivedState() } @@ -183,7 +199,7 @@ final class HwWalletManager { var seen = Set() var specs: [WatcherSpec] = [] for device in knownDevices { - guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } + guard let walletId = walletId(for: device.xpubs) else { continue } for (addressType, xpub) in device.xpubs where monitored.contains(addressType) { guard seen.insert(dedupKey(addressType: addressType, xpub: xpub)).inserted else { continue } specs.append(WatcherSpec(deviceId: device.id, walletId: walletId, addressType: addressType, xpub: xpub, electrumUrl: electrumUrl)) @@ -198,6 +214,30 @@ final class HwWalletManager { "\(addressType)\u{1}\(xpub)" } + /// Derive (and memoize) the wallet id for a device's xpubs. Returns nil when derivation fails + /// (e.g. no captured xpubs — `HwWalletId.derive` throws on empty), so callers skip the device. + private func walletId(for xpubs: [String: String]) -> String? { + let signature = xpubsSignature(xpubs) + if let cached = walletIdCache[signature] { return cached } + guard let derived = try? HwWalletId.derive(xpubs: xpubs) else { return nil } + walletIdCache[signature] = derived + return derived + } + + private func xpubsSignature(_ xpubs: [String: String]) -> String { + xpubs.sorted { $0.key < $1.key } + .map { dedupKey(addressType: $0.key, xpub: $0.value) } + .joined(separator: "\u{1f}") + } + + /// Drop cache entries for devices no longer in the snapshot, so the caches stay bounded to + /// live devices. + private func pruneCaches() { + let liveSignatures = Set(knownDevices.filter { !$0.xpubs.isEmpty }.map { xpubsSignature($0.xpubs) }) + walletIdCache = walletIdCache.filter { liveSignatures.contains($0.key) } + lastPersisted = lastPersisted.filter { hwWalletIds.contains($0.key) } + } + private func desiredWatcherIds() -> Set { Set(desiredWatcherSpecs().map(\.watcherId)) } @@ -276,14 +316,16 @@ final class HwWalletManager { /// stores, aggregates, and scopes them to the device. func handleWatcherEvent(watcherId: String, event: WatcherEvent) { guard case let .transactionsChanged(activities, _, balance, _, _, _) = event else { return } + let deviceId = deviceId(fromWatcherId: watcherId) let previous = watcherData[watcherId] watcherData[watcherId] = HwWatcherData( - deviceId: deviceId(fromWatcherId: watcherId), + deviceId: deviceId, balanceSats: balance.total, activities: activities ) - recomputeDerivedState() - persistGroupActivities(forDevice: deviceId(fromWatcherId: watcherId)) + let groups = deviceGroups() + recomputeDerivedState(groups: groups) + persistGroupActivities(forDevice: deviceId, groups: groups) emitReceivedTxs(previous: previous, activities: activities) } @@ -307,9 +349,14 @@ final class HwWalletManager { // MARK: - Persistence - private func persistGroupActivities(forDevice deviceId: String) { - guard let group = deviceGroups().first(where: { $0.ids.contains(deviceId) }) else { return } - persistActivities(mergedActivities(for: group)) + private func persistGroupActivities(forDevice deviceId: String, groups: [DeviceGroup]? = nil) { + let groups = groups ?? deviceGroups() + guard let group = groups.first(where: { $0.ids.contains(deviceId) }) else { return } + let merged = mergedActivities(for: group) + // Skip the core upsert + activity-list reload when nothing changed for this group. + guard lastPersisted[group.walletId] != merged else { return } + lastPersisted[group.walletId] = merged + persistActivities(merged) } /// Aggregate the activities core emitted across a device-group's watchers, scoping each to the @@ -351,8 +398,8 @@ final class HwWalletManager { // MARK: - Aggregation - private func recomputeDerivedState() { - let groups = deviceGroups() + private func recomputeDerivedState(groups: [DeviceGroup]? = nil) { + let groups = groups ?? deviceGroups() wallets = groups.map { group in let connectedDevice = group.devices.first { $0.id == connectedDeviceId } @@ -379,7 +426,7 @@ final class HwWalletManager { var order: [String] = [] var grouped: [String: [TrezorKnownDevice]] = [:] for device in knownDevices where !device.xpubs.isEmpty { - guard let walletId = try? HwWalletId.derive(xpubs: device.xpubs) else { continue } + guard let walletId = walletId(for: device.xpubs) else { continue } if grouped[walletId] == nil { order.append(walletId) } grouped[walletId, default: []].append(device) } diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 6fcca9fc8..106c5be51 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -250,6 +250,29 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(onchain.value, 40000) } + func testUnchangedWatcherEventDoesNotRepersist() { + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) + let vm = makeViewModel() + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + let wid = watcherId("dev1", "nativeSegwit") + let event = makeEvent([makeActivity(txId: "tx1", value: 40000, txType: .received)], total: 40000) + + vm.handleWatcherEvent(watcherId: wid, event: event) + XCTAssertEqual(persisted.count, 1) + + // Identical event again → no re-upsert / no redundant activity-list reload. + vm.handleWatcherEvent(watcherId: wid, event: event) + XCTAssertEqual(persisted.count, 1) + + // A changed event (new tx) → persists again. + let changed = makeEvent([ + makeActivity(txId: "tx1", value: 40000, txType: .received), + makeActivity(txId: "tx2", value: 10000, txType: .received), + ], total: 50000) + vm.handleWatcherEvent(watcherId: wid, event: changed) + XCTAssertEqual(persisted.count, 2) + } + func testReceivedTxDetection() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zpubNS"]) let vm = makeViewModel() From a8fe2c8eb803071992c0e950ace9ed2d7e151bc6 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 11:12:46 -0300 Subject: [PATCH 42/52] refactor: consolidate HwAddressType --- Bitkit/Extensions/LDKNode+AddressType.swift | 25 +++++++++ Bitkit/Managers/HwWalletManager.swift | 2 +- Bitkit/Managers/TrezorManager.swift | 9 +-- Bitkit/Models/HwAddressType.swift | 56 ------------------- Bitkit/Services/SamRockService.swift | 12 +--- .../Trezor/TrezorKnownDeviceStorage.swift | 2 +- BitkitTests/AddressTypeAccountTests.swift | 34 +++++++++++ BitkitTests/HwAddressTypeTests.swift | 43 -------------- 8 files changed, 68 insertions(+), 115 deletions(-) delete mode 100644 Bitkit/Models/HwAddressType.swift create mode 100644 BitkitTests/AddressTypeAccountTests.swift delete mode 100644 BitkitTests/HwAddressTypeTests.swift diff --git a/Bitkit/Extensions/LDKNode+AddressType.swift b/Bitkit/Extensions/LDKNode+AddressType.swift index f42f862d3..c62fb5a4e 100644 --- a/Bitkit/Extensions/LDKNode+AddressType.swift +++ b/Bitkit/Extensions/LDKNode+AddressType.swift @@ -1,3 +1,4 @@ +import BitkitCore import LDKNode extension LDKNode.AddressType { @@ -68,6 +69,30 @@ extension LDKNode.AddressType { } } + /// Account-level BIP path (no chain/index suffix), e.g. `m/84'/0'/0'` — used to request a + /// device's account xpub. Distinct from `derivationPath`, which is the chain-level path. + func accountDerivationPath(coinType: String) -> String { + switch self { + case .legacy: return "m/44'/\(coinType)'/0'" // BIP 44 + case .nestedSegwit: return "m/49'/\(coinType)'/0'" // BIP 49 + case .nativeSegwit: return "m/84'/\(coinType)'/0'" // BIP 84 + case .taproot: return "m/86'/\(coinType)'/0'" // BIP 86 + } + } + + // MARK: - BitkitCore account type + + /// bitkit-core `AccountType` for this address type (used when deriving descriptors and + /// starting watch-only watchers). + var accountType: AccountType { + switch self { + case .legacy: return .legacy + case .nestedSegwit: return .wrappedSegwit + case .nativeSegwit: return .nativeSegwit + case .taproot: return .taproot + } + } + // MARK: - Localized display var localizedTitle: String { diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 1014d4f06..ce420b1c3 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -243,7 +243,7 @@ final class HwWalletManager { } private func startWatcher(_ spec: WatcherSpec) { - guard let addressType = HwAddressType(settingsString: spec.addressType) else { return } + guard let addressType = AddressScriptType.from(string: spec.addressType) else { return } let network = networkProvider() let params = WatcherParams( watcherId: spec.watcherId, diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index 1632a7f98..48ad053d1 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -445,18 +445,19 @@ final class TrezorManager { /// Per-type failures are swallowed so a single missing type doesn't block the rest. func fetchAccountXpubs() async -> [String: String] { + let coinType = selectedNetwork == .bitcoin ? "0" : "1" var result: [String: String] = [:] - for addressType in HwAddressType.allCases { + for addressType in AddressScriptType.allAddressTypes { do { let params = TrezorGetPublicKeyParams( - path: addressType.accountDerivationPath(network: selectedNetwork), + path: addressType.accountDerivationPath(coinType: coinType), coin: selectedNetwork, showOnTrezor: false ) let response = try await trezorService.getPublicKey(params: params) - result[addressType.settingsString] = response.xpub + result[addressType.stringValue] = response.xpub } catch { - trezorLog("Could not read xpub for '\(addressType.settingsString)': \(error)", level: "warn") + trezorLog("Could not read xpub for '\(addressType.stringValue)': \(error)", level: "warn") } } return result diff --git a/Bitkit/Models/HwAddressType.swift b/Bitkit/Models/HwAddressType.swift deleted file mode 100644 index 1b7e1af70..000000000 --- a/Bitkit/Models/HwAddressType.swift +++ /dev/null @@ -1,56 +0,0 @@ -import BitkitCore - -/// Bitcoin account address types tracked for hardware (watch-only) wallets. -/// Mirrors the four BIP account levels Bitkit derives account xpubs for. -/// `allCases` order matches bitkit-android's `ALL_ADDRESS_TYPES`. -enum HwAddressType: CaseIterable { - case legacy - case nestedSegwit - case nativeSegwit - case taproot - - /// Storage key used in `TrezorKnownDevice.xpubs` and address-type settings. - var settingsString: String { - switch self { - case .legacy: "legacy" - case .nestedSegwit: "nestedSegwit" - case .nativeSegwit: "nativeSegwit" - case .taproot: "taproot" - } - } - - /// bitkit-core account type used when starting a watcher for this address type. - var accountType: AccountType { - switch self { - case .legacy: .legacy - case .nestedSegwit: .wrappedSegwit - case .nativeSegwit: .nativeSegwit - case .taproot: .taproot - } - } - - private var purpose: Int { - switch self { - case .legacy: 44 - case .nestedSegwit: 49 - case .nativeSegwit: 84 - case .taproot: 86 - } - } - - /// Account-level derivation path, e.g. `m/84'/0'/0'` (coin type `1'` for non-mainnet). - func accountDerivationPath(network: TrezorCoinType) -> String { - let coinType = network == .bitcoin ? 0 : 1 - return "m/\(purpose)'/\(coinType)'/0'" - } - - init?(settingsString: String) { - switch settingsString { - case "legacy": self = .legacy - case "nestedSegwit": self = .nestedSegwit - case "nativeSegwit": self = .nativeSegwit - case "taproot": self = .taproot - default: return nil - } - } -} diff --git a/Bitkit/Services/SamRockService.swift b/Bitkit/Services/SamRockService.swift index d0ddafbb6..c2327e340 100644 --- a/Bitkit/Services/SamRockService.swift +++ b/Bitkit/Services/SamRockService.swift @@ -341,18 +341,10 @@ final class SamRockService { } static func accountType(forSelectedAddressType selectedAddressType: String?) -> AccountType { - switch selectedAddressType { - case "legacy": - return .legacy - case "nestedSegwit": - return .wrappedSegwit - case "taproot": - return .taproot - case "nativeSegwit": - return .nativeSegwit - default: + guard let selectedAddressType, let addressType = AddressScriptType.from(string: selectedAddressType) else { return .nativeSegwit } + return addressType.accountType } private static func formEncode(_ value: String) -> String { diff --git a/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift b/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift index 8b96d67c9..63f22d649 100644 --- a/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift +++ b/Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift @@ -9,7 +9,7 @@ struct TrezorKnownDevice: Codable, Identifiable { var label: String? var model: String? var lastConnectedAt: Date - /// Account-level extended public keys keyed by `HwAddressType.settingsString`. + /// Account-level extended public keys keyed by `AddressScriptType.stringValue`. /// Persisted so watch-only balances/activity stay available while disconnected. var xpubs: [String: String] diff --git a/BitkitTests/AddressTypeAccountTests.swift b/BitkitTests/AddressTypeAccountTests.swift new file mode 100644 index 000000000..4f7c1d1d0 --- /dev/null +++ b/BitkitTests/AddressTypeAccountTests.swift @@ -0,0 +1,34 @@ +@testable import Bitkit +import BitkitCore +import LDKNode +import XCTest + +/// Covers the hardware-wallet additions to `LDKNode.AddressType` (`AddressScriptType`): +/// the bitkit-core `accountType` mapping and the account-level derivation path. +final class AddressTypeAccountTests: XCTestCase { + func testAccountTypeMapping() { + XCTAssertEqual(AddressScriptType.legacy.accountType, .legacy) + XCTAssertEqual(AddressScriptType.nestedSegwit.accountType, .wrappedSegwit) + XCTAssertEqual(AddressScriptType.nativeSegwit.accountType, .nativeSegwit) + XCTAssertEqual(AddressScriptType.taproot.accountType, .taproot) + } + + func testAccountDerivationPathMainnet() { + XCTAssertEqual(AddressScriptType.legacy.accountDerivationPath(coinType: "0"), "m/44'/0'/0'") + XCTAssertEqual(AddressScriptType.nestedSegwit.accountDerivationPath(coinType: "0"), "m/49'/0'/0'") + XCTAssertEqual(AddressScriptType.nativeSegwit.accountDerivationPath(coinType: "0"), "m/84'/0'/0'") + XCTAssertEqual(AddressScriptType.taproot.accountDerivationPath(coinType: "0"), "m/86'/0'/0'") + } + + func testAccountDerivationPathTestNetworks() { + XCTAssertEqual(AddressScriptType.nativeSegwit.accountDerivationPath(coinType: "1"), "m/84'/1'/0'") + XCTAssertEqual(AddressScriptType.taproot.accountDerivationPath(coinType: "1"), "m/86'/1'/0'") + } + + /// The account path is the chain-level `derivationPath` without the trailing chain/index. + func testAccountPathIsChainPathWithoutSuffix() { + for type in AddressScriptType.allAddressTypes { + XCTAssertEqual(type.derivationPath(coinType: "0"), type.accountDerivationPath(coinType: "0") + "/0") + } + } +} diff --git a/BitkitTests/HwAddressTypeTests.swift b/BitkitTests/HwAddressTypeTests.swift deleted file mode 100644 index ff9b184d6..000000000 --- a/BitkitTests/HwAddressTypeTests.swift +++ /dev/null @@ -1,43 +0,0 @@ -@testable import Bitkit -import BitkitCore -import XCTest - -final class HwAddressTypeTests: XCTestCase { - func testAllCasesOrderMatchesAndroid() { - XCTAssertEqual(HwAddressType.allCases, [.legacy, .nestedSegwit, .nativeSegwit, .taproot]) - } - - func testSettingsStrings() { - XCTAssertEqual(HwAddressType.legacy.settingsString, "legacy") - XCTAssertEqual(HwAddressType.nestedSegwit.settingsString, "nestedSegwit") - XCTAssertEqual(HwAddressType.nativeSegwit.settingsString, "nativeSegwit") - XCTAssertEqual(HwAddressType.taproot.settingsString, "taproot") - } - - func testAccountTypeMapping() { - XCTAssertEqual(HwAddressType.legacy.accountType, .legacy) - XCTAssertEqual(HwAddressType.nestedSegwit.accountType, .wrappedSegwit) - XCTAssertEqual(HwAddressType.nativeSegwit.accountType, .nativeSegwit) - XCTAssertEqual(HwAddressType.taproot.accountType, .taproot) - } - - func testAccountDerivationPathMainnet() { - XCTAssertEqual(HwAddressType.legacy.accountDerivationPath(network: .bitcoin), "m/44'/0'/0'") - XCTAssertEqual(HwAddressType.nestedSegwit.accountDerivationPath(network: .bitcoin), "m/49'/0'/0'") - XCTAssertEqual(HwAddressType.nativeSegwit.accountDerivationPath(network: .bitcoin), "m/84'/0'/0'") - XCTAssertEqual(HwAddressType.taproot.accountDerivationPath(network: .bitcoin), "m/86'/0'/0'") - } - - func testAccountDerivationPathUsesCoinType1ForTestNetworks() { - XCTAssertEqual(HwAddressType.nativeSegwit.accountDerivationPath(network: .regtest), "m/84'/1'/0'") - XCTAssertEqual(HwAddressType.taproot.accountDerivationPath(network: .testnet), "m/86'/1'/0'") - } - - func testInitFromSettingsStringRoundTrips() { - for type in HwAddressType.allCases { - XCTAssertEqual(HwAddressType(settingsString: type.settingsString), type) - } - XCTAssertNil(HwAddressType(settingsString: "p2wpkh")) - XCTAssertNil(HwAddressType(settingsString: "")) - } -} From 5777dbbb4e2ca76b925619417caeb3d36cd6877e Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 11:32:51 -0300 Subject: [PATCH 43/52] fix: update balance on watcher update, like adding/removing address type --- Bitkit/Managers/HwWalletManager.swift | 5 ++++- BitkitTests/HwWalletManagerTests.swift | 29 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index ce420b1c3..1d99a5019 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -120,7 +120,6 @@ final class HwWalletManager { self.connectedDeviceId = connectedDeviceId walletsLoaded = true syncWatchers() - recomputeDerivedState() // A device that dropped out of the snapshot (e.g. the user forgot it) would otherwise // leave its watch-only activities orphaned in the merged activity list, which queries @@ -187,6 +186,10 @@ final class HwWalletManager { for staleId in activeWatchers.subtracting(desiredIds) { _ = stopActiveWatcher(staleId) } + + // Stopping a stale watcher clears its cached balance/activities; recompute so the published + // totals reflect it immediately (a started watcher recomputes again on its first event). + recomputeDerivedState() } /// Build the watcher specs the current device/settings snapshot wants running: one per diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 106c5be51..8d3986dd2 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -499,6 +499,35 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(mock.startedParams.count, 2) } + func testDisablingAddressTypeClearsBalanceImmediately() async { + let mock = MockWatcherService() + var monitored: Set = ["nativeSegwit"] + let vm = HwWalletManager( + watcherService: mock, + monitoredTypes: { monitored }, + electrumUrl: { "ssl://test:1" }, + network: { .regtest }, + persistActivities: { _ in }, + deleteActivities: { _ in } + ) + let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS"]) + vm.updateDevices(knownDevices: [device], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeActivity(txId: "tx1", value: 50000, txType: .received)], total: 50000 + )) + XCTAssertEqual(vm.totalSats, 50000) + + // Disabling the only monitored address type stops the watcher; the published totals must + // drop immediately, without waiting for any further watcher event. + monitored = [] + vm.reconcileForSettingsChange() + + XCTAssertEqual(vm.totalSats, 0) + XCTAssertEqual(vm.wallets.first?.balanceSats, 0) + } + func testReceivedTxEmittedOnceAcrossMultipleWatchers() { let device = makeDevice(id: "dev1", xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) let vm = makeViewModel() From 798ba4c34de0f98c763f6e128874b5ecbb221cc0 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 12:10:56 -0300 Subject: [PATCH 44/52] refactor: consolidate saturation check --- .../FixedWidthInteger+Saturating.swift | 8 +++++ Bitkit/Managers/HwWalletManager.swift | 9 ++---- Bitkit/Views/Home/HomeWalletView.swift | 3 +- BitkitTests/HwWalletIdTests.swift | 30 ++++++++++++++++--- 4 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 Bitkit/Extensions/FixedWidthInteger+Saturating.swift diff --git a/Bitkit/Extensions/FixedWidthInteger+Saturating.swift b/Bitkit/Extensions/FixedWidthInteger+Saturating.swift new file mode 100644 index 000000000..3a954b13a --- /dev/null +++ b/Bitkit/Extensions/FixedWidthInteger+Saturating.swift @@ -0,0 +1,8 @@ +import Foundation + +extension FixedWidthInteger { + func saturatingAdd(_ other: Self) -> Self { + let (sum, overflow) = addingReportingOverflow(other) + return overflow ? Self.max : sum + } +} diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 1d99a5019..5fadf1abb 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -414,12 +414,12 @@ final class HwWalletManager { name: displayName(of: device), model: device.model, isConnected: connectedDevice != nil, - balanceSats: deviceWatchers.reduce(UInt64(0)) { saturatingAdd($0, $1.balanceSats) }, + balanceSats: deviceWatchers.reduce(UInt64(0)) { $0.saturatingAdd($1.balanceSats) }, deviceIds: group.ids ) } - totalSats = wallets.reduce(UInt64(0)) { saturatingAdd($0, $1.balanceSats) } + totalSats = wallets.reduce(UInt64(0)) { $0.saturatingAdd($1.balanceSats) } hwWalletIds = Set(groups.map(\.walletId)) } @@ -454,11 +454,6 @@ final class HwWalletManager { return String(watcherId[.. UInt64 { - let (sum, overflow) = a.addingReportingOverflow(b) - return overflow ? .max : sum - } - // MARK: - Supporting types private struct WatcherSpec { diff --git a/Bitkit/Views/Home/HomeWalletView.swift b/Bitkit/Views/Home/HomeWalletView.swift index 990f8f5ee..0a033425e 100644 --- a/Bitkit/Views/Home/HomeWalletView.swift +++ b/Bitkit/Views/Home/HomeWalletView.swift @@ -15,8 +15,7 @@ struct HomeWalletView: View { /// semantics unchanged for send/transfer logic; only the headline folds hardware in). private var headlineSats: Int { let hw = Int(clamping: hwWalletManager.totalSats) - let (result, overflow) = wallet.totalBalanceSats.addingReportingOverflow(hw) - return overflow ? .max : result + return wallet.totalBalanceSats.saturatingAdd(hw) } var body: some View { diff --git a/BitkitTests/HwWalletIdTests.swift b/BitkitTests/HwWalletIdTests.swift index 2ba2632ec..46bce75ed 100644 --- a/BitkitTests/HwWalletIdTests.swift +++ b/BitkitTests/HwWalletIdTests.swift @@ -1,4 +1,5 @@ @testable import Bitkit +import CryptoKit import XCTest final class HwWalletIdTests: XCTestCase { @@ -8,10 +9,24 @@ final class HwWalletIdTests: XCTestCase { XCTAssertEqual(a, b, "id derives deterministically from xpubs") } - func testOrderIndependent() throws { - let a = try HwWalletId.derive(xpubs: ["nativeSegwit": "zNS", "taproot": "zTR"]) - let b = try HwWalletId.derive(xpubs: ["taproot": "zTR", "nativeSegwit": "zNS"]) - XCTAssertEqual(a, b, "values are sorted before hashing") + /// Pins the exact derivation against an independent reproduction of core's + /// `derive_wallet_id` (sort values, join with "\n", SHA256, lowercase hex, + /// prefix "{deviceType}:"). Fails if either core's contract or the Swift call + /// site (e.g. accidentally folding in the dictionary keys) drifts. + func testMatchesCanonicalDerivation() throws { + let xpubs = ["taproot": "zTR", "nativeSegwit": "zNS"] + let expected = "trezor:" + expectedHash(ofSortedValues: xpubs) + XCTAssertEqual(try HwWalletId.derive(xpubs: xpubs), expected) + } + + // The id must depend only on the set of xpub values, never on the address-type + // keys: the same values mapped to swapped keys yield two genuinely different + // dictionaries, yet must derive the same id (unlike two equal literals, this + // can fail if derivation ever starts depending on keys or insertion order). + func testIndependentOfAddressTypeKeys() throws { + let a = try HwWalletId.derive(xpubs: ["nativeSegwit": "xpubA", "taproot": "xpubB"]) + let b = try HwWalletId.derive(xpubs: ["taproot": "xpubA", "nativeSegwit": "xpubB"]) + XCTAssertEqual(a, b, "id depends on the value set, not the keys or their order") } func testDifferentXpubsProduceDifferentIds() throws { @@ -27,4 +42,11 @@ final class HwWalletIdTests: XCTestCase { func testThrowsWhenNoXpubs() { XCTAssertThrowsError(try HwWalletId.derive(xpubs: [:])) } + + private func expectedHash(ofSortedValues xpubs: [String: String]) -> String { + let joined = xpubs.values.sorted().joined(separator: "\n") + return SHA256.hash(data: Data(joined.utf8)) + .compactMap { String(format: "%02x", $0) } + .joined() + } } From f0d63f8adaacf2c3e52eaf4d5bc22bbfdc632b65 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 13:17:55 -0300 Subject: [PATCH 45/52] fix: restart hardware watcher when a device's xpub changes --- Bitkit/Managers/HwWalletManager.swift | 13 ++++++++++++- BitkitTests/HwWalletManagerTests.swift | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index 5fadf1abb..b99c5a00d 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -53,6 +53,13 @@ final class HwWalletManager { private var watcherData: [String: HwWatcherData] = [:] private var activeWatchers: Set = [] private var activeWatcherElectrumUrls: [String: String] = [:] + + /// Xpub each active watcher was started with. The watcher id is only `deviceId|addressType`, so + /// the same physical device re-saved with a different xpub for that type (e.g. a passphrase/ + /// hidden wallet, or re-fetched accounts) keeps the same watcher id and derives a new wallet id. + /// Tracked here so `syncWatchers()` restarts the watcher on the new xpub instead of leaving the + /// old one feeding the old wallet's balance/activity under the new wallet id. + private var activeWatcherXpubs: [String: String] = [:] private var retryingWatcherStarts: Set = [] /// Watchers whose async start is dispatched but not yet confirmed in `activeWatchers`. @@ -176,7 +183,9 @@ final class HwWalletManager { // The next sync after it completes reconciles any electrum-url change. if pendingWatcherStarts.contains(spec.watcherId) { continue } let isActive = activeWatchers.contains(spec.watcherId) - if isActive, activeWatcherElectrumUrls[spec.watcherId] == spec.electrumUrl { continue } + if isActive, + activeWatcherElectrumUrls[spec.watcherId] == spec.electrumUrl, + activeWatcherXpubs[spec.watcherId] == spec.xpub { continue } if isActive, !stopActiveWatcher(spec.watcherId) { continue } startWatcher(spec) } @@ -278,6 +287,7 @@ final class HwWalletManager { } activeWatchers.insert(spec.watcherId) activeWatcherElectrumUrls[spec.watcherId] = spec.electrumUrl + activeWatcherXpubs[spec.watcherId] = spec.xpub retryingWatcherStarts.remove(spec.watcherId) } catch { pendingWatcherStarts.remove(spec.watcherId) @@ -294,6 +304,7 @@ final class HwWalletManager { try watcherService.stopWatcher(watcherId: watcherId) activeWatchers.remove(watcherId) activeWatcherElectrumUrls[watcherId] = nil + activeWatcherXpubs[watcherId] = nil watcherData[watcherId] = nil listeners[watcherId] = nil return true diff --git a/BitkitTests/HwWalletManagerTests.swift b/BitkitTests/HwWalletManagerTests.swift index 8d3986dd2..6a07849fc 100644 --- a/BitkitTests/HwWalletManagerTests.swift +++ b/BitkitTests/HwWalletManagerTests.swift @@ -465,6 +465,29 @@ final class HwWalletManagerTests: XCTestCase { XCTAssertEqual(params?.accountType, .nativeSegwit) } + func testWatcherRestartsWhenXpubChangesForSameDeviceAndType() async { + let mock = MockWatcherService() + let vm = makeViewModel(watcherService: mock, monitored: ["nativeSegwit"]) + vm.updateDevices(knownDevices: [makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z"])], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 1 } + vm.handleWatcherEvent(watcherId: watcherId("dev1", "nativeSegwit"), event: makeEvent( + [makeActivity(txId: "t1", value: 40000, txType: .received)], total: 40000 + )) + let originalWalletId = vm.wallets.first?.walletId + + // Same device id + address type, new xpub (e.g. a passphrase/hidden wallet, or re-fetched + // accounts): the watcher id is unchanged but the watched key — and the derived wallet id — + // differ, so the old watcher must be torn down and a new one started on the new xpub + // instead of feeding the old wallet's balance under the new wallet id. + vm.updateDevices(knownDevices: [makeDevice(id: "dev1", xpubs: ["nativeSegwit": "z2"])], connectedDeviceId: nil) + await waitUntil { mock.startedParams.count == 2 } + + XCTAssertTrue(mock.stoppedWatcherIds.contains(watcherId("dev1", "nativeSegwit"))) + XCTAssertEqual(mock.startedParams.last?.extendedKey, "z2") + XCTAssertNotEqual(vm.wallets.first?.walletId, originalWalletId) + XCTAssertEqual(vm.wallets.first?.balanceSats, 0, "stale old-xpub balance is dropped until the new watcher reports") + } + func testReconcileForSettingsChangeSkipsUnchangedAndActsOnChange() async { let mock = MockWatcherService() var monitored: Set = ["nativeSegwit"] From 4d788bd176c3429d90948796078adc55d4f74a63 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 14:23:42 -0300 Subject: [PATCH 46/52] fix: only save device after successfully fetch all addressess --- Bitkit/Managers/TrezorManager.swift | 102 ++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 20 deletions(-) diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index 48ad053d1..bea6be50c 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -267,8 +267,12 @@ final class TrezorManager { deviceFeatures = features showConfirmOnDevice = false - await saveCurrentDeviceAsKnown() - trezorLog("Connected to Trezor: \(device.path)") + let savedComplete = await saveCurrentDeviceAsKnown() + if savedComplete { + trezorLog("Connected to Trezor: \(device.path)") + } else { + trezorLog("Connected to Trezor: \(device.path) with incomplete account-key capture", level: "warn") + } } catch { let errorMsg = errorMessage(from: error) self.error = errorMsg @@ -421,13 +425,35 @@ final class TrezorManager { knownDevices = TrezorKnownDeviceStorage.loadAll() } - /// Captures the connected device's account xpubs so watch-only balances/activity - /// stay available while disconnected. - func saveCurrentDeviceAsKnown() async { - guard let device = connectedDevice else { return } + /// Captures the connected device's account xpubs so watch-only balances/activity stay available + /// while disconnected. The watch-only wallet id is derived from the captured xpub set, so a save + /// is blocked only when an address type failed *transiently* (a retryable transport error) and + /// isn't already covered by a previous capture — saving then would start a watcher under an id + /// that changes once that type is read on a later connect. A type the device genuinely lacks + /// (e.g. unsupported taproot) is accepted: its absence is stable across reconnects, so it neither + /// blocks the device nor churns the id. Merging keeps previously-captured xpubs. + /// Returns whether the device was saved. + @discardableResult + func saveCurrentDeviceAsKnown() async -> Bool { + guard let device = connectedDevice else { return false } let previous = TrezorKnownDeviceStorage.loadAll().first { $0.id == device.id } - let fetched = await fetchAccountXpubs() + let (fetched, transientFailures) = await fetchAccountXpubs() let mergedXpubs = (previous?.xpubs ?? [:]).merging(fetched) { _, new in new } + + guard !mergedXpubs.isEmpty else { + trezorLog("No account xpubs could be read from device; not saving", level: "warn") + error = "Couldn't read any account keys from your Trezor. Please reconnect to try again." + return false + } + + let retryableGaps = transientFailures.filter { mergedXpubs[$0.stringValue] == nil } + guard retryableGaps.isEmpty else { + let names = retryableGaps.map(\.localizedTitle).sorted().joined(separator: ", ") + trezorLog("Incomplete xpub capture (transient failures: \(names)); not saving partial device", level: "warn") + error = "Couldn't read all account keys from your Trezor (\(names)). Please reconnect to try again." + return false + } + let known = TrezorKnownDevice( id: device.id, name: device.name ?? "Trezor", @@ -441,26 +467,62 @@ final class TrezorManager { TrezorKnownDeviceStorage.save(known) loadKnownDevices() trezorLog("Saved known device: \(known.name) with \(mergedXpubs.count) xpubs") + return true + } + + private static let maxXpubFetchAttempts = 3 + private static let xpubFetchRetryDelayNanos: UInt64 = 300_000_000 + + /// Markers (matched against the underlying `TrezorError` carried in the wrapped error's text) + /// for transient transport problems worth retrying. Anything else is treated as the address + /// type being genuinely unavailable on this device — e.g. taproot on firmware without BIP86 — + /// which must not block the device, since that absence is stable across reconnects. + private static let transientFailureMarkers = [ + "TransportError", "ConnectionError", "DeviceDisconnected", "DeviceBusy", "Timeout", "IoError", "SessionError", + ] + + private static func isTransientTransportFailure(_ error: Error) -> Bool { + let text = (error as? AppError)?.debugMessage ?? "\(error)" + return transientFailureMarkers.contains { text.contains($0) } } - /// Per-type failures are swallowed so a single missing type doesn't block the rest. - func fetchAccountXpubs() async -> [String: String] { + /// Reads one account xpub per address type. Transient transport failures (e.g. a BLE timeout + /// under load) are retried; a permanent rejection (an unsupported address type) is not. Returns + /// the captured xpubs and the address types that still failed *transiently* after all retries, + /// so the caller can block a save on those while accepting a device that merely lacks a type. + func fetchAccountXpubs() async -> (xpubs: [String: String], transientFailures: Set) { let coinType = selectedNetwork == .bitcoin ? "0" : "1" var result: [String: String] = [:] + var transientFailures: Set = [] for addressType in AddressScriptType.allAddressTypes { - do { - let params = TrezorGetPublicKeyParams( - path: addressType.accountDerivationPath(coinType: coinType), - coin: selectedNetwork, - showOnTrezor: false - ) - let response = try await trezorService.getPublicKey(params: params) - result[addressType.stringValue] = response.xpub - } catch { - trezorLog("Could not read xpub for '\(addressType.stringValue)': \(error)", level: "warn") + let params = TrezorGetPublicKeyParams( + path: addressType.accountDerivationPath(coinType: coinType), + coin: selectedNetwork, + showOnTrezor: false + ) + var lastError: Error? + for attempt in 1 ... Self.maxXpubFetchAttempts { + do { + result[addressType.stringValue] = try await trezorService.getPublicKey(params: params).xpub + lastError = nil + break + } catch { + lastError = error + trezorLog( + "Could not read xpub for '\(addressType.stringValue)' (attempt \(attempt)/\(Self.maxXpubFetchAttempts)): \(error)", + level: "warn" + ) + guard Self.isTransientTransportFailure(error) else { break } + if attempt < Self.maxXpubFetchAttempts { + try? await Task.sleep(nanoseconds: Self.xpubFetchRetryDelayNanos) + } + } + } + if let lastError, Self.isTransientTransportFailure(lastError) { + transientFailures.insert(addressType) } } - return result + return (result, transientFailures) } func forgetDevice(id: String) async { From 14566f655036514a63302dc2d8ef67baa7ba2f88 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Thu, 25 Jun 2026 14:27:41 -0300 Subject: [PATCH 47/52] fix: match zero balance sugggestion with android --- Bitkit/Components/Widgets/Suggestions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bitkit/Components/Widgets/Suggestions.swift b/Bitkit/Components/Widgets/Suggestions.swift index ac4195d1d..779f0bb13 100644 --- a/Bitkit/Components/Widgets/Suggestions.swift +++ b/Bitkit/Components/Widgets/Suggestions.swift @@ -33,7 +33,7 @@ enum WalletSuggestionState { /// Ordered suggestion card IDs per wallet state (priority: first = highest). /// Max 4 cards are shown; when one is dismissed or completed, the next in this list is shown. private let suggestionOrderByState: [WalletSuggestionState: [String]] = [ - .empty: ["buyBitcoin", "transferToSpending", "support", "backupSeedPhrase", "pin", "profile", "invite"], + .empty: ["buyBitcoin", "transferToSpending", "hardware", "support", "backupSeedPhrase", "pin", "profile", "invite"], .onchain: ["backupSeedPhrase", "pin", "transferToSpending", "hardware", "support", "profile", "invite", "buyBitcoin"], .spending: ["quickpay", "notifications", "shop", "hardware", "profile", "support", "invite", "buyBitcoin"], ] From e83dd03d208ede828f61e2729405884e11734e8c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Fri, 26 Jun 2026 08:09:10 -0300 Subject: [PATCH 48/52] fix: remove old remove device check with possibly stable data and reuse syncWatcher check logic --- Bitkit/Managers/HwWalletManager.swift | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index b99c5a00d..bb7c64d8e 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -250,10 +250,6 @@ final class HwWalletManager { lastPersisted = lastPersisted.filter { hwWalletIds.contains($0.key) } } - private func desiredWatcherIds() -> Set { - Set(desiredWatcherSpecs().map(\.watcherId)) - } - private func startWatcher(_ spec: WatcherSpec) { guard let addressType = AddressScriptType.from(string: spec.addressType) else { return } let network = networkProvider() @@ -276,19 +272,11 @@ final class HwWalletManager { do { try await watcherService.startWatcher(params: params, listener: listener) pendingWatcherStarts.remove(spec.watcherId) - // The device may have been forgotten or its address type disabled while the start - // was in flight; if this watcher is no longer desired, tear it down instead of - // resurrecting a forgotten wallet or a stale address type. - guard desiredWatcherIds().contains(spec.watcherId) else { - try? watcherService.stopWatcher(watcherId: spec.watcherId) - listeners[spec.watcherId] = nil - retryingWatcherStarts.remove(spec.watcherId) - return - } activeWatchers.insert(spec.watcherId) activeWatcherElectrumUrls[spec.watcherId] = spec.electrumUrl activeWatcherXpubs[spec.watcherId] = spec.xpub retryingWatcherStarts.remove(spec.watcherId) + syncWatchers() } catch { pendingWatcherStarts.remove(spec.watcherId) listeners[spec.watcherId] = nil From a80db295b6f5dc219a55c0a13738925dd0eda887 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Fri, 26 Jun 2026 08:11:50 -0300 Subject: [PATCH 49/52] fix: set device as know after setting passphrase --- Bitkit/Managers/TrezorManager.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Bitkit/Managers/TrezorManager.swift b/Bitkit/Managers/TrezorManager.swift index bea6be50c..50f9451a5 100644 --- a/Bitkit/Managers/TrezorManager.swift +++ b/Bitkit/Managers/TrezorManager.swift @@ -398,6 +398,8 @@ final class TrezorManager { deviceFeatures = features showConfirmOnDevice = false trezorLog("Reconnected with wallet mode \(mode)") + + await saveCurrentDeviceAsKnown() } catch { clearDisconnectedDeviceState(errorMessage: errorMessage(from: error)) trezorLog("Reconnect after wallet-mode switch failed: \(error)", level: "error") From eea9bb1ac10f1df5f31f78d83c573bbd9a427f70 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Fri, 26 Jun 2026 08:16:43 -0300 Subject: [PATCH 50/52] fix: auto-reconnect gated on isPinVerified || with an .onChange(of: isPinVerified) to reconnect on unlock so the pairing-code sheet can present. --- Bitkit/AppScene.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Bitkit/AppScene.swift b/Bitkit/AppScene.swift index 0ac425c24..dd9bd46b0 100644 --- a/Bitkit/AppScene.swift +++ b/Bitkit/AppScene.swift @@ -117,6 +117,9 @@ struct AppScene: View { // Bridge Trezor device state into the watch-only manager without coupling the two: // TrezorManager bumps devicesRevision on any device/connection change. .onChange(of: trezorManager.devicesRevision) { _, _ in pushHardwareDevices() } + .onChange(of: isPinVerified) { _, verified in + if verified { Task { await trezorManager.autoReconnect() } } + } .onReceive(settings.settingsPublisher) { _ in hwWalletManager.reconcileForSettingsChange() } .onChange(of: migrations.isShowingMigrationLoading) { _, isLoading in if !isLoading { @@ -622,8 +625,9 @@ struct AppScene: View { if newPhase == .active { // Reconnect a known hardware device so its connection indicator turns green again; - // watch-only balances stay live regardless. - Task { await trezorManager.autoReconnect() } + if isPinVerified || !settings.pinEnabled { + Task { await trezorManager.autoReconnect() } + } if wallet.walletExists == true { Task { await clearDeliveredNotifications() From 6ca4ce722a55b06e50fa3a7f4f1f10bfffc38edd Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Fri, 26 Jun 2026 10:06:20 -0300 Subject: [PATCH 51/52] refactor: single source of true electrum url --- Bitkit/Constants/Env.swift | 13 ++++++++----- Bitkit/Services/OnChainHwService.swift | 22 +++++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Bitkit/Constants/Env.swift b/Bitkit/Constants/Env.swift index ce029cfd6..fa4f346ea 100644 --- a/Bitkit/Constants/Env.swift +++ b/Bitkit/Constants/Env.swift @@ -164,11 +164,7 @@ enum Env { // MARK: Server URLs - static var electrumServerUrl: String { - if isE2E, e2eBackend == "local" { - return "tcp://127.0.0.1:60001" - } - + static func electrumServerUrl(for network: LDKNode.Network) -> String { switch network { case .bitcoin: return "ssl://bitkit.to:9999" case .signet: return "ssl://mempool.space:60602" @@ -177,6 +173,13 @@ enum Env { } } + static var electrumServerUrl: String { + if isE2E, e2eBackend == "local" { + return "tcp://127.0.0.1:60001" + } + return electrumServerUrl(for: network) + } + static var trezorBridgeEnabled: Bool { (isDebug || isE2E) && boolConfigValue("TREZOR_BRIDGE") } diff --git a/Bitkit/Services/OnChainHwService.swift b/Bitkit/Services/OnChainHwService.swift index 619489809..2cabcf081 100644 --- a/Bitkit/Services/OnChainHwService.swift +++ b/Bitkit/Services/OnChainHwService.swift @@ -1,5 +1,6 @@ import BitkitCore import Foundation +import LDKNode /// Watcher-related service calls, extracted as a protocol so unit tests can /// substitute a mock. @@ -165,19 +166,12 @@ extension OnChainHwService { Env.network == .bitcoin ? "0'" : "1'" } - /// Hardcoded Electrum server URL per network (with the regtest dev override). + /// Electrum server URL per network (with the regtest dev override), delegating to `Env`. static func electrumUrlForNetwork(_ network: TrezorCoinType) -> String { if network == .regtest, let trezorElectrumUrl = Env.trezorElectrumUrl { return trezorElectrumUrl } - switch network { - case .bitcoin: - return "ssl://bitkit.to:9999" - case .testnet, .signet: - return "ssl://electrum.blockstream.info:60002" - case .regtest: - return "ssl://electrs.bitkit.stag0.blocktank.to:9999" - } + return Env.electrumServerUrl(for: network.ldkNetwork) } /// The app's configured Electrum server (falls back to the default). @@ -197,4 +191,14 @@ extension TrezorCoinType { case .regtest: .regtest } } + + /// The `LDKNode.Network` this coin type maps to, used to resolve the Electrum URL from `Env`. + var ldkNetwork: LDKNode.Network { + switch self { + case .bitcoin: .bitcoin + case .testnet: .testnet + case .signet: .signet + case .regtest: .regtest + } + } } From 136d6df75a4ffe1699658570cd48edc9d284aa94 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Fri, 26 Jun 2026 10:10:43 -0300 Subject: [PATCH 52/52] fix: unniform device name rules --- .../Components/Trezor/TrezorDeviceRow.swift | 18 ++---------- .../Extensions/TrezorDevice+DisplayName.swift | 21 ++++++++++++++ Bitkit/Managers/HwWalletManager.swift | 10 +------ BitkitTests/HwWalletNameTests.swift | 28 +++++++++++++++++++ 4 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 Bitkit/Extensions/TrezorDevice+DisplayName.swift create mode 100644 BitkitTests/HwWalletNameTests.swift diff --git a/Bitkit/Components/Trezor/TrezorDeviceRow.swift b/Bitkit/Components/Trezor/TrezorDeviceRow.swift index 7c8feacfc..04adeda98 100644 --- a/Bitkit/Components/Trezor/TrezorDeviceRow.swift +++ b/Bitkit/Components/Trezor/TrezorDeviceRow.swift @@ -24,7 +24,7 @@ struct TrezorDeviceRow: View { // Device info VStack(alignment: .leading, spacing: 4) { - Text(displayName) + Text(device.displayName) .font(.system(size: 16, weight: .semibold)) .foregroundColor(.white) @@ -58,20 +58,6 @@ struct TrezorDeviceRow: View { .accessibilityIdentifier(device.path.hasPrefix("bridge:") ? "TrezorDevice-bridge" : "TrezorDevice-\(device.path)") } - private var displayName: String { - if let label = device.label, !label.isEmpty { - return label - } - return modelName - } - - private var modelName: String { - if let model = device.model { - return "Trezor \(model)" - } - return "Trezor" - } - private var transportIcon: String { switch device.transportType { case .bluetooth: @@ -119,7 +105,7 @@ struct KnownDeviceRow: View { // Device info VStack(alignment: .leading, spacing: 4) { - Text(device.label ?? device.name) + Text(device.displayName) .font(.system(size: 16, weight: .semibold)) .foregroundColor(.white) diff --git a/Bitkit/Extensions/TrezorDevice+DisplayName.swift b/Bitkit/Extensions/TrezorDevice+DisplayName.swift new file mode 100644 index 000000000..343816001 --- /dev/null +++ b/Bitkit/Extensions/TrezorDevice+DisplayName.swift @@ -0,0 +1,21 @@ +import BitkitCore + +/// Canonical Trezor display name: the user-set label when it differs from the factory model, +/// otherwise the vendor-prefixed model, falling back to "Trezor". +func resolveHwWalletName(label: String?, model: String?) -> String { + if let label, !label.isEmpty, label != model { return label } + guard let model else { return "Trezor" } + return model.hasPrefix("Trezor") ? model : "Trezor \(model)" +} + +extension TrezorKnownDevice { + var displayName: String { + resolveHwWalletName(label: label, model: model) + } +} + +extension TrezorDeviceInfo { + var displayName: String { + resolveHwWalletName(label: label, model: model) + } +} diff --git a/Bitkit/Managers/HwWalletManager.swift b/Bitkit/Managers/HwWalletManager.swift index bb7c64d8e..ee8e8c7b9 100644 --- a/Bitkit/Managers/HwWalletManager.swift +++ b/Bitkit/Managers/HwWalletManager.swift @@ -410,7 +410,7 @@ final class HwWalletManager { return HwWallet( id: device.id, walletId: group.walletId, - name: displayName(of: device), + name: device.displayName, model: device.model, isConnected: connectedDevice != nil, balanceSats: deviceWatchers.reduce(UInt64(0)) { $0.saturatingAdd($1.balanceSats) }, @@ -440,14 +440,6 @@ final class HwWalletManager { // MARK: - Helpers - /// The label is the user-set name stored on the device; without one (or with the factory - /// default that mirrors the model), fall back to the vendor-prefixed model. - private func displayName(of device: TrezorKnownDevice) -> String { - if let label = device.label, label != device.model { return label } - guard let model = device.model else { return "Trezor" } - return model.hasPrefix("Trezor") ? model : "Trezor \(model)" - } - private func deviceId(fromWatcherId watcherId: String) -> String { guard let range = watcherId.range(of: Constants.watcherIdSeparator) else { return watcherId } return String(watcherId[..