@@ -285,6 +285,20 @@ impl error::Error for DescriptorKeyParseError {
285
285
}
286
286
}
287
287
288
+ impl fmt:: Display for DescriptorExtendedPublicKey {
289
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
290
+ maybe_fmt_master_id ( f, & self . origin ) ?;
291
+ self . xkey . fmt ( f) ?;
292
+ fmt_derivation_path ( f, & self . derivation_path ) ?;
293
+ match self . wildcard {
294
+ Wildcard :: None => { }
295
+ Wildcard :: Unhardened => write ! ( f, "/*" ) ?,
296
+ Wildcard :: Hardened => write ! ( f, "/*h" ) ?,
297
+ }
298
+ Ok ( ( ) )
299
+ }
300
+ }
301
+
288
302
impl fmt:: Display for DescriptorPublicKey {
289
303
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
290
304
match * self {
@@ -296,17 +310,7 @@ impl fmt::Display for DescriptorPublicKey {
296
310
} ?;
297
311
Ok ( ( ) )
298
312
}
299
- DescriptorPublicKey :: XPub ( ref xpub) => {
300
- maybe_fmt_master_id ( f, & xpub. origin ) ?;
301
- xpub. xkey . fmt ( f) ?;
302
- fmt_derivation_path ( f, & xpub. derivation_path ) ?;
303
- match xpub. wildcard {
304
- Wildcard :: None => { }
305
- Wildcard :: Unhardened => write ! ( f, "/*" ) ?,
306
- Wildcard :: Hardened => write ! ( f, "/*h" ) ?,
307
- }
308
- Ok ( ( ) )
309
- }
313
+ DescriptorPublicKey :: XPub ( ref xpub) => xpub. fmt ( f) ,
310
314
DescriptorPublicKey :: MultiXPub ( ref xpub) => {
311
315
maybe_fmt_master_id ( f, & xpub. origin ) ?;
312
316
xpub. xkey . fmt ( f) ?;
@@ -527,17 +531,85 @@ impl error::Error for ConversionError {
527
531
}
528
532
}
529
533
534
+ impl DescriptorExtendedPublicKey {
535
+ /// The fingerprint of the master key associated with this key, `0x00000000` if none.
536
+ pub fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
537
+ if let Some ( ( fingerprint, _) ) = self . origin {
538
+ fingerprint
539
+ } else {
540
+ self . xkey . fingerprint ( )
541
+ }
542
+ }
543
+
544
+ /// Full path, from the master key
545
+ ///
546
+ /// For wildcard keys this will return the path up to the wildcard, so you
547
+ /// can get full paths by appending one additional derivation step, according
548
+ /// to the wildcard type (hardened or normal).
549
+ ///
550
+ /// For multipath extended keys, this returns `None`.
551
+ pub fn full_derivation_path ( & self ) -> Option < bip32:: DerivationPath > {
552
+ let origin_path = if let Some ( ( _, ref path) ) = self . origin {
553
+ path. clone ( )
554
+ } else {
555
+ bip32:: DerivationPath :: from ( vec ! [ ] )
556
+ } ;
557
+ Some ( origin_path. extend ( & self . derivation_path ) )
558
+ }
559
+
560
+ /// Whether or not the key has a wildcard
561
+ pub fn has_wildcard ( & self ) -> bool {
562
+ self . wildcard != Wildcard :: None
563
+ }
564
+
565
+ /// Replaces any wildcard (i.e. `/*`) in the key with a particular derivation index, turning it into a
566
+ /// *definite* key (i.e. one where all the derivation paths are set).
567
+ ///
568
+ /// # Returns
569
+ ///
570
+ /// - If this key is not an xpub, returns `self`.
571
+ /// - If this key is an xpub but does not have a wildcard, returns `self`.
572
+ /// - Otherwise, returns the xpub at derivation `index` (removing the wildcard).
573
+ ///
574
+ /// # Errors
575
+ ///
576
+ /// - If `index` is hardened.
577
+ pub fn at_derivation_index ( self , index : u32 ) -> Result < DefiniteDescriptorKey , ConversionError > {
578
+ let derivation_path = match self . wildcard {
579
+ Wildcard :: None => self . derivation_path ,
580
+ Wildcard :: Unhardened => self . derivation_path . into_child (
581
+ bip32:: ChildNumber :: from_normal_idx ( index)
582
+ . ok ( )
583
+ . ok_or ( ConversionError :: HardenedChild ) ?,
584
+ ) ,
585
+ Wildcard :: Hardened => self . derivation_path . into_child (
586
+ bip32:: ChildNumber :: from_hardened_idx ( index)
587
+ . ok ( )
588
+ . ok_or ( ConversionError :: HardenedChild ) ?,
589
+ ) ,
590
+ } ;
591
+ let definite = DescriptorPublicKey :: XPub ( DescriptorXKey {
592
+ origin : self . origin ,
593
+ xkey : self . xkey ,
594
+ derivation_path,
595
+ wildcard : Wildcard :: None ,
596
+ } ) ;
597
+
598
+ Ok ( DefiniteDescriptorKey :: new ( definite)
599
+ . expect ( "The key should not contain any wildcards at this point" ) )
600
+ }
601
+
602
+ /// Whether or not this key has multiple derivation paths.
603
+ pub fn is_multipath ( & self ) -> bool {
604
+ false
605
+ }
606
+ }
607
+
530
608
impl DescriptorPublicKey {
531
609
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
532
610
pub fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
533
611
match * self {
534
- DescriptorPublicKey :: XPub ( ref xpub) => {
535
- if let Some ( ( fingerprint, _) ) = xpub. origin {
536
- fingerprint
537
- } else {
538
- xpub. xkey . fingerprint ( )
539
- }
540
- }
612
+ DescriptorPublicKey :: XPub ( ref xpub) => xpub. master_fingerprint ( ) ,
541
613
DescriptorPublicKey :: MultiXPub ( ref xpub) => {
542
614
if let Some ( ( fingerprint, _) ) = xpub. origin {
543
615
fingerprint
@@ -575,14 +647,7 @@ impl DescriptorPublicKey {
575
647
/// For multipath extended keys, this returns `None`.
576
648
pub fn full_derivation_path ( & self ) -> Option < bip32:: DerivationPath > {
577
649
match * self {
578
- DescriptorPublicKey :: XPub ( ref xpub) => {
579
- let origin_path = if let Some ( ( _, ref path) ) = xpub. origin {
580
- path. clone ( )
581
- } else {
582
- bip32:: DerivationPath :: from ( vec ! [ ] )
583
- } ;
584
- Some ( origin_path. extend ( & xpub. derivation_path ) )
585
- }
650
+ DescriptorPublicKey :: XPub ( ref xpub) => xpub. full_derivation_path ( ) ,
586
651
DescriptorPublicKey :: Single ( ref single) => {
587
652
Some ( if let Some ( ( _, ref path) ) = single. origin {
588
653
path. clone ( )
@@ -604,7 +669,7 @@ impl DescriptorPublicKey {
604
669
pub fn has_wildcard ( & self ) -> bool {
605
670
match * self {
606
671
DescriptorPublicKey :: Single ( ..) => false ,
607
- DescriptorPublicKey :: XPub ( ref xpub) => xpub. wildcard != Wildcard :: None ,
672
+ DescriptorPublicKey :: XPub ( ref xpub) => xpub. has_wildcard ( ) ,
608
673
DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. wildcard != Wildcard :: None ,
609
674
}
610
675
}
@@ -628,40 +693,19 @@ impl DescriptorPublicKey {
628
693
///
629
694
/// - If `index` is hardened.
630
695
pub fn at_derivation_index ( self , index : u32 ) -> Result < DefiniteDescriptorKey , ConversionError > {
631
- let definite = match self {
632
- DescriptorPublicKey :: Single ( _) => self ,
633
- DescriptorPublicKey :: XPub ( xpub) => {
634
- let derivation_path = match xpub. wildcard {
635
- Wildcard :: None => xpub. derivation_path ,
636
- Wildcard :: Unhardened => xpub. derivation_path . into_child (
637
- bip32:: ChildNumber :: from_normal_idx ( index)
638
- . ok ( )
639
- . ok_or ( ConversionError :: HardenedChild ) ?,
640
- ) ,
641
- Wildcard :: Hardened => xpub. derivation_path . into_child (
642
- bip32:: ChildNumber :: from_hardened_idx ( index)
643
- . ok ( )
644
- . ok_or ( ConversionError :: HardenedChild ) ?,
645
- ) ,
646
- } ;
647
- DescriptorPublicKey :: XPub ( DescriptorXKey {
648
- origin : xpub. origin ,
649
- xkey : xpub. xkey ,
650
- derivation_path,
651
- wildcard : Wildcard :: None ,
652
- } )
653
- }
654
- DescriptorPublicKey :: MultiXPub ( _) => return Err ( ConversionError :: MultiKey ) ,
655
- } ;
656
-
657
- Ok ( DefiniteDescriptorKey :: new ( definite)
658
- . expect ( "The key should not contain any wildcards at this point" ) )
696
+ match self {
697
+ DescriptorPublicKey :: Single ( _) => Ok ( DefiniteDescriptorKey :: new ( self )
698
+ . expect ( "The key should not contain any wildcards at this point" ) ) ,
699
+ DescriptorPublicKey :: XPub ( xpub) => xpub. at_derivation_index ( index) ,
700
+ DescriptorPublicKey :: MultiXPub ( _) => Err ( ConversionError :: MultiKey ) ,
701
+ }
659
702
}
660
703
661
704
/// Whether or not this key has multiple derivation paths.
662
705
pub fn is_multipath ( & self ) -> bool {
663
706
match * self {
664
- DescriptorPublicKey :: Single ( ..) | DescriptorPublicKey :: XPub ( ..) => false ,
707
+ DescriptorPublicKey :: Single ( ..) => false ,
708
+ DescriptorPublicKey :: XPub ( ..) => self . is_multipath ( ) ,
665
709
DescriptorPublicKey :: MultiXPub ( _) => true ,
666
710
}
667
711
}
0 commit comments