@@ -92,6 +92,12 @@ pub struct DescriptorXPub {
9292#[ derive( Debug , PartialEq ) ]
9393pub struct DescriptorKeyParseError ( & ' static str ) ;
9494
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+
95101impl fmt:: Display for DescriptorPublicKey {
96102 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
97103 match * self {
@@ -226,6 +232,34 @@ impl DescriptorPublicKey {
226232 ) )
227233 }
228234 }
235+
236+ /// Derives a new key using the path if self is a wildcard xpub. Otehrwise returns a copy of
237+ /// self.
238+ ///
239+ /// Panics if derivation path contains a hardened child number
240+ pub fn derive ( & self , path : & [ bip32:: ChildNumber ] ) -> DescriptorPublicKey {
241+ assert ! ( path. into_iter( ) . all( |c| c. is_normal( ) ) ) ;
242+
243+ match * self {
244+ DescriptorPublicKey :: PukKey ( ref pk) => DescriptorPublicKey :: PukKey ( * pk) ,
245+ DescriptorPublicKey :: XPub ( ref xpub) => {
246+ if xpub. is_wildcard {
247+ DescriptorPublicKey :: XPub ( DescriptorXPub {
248+ origin : xpub. origin . clone ( ) ,
249+ xpub : xpub. xpub . clone ( ) ,
250+ derivation_path : ( & xpub. derivation_path )
251+ . into_iter ( )
252+ . chain ( path. iter ( ) )
253+ . cloned ( )
254+ . collect ( ) ,
255+ is_wildcard : false ,
256+ } )
257+ } else {
258+ self . clone ( )
259+ }
260+ }
261+ }
262+ }
229263}
230264
231265impl MiniscriptKey for DescriptorPublicKey {
@@ -624,6 +658,17 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
624658 }
625659}
626660
661+ impl Descriptor < DescriptorPublicKey > {
662+ /// Derives all wildcard keys in the descriptor using the supplied `path`
663+ pub fn derive ( & self , path : & [ bip32:: ChildNumber ] ) -> Descriptor < DescriptorPublicKey > {
664+ self . translate_pk (
665+ |pk| Result :: Ok :: < DescriptorPublicKey , ( ) > ( pk. derive ( path) ) ,
666+ |pkh| Result :: Ok :: < hash160:: Hash , ( ) > ( * pkh) ,
667+ )
668+ . expect ( "Translation fn can't fail." )
669+ }
670+ }
671+
627672impl < Pk > expression:: FromTree for Descriptor < Pk >
628673where
629674 Pk : MiniscriptKey ,
0 commit comments