From eb752aefa0d2714e7c128f3b83eca14ff40460d2 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 8 Aug 2025 11:29:25 -0500 Subject: [PATCH] feat(wip): sub 1 sat fee --- .../Service/BDK Service/BDKService.swift | 33 +++++++++++++++++-- .../Send/BuildTransactionViewModel.swift | 21 ++++++++++++ .../View/Send/BuildTransactionView.swift | 11 +++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift b/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift index 45ca24b5..52ba1038 100644 --- a/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift +++ b/BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift @@ -462,17 +462,28 @@ private class BDKService { amount: UInt64, feeRate: UInt64 ) async throws { + print("[BDKService.send] Starting send with address: \(address), amount: \(amount), feeRate: \(feeRate)") let psbt = try buildTransaction( address: address, amount: amount, feeRate: feeRate ) + print("[BDKService.send] PSBT built successfully") try signAndBroadcast(psbt: psbt) + print("[BDKService.send] Transaction signed and broadcast successfully") } func buildTransaction(address: String, amount: UInt64, feeRate: UInt64) throws -> Psbt { + print("[BDKService.buildTransaction] Building transaction with:") + print(" - Network: \(self.network)") + print(" - Esplora URL: \(self.blockchainURL)") + print(" - Address: \(address)") + print(" - Amount: \(amount) sats") + print(" - Original feeRate param: \(feeRate) sat/vB") + print(" - Using hardcoded: 247 sat/kwu (0.99 sat/vB)") + guard let wallet = self.wallet else { throw WalletError.walletNotFound } let script = try Address(address: address, network: self.network) .scriptPubkey() @@ -481,18 +492,36 @@ private class BDKService { script: script, amount: Amount.fromSat(satoshi: amount) ) - .feeRate(feeRate: FeeRate.fromSatPerVb(satVb: feeRate)) + .feeRate(feeRate: FeeRate.fromSatPerKwu(satKwu: 247)) // for 0.99 sat/vB //.feeRate(feeRate: FeeRate.fromSatPerVb(satVb: feeRate)) .finish(wallet: wallet) + + print("[BDKService.buildTransaction] Transaction built successfully") return txBuilder } private func signAndBroadcast(psbt: Psbt) throws { + print("[BDKService.signAndBroadcast] Starting sign and broadcast") guard let wallet = self.wallet else { throw WalletError.walletNotFound } + let isSigned = try wallet.sign(psbt: psbt) + print("[BDKService.signAndBroadcast] Signing result: \(isSigned)") + if isSigned { let transaction = try psbt.extractTx() - try self.blockchainClient.broadcast(transaction) + let txid = transaction.computeTxid() + print("[BDKService.signAndBroadcast] Transaction ID: \(txid)") + + do { + try self.blockchainClient.broadcast(transaction) + print("[BDKService.signAndBroadcast] Broadcast successful!") + } catch { + print("[BDKService.signAndBroadcast] Broadcast failed with error: \(error)") + print("[BDKService.signAndBroadcast] Error type: \(type(of: error))") + print("[BDKService.signAndBroadcast] Error details: \(error.localizedDescription)") + throw error + } } else { + print("[BDKService.signAndBroadcast] Failed to sign transaction") throw WalletError.notSigned } } diff --git a/BDKSwiftExampleWallet/View Model/Send/BuildTransactionViewModel.swift b/BDKSwiftExampleWallet/View Model/Send/BuildTransactionViewModel.swift index 0d28276a..fd152f63 100644 --- a/BDKSwiftExampleWallet/View Model/Send/BuildTransactionViewModel.swift +++ b/BDKSwiftExampleWallet/View Model/Send/BuildTransactionViewModel.swift @@ -25,16 +25,26 @@ class BuildTransactionViewModel { } func buildTransaction(address: String, amount: UInt64, feeRate: UInt64) { + print("[BuildTransactionViewModel.buildTransaction] Called with:") + print(" - Address: \(address)") + print(" - Amount: \(amount) sats") + print(" - FeeRate: \(feeRate) sat/vB") + do { let txBuilderResult = try bdkClient.buildTransaction(address, amount, feeRate) self.psbt = txBuilderResult + print("[BuildTransactionViewModel.buildTransaction] PSBT created successfully") } catch let error as WalletError { + print("[BuildTransactionViewModel.buildTransaction] WalletError: \(error.localizedDescription)") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } catch let error as AddressParseError { + print("[BuildTransactionViewModel.buildTransaction] AddressParseError: \(error.localizedDescription)") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } catch { + print("[BuildTransactionViewModel.buildTransaction] Unknown error: \(error.localizedDescription)") + print("[BuildTransactionViewModel.buildTransaction] Error type: \(type(of: error))") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } @@ -69,22 +79,33 @@ class BuildTransactionViewModel { } func send(address: String, amount: UInt64, feeRate: UInt64) { + print("[BuildTransactionViewModel.send] Called with:") + print(" - Address: \(address)") + print(" - Amount: \(amount) sats") + print(" - FeeRate: \(feeRate) sat/vB") + do { try bdkClient.send(address, amount, feeRate) + print("[BuildTransactionViewModel.send] Transaction sent successfully!") NotificationCenter.default.post( name: Notification.Name("TransactionSent"), object: nil ) } catch let error as EsploraError { + print("[BuildTransactionViewModel.send] EsploraError: \(error.localizedDescription)") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } catch let error as SignerError { + print("[BuildTransactionViewModel.send] SignerError: \(error.localizedDescription)") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } catch let error as WalletError { + print("[BuildTransactionViewModel.send] WalletError: \(error.localizedDescription)") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } catch { + print("[BuildTransactionViewModel.send] Unknown error: \(error.localizedDescription)") + print("[BuildTransactionViewModel.send] Error type: \(type(of: error))") self.buildTransactionViewError = .generic(message: error.localizedDescription) self.showingBuildTransactionViewErrorAlert = true } diff --git a/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift b/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift index 728c30a1..8c9401ee 100644 --- a/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift +++ b/BDKSwiftExampleWallet/View/Send/BuildTransactionView.swift @@ -118,6 +118,10 @@ struct BuildTransactionView: View { if !isSent { Button { if let amt = UInt64(amount) { + print("[BuildTransactionView] Send button pressed with:") + print(" - Address: \(address)") + print(" - Amount: \(amt) sats") + print(" - Fee: \(fee) sat/vB") viewModel.buildTransactionViewError = nil isError = false viewModel.send( @@ -208,13 +212,20 @@ struct BuildTransactionView: View { .padding() .navigationTitle("Transaction") .onAppear { + print("[BuildTransactionView.onAppear] View appeared with:") + print(" - Address: \(address)") + print(" - Amount: \(amount) sats") + print(" - Fee: \(fee) sat/vB") viewModel.buildTransaction( address: address, amount: UInt64(amount) ?? 0, feeRate: UInt64(fee) ) if let tx = viewModel.extractTransaction() { + print("[BuildTransactionView.onAppear] Extracted transaction, calculating fee") viewModel.getCalulateFee(tx: tx) + } else { + print("[BuildTransactionView.onAppear] Failed to extract transaction") } } .alert(isPresented: $viewModel.showingBuildTransactionViewErrorAlert) {