From 4e1c6bd62b18dcf3b731dc42b73370c2f2bb76b5 Mon Sep 17 00:00:00 2001 From: Sudarsan Balaji Date: Sat, 16 Oct 2021 20:19:34 +0530 Subject: [PATCH] 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 {