From 4e1c6bd62b18dcf3b731dc42b73370c2f2bb76b5 Mon Sep 17 00:00:00 2001 From: Sudarsan Balaji Date: Sat, 16 Oct 2021 20:19:34 +0530 Subject: [PATCH 1/3] Add sign and broadcast to wallet --- src/bdk.udl | 4 ++++ src/lib.rs | 35 +++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/bdk.udl b/src/bdk.udl index 6bc08b0..c0ac19d 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -104,6 +104,10 @@ interface OnlineWallet { void sync(BdkProgress progress_update, u32? max_address_param); [Throws=BdkError] u64 get_balance(); + [Throws=BdkError] + void sign([ByRef] PartiallySignedBitcoinTransaction psbt); + [Throws=BdkError] + string broadcast([ByRef] PartiallySignedBitcoinTransaction psbt); }; interface PartiallySignedBitcoinTransaction { diff --git a/src/lib.rs b/src/lib.rs index 99f50ed..3c232b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ -use bdk::address_validator::AddressValidatorError; use bdk::bitcoin::util::psbt::PartiallySignedTransaction; use bdk::bitcoin::{Address, Network}; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; @@ -9,7 +8,7 @@ use bdk::blockchain::{ use bdk::database::any::{AnyDatabase, SledDbConfiguration}; use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase}; use bdk::wallet::AddressIndex; -use bdk::{Error, Wallet}; +use bdk::{Error, SignOptions, Wallet}; use std::convert::TryFrom; use std::str::FromStr; use std::sync::{Mutex, MutexGuard}; @@ -114,15 +113,17 @@ impl PartiallySignedBitcoinTransaction { let wallet = online_wallet.get_wallet(); match Address::from_str(&recipient) { Ok(address) => { - let mut builder = wallet.build_tx(); - builder.add_recipient(address.script_pubkey(), amount); - let (pst, ..) = builder.finish()?; + let (psbt, _) = { + let mut builder = wallet.build_tx(); + builder.add_recipient(address.script_pubkey(), amount); + builder.finish()? + }; Ok(PartiallySignedBitcoinTransaction { - internal: Mutex::new(pst), + internal: Mutex::new(psbt), }) } - Err(..) => Err(BdkError::AddressValidator( - AddressValidatorError::InvalidScript, + Err(..) => Err(BdkError::Generic( + "failed to read wallet address".to_string(), )), } } @@ -190,6 +191,24 @@ impl OnlineWallet { fn get_balance(&self) -> Result { self.wallet.lock().unwrap().get_balance() } + + fn sign<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<(), Error> { + let mut psbt = psbt.internal.lock().unwrap(); + let finalized = self.get_wallet().sign(&mut psbt, SignOptions::default())?; + match finalized { + true => Ok(()), + false => Err(BdkError::Generic(format!( + "transaction signing not finalized {:?}", + psbt + ))), + } + } + + fn broadcast<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result { + let tx = psbt.internal.lock().unwrap().clone().extract_tx(); + let tx_id = self.get_wallet().broadcast(tx)?; + Ok(tx_id.to_string()) + } } impl WalletHolder for OnlineWallet { From d97a13d186c09e557293dadd22162d69efdcfc10 Mon Sep 17 00:00:00 2001 From: Sudarsan Balaji Date: Sat, 16 Oct 2021 20:19:56 +0530 Subject: [PATCH 2/3] Fix formatting --- src/bdk.udl | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/bdk.udl b/src/bdk.udl index c0ac19d..5ee8f95 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -64,25 +64,25 @@ interface DatabaseConfig { }; interface OfflineWallet { - [Throws=BdkError] - constructor(string descriptor, Network network, DatabaseConfig database_config); - string get_new_address(); + [Throws=BdkError] + constructor(string descriptor, Network network, DatabaseConfig database_config); + string get_new_address(); }; dictionary ElectrumConfig { - string url; - string? socks5; - u8 retry; - u8? timeout; - u64 stop_gap; + string url; + string? socks5; + u8 retry; + u8? timeout; + u64 stop_gap; }; dictionary EsploraConfig { - string base_url; - string? proxy; - u64 timeout_read; - u64 timeout_write; - u64 stop_gap; + string base_url; + string? proxy; + u64 timeout_read; + u64 timeout_write; + u64 stop_gap; }; [Enum] @@ -96,14 +96,14 @@ callback interface BdkProgress { }; interface OnlineWallet { - [Throws=BdkError] - constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config); - string get_new_address(); - Network get_network(); - [Throws=BdkError] - void sync(BdkProgress progress_update, u32? max_address_param); - [Throws=BdkError] - u64 get_balance(); + [Throws=BdkError] + constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config); + string get_new_address(); + Network get_network(); + [Throws=BdkError] + void sync(BdkProgress progress_update, u32? max_address_param); + [Throws=BdkError] + u64 get_balance(); [Throws=BdkError] void sign([ByRef] PartiallySignedBitcoinTransaction psbt); [Throws=BdkError] From 3693e99372e6ff48ce4a81d1cc59a835399abf4d Mon Sep 17 00:00:00 2001 From: Sudarsan Balaji Date: Sat, 16 Oct 2021 20:25:58 +0530 Subject: [PATCH 3/3] Share Wallet::getBalance and Wallet::sign --- src/bdk.udl | 16 +++++++++++++--- src/lib.rs | 32 ++++++++++++++++---------------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/bdk.udl b/src/bdk.udl index 5ee8f95..9f386de 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -66,7 +66,13 @@ interface DatabaseConfig { interface OfflineWallet { [Throws=BdkError] constructor(string descriptor, Network network, DatabaseConfig database_config); + + // OfflineWalletOperations string get_new_address(); + [Throws=BdkError] + u64 get_balance(); + [Throws=BdkError] + void sign([ByRef] PartiallySignedBitcoinTransaction psbt); }; dictionary ElectrumConfig { @@ -98,14 +104,18 @@ callback interface BdkProgress { interface OnlineWallet { [Throws=BdkError] constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config); + + // OfflineWalletOperations string get_new_address(); - Network get_network(); - [Throws=BdkError] - void sync(BdkProgress progress_update, u32? max_address_param); [Throws=BdkError] u64 get_balance(); [Throws=BdkError] void sign([ByRef] PartiallySignedBitcoinTransaction psbt); + + // OnlineWalletInterface + Network get_network(); + [Throws=BdkError] + void sync(BdkProgress progress_update, u32? max_address_param); [Throws=BdkError] string broadcast([ByRef] PartiallySignedBitcoinTransaction psbt); }; diff --git a/src/lib.rs b/src/lib.rs index 3c232b4..d9d375f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,22 @@ trait OfflineWalletOperations: WalletHolder { .address .to_string() } + + fn get_balance(&self) -> Result { + self.get_wallet().get_balance() + } + + fn sign<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<(), Error> { + let mut psbt = psbt.internal.lock().unwrap(); + let finalized = self.get_wallet().sign(&mut psbt, SignOptions::default())?; + match finalized { + true => Ok(()), + false => Err(BdkError::Generic(format!( + "transaction signing not finalized {:?}", + psbt + ))), + } + } } impl OfflineWallet { @@ -188,22 +204,6 @@ impl OnlineWallet { .sync(BdkProgressHolder { progress_update }, max_address_param) } - fn get_balance(&self) -> Result { - self.wallet.lock().unwrap().get_balance() - } - - fn sign<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<(), Error> { - let mut psbt = psbt.internal.lock().unwrap(); - let finalized = self.get_wallet().sign(&mut psbt, SignOptions::default())?; - match finalized { - true => Ok(()), - false => Err(BdkError::Generic(format!( - "transaction signing not finalized {:?}", - psbt - ))), - } - } - fn broadcast<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result { let tx = psbt.internal.lock().unwrap().clone().extract_tx(); let tx_id = self.get_wallet().broadcast(tx)?;