@@ -21,7 +21,8 @@ use super::{sanity_check, Error, InputError, Psbt, PsbtInputSatisfier};
21
21
use crate :: prelude:: * ;
22
22
use crate :: util:: witness_size;
23
23
use crate :: {
24
- interpreter, BareCtx , Descriptor , ExtParams , Legacy , Miniscript , Satisfier , Segwitv0 , Tap ,
24
+ interpreter, BareCtx , Descriptor , ExtParams , Legacy , Miniscript , Satisfier , Segwitv0 , SigType ,
25
+ Tap , ToPublicKey ,
25
26
} ;
26
27
27
28
// Satisfy the taproot descriptor. It is not possible to infer the complete
@@ -33,6 +34,22 @@ fn construct_tap_witness(
33
34
sat : & PsbtInputSatisfier ,
34
35
allow_mall : bool ,
35
36
) -> Result < Vec < Vec < u8 > > , InputError > {
37
+ // When miniscript tries to finalize the PSBT, it doesn't have the full descriptor (which contained a pkh() fragment)
38
+ // and instead resorts to parsing the raw script sig, which is translated into a "expr_raw_pkh" internally.
39
+ let mut hash_map: BTreeMap < hash160:: Hash , bitcoin:: key:: XOnlyPublicKey > = BTreeMap :: new ( ) ;
40
+ let psbt_inputs = & sat. psbt . inputs ;
41
+ for psbt_input in psbt_inputs {
42
+ // We need to satisfy or dissatisfy any given key. `tap_key_origin` is the only field of PSBT Input which consist of
43
+ // all the keys added on a descriptor and thus we get keys from it.
44
+ let public_keys = psbt_input. tap_key_origins . keys ( ) ;
45
+ for key in public_keys {
46
+ let bitcoin_key = * key;
47
+ // Convert PubKeyHash into Hash::hash160
48
+ let hash = bitcoin_key. to_pubkeyhash ( SigType :: Schnorr ) ;
49
+ // Insert pair in HashMap
50
+ hash_map. insert ( hash, bitcoin_key) ;
51
+ }
52
+ }
36
53
assert ! ( spk. is_v1_p2tr( ) ) ;
37
54
38
55
// try the key spend path first
@@ -55,7 +72,7 @@ fn construct_tap_witness(
55
72
script,
56
73
& ExtParams :: allow_all ( ) ,
57
74
) {
58
- Ok ( ms) => ms,
75
+ Ok ( ms) => ms. substitute_raw_pkh ( & hash_map ) ,
59
76
Err ( ..) => continue , // try another script
60
77
} ;
61
78
let mut wit = if allow_mall {
0 commit comments