diff --git a/BDKSwiftExampleWallet.xcodeproj/project.pbxproj b/BDKSwiftExampleWallet.xcodeproj/project.pbxproj index ef41cd63..6dbdcb35 100644 --- a/BDKSwiftExampleWallet.xcodeproj/project.pbxproj +++ b/BDKSwiftExampleWallet.xcodeproj/project.pbxproj @@ -59,6 +59,9 @@ AE6716012A9AC089005C193F /* KeyServiceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6716002A9AC089005C193F /* KeyServiceError.swift */; }; AE6F34D82AA6C1800087E700 /* Network+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6F34D72AA6C1800087E700 /* Network+Extensions.swift */; }; AE6F34DA2AA6C1E00087E700 /* Balance+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6F34D92AA6C1E00087E700 /* Balance+Extensions.swift */; }; + AE7053262DE79AA30091DD78 /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = AE7053252DE79AA30091DD78 /* BitcoinDevKit */; }; + AE7323992DF9BF9700D9BAE2 /* TxDetails+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE7323982DF9BF9700D9BAE2 /* TxDetails+Extensions.swift */; }; + AE73239B2DF9C00F00D9BAE2 /* TxId+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE73239A2DF9C00F00D9BAE2 /* TxId+Extensions.swift */; }; AE7839FD2AB4E18D005F0CBA /* AmountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE7839FC2AB4E18D005F0CBA /* AmountView.swift */; }; AE783A012AB4E5E1005F0CBA /* BuildTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE783A002AB4E5E1005F0CBA /* BuildTransactionView.swift */; }; AE783A032AB4ECC2005F0CBA /* AddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE783A022AB4ECC2005F0CBA /* AddressView.swift */; }; @@ -77,6 +80,7 @@ AE91CEED2C0FDB70000AAD20 /* SentAndReceivedValues+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE91CEEC2C0FDB70000AAD20 /* SentAndReceivedValues+Extensions.swift */; }; AE91CEEF2C0FDBC7000AAD20 /* CanonicalTx+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE91CEEE2C0FDBC7000AAD20 /* CanonicalTx+Extensions.swift */; }; AE96F6622A424C400055623C /* BDKSwiftExampleWalletReceiveViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE96F6612A424C400055623C /* BDKSwiftExampleWalletReceiveViewModelTests.swift */; }; + AEA0A6272E297203008A525B /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = AEA0A6262E297203008A525B /* BitcoinDevKit */; }; AEAB03112ABDDB86000C9528 /* FeeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEAB03102ABDDB86000C9528 /* FeeViewModel.swift */; }; AEAB03132ABDDBF4000C9528 /* AmountViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEAB03122ABDDBF4000C9528 /* AmountViewModel.swift */; }; AEAF83B62B7BD4D10019B23B /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = AEAF83B52B7BD4D10019B23B /* CodeScanner */; }; @@ -99,6 +103,7 @@ AEE6C74C2ABCB3E200442ADD /* Transaction+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6C74B2ABCB3E200442ADD /* Transaction+Extensions.swift */; }; AEE6C74F2ABCBA4600442ADD /* WalletSyncState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6C74E2ABCBA4600442ADD /* WalletSyncState.swift */; }; AEE83A492C07F54B00834468 /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = AEE83A482C07F54B00834468 /* BitcoinDevKit */; }; + AEEA0E402DEF80B600C83255 /* Outpoint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEA0E3F2DEF80B600C83255 /* Outpoint+Extensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -161,6 +166,8 @@ AE6716002A9AC089005C193F /* KeyServiceError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyServiceError.swift; sourceTree = ""; }; AE6F34D72AA6C1800087E700 /* Network+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Network+Extensions.swift"; sourceTree = ""; }; AE6F34D92AA6C1E00087E700 /* Balance+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Balance+Extensions.swift"; sourceTree = ""; }; + AE7323982DF9BF9700D9BAE2 /* TxDetails+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TxDetails+Extensions.swift"; sourceTree = ""; }; + AE73239A2DF9C00F00D9BAE2 /* TxId+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TxId+Extensions.swift"; sourceTree = ""; }; AE7839FC2AB4E18D005F0CBA /* AmountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmountView.swift; sourceTree = ""; }; AE783A002AB4E5E1005F0CBA /* BuildTransactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildTransactionView.swift; sourceTree = ""; }; AE783A022AB4ECC2005F0CBA /* AddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressView.swift; sourceTree = ""; }; @@ -197,6 +204,7 @@ AED79FC42A97D47D00FD3C7D /* BDKSwiftExampleWalletSendViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BDKSwiftExampleWalletSendViewModelTests.swift; sourceTree = ""; }; AEE6C74B2ABCB3E200442ADD /* Transaction+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Transaction+Extensions.swift"; sourceTree = ""; }; AEE6C74E2ABCBA4600442ADD /* WalletSyncState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSyncState.swift; sourceTree = ""; }; + AEEA0E3F2DEF80B600C83255 /* Outpoint+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Outpoint+Extensions.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -204,7 +212,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + AE7053262DE79AA30091DD78 /* BitcoinDevKit in Frameworks */, AE2DD83F2D6FEF3600E5F212 /* BitcoinDevKit in Frameworks */, + AEA0A6272E297203008A525B /* BitcoinDevKit in Frameworks */, AE187D782C9BB3B50081D0C3 /* BitcoinDevKit in Frameworks */, AE29ED0F2BBE2E7100EB9C4F /* BitcoinDevKit in Frameworks */, AEAF83B62B7BD4D10019B23B /* CodeScanner in Frameworks */, @@ -563,6 +573,9 @@ AE184EFB2BFE52C800374362 /* Amount+Extensions.swift */, AE91CEEC2C0FDB70000AAD20 /* SentAndReceivedValues+Extensions.swift */, AE91CEEE2C0FDBC7000AAD20 /* CanonicalTx+Extensions.swift */, + AEEA0E3F2DEF80B600C83255 /* Outpoint+Extensions.swift */, + AE7323982DF9BF9700D9BAE2 /* TxDetails+Extensions.swift */, + AE73239A2DF9C00F00D9BAE2 /* TxId+Extensions.swift */, ); path = "BDK+Extensions"; sourceTree = ""; @@ -595,6 +608,8 @@ AE2DD8382D6FE9B000E5F212 /* BitcoinDevKit */, AE2DD83B2D6FEC3100E5F212 /* BitcoinDevKit */, AE2DD83E2D6FEF3600E5F212 /* BitcoinDevKit */, + AE7053252DE79AA30091DD78 /* BitcoinDevKit */, + AEA0A6262E297203008A525B /* BitcoinDevKit */, ); productName = BDKSwiftExampleWallet; productReference = AE4984782A1BBBD6009951E2 /* BDKSwiftExampleWallet.app */; @@ -652,7 +667,7 @@ AE7D5A0C2A7EE62200EAC8CE /* XCRemoteSwiftPackageReference "KeychainAccess" */, AEB735D12B2CC4B900F99DBB /* XCRemoteSwiftPackageReference "BitcoinUI" */, AEAF83B42B7BD4D10019B23B /* XCRemoteSwiftPackageReference "CodeScanner" */, - AEA2DEF12D70F8840067C0EB /* XCRemoteSwiftPackageReference "bdk-swift" */, + AEA0A6252E297203008A525B /* XCRemoteSwiftPackageReference "bdk-swift" */, ); productRefGroup = AE4984792A1BBBD6009951E2 /* Products */; projectDirPath = ""; @@ -728,12 +743,14 @@ AE2ADD742B61E8F500C2A823 /* SettingsView.swift in Sources */, AE2381AF2C605B1D00F6B00C /* ActivityListViewModel.swift in Sources */, AE6F34D82AA6C1800087E700 /* Network+Extensions.swift in Sources */, + AE73239B2DF9C00F00D9BAE2 /* TxId+Extensions.swift in Sources */, AE1390C72A7DB0AF0098127A /* KeyService.swift in Sources */, AED4CC0A2A1D297600CE1831 /* BDKService.swift in Sources */, AED4CC102A1D522100CE1831 /* WalletView.swift in Sources */, AE7F67092A7451AA00CED561 /* Price.swift in Sources */, AE184EFC2BFE52C800374362 /* Amount+Extensions.swift in Sources */, 779E70892DB9C9AB006E22D3 /* WalletFullScanScriptInspector.swift in Sources */, + AEEA0E402DEF80B600C83255 /* Outpoint+Extensions.swift in Sources */, AE2381B12C60690900F6B00C /* LocalOutput+Extensions.swift in Sources */, 779E70872DB9C98A006E22D3 /* WalletSyncScriptInspector.swift in Sources */, AE7F67072A744CE200CED561 /* Double+Extensions.swift in Sources */, @@ -755,6 +772,7 @@ AE34DDAE2B6B320F00F04AD4 /* WalletRecoveryViewModel.swift in Sources */, AE0C30F92A804B65008F1EAE /* OnboardingViewModel.swift in Sources */, AE3902A42A3B4CD900BEC318 /* HomeView.swift in Sources */, + AE7323992DF9BF9700D9BAE2 /* TxDetails+Extensions.swift in Sources */, AE0C30FD2A804BC1008F1EAE /* ReceiveViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1063,12 +1081,12 @@ version = 4.2.2; }; }; - AEA2DEF12D70F8840067C0EB /* XCRemoteSwiftPackageReference "bdk-swift" */ = { + AEA0A6252E297203008A525B /* XCRemoteSwiftPackageReference "bdk-swift" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/bitcoindevkit/bdk-swift"; requirement = { kind = exactVersion; - version = 1.2.0; + version = 2.0.0; }; }; AEAF83B42B7BD4D10019B23B /* XCRemoteSwiftPackageReference "CodeScanner" */ = { @@ -1118,11 +1136,20 @@ isa = XCSwiftPackageProductDependency; productName = BitcoinDevKit; }; + AE7053252DE79AA30091DD78 /* BitcoinDevKit */ = { + isa = XCSwiftPackageProductDependency; + productName = BitcoinDevKit; + }; AE7D5A0D2A7EE62200EAC8CE /* KeychainAccess */ = { isa = XCSwiftPackageProductDependency; package = AE7D5A0C2A7EE62200EAC8CE /* XCRemoteSwiftPackageReference "KeychainAccess" */; productName = KeychainAccess; }; + AEA0A6262E297203008A525B /* BitcoinDevKit */ = { + isa = XCSwiftPackageProductDependency; + package = AEA0A6252E297203008A525B /* XCRemoteSwiftPackageReference "bdk-swift" */; + productName = BitcoinDevKit; + }; AEAF83B52B7BD4D10019B23B /* CodeScanner */ = { isa = XCSwiftPackageProductDependency; package = AEAF83B42B7BD4D10019B23B /* XCRemoteSwiftPackageReference "CodeScanner" */; diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Amount+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Amount+Extensions.swift index f6748480..ecf30940 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Amount+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Amount+Extensions.swift @@ -13,3 +13,7 @@ extension Amount: @retroactive Equatable { return lhs.toSat() == rhs.toSat() } } + +extension Amount { + static let mock = Amount.fromSat(satoshi: 100_000) +} diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/CanonicalTx+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/CanonicalTx+Extensions.swift index 384e0122..9ae22215 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/CanonicalTx+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/CanonicalTx+Extensions.swift @@ -16,11 +16,27 @@ extension CanonicalTx { confirmationBlockTime: .init( blockId: .init( height: UInt32(12), - hash: "hash" + // hash: try! BlockHash.fromBytes( + // bytes: Data([ + // 0xc1, 0xf9, 0xfe, 0x0d, 0x7f, 0x97, 0xc6, 0x49, + // 0x0f, 0x83, 0x60, 0xcf, 0x71, 0xbb, 0xef, 0x15, + // 0x1f, 0x2e, 0x73, 0x30, 0x2b, 0xd0, 0x6f, 0x16, + // 0x90, 0xd6, 0x40, 0xb9, 0x6f, 0xb9, 0x44, 0x57, + // ]) + // ) + hash: try! BlockHash.fromString(hex: String.mockHashHex) ), confirmationTime: UInt64(21) ), - transitively: "c1f9fe0d7f97c6490f8360cf71bbef151f2e73302bd06f1690d640b96fb94457" + // transitively: try! Txid.fromBytes( + // bytes: Data([ + // 0xc1, 0xf9, 0xfe, 0x0d, 0x7f, 0x97, 0xc6, 0x49, + // 0x0f, 0x83, 0x60, 0xcf, 0x71, 0xbb, 0xef, 0x15, + // 0x1f, 0x2e, 0x73, 0x30, 0x2b, 0xd0, 0x6f, 0x16, + // 0x90, 0xd6, 0x40, 0xb9, 0x6f, 0xb9, 0x44, 0x57, + // ]) + // ) + transitively: try! Txid.fromString(hex: String.mockHashHex) ) ) } diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/ChainPosition+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/ChainPosition+Extensions.swift index a863a03e..c111900e 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/ChainPosition+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/ChainPosition+Extensions.swift @@ -32,3 +32,7 @@ extension ChainPosition { } } } + +extension ChainPosition { + static let mock = ChainPosition.unconfirmed(timestamp: nil) +} diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Connection+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Connection+Extensions.swift index 3f09b059..d854537b 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Connection+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Connection+Extensions.swift @@ -1,8 +1,8 @@ import BitcoinDevKit import Foundation -extension Connection { - static func createConnection() throws -> Connection { +extension Persister { + static func createConnection() throws -> Persister { let documentsDirectoryURL = URL.documentsDirectory let walletDataDirectoryURL = documentsDirectoryURL.appendingPathComponent("wallet_data") @@ -14,7 +14,7 @@ extension Connection { try FileManager.default.removeOldFlatFileIfNeeded(at: documentsDirectoryURL) let persistenceBackendPath = walletDataDirectoryURL.appendingPathComponent("wallet.sqlite") .path - let connection = try Connection(path: persistenceBackendPath) - return connection + let persister = try Persister.newSqlite(path: persistenceBackendPath) + return persister } } diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/LocalOutput+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/LocalOutput+Extensions.swift index 03e2f132..2003f03b 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/LocalOutput+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/LocalOutput+Extensions.swift @@ -6,17 +6,26 @@ // import BitcoinDevKit +import Foundation //#if DEBUG extension LocalOutput { static var mock = LocalOutput( outpoint: OutPoint( - txid: "txid", + // txid: try! Txid.fromBytes( + // bytes: Data([ + // 0xc1, 0xf9, 0xfe, 0x0d, 0x7f, 0x97, 0xc6, 0x49, + // 0x0f, 0x83, 0x60, 0xcf, 0x71, 0xbb, 0xef, 0x15, + // 0x1f, 0x2e, 0x73, 0x30, 0x2b, 0xd0, 0x6f, 0x16, + // 0x90, 0xd6, 0x40, 0xb9, 0x6f, 0xb9, 0x44, 0x57, + // ]) + // ), + txid: try! Txid.fromString(hex: String.mockHashHex), vout: UInt32(1) ), txout: TxOut( - value: UInt64(1), - scriptPubkey: Script(rawOutputScript: [UInt8(1)]) + value: .fromSat(satoshi: 1), + scriptPubkey: Script.init(rawOutputScript: Data([0x51])) ), keychain: .external, isSpent: false, diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Outpoint+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Outpoint+Extensions.swift new file mode 100644 index 00000000..4e373df3 --- /dev/null +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Outpoint+Extensions.swift @@ -0,0 +1,20 @@ +// +// Outpoint+Extensions.swift +// BDKSwiftExampleWallet +// +// Created by Matthew Ramsden on 6/3/25. +// + +import BitcoinDevKit +import Foundation + +extension OutPoint: Hashable { + public static func == (lhs: OutPoint, rhs: OutPoint) -> Bool { + lhs.txid == rhs.txid && lhs.vout == rhs.vout + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(txid) + hasher.combine(vout) + } +} diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Transaction+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Transaction+Extensions.swift index 5143ecdc..bb6c0805 100644 --- a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Transaction+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/Transaction+Extensions.swift @@ -6,17 +6,18 @@ // import BitcoinDevKit +import Foundation extension Transaction { var transactionID: String { - return self.computeTxid() + return "\(self.computeTxid())" } } //#if DEBUG extension Transaction { static var mock = try? Transaction( - transactionBytes: String.mockTransactionHex.hexStringToByteArray() + transactionBytes: Data(String.mockTransactionHex.hexStringToByteArray()) ) } //#endif diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxDetails+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxDetails+Extensions.swift new file mode 100644 index 00000000..23c001d4 --- /dev/null +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxDetails+Extensions.swift @@ -0,0 +1,22 @@ +// +// TxDetails+Extensions.swift +// BDKSwiftExampleWallet +// +// Created by Matthew Ramsden on 6/11/25. +// + +import BitcoinDevKit +import Foundation + +extension TxDetails { + static let mock = TxDetails( + txid: .mock!, + sent: .mock, + received: .mock, + fee: nil, + feeRate: nil, + balanceDelta: Int64(0), + chainPosition: .mock, + tx: .mock! + ) +} diff --git a/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxId+Extensions.swift b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxId+Extensions.swift new file mode 100644 index 00000000..bca094cb --- /dev/null +++ b/BDKSwiftExampleWallet/Extensions/BDK+Extensions/TxId+Extensions.swift @@ -0,0 +1,20 @@ +// +// TxId+Extensions.swift +// BDKSwiftExampleWallet +// +// Created by Matthew Ramsden on 6/11/25. +// + +import BitcoinDevKit +import Foundation + +extension Txid { + static let mock = try? Txid.fromBytes( + bytes: Data([ + 0xc1, 0xf9, 0xfe, 0x0d, 0x7f, 0x97, 0xc6, 0x49, + 0x0f, 0x83, 0x60, 0xcf, 0x71, 0xbb, 0xef, 0x15, + 0x1f, 0x2e, 0x73, 0x30, 0x2b, 0xd0, 0x6f, 0x16, + 0x90, 0xd6, 0x40, 0xb9, 0x6f, 0xb9, 0x44, 0x57, + ]) + ) +} diff --git a/BDKSwiftExampleWallet/Extensions/Int+Extensions.swift b/BDKSwiftExampleWallet/Extensions/Int+Extensions.swift index 1802ca84..c9bdbcd9 100644 --- a/BDKSwiftExampleWallet/Extensions/Int+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/Int+Extensions.swift @@ -76,3 +76,16 @@ extension UInt64 { return Date(timeIntervalSince1970: TimeInterval(self)) } } + +extension Int64 { + private static var numberFormatter: NumberFormatter = { + let numberFormatter = NumberFormatter() + numberFormatter.numberStyle = .decimal + + return numberFormatter + }() + + var delimiter: String { + return Int64.numberFormatter.string(from: NSNumber(value: self)) ?? "" + } +} diff --git a/BDKSwiftExampleWallet/Extensions/String+Extensions.swift b/BDKSwiftExampleWallet/Extensions/String+Extensions.swift index 68660234..4f07315f 100644 --- a/BDKSwiftExampleWallet/Extensions/String+Extensions.swift +++ b/BDKSwiftExampleWallet/Extensions/String+Extensions.swift @@ -42,4 +42,9 @@ extension String { static var mockTransactionHex = "01000000000101604350f234b3b4b5fde5513ff89d222e91cabf452182ba0b8d076cf08a3813a30100000000ffffffff0240420f0000000000225120c8b7757fff5ceb41908a43bfadf749afbb97b50ece0896e88f2cd14f90844d7b8df6731d00000000225120ff38f143374565d74648006f8aabef9dad548344549d8516177ff613e26f7d360140298823f597d3cb7f4934a5ef0b1814e2ca8caa9f9da0a0b59a73922d98f83ec62587add48e3fa0d0b7cf704b2fce0277e2a70f9aed8a41f2823b810b92e0421d00000000" } +extension String { + static var mockHashHex: String { + "c1f9fe0d7f97c6490f8360cf71bbef151f2e73302bd06f1690d640b96fb94457" + } +} //#endif diff --git a/BDKSwiftExampleWallet/Resources/Localizable.xcstrings b/BDKSwiftExampleWallet/Resources/Localizable.xcstrings index 2744a873..c6dfee6d 100644 --- a/BDKSwiftExampleWallet/Resources/Localizable.xcstrings +++ b/BDKSwiftExampleWallet/Resources/Localizable.xcstrings @@ -66,6 +66,7 @@ } }, "- %llu sats" : { + "extractionState" : "stale", "localizations" : { "fr" : { "stringUnit" : { @@ -82,6 +83,7 @@ } }, "?" : { + "extractionState" : "stale", "localizations" : { "fr" : { "stringUnit" : { @@ -183,6 +185,16 @@ } } }, + "%@%lld sats" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$@%2$lld sats" + } + } + } + }, "%lld Output%@" : { "localizations" : { "en" : { @@ -254,6 +266,7 @@ } }, "%llu sats" : { + "extractionState" : "stale", "localizations" : { "fr" : { "stringUnit" : { @@ -270,6 +283,7 @@ } }, "+ %llu sats" : { + "extractionState" : "stale", "localizations" : { "fr" : { "stringUnit" : { diff --git a/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift b/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift index 1d4ac2e5..b866ac2b 100644 --- a/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift +++ b/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift @@ -12,7 +12,7 @@ private class BDKService { static var shared: BDKService = BDKService() private var balance: Balance? - private var connection: Connection? + private var persister: Persister? private var esploraClient: EsploraClient private let keyClient: KeyClient private var needsFullScan: Bool = false @@ -60,11 +60,11 @@ private class BDKService { guard let wallet = self.wallet else { throw WalletError.walletNotFound } - guard let connection = self.connection else { + guard let persister = self.persister else { throw WalletError.dbNotFound } let addressInfo = wallet.revealNextAddress(keychain: .external) - let _ = try wallet.persist(connection: connection) + let _ = try wallet.persist(persister: persister) return addressInfo.address.description } @@ -94,8 +94,8 @@ private class BDKService { } func createWallet(words: String?) throws { - self.connection = try Connection.createConnection() - guard let connection = connection else { + self.persister = try Persister.createConnection() + guard let persister = persister else { throw WalletError.dbNotFound } @@ -119,12 +119,12 @@ private class BDKService { ) let descriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .external, + keychainKind: .external, network: network ) let changeDescriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .internal, + keychainKind: .internal, network: network ) let backupInfo = BackupInfo( @@ -143,14 +143,14 @@ private class BDKService { descriptor: descriptor, changeDescriptor: changeDescriptor, network: network, - connection: connection + persister: persister ) self.wallet = wallet } func createWallet(descriptor: String?) throws { - self.connection = try Connection.createConnection() - guard let connection = connection else { + self.persister = try Persister.createConnection() + guard let persister = persister else { throw WalletError.dbNotFound } @@ -198,14 +198,14 @@ private class BDKService { descriptor: descriptor, changeDescriptor: changeDescriptor, network: network, - connection: connection + persister: persister ) self.wallet = wallet } func createWallet(xpub: String?) throws { - self.connection = try Connection.createConnection() - guard let connection = connection else { + self.persister = try Persister.createConnection() + guard let persister = persister else { throw WalletError.dbNotFound } @@ -222,13 +222,13 @@ private class BDKService { let descriptor = Descriptor.newBip86Public( publicKey: descriptorPublicKey, fingerprint: fingerprint, - keychain: .external, + keychainKind: .external, network: network ) let changeDescriptor = Descriptor.newBip86Public( publicKey: descriptorPublicKey, fingerprint: fingerprint, - keychain: .internal, + keychainKind: .internal, network: network ) @@ -248,7 +248,7 @@ private class BDKService { descriptor: descriptor, changeDescriptor: changeDescriptor, network: network, - connection: connection + persister: persister ) self.wallet = wallet } @@ -260,12 +260,12 @@ private class BDKService { try FileManager.default.removeOldFlatFileIfNeeded(at: documentsDirectoryURL) let persistenceBackendPath = walletDataDirectoryURL.appendingPathComponent("wallet.sqlite") .path - let connection = try Connection(path: persistenceBackendPath) - self.connection = connection + let persister = try Persister.newSqlite(path: persistenceBackendPath) + self.persister = persister let wallet = try Wallet.load( descriptor: descriptor, changeDescriptor: changeDescriptor, - connection: connection + persister: persister ) self.wallet = wallet } @@ -363,10 +363,10 @@ private class BDKService { parallelRequests: UInt64(5) ) let _ = try wallet.applyUpdate(update: update) - guard let connection = self.connection else { + guard let persister = self.persister else { throw WalletError.dbNotFound } - let _ = try wallet.persist(connection: connection) + let _ = try wallet.persist(persister: persister) } func fullScanWithInspector(inspector: FullScanScriptInspector) async throws { @@ -383,10 +383,10 @@ private class BDKService { parallelRequests: UInt64(5) ) let _ = try wallet.applyUpdate(update: update) - guard let connection = self.connection else { + guard let persister = self.persister else { throw WalletError.dbNotFound } - let _ = try wallet.persist(connection: connection) + let _ = try wallet.persist(persister: persister) } func calculateFee(tx: Transaction) throws -> Amount { @@ -412,6 +412,14 @@ private class BDKService { let values = wallet.sentAndReceived(tx: tx) return values } + + func txDetails(txid: Txid) throws -> TxDetails? { + guard let wallet = self.wallet else { + throw WalletError.walletNotFound + } + let txDetails = wallet.txDetails(txid: txid) + return txDetails + } } extension BDKService { @@ -440,6 +448,7 @@ struct BDKClient { let calculateFee: (Transaction) throws -> Amount let calculateFeeRate: (Transaction) throws -> UInt64 let sentAndReceived: (Transaction) throws -> SentAndReceivedValues + let txDetails: (Txid) throws -> TxDetails? let buildTransaction: (String, UInt64, UInt64) throws -> Psbt let getBackupInfo: () throws -> BackupInfo let needsFullScan: () -> Bool @@ -479,6 +488,7 @@ extension BDKClient { calculateFee: { tx in try BDKService.shared.calculateFee(tx: tx) }, calculateFeeRate: { tx in try BDKService.shared.calculateFeeRate(tx: tx) }, sentAndReceived: { tx in try BDKService.shared.sentAndReceived(tx: tx) }, + txDetails: { txid in try BDKService.shared.txDetails(txid: txid) }, buildTransaction: { (address, amount, feeRate) in try BDKService.shared.buildTransaction( address: address, @@ -527,19 +537,20 @@ extension BDKClient { fullScanWithInspector: { _ in }, getAddress: { "tb1pd8jmenqpe7rz2mavfdx7uc8pj7vskxv4rl6avxlqsw2u8u7d4gfs97durt" }, send: { _, _, _ in }, - calculateFee: { _ in Amount.fromSat(satoshi: UInt64(615)) }, - calculateFeeRate: { _ in return UInt64(6.15) }, + calculateFee: { _ in Amount.mock }, + calculateFeeRate: { _ in UInt64(6.15) }, sentAndReceived: { _ in return SentAndReceivedValues( - sent: Amount.fromSat(satoshi: UInt64(20000)), - received: Amount.fromSat(satoshi: UInt64(210)) + sent: .mock, + received: .mock ) }, + txDetails: { _ in .mock }, buildTransaction: { _, _, _ in let pb64 = """ cHNidP8BAIkBAAAAAeaWcxp4/+xSRJ2rhkpUJ+jQclqocoyuJ/ulSZEgEkaoAQAAAAD+////Ak/cDgAAAAAAIlEgqxShDO8ifAouGyRHTFxWnTjpY69Cssr3IoNQvMYOKG/OVgAAAAAAACJRIGnlvMwBz4Ylb6xLTe5g4ZeZCxmVH/XWG+CDlcPzzaoT8qoGAAABAStAQg8AAAAAACJRIFGGvSoLWt3hRAIwYa8KEyawiFTXoOCVWFxYtSofZuAsIRZ2b8YiEpzexWYGt8B5EqLM8BE4qxJY3pkiGw/8zOZGYxkAvh7sj1YAAIABAACAAAAAgAAAAAAEAAAAARcgdm/GIhKc3sVmBrfAeRKizPAROKsSWN6ZIhsP/MzmRmMAAQUge7cvJMsJmR56NzObGOGkm8vNqaAIJdnBXLZD2PvrinIhB3u3LyTLCZkeejczmxjhpJvLzamgCCXZwVy2Q9j764pyGQC+HuyPVgAAgAEAAIAAAACAAQAAAAYAAAAAAQUgtIFPrI2EW/+PJiAmYdmux88p0KgeAxDFLMoeQoS66hIhB7SBT6yNhFv/jyYgJmHZrsfPKdCoHgMQxSzKHkKEuuoSGQC+HuyPVgAAgAEAAIAAAACAAAAAAAIAAAAA """ - return try! Psbt(psbtBase64: pb64) + return try Psbt(psbtBase64: pb64) }, getBackupInfo: { BackupInfo( diff --git a/BDKSwiftExampleWallet/Service/Key Service/KeyService.swift b/BDKSwiftExampleWallet/Service/Key Service/KeyService.swift index 5ac41e8e..51714028 100644 --- a/BDKSwiftExampleWallet/Service/Key Service/KeyService.swift +++ b/BDKSwiftExampleWallet/Service/Key Service/KeyService.swift @@ -129,12 +129,12 @@ extension KeyClient { ) let descriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .external, + keychainKind: .external, network: mockKeyClientNetwork ) let changeDescriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .internal, + keychainKind: .internal, network: mockKeyClientNetwork ) let backupInfo = BackupInfo( diff --git a/BDKSwiftExampleWallet/View Model/Activity/TransactionDetailViewModel.swift b/BDKSwiftExampleWallet/View Model/Activity/TransactionDetailViewModel.swift index e500e67e..76b88893 100644 --- a/BDKSwiftExampleWallet/View Model/Activity/TransactionDetailViewModel.swift +++ b/BDKSwiftExampleWallet/View Model/Activity/TransactionDetailViewModel.swift @@ -14,8 +14,6 @@ import Observation class TransactionDetailViewModel { let bdkClient: BDKClient - var calculateFee: String? - var calculateFeeError: CalculateFeeError? var esploraError: EsploraError? var esploraURL: String? var network: String? @@ -28,18 +26,6 @@ class TransactionDetailViewModel { self.bdkClient = bdkClient } - func getCalulateFee(tx: BitcoinDevKit.Transaction) { - do { - let calculateFee = try bdkClient.calculateFee(tx) - let feeString = String(calculateFee.toSat()) - self.calculateFee = feeString - } catch let error as CalculateFeeError { - DispatchQueue.main.async { - self.calculateFeeError = error - } - } catch {} - } - func getEsploraUrl() { let savedEsploraURL = bdkClient.getEsploraURL() @@ -65,16 +51,4 @@ class TransactionDetailViewModel { self.network = bdkClient.getNetwork().description } - func getSentAndReceived(tx: BitcoinDevKit.Transaction) -> SentAndReceivedValues? { - do { - let sentAndReceived = try bdkClient.sentAndReceived(tx) - return sentAndReceived - } catch { - DispatchQueue.main.async { - self.transactionDetailsError = .generic(message: error.localizedDescription) - } - return nil - } - } - } diff --git a/BDKSwiftExampleWallet/View Model/Activity/TransactionListViewModel.swift b/BDKSwiftExampleWallet/View Model/Activity/TransactionListViewModel.swift index 18a3d6a3..e468f20a 100644 --- a/BDKSwiftExampleWallet/View Model/Activity/TransactionListViewModel.swift +++ b/BDKSwiftExampleWallet/View Model/Activity/TransactionListViewModel.swift @@ -22,10 +22,10 @@ class TransactionListViewModel { self.bdkClient = bdkClient } - func getSentAndReceived(tx: BitcoinDevKit.Transaction) -> SentAndReceivedValues? { + func getTxDetails(txid: Txid) -> TxDetails? { do { - let sentAndReceived = try bdkClient.sentAndReceived(tx) - return sentAndReceived + let txDetails = try bdkClient.txDetails(txid) + return txDetails } catch { self.walletTransactionsViewError = .generic( message: error.localizedDescription diff --git a/BDKSwiftExampleWallet/View/Activity/LocalOutputItemView.swift b/BDKSwiftExampleWallet/View/Activity/LocalOutputItemView.swift index 15e1a5c0..678dc146 100644 --- a/BDKSwiftExampleWallet/View/Activity/LocalOutputItemView.swift +++ b/BDKSwiftExampleWallet/View/Activity/LocalOutputItemView.swift @@ -33,7 +33,7 @@ struct LocalOutputItemView: View { VStack(alignment: .leading, spacing: 5) { - Text(output.outpoint.txid) + Text(output.outpoint.txid.description) .truncationMode(.middle) .lineLimit(1) .fontDesign(.monospaced) diff --git a/BDKSwiftExampleWallet/View/Activity/TransactionDetailView.swift b/BDKSwiftExampleWallet/View/Activity/TransactionDetailView.swift index b9970e23..7d267876 100644 --- a/BDKSwiftExampleWallet/View/Activity/TransactionDetailView.swift +++ b/BDKSwiftExampleWallet/View/Activity/TransactionDetailView.swift @@ -13,8 +13,7 @@ struct TransactionDetailView: View { @Bindable var viewModel: TransactionDetailViewModel @State private var isCopied = false @State private var showCheckmark = false - let amount: UInt64 - let canonicalTx: CanonicalTx + let txDetails: TxDetails var body: some View { @@ -22,34 +21,25 @@ struct TransactionDetailView: View { VStack(spacing: 8) { HStack(spacing: 3) { - let sentAndReceivedValues = viewModel.getSentAndReceived( - tx: canonicalTx.transaction - ) - if let value = sentAndReceivedValues { - let sent = value.sent - let received = value.received - if sent.toSat() == 0 && received.toSat() > 0 { - VStack { - Image("bitcoinsign.arrow.down") - .symbolRenderingMode(.hierarchical) - .font(.title) - Text("Receive") - } - } else if sent.toSat() > 0 && received.toSat() >= 0 { - VStack { - Image("bitcoinsign.arrow.up") - .symbolRenderingMode(.hierarchical) - .font(.title) - Text("Send") - } - } else { - Text("?") + if txDetails.balanceDelta >= 0 { + VStack { + Image("bitcoinsign.arrow.down") + .symbolRenderingMode(.hierarchical) + .font(.title) + Text("Receive") + } + } else { + VStack { + Image("bitcoinsign.arrow.up") + .symbolRenderingMode(.hierarchical) + .font(.title) + Text("Send") } } } .fontWeight(.semibold) - switch canonicalTx.chainPosition { + switch txDetails.chainPosition { case .confirmed(let confirmationBlockTime, _): Text("Block \(confirmationBlockTime.blockId.height.delimiter)") .foregroundStyle(.secondary) @@ -65,7 +55,7 @@ struct TransactionDetailView: View { VStack(spacing: 8) { HStack { - Text(amount.delimiter) + Text(abs(txDetails.balanceDelta).delimiter) Text("sats") } .lineLimit(1) @@ -75,7 +65,7 @@ struct TransactionDetailView: View { .fontWeight(.bold) .fontDesign(.rounded) VStack(spacing: 4) { - switch canonicalTx.chainPosition { + switch txDetails.chainPosition { case .confirmed(let confirmationBlockTime, _): Text( confirmationBlockTime.confirmationTime.toDate().formatted( @@ -95,8 +85,8 @@ struct TransactionDetailView: View { Text("Pending") } } - if let fee = viewModel.calculateFee { - Text("\(fee.formattedWithSeparator) sats fee") + if let fee = txDetails.fee { + Text("\(fee.toSat().delimiter) sats fee") } } .foregroundStyle(.secondary) @@ -110,7 +100,7 @@ struct TransactionDetailView: View { Button { if let esploraURL = viewModel.esploraURL { let urlString = - "\(esploraURL)/tx/\(canonicalTx.transaction.computeTxid())" + "\(esploraURL)/tx/\(txDetails.txid)" .replacingOccurrences(of: "/api", with: "") if let url = URL(string: urlString) { UIApplication.shared.open(url) @@ -124,7 +114,7 @@ struct TransactionDetailView: View { Spacer() } Button { - UIPasteboard.general.string = canonicalTx.transaction.computeTxid() + UIPasteboard.general.string = "\(txDetails.txid)" isCopied = true showCheckmark = true DispatchQueue.main.asyncAfter(deadline: .now() + 1) { @@ -133,7 +123,7 @@ struct TransactionDetailView: View { } } label: { HStack { - Text(canonicalTx.transaction.computeTxid()) + Text("\(txDetails.txid)") .lineLimit(1) .truncationMode(.middle) withAnimation { @@ -154,7 +144,6 @@ struct TransactionDetailView: View { .task { viewModel.getNetwork() viewModel.getEsploraUrl() - viewModel.getCalulateFee(tx: canonicalTx.transaction) } } @@ -179,8 +168,7 @@ struct TransactionDetailView: View { viewModel: .init( bdkClient: .mock ), - amount: UInt64(1_000_000), - canonicalTx: .mock + txDetails: .mock ) } #endif diff --git a/BDKSwiftExampleWallet/View/Activity/TransactionItemView.swift b/BDKSwiftExampleWallet/View/Activity/TransactionItemView.swift index 27dcb3b1..afd637c8 100644 --- a/BDKSwiftExampleWallet/View/Activity/TransactionItemView.swift +++ b/BDKSwiftExampleWallet/View/Activity/TransactionItemView.swift @@ -11,9 +11,8 @@ import SwiftUI struct TransactionItemView: View { @Environment(\.dynamicTypeSize) var dynamicTypeSize - let canonicalTx: CanonicalTx + let txDetails: TxDetails let isRedacted: Bool - let sentAndReceivedValues: SentAndReceivedValues var body: some View { @@ -36,14 +35,13 @@ struct TransactionItemView: View { .foregroundStyle(Color.gray.opacity(0.25)) Image( systemName: - sentAndReceivedValues.sent.toSat() == 0 - && sentAndReceivedValues.received.toSat() > 0 + txDetails.balanceDelta >= 0 ? "arrow.down" : "arrow.up" ) .font(.callout) .foregroundStyle( { - switch canonicalTx.chainPosition { + switch txDetails.chainPosition { case .confirmed(_, _): Color.bitcoinOrange case .unconfirmed(_): @@ -55,14 +53,14 @@ struct TransactionItemView: View { } VStack(alignment: .leading, spacing: 5) { - Text(canonicalTx.transaction.computeTxid()) + Text(txDetails.txid.description) .truncationMode(.middle) .lineLimit(1) .fontDesign(.monospaced) .fontWeight(.semibold) .font(.title) .foregroundStyle(.primary) - switch canonicalTx.chainPosition { + switch txDetails.chainPosition { case .confirmed(let confirmationBlockTime, _): Text( confirmationBlockTime.confirmationTime.toDate().formatted( @@ -99,17 +97,16 @@ struct TransactionItemView: View { Spacer() - Text( - sentAndReceivedValues.sent.toSat() == 0 - && sentAndReceivedValues.received.toSat() > 0 - ? "+ \(sentAndReceivedValues.received.toSat()) sats" - : "- \(sentAndReceivedValues.sent.toSat() - sentAndReceivedValues.received.toSat()) sats" - ) - .font(.subheadline) - .fontWeight(.semibold) - .fontDesign(.rounded) - .lineLimit(1) - .redacted(reason: isRedacted ? .placeholder : []) + let delta = txDetails.balanceDelta + let prefix = delta >= 0 ? "+ " : "- " + let amount = abs(delta) + + Text("\(prefix)\(amount) sats") + .font(.subheadline) + .fontWeight(.semibold) + .fontDesign(.rounded) + .lineLimit(1) + .redacted(reason: isRedacted ? .placeholder : []) } .padding(.vertical, 15.0) @@ -122,9 +119,8 @@ struct TransactionItemView: View { #if DEBUG #Preview { TransactionItemView( - canonicalTx: .mock, - isRedacted: false, - sentAndReceivedValues: .mock + txDetails: .mock, + isRedacted: false ) } #endif diff --git a/BDKSwiftExampleWallet/View/Activity/TransactionListView.swift b/BDKSwiftExampleWallet/View/Activity/TransactionListView.swift index 43104481..96c48935 100644 --- a/BDKSwiftExampleWallet/View/Activity/TransactionListView.swift +++ b/BDKSwiftExampleWallet/View/Activity/TransactionListView.swift @@ -19,12 +19,8 @@ struct TransactionListView: View { List { if transactions.isEmpty && walletSyncState == .syncing { TransactionItemView( - canonicalTx: .mock, - isRedacted: true, - sentAndReceivedValues: .init( - sent: Amount.fromSat(satoshi: UInt64(0)), - received: Amount.fromSat(satoshi: UInt64(0)) - ) + txDetails: .mock, + isRedacted: true ) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) @@ -94,24 +90,19 @@ struct TransactionListView: View { ) { item in let canonicalTx = item let tx = canonicalTx.transaction - if let sentAndReceivedValues = viewModel.getSentAndReceived(tx: tx) { + if let txDetails = viewModel.getTxDetails(txid: tx.computeTxid()) { NavigationLink( destination: TransactionDetailView( viewModel: .init( bdkClient: .live ), - amount: sentAndReceivedValues.sent.toSat() == 0 - ? sentAndReceivedValues.received.toSat() - : sentAndReceivedValues.sent.toSat() - - sentAndReceivedValues.received.toSat(), - canonicalTx: canonicalTx + txDetails: txDetails ) ) { TransactionItemView( - canonicalTx: canonicalTx, - isRedacted: false, - sentAndReceivedValues: sentAndReceivedValues + txDetails: txDetails, + isRedacted: false ) } diff --git a/BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift b/BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift index 2309f52b..2da5b4f8 100644 --- a/BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift +++ b/BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift @@ -8,20 +8,20 @@ import SwiftUI struct ActivityHomeHeaderView: View { - + let walletSyncState: WalletSyncState let progress: Float let inspectedScripts: UInt64 let totalScripts: UInt64 let needsFullScan: Bool - + let showAllTransactions: () -> Void - + var body: some View { HStack { Text("Activity") Spacer() - + HStack { if needsFullScan { Text("\(inspectedScripts)") @@ -78,7 +78,7 @@ struct ActivityHomeHeaderView: View { } .foregroundStyle(.secondary) .font(.caption) - + if walletSyncState == .synced { Button { self.showAllTransactions() @@ -95,7 +95,7 @@ struct ActivityHomeHeaderView: View { } .fontWeight(.bold) } - + @ViewBuilder private func syncImageIndicator() -> some View { switch walletSyncState { @@ -104,7 +104,7 @@ struct ActivityHomeHeaderView: View { Image(systemName: "checkmark.circle.fill") .foregroundStyle(.green) ) - + case .syncing: AnyView( Image(systemName: "slowmo") @@ -112,7 +112,7 @@ struct ActivityHomeHeaderView: View { .variableColor.cumulative ) ) - + case .notStarted: AnyView( Image(systemName: "arrow.clockwise") diff --git a/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift b/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift index 9c1e79ea..728c30a1 100644 --- a/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift +++ b/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift @@ -169,12 +169,12 @@ struct BuildTransactionView: View { .foregroundStyle(.green) if let transaction = viewModel.extractTransaction() { HStack { - Text(transaction.computeTxid()) + Text("\(transaction.computeTxid())") .lineLimit(1) .truncationMode(.middle) Spacer() Button { - UIPasteboard.general.string = transaction.computeTxid() + UIPasteboard.general.string = "\(transaction.computeTxid())" isCopied = true showCheckmark = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { diff --git a/BDKSwiftExampleWallet/View/WalletView.swift b/BDKSwiftExampleWallet/View/WalletView.swift index c6e59eff..010a6223 100644 --- a/BDKSwiftExampleWallet/View/WalletView.swift +++ b/BDKSwiftExampleWallet/View/WalletView.swift @@ -51,7 +51,7 @@ struct WalletView: View { ) { showAllTransactions = true } - + TransactionListView( viewModel: .init(), transactions: viewModel.recentTransactions, diff --git a/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletBDKServiceTests.swift b/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletBDKServiceTests.swift index f1999c62..9fb3b624 100644 --- a/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletBDKServiceTests.swift +++ b/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletBDKServiceTests.swift @@ -29,7 +29,7 @@ final class BDKSwiftExampleWalletBDKServiceTests: XCTestCase { XCTAssertEqual( transactionDetails.first?.transaction.transactionID, - Transaction.mock?.computeTxid() + Transaction.mock?.transactionID ) } diff --git a/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletKeyServiceTests.swift b/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletKeyServiceTests.swift index 3b5f63b8..e390595c 100644 --- a/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletKeyServiceTests.swift +++ b/BDKSwiftExampleWalletTests/Service/BDKSwiftExampleWalletKeyServiceTests.swift @@ -25,12 +25,12 @@ final class BDKSwiftExampleWalletKeyServiceTests: XCTestCase { ) let descriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .external, + keychainKind: .external, network: mockKeyClientNetwork ) let changeDescriptor = Descriptor.newBip86( secretKey: secretKey, - keychain: .internal, + keychainKind: .internal, network: mockKeyClientNetwork ) let backupInfoMock = BackupInfo( diff --git a/BDKSwiftExampleWalletTests/View Model/BDKSwiftExampleWalletSendViewModelTests.swift b/BDKSwiftExampleWalletTests/View Model/BDKSwiftExampleWalletSendViewModelTests.swift index fce9be97..eb7b6718 100644 --- a/BDKSwiftExampleWalletTests/View Model/BDKSwiftExampleWalletSendViewModelTests.swift +++ b/BDKSwiftExampleWalletTests/View Model/BDKSwiftExampleWalletSendViewModelTests.swift @@ -47,7 +47,7 @@ final class BDKSwiftExampleWalletSendViewModelTests: XCTestCase { feeRate: fee ) XCTAssertEqual( - try? viewModel.psbt?.extractTx().computeTxid(), + try? viewModel.psbt?.extractTx().transactionID, "cab34ffffbde93c6a91d1ae755f6e256bad7c7e480a8c7d64caf3c2afc848ca4" ) }