Merge pull request #14 from notmandatory/allow-signing-partially-signed-transactions

Allow signing partially signed transactions
This commit is contained in:
Sudarsan Balaji 2021-10-16 20:28:03 +05:30 committed by GitHub
commit 38b8589526
2 changed files with 64 additions and 31 deletions

View File

@ -64,25 +64,31 @@ interface DatabaseConfig {
}; };
interface OfflineWallet { interface OfflineWallet {
[Throws=BdkError] [Throws=BdkError]
constructor(string descriptor, Network network, DatabaseConfig database_config); constructor(string descriptor, Network network, DatabaseConfig database_config);
string get_new_address();
// OfflineWalletOperations
string get_new_address();
[Throws=BdkError]
u64 get_balance();
[Throws=BdkError]
void sign([ByRef] PartiallySignedBitcoinTransaction psbt);
}; };
dictionary ElectrumConfig { dictionary ElectrumConfig {
string url; string url;
string? socks5; string? socks5;
u8 retry; u8 retry;
u8? timeout; u8? timeout;
u64 stop_gap; u64 stop_gap;
}; };
dictionary EsploraConfig { dictionary EsploraConfig {
string base_url; string base_url;
string? proxy; string? proxy;
u64 timeout_read; u64 timeout_read;
u64 timeout_write; u64 timeout_write;
u64 stop_gap; u64 stop_gap;
}; };
[Enum] [Enum]
@ -96,14 +102,22 @@ callback interface BdkProgress {
}; };
interface OnlineWallet { interface OnlineWallet {
[Throws=BdkError] [Throws=BdkError]
constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config); constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config);
string get_new_address();
Network get_network(); // OfflineWalletOperations
[Throws=BdkError] string get_new_address();
void sync(BdkProgress progress_update, u32? max_address_param); [Throws=BdkError]
[Throws=BdkError] u64 get_balance();
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);
}; };
interface PartiallySignedBitcoinTransaction { interface PartiallySignedBitcoinTransaction {

View File

@ -1,4 +1,3 @@
use bdk::address_validator::AddressValidatorError;
use bdk::bitcoin::util::psbt::PartiallySignedTransaction; use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
use bdk::bitcoin::{Address, Network}; use bdk::bitcoin::{Address, Network};
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
@ -9,7 +8,7 @@ use bdk::blockchain::{
use bdk::database::any::{AnyDatabase, SledDbConfiguration}; use bdk::database::any::{AnyDatabase, SledDbConfiguration};
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase}; use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
use bdk::wallet::AddressIndex; use bdk::wallet::AddressIndex;
use bdk::{Error, Wallet}; use bdk::{Error, SignOptions, Wallet};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Mutex, MutexGuard}; use std::sync::{Mutex, MutexGuard};
@ -66,6 +65,22 @@ trait OfflineWalletOperations<B>: WalletHolder<B> {
.address .address
.to_string() .to_string()
} }
fn get_balance(&self) -> Result<u64, Error> {
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 { impl OfflineWallet {
@ -114,15 +129,17 @@ impl PartiallySignedBitcoinTransaction {
let wallet = online_wallet.get_wallet(); let wallet = online_wallet.get_wallet();
match Address::from_str(&recipient) { match Address::from_str(&recipient) {
Ok(address) => { Ok(address) => {
let mut builder = wallet.build_tx(); let (psbt, _) = {
builder.add_recipient(address.script_pubkey(), amount); let mut builder = wallet.build_tx();
let (pst, ..) = builder.finish()?; builder.add_recipient(address.script_pubkey(), amount);
builder.finish()?
};
Ok(PartiallySignedBitcoinTransaction { Ok(PartiallySignedBitcoinTransaction {
internal: Mutex::new(pst), internal: Mutex::new(psbt),
}) })
} }
Err(..) => Err(BdkError::AddressValidator( Err(..) => Err(BdkError::Generic(
AddressValidatorError::InvalidScript, "failed to read wallet address".to_string(),
)), )),
} }
} }
@ -187,8 +204,10 @@ impl OnlineWallet {
.sync(BdkProgressHolder { progress_update }, max_address_param) .sync(BdkProgressHolder { progress_update }, max_address_param)
} }
fn get_balance(&self) -> Result<u64, Error> { fn broadcast<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<String, Error> {
self.wallet.lock().unwrap().get_balance() let tx = psbt.internal.lock().unwrap().clone().extract_tx();
let tx_id = self.get_wallet().broadcast(tx)?;
Ok(tx_id.to_string())
} }
} }