{
let (desc, _) = self.get_descriptor_for_script_type(script_type);
psbt_output.hd_keypaths = desc.get_hd_keypaths(child, &self.secp)?;
+ if builder.include_output_redeem_witness_script {
+ let derived_descriptor = desc.derive(ChildNumber::from_normal_idx(child)?);
+ psbt_output.witness_script = derived_descriptor.psbt_witness_script(&self.secp);
+ psbt_output.redeem_script = derived_descriptor.psbt_redeem_script(&self.secp);
+ };
}
}
let extracted = signed_psbt.extract_tx();
assert_eq!(extracted.input[0].witness.len(), 2);
}
+
+ #[test]
+ fn test_include_output_redeem_witness_script() {
+ let (wallet, _, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
+ let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+ let (psbt, _) = wallet
+ .create_tx(
+ TxBuilder::with_recipients(vec![(addr.script_pubkey(), 45_000)])
+ .include_output_redeem_witness_script(),
+ )
+ .unwrap();
+
+ // p2sh-p2wsh transaction should contain both witness and redeem scripts
+ assert!(psbt
+ .outputs
+ .iter()
+ .any(|output| output.redeem_script.is_some() && output.witness_script.is_some()));
+ }
}
pub(crate) change_policy: ChangeSpendPolicy,
pub(crate) force_non_witness_utxo: bool,
pub(crate) coin_selection: Cs,
+ pub(crate) include_output_redeem_witness_script: bool,
phantom: PhantomData<(D, Ctx)>,
}
change_policy: Default::default(),
force_non_witness_utxo: Default::default(),
coin_selection: Default::default(),
+ include_output_redeem_witness_script: Default::default(),
phantom: PhantomData,
}
change_policy: self.change_policy,
force_non_witness_utxo: self.force_non_witness_utxo,
coin_selection,
+ include_output_redeem_witness_script: self.include_output_redeem_witness_script,
phantom: PhantomData,
}
}
+
+ /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::util::psbt::Output::redeem_script) and
+ /// [`psbt::Output::witness_script`](bitcoin::util::psbt::Output::witness_script) fields.
+ ///
+ /// This is useful for signers which always require it, like ColdCard hardware wallets.
+ pub fn include_output_redeem_witness_script(mut self) -> Self {
+ self.include_output_redeem_witness_script = true;
+ self
+ }
}
// methods supported only by create_tx, and only for `DefaultCoinSelectionAlgorithm`