@@ -20,6 +20,7 @@ use crate::{hash256, MiniscriptKey, ToPublicKey};
20
20
21
21
type DescriptorSinglePublicKey = SinglePub ;
22
22
type DescriptorExtendedPublicKey = DescriptorXKey < bip32:: ExtendedPubKey > ;
23
+ type DescriptorMultiExtendedPublicKey = DescriptorMultiXKey < bip32:: ExtendedPubKey > ;
23
24
24
25
/// The descriptor pubkey, either a single pubkey or an xpub.
25
26
#[ derive( Debug , Eq , PartialEq , Clone , Ord , PartialOrd , Hash ) ]
@@ -29,7 +30,7 @@ pub enum DescriptorPublicKey {
29
30
/// Extended public key (xpub).
30
31
XPub ( DescriptorExtendedPublicKey ) ,
31
32
/// Multiple extended public keys.
32
- MultiXPub ( DescriptorMultiXKey < bip32 :: ExtendedPubKey > ) ,
33
+ MultiXPub ( DescriptorMultiExtendedPublicKey ) ,
33
34
}
34
35
35
36
/// The descriptor secret key, either a single private key or an xprv.
@@ -310,22 +311,26 @@ impl fmt::Display for DescriptorExtendedPublicKey {
310
311
}
311
312
}
312
313
314
+ impl fmt:: Display for DescriptorMultiExtendedPublicKey {
315
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
316
+ maybe_fmt_master_id ( f, & self . origin ) ?;
317
+ self . xkey . fmt ( f) ?;
318
+ fmt_derivation_paths ( f, self . derivation_paths . paths ( ) ) ?;
319
+ match self . wildcard {
320
+ Wildcard :: None => { }
321
+ Wildcard :: Unhardened => write ! ( f, "/*" ) ?,
322
+ Wildcard :: Hardened => write ! ( f, "/*h" ) ?,
323
+ }
324
+ Ok ( ( ) )
325
+ }
326
+ }
327
+
313
328
impl fmt:: Display for DescriptorPublicKey {
314
329
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
315
330
match * self {
316
331
DescriptorPublicKey :: Single ( ref pk) => pk. fmt ( f) ,
317
332
DescriptorPublicKey :: XPub ( ref xpub) => xpub. fmt ( f) ,
318
- DescriptorPublicKey :: MultiXPub ( ref xpub) => {
319
- maybe_fmt_master_id ( f, & xpub. origin ) ?;
320
- xpub. xkey . fmt ( f) ?;
321
- fmt_derivation_paths ( f, xpub. derivation_paths . paths ( ) ) ?;
322
- match xpub. wildcard {
323
- Wildcard :: None => { }
324
- Wildcard :: Unhardened => write ! ( f, "/*" ) ?,
325
- Wildcard :: Hardened => write ! ( f, "/*h" ) ?,
326
- }
327
- Ok ( ( ) )
328
- }
333
+ DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. fmt ( f) ,
329
334
}
330
335
}
331
336
}
@@ -501,6 +506,30 @@ impl FromStr for DescriptorExtendedPublicKey {
501
506
}
502
507
}
503
508
509
+ impl FromStr for DescriptorMultiExtendedPublicKey {
510
+ type Err = DescriptorKeyParseError ;
511
+
512
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
513
+ let ( key_part, origin) = parse_key_origin ( s) ?;
514
+
515
+ let ( xpub, derivation_paths, wildcard) =
516
+ parse_xkey_deriv :: < bip32:: ExtendedPubKey > ( key_part) ?;
517
+
518
+ if derivation_paths. len ( ) < 2 {
519
+ return Err ( DescriptorKeyParseError (
520
+ "Multiple derivation paths are required for multi extended keys" ,
521
+ ) ) ;
522
+ }
523
+
524
+ Ok ( Self {
525
+ origin,
526
+ xkey : xpub,
527
+ derivation_paths : DerivPaths :: new ( derivation_paths) . expect ( "Not empty" ) ,
528
+ wildcard,
529
+ } )
530
+ }
531
+ }
532
+
504
533
impl FromStr for DescriptorPublicKey {
505
534
type Err = DescriptorKeyParseError ;
506
535
@@ -518,12 +547,7 @@ impl FromStr for DescriptorPublicKey {
518
547
let ( xpub, derivation_paths, wildcard) =
519
548
parse_xkey_deriv :: < bip32:: ExtendedPubKey > ( key_part) ?;
520
549
if derivation_paths. len ( ) > 1 {
521
- Ok ( DescriptorPublicKey :: MultiXPub ( DescriptorMultiXKey {
522
- origin,
523
- xkey : xpub,
524
- derivation_paths : DerivPaths :: new ( derivation_paths) . expect ( "Not empty" ) ,
525
- wildcard,
526
- } ) )
550
+ DescriptorMultiExtendedPublicKey :: from_str ( s) . map ( Self :: MultiXPub )
527
551
} else {
528
552
DescriptorExtendedPublicKey :: from_str ( s) . map ( Self :: XPub )
529
553
}
@@ -757,18 +781,45 @@ impl DescriptorKey for DescriptorExtendedPublicKey {
757
781
}
758
782
}
759
783
784
+ impl DescriptorKey for DescriptorMultiExtendedPublicKey {
785
+ fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
786
+ if let Some ( ( fingerprint, _) ) = self . origin {
787
+ fingerprint
788
+ } else {
789
+ self . xkey . fingerprint ( )
790
+ }
791
+ }
792
+
793
+ fn full_derivation_path ( & self ) -> Option < bip32:: DerivationPath > {
794
+ None
795
+ }
796
+
797
+ fn has_wildcard ( & self ) -> bool {
798
+ self . wildcard != Wildcard :: None
799
+ }
800
+
801
+ fn at_derivation_index ( self , _index : u32 ) -> Result < DefiniteDescriptorKey , ConversionError > {
802
+ Err ( ConversionError :: MultiKey )
803
+ }
804
+
805
+ fn is_multipath ( & self ) -> bool {
806
+ true
807
+ }
808
+
809
+ fn derive_public_key < C : Verification > (
810
+ & self ,
811
+ _secp : & Secp256k1 < C > ,
812
+ ) -> Result < bitcoin:: PublicKey , ConversionError > {
813
+ Err ( ConversionError :: MultiKey )
814
+ }
815
+ }
816
+
760
817
impl DescriptorPublicKey {
761
818
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
762
819
pub fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
763
820
match * self {
764
821
DescriptorPublicKey :: XPub ( ref xpub) => xpub. master_fingerprint ( ) ,
765
- DescriptorPublicKey :: MultiXPub ( ref xpub) => {
766
- if let Some ( ( fingerprint, _) ) = xpub. origin {
767
- fingerprint
768
- } else {
769
- xpub. xkey . fingerprint ( )
770
- }
771
- }
822
+ DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. master_fingerprint ( ) ,
772
823
DescriptorPublicKey :: Single ( ref single) => single. master_fingerprint ( ) ,
773
824
}
774
825
}
@@ -784,7 +835,7 @@ impl DescriptorPublicKey {
784
835
match * self {
785
836
DescriptorPublicKey :: XPub ( ref xpub) => xpub. full_derivation_path ( ) ,
786
837
DescriptorPublicKey :: Single ( ref single) => single. full_derivation_path ( ) ,
787
- DescriptorPublicKey :: MultiXPub ( _ ) => None ,
838
+ DescriptorPublicKey :: MultiXPub ( ref xpub ) => xpub . full_derivation_path ( ) ,
788
839
}
789
840
}
790
841
@@ -799,7 +850,7 @@ impl DescriptorPublicKey {
799
850
match * self {
800
851
DescriptorPublicKey :: Single ( ref single) => single. has_wildcard ( ) ,
801
852
DescriptorPublicKey :: XPub ( ref xpub) => xpub. has_wildcard ( ) ,
802
- DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. wildcard != Wildcard :: None ,
853
+ DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. has_wildcard ( ) ,
803
854
}
804
855
}
805
856
@@ -825,7 +876,7 @@ impl DescriptorPublicKey {
825
876
match self {
826
877
DescriptorPublicKey :: Single ( single) => single. at_derivation_index ( index) ,
827
878
DescriptorPublicKey :: XPub ( xpub) => xpub. at_derivation_index ( index) ,
828
- DescriptorPublicKey :: MultiXPub ( _ ) => Err ( ConversionError :: MultiKey ) ,
879
+ DescriptorPublicKey :: MultiXPub ( xpub ) => xpub . at_derivation_index ( index ) ,
829
880
}
830
881
}
831
882
@@ -834,7 +885,7 @@ impl DescriptorPublicKey {
834
885
match self {
835
886
DescriptorPublicKey :: Single ( single) => single. is_multipath ( ) ,
836
887
DescriptorPublicKey :: XPub ( xpub) => xpub. is_multipath ( ) ,
837
- DescriptorPublicKey :: MultiXPub ( _ ) => true ,
888
+ DescriptorPublicKey :: MultiXPub ( xpub ) => xpub . is_multipath ( ) ,
838
889
}
839
890
}
840
891
@@ -1208,9 +1259,7 @@ impl DefiniteDescriptorKey {
1208
1259
match self . 0 {
1209
1260
DescriptorPublicKey :: Single ( ref pk) => pk. derive_public_key ( secp) ,
1210
1261
DescriptorPublicKey :: XPub ( ref xpk) => xpk. derive_public_key ( secp) ,
1211
- DescriptorPublicKey :: MultiXPub ( _) => {
1212
- unreachable ! ( "A definite key cannot contain a multipath key." )
1213
- }
1262
+ DescriptorPublicKey :: MultiXPub ( ref xpk) => xpk. derive_public_key ( secp) ,
1214
1263
}
1215
1264
}
1216
1265
0 commit comments