Add SignOptions to Wallet.sign() params
This commit is contained in:
@@ -230,7 +230,7 @@ interface Wallet {
|
||||
Balance get_balance();
|
||||
|
||||
[Throws=BdkError]
|
||||
boolean sign([ByRef] PartiallySignedTransaction psbt);
|
||||
boolean sign([ByRef] PartiallySignedTransaction psbt, SignOptions? sign_options);
|
||||
|
||||
[Throws=BdkError]
|
||||
sequence<TransactionDetails> list_transactions(boolean include_raw);
|
||||
@@ -251,6 +251,16 @@ interface FeeRate {
|
||||
float as_sat_per_vb();
|
||||
};
|
||||
|
||||
dictionary SignOptions {
|
||||
boolean trust_witness_utxo;
|
||||
u32? assume_height;
|
||||
boolean allow_all_sighashes;
|
||||
boolean remove_partial_sigs;
|
||||
boolean try_finalize;
|
||||
boolean sign_with_tap_internal_key;
|
||||
boolean allow_grinding;
|
||||
};
|
||||
|
||||
interface Transaction {
|
||||
[Throws=BdkError]
|
||||
constructor(sequence<u8> transaction_bytes);
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::descriptor::Descriptor;
|
||||
use crate::keys::DerivationPath;
|
||||
use crate::keys::{DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
|
||||
use crate::psbt::PartiallySignedTransaction;
|
||||
use crate::wallet::SignOptions;
|
||||
use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet};
|
||||
use bdk::bitcoin::blockdata::script::Script as BdkScript;
|
||||
use bdk::bitcoin::blockdata::transaction::TxIn as BdkTxIn;
|
||||
|
||||
@@ -4,8 +4,8 @@ use bdk::database::any::AnyDatabase;
|
||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
||||
use bdk::{
|
||||
FeeRate, LocalUtxo as BdkLocalUtxo, SignOptions, SyncOptions as BdkSyncOptions,
|
||||
Wallet as BdkWallet,
|
||||
FeeRate, LocalUtxo as BdkLocalUtxo, SignOptions as BdkSignOptions,
|
||||
SyncOptions as BdkSyncOptions, Wallet as BdkWallet,
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Deref;
|
||||
@@ -113,10 +113,24 @@ impl Wallet {
|
||||
self.get_wallet().get_balance().map(|b| b.into())
|
||||
}
|
||||
|
||||
/// Sign a transaction with all the wallet’s signers.
|
||||
pub(crate) fn sign(&self, psbt: &PartiallySignedTransaction) -> Result<bool, BdkError> {
|
||||
/// Sign a transaction with all the wallet's signers, in the order specified by every signer's
|
||||
/// [`SignerOrdering`]. This function returns the `Result` type with an encapsulated `bool` that
|
||||
/// has the value true if the PSBT was finalized, or false otherwise.
|
||||
///
|
||||
/// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way
|
||||
/// the transaction is finalized at the end. Note that it can't be guaranteed that *every*
|
||||
/// signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
|
||||
/// in this library will.
|
||||
pub(crate) fn sign(
|
||||
&self,
|
||||
psbt: &PartiallySignedTransaction,
|
||||
sign_options: Option<SignOptions>,
|
||||
) -> Result<bool, BdkError> {
|
||||
let mut psbt = psbt.internal.lock().unwrap();
|
||||
self.get_wallet().sign(&mut psbt, SignOptions::default())
|
||||
self.get_wallet().sign(
|
||||
&mut psbt,
|
||||
sign_options.map(SignOptions::into).unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the list of transactions made and received by the wallet. Note that this method only operate on the internal database, which first needs to be [Wallet.sync] manually.
|
||||
@@ -139,6 +153,81 @@ impl Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for a software signer
|
||||
///
|
||||
/// Adjust the behavior of our software signers and the way a transaction is finalized
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SignOptions {
|
||||
/// Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been
|
||||
/// provided
|
||||
///
|
||||
/// Defaults to `false` to mitigate the "SegWit bug" which should trick the wallet into
|
||||
/// paying a fee larger than expected.
|
||||
///
|
||||
/// Some wallets, especially if relatively old, might not provide the `non_witness_utxo` for
|
||||
/// SegWit transactions in the PSBT they generate: in those cases setting this to `true`
|
||||
/// should correctly produce a signature, at the expense of an increased trust in the creator
|
||||
/// of the PSBT.
|
||||
///
|
||||
/// For more details see: <https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd>
|
||||
pub trust_witness_utxo: bool,
|
||||
|
||||
/// Whether the wallet should assume a specific height has been reached when trying to finalize
|
||||
/// a transaction
|
||||
///
|
||||
/// The wallet will only "use" a timelock to satisfy the spending policy of an input if the
|
||||
/// timelock height has already been reached. This option allows overriding the "current height" to let the
|
||||
/// wallet use timelocks in the future to spend a coin.
|
||||
pub assume_height: Option<u32>,
|
||||
|
||||
/// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter
|
||||
/// what its value is
|
||||
///
|
||||
/// Defaults to `false` which will only allow signing using `SIGHASH_ALL`.
|
||||
pub allow_all_sighashes: bool,
|
||||
|
||||
/// Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.
|
||||
///
|
||||
/// Defaults to `true` which will remove partial signatures during finalization.
|
||||
pub remove_partial_sigs: bool,
|
||||
|
||||
/// Whether to try finalizing the PSBT after the inputs are signed.
|
||||
///
|
||||
/// Defaults to `true` which will try finalizing PSBT after inputs are signed.
|
||||
pub try_finalize: bool,
|
||||
|
||||
// Specifies which Taproot script-spend leaves we should sign for. This option is
|
||||
// ignored if we're signing a non-taproot PSBT.
|
||||
//
|
||||
// Defaults to All, i.e., the wallet will sign all the leaves it has a key for.
|
||||
// TODO pub tap_leaves_options: TapLeavesOptions,
|
||||
/// Whether we should try to sign a taproot transaction with the taproot internal key
|
||||
/// or not. This option is ignored if we're signing a non-taproot PSBT.
|
||||
///
|
||||
/// Defaults to `true`, i.e., we always try to sign with the taproot internal key.
|
||||
pub sign_with_tap_internal_key: bool,
|
||||
|
||||
/// Whether we should grind ECDSA signature to ensure signing with low r
|
||||
/// or not.
|
||||
/// Defaults to `true`, i.e., we always grind ECDSA signature to sign with low r.
|
||||
pub allow_grinding: bool,
|
||||
}
|
||||
|
||||
impl From<SignOptions> for BdkSignOptions {
|
||||
fn from(sign_options: SignOptions) -> Self {
|
||||
BdkSignOptions {
|
||||
trust_witness_utxo: sign_options.trust_witness_utxo,
|
||||
assume_height: sign_options.assume_height,
|
||||
allow_all_sighashes: sign_options.allow_all_sighashes,
|
||||
remove_partial_sigs: sign_options.remove_partial_sigs,
|
||||
try_finalize: sign_options.try_finalize,
|
||||
tap_leaves_options: Default::default(),
|
||||
sign_with_tap_internal_key: sign_options.sign_with_tap_internal_key,
|
||||
allow_grinding: sign_options.allow_grinding,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A transaction builder.
|
||||
/// After creating the TxBuilder, you set options on it until finally calling finish to consume the builder and generate the transaction.
|
||||
/// Each method on the TxBuilder returns an instance of a new TxBuilder with the option set/added.
|
||||
|
||||
Reference in New Issue
Block a user