@@ -92,6 +92,12 @@ pub struct DescriptorXPub {
92
92
#[ derive( Debug , PartialEq , Clone , Copy ) ]
93
93
pub struct DescriptorKeyParseError ( & ' static str ) ;
94
94
95
+ impl fmt:: Display for DescriptorKeyParseError {
96
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
97
+ f. write_str ( self . 0 )
98
+ }
99
+ }
100
+
95
101
impl fmt:: Display for DescriptorPublicKey {
96
102
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
97
103
match * self {
@@ -225,6 +231,34 @@ impl DescriptorPublicKey {
225
231
) )
226
232
}
227
233
}
234
+
235
+ /// Derives a new key using the path if self is a wildcard xpub. Otherwise returns self.
236
+ ///
237
+ /// Panics if derivation path contains a hardened child number
238
+ pub fn derive ( self , path : & [ bip32:: ChildNumber ] ) -> DescriptorPublicKey {
239
+ assert ! ( path. into_iter( ) . all( |c| c. is_normal( ) ) ) ;
240
+
241
+ match self {
242
+ DescriptorPublicKey :: PubKey ( _) => self ,
243
+ DescriptorPublicKey :: XPub ( xpub) => {
244
+ if xpub. is_wildcard {
245
+ DescriptorPublicKey :: XPub ( DescriptorXPub {
246
+ origin : xpub. origin ,
247
+ xpub : xpub. xpub ,
248
+ derivation_path : xpub
249
+ . derivation_path
250
+ . into_iter ( )
251
+ . chain ( path. iter ( ) )
252
+ . cloned ( )
253
+ . collect ( ) ,
254
+ is_wildcard : false ,
255
+ } )
256
+ } else {
257
+ DescriptorPublicKey :: XPub ( xpub)
258
+ }
259
+ }
260
+ }
261
+ }
228
262
}
229
263
230
264
impl MiniscriptKey for DescriptorPublicKey {
@@ -613,6 +647,17 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
613
647
}
614
648
}
615
649
650
+ impl Descriptor < DescriptorPublicKey > {
651
+ /// Derives all wildcard keys in the descriptor using the supplied `path`
652
+ pub fn derive ( & self , path : & [ bip32:: ChildNumber ] ) -> Descriptor < DescriptorPublicKey > {
653
+ self . translate_pk (
654
+ |pk| Result :: Ok :: < DescriptorPublicKey , ( ) > ( pk. clone ( ) . derive ( path) ) ,
655
+ |pkh| Result :: Ok :: < hash160:: Hash , ( ) > ( * pkh) ,
656
+ )
657
+ . expect ( "Translation fn can't fail." )
658
+ }
659
+ }
660
+
616
661
impl < Pk > expression:: FromTree for Descriptor < Pk >
617
662
where
618
663
Pk : MiniscriptKey ,
0 commit comments