Merge pull request #14 from notmandatory/allow-signing-partially-signed-transactions
Allow signing partially signed transactions
This commit is contained in:
commit
38b8589526
56
src/bdk.udl
56
src/bdk.udl
@ -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 {
|
||||||
|
39
src/lib.rs
39
src/lib.rs
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user