Skip to content

Commit 5e9965f

Browse files
committed
Enable signing taproot transactions with only non_witness_utxos
Some wallets may only specify the `non_witness_utxo` for a PSBT input. If that's the case, BDK should still be able to sign. This was pointed out in the discussion of #734
1 parent dfeb08f commit 5e9965f

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/wallet/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4964,6 +4964,29 @@ pub(crate) mod test {
49644964
);
49654965
}
49664966

4967+
#[test]
4968+
fn test_taproot_sign_using_non_witness_utxo() {
4969+
let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
4970+
let addr = wallet.get_address(New).unwrap();
4971+
let mut builder = wallet.build_tx();
4972+
builder.drain_to(addr.script_pubkey()).drain_wallet();
4973+
let (mut psbt, _) = builder.finish().unwrap();
4974+
4975+
psbt.inputs[0].witness_utxo = None;
4976+
psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
4977+
assert!(
4978+
psbt.inputs[0].non_witness_utxo.is_some(),
4979+
"Previous tx should be present in the database"
4980+
);
4981+
4982+
let result = wallet.sign(&mut psbt, Default::default());
4983+
assert!(result.is_ok(), "Signing should have worked");
4984+
assert!(
4985+
result.unwrap(),
4986+
"Should finalize the input since we can produce signatures"
4987+
);
4988+
}
4989+
49674990
#[test]
49684991
fn test_taproot_foreign_utxo() {
49694992
let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());

src/wallet/signer.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use miniscript::{Legacy, MiniscriptKey, Segwitv0, Tap};
103103

104104
use super::utils::SecpCtx;
105105
use crate::descriptor::{DescriptorMeta, XKeyUtils};
106+
use crate::psbt::PsbtUtils;
106107

107108
/// Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among
108109
/// multiple of them
@@ -921,11 +922,8 @@ impl ComputeSighash for Tap {
921922
.unwrap_or_else(|| SchnorrSighashType::Default.into())
922923
.schnorr_hash_ty()
923924
.map_err(|_| SignerError::InvalidSighash)?;
924-
let witness_utxos = psbt
925-
.inputs
926-
.iter()
927-
.cloned()
928-
.map(|i| i.witness_utxo)
925+
let witness_utxos = (0..psbt.inputs.len())
926+
.map(|i| psbt.get_utxo_for(i))
929927
.collect::<Vec<_>>();
930928
let mut all_witness_utxos = vec![];
931929

0 commit comments

Comments
 (0)