1
1
use std:: fmt;
2
2
use std:: marker:: PhantomData ;
3
+ use std:: sync:: Arc ;
3
4
4
5
use bitcoin:: bip32:: { self , ChildNumber , DerivationPath , IntoDerivationPath } ;
5
6
use bitcoin:: hashes:: { sha256, Hash } ;
6
7
use bitcoin:: hex:: DisplayHex ;
7
- use bitcoin:: { psbt, secp256k1, taproot, PublicKey } ;
8
+ use bitcoin:: taproot:: TaprootSpendInfo ;
9
+ use bitcoin:: { psbt, secp256k1, PublicKey } ;
8
10
use miniscript:: descriptor:: {
9
- DerivPaths , DescriptorMultiXKey , DescriptorPublicKey , DescriptorSecretKey , Wildcard ,
11
+ self , DerivPaths , DescriptorMultiXKey , DescriptorPublicKey , DescriptorSecretKey , Wildcard ,
10
12
} ;
11
13
use miniscript:: {
12
14
bitcoin, DefiniteDescriptorKey , Descriptor , ForEachKey , MiniscriptKey , TranslatePk , Translator ,
@@ -26,18 +28,18 @@ pub trait TapInfoExt {
26
28
bitcoin:: ScriptBuf :: new_witness_program ( & self . witness_program ( ) )
27
29
}
28
30
}
29
- impl TapInfoExt for taproot :: TaprootSpendInfo {
31
+ impl TapInfoExt for TaprootSpendInfo {
30
32
fn witness_program ( & self ) -> bitcoin:: WitnessProgram {
31
33
bitcoin:: WitnessProgram :: p2tr_tweaked ( self . output_key ( ) )
32
34
}
33
35
}
34
36
35
37
pub trait PsbtTaprootExt {
36
38
/// Update PSBT fields using the TaprootSpendInfo
37
- fn update_with_taproot ( & mut self , tapinfo : & taproot :: TaprootSpendInfo ) -> Result < ( ) > ;
39
+ fn update_with_taproot ( & mut self , tapinfo : & TaprootSpendInfo ) -> Result < ( ) > ;
38
40
}
39
41
impl PsbtTaprootExt for psbt:: Input {
40
- fn update_with_taproot ( & mut self , tapinfo : & taproot :: TaprootSpendInfo ) -> Result < ( ) > {
42
+ fn update_with_taproot ( & mut self , tapinfo : & TaprootSpendInfo ) -> Result < ( ) > {
41
43
self . tap_merkle_root = tapinfo. merkle_root ( ) ;
42
44
self . tap_internal_key = Some ( tapinfo. internal_key ( ) ) ;
43
45
self . tap_scripts = tapinfo
@@ -53,7 +55,7 @@ impl PsbtTaprootExt for psbt::Input {
53
55
}
54
56
}
55
57
impl PsbtTaprootExt for psbt:: Output {
56
- fn update_with_taproot ( & mut self , tapinfo : & taproot :: TaprootSpendInfo ) -> Result < ( ) > {
58
+ fn update_with_taproot ( & mut self , tapinfo : & TaprootSpendInfo ) -> Result < ( ) > {
57
59
self . tap_internal_key = Some ( tapinfo. internal_key ( ) ) ;
58
60
// `tap_key_origins` needs to be filled in manually
59
61
// TODO autofill `tap_tree`
@@ -101,6 +103,21 @@ pub trait DescriptorExt {
101
103
fn to_address ( & self , network : bitcoin:: Network ) -> Result < bitcoin:: Address > {
102
104
Ok ( self . derive_definite ( ) ?. address ( network) ?)
103
105
}
106
+
107
+ /// Get the witness program. Errors if the descriptor contains underived wildcards or multi-path derivations.
108
+ fn witness_program ( & self ) -> Result < Option < bitcoin:: WitnessProgram > > {
109
+ Ok ( self
110
+ . to_address ( bitcoin:: Network :: Bitcoin ) ?
111
+ . witness_program ( ) )
112
+ }
113
+
114
+ /// Get the inner Tr, if it is a Tr descriptors
115
+ fn tr ( & self ) -> Option < & descriptor:: Tr < DescriptorPublicKey > > ;
116
+
117
+ /// Get a TaprootSpendInfo representation of this Tr descriptor
118
+ /// Returna an Ok(None) for non-Taproot descriptors, or an Err for Taproot
119
+ /// descriptors that are not definite (contain underived wildcards).
120
+ fn tap_info ( & self ) -> Result < Option < Arc < TaprootSpendInfo > > > ;
104
121
}
105
122
106
123
impl DescriptorExt for Descriptor < DescriptorPublicKey > {
@@ -115,6 +132,24 @@ impl DescriptorExt for Descriptor<DescriptorPublicKey> {
115
132
) ;
116
133
Ok ( self . at_derivation_index ( 0 ) . expect ( "index is valid" ) )
117
134
}
135
+
136
+ fn tr ( & self ) -> Option < & descriptor:: Tr < DescriptorPublicKey > > {
137
+ match self {
138
+ Descriptor :: Tr ( tr) => Some ( tr) ,
139
+ _ => None ,
140
+ }
141
+ }
142
+
143
+ fn tap_info ( & self ) -> Result < Option < Arc < TaprootSpendInfo > > > {
144
+ if matches ! ( self , Descriptor :: Tr ( _) ) {
145
+ Ok ( match self . definite ( ) ? {
146
+ Descriptor :: Tr ( tr) => Some ( tr. spend_info ( ) . clone ( ) ) ,
147
+ _ => unreachable ! ( ) ,
148
+ } )
149
+ } else {
150
+ Ok ( None )
151
+ }
152
+ }
118
153
}
119
154
120
155
// BIP32 derivation utilities
0 commit comments