@@ -18,6 +18,7 @@ use crate::prelude::*;
18
18
use crate :: serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
19
19
use crate :: { hash256, MiniscriptKey , ToPublicKey } ;
20
20
21
+ type DescriptorSinglePublicKey = SinglePub ;
21
22
type DescriptorExtendedPublicKey = DescriptorXKey < bip32:: ExtendedPubKey > ;
22
23
23
24
/// The descriptor pubkey, either a single pubkey or an xpub.
@@ -285,6 +286,16 @@ impl error::Error for DescriptorKeyParseError {
285
286
}
286
287
}
287
288
289
+ impl fmt:: Display for DescriptorSinglePublicKey {
290
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
291
+ maybe_fmt_master_id ( f, & self . origin ) ?;
292
+ match self . key {
293
+ SinglePubKey :: FullKey ( full_key) => full_key. fmt ( f) ,
294
+ SinglePubKey :: XOnly ( x_only_key) => x_only_key. fmt ( f) ,
295
+ }
296
+ }
297
+ }
298
+
288
299
impl fmt:: Display for DescriptorExtendedPublicKey {
289
300
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
290
301
maybe_fmt_master_id ( f, & self . origin ) ?;
@@ -302,14 +313,7 @@ impl fmt::Display for DescriptorExtendedPublicKey {
302
313
impl fmt:: Display for DescriptorPublicKey {
303
314
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
304
315
match * self {
305
- DescriptorPublicKey :: Single ( ref pk) => {
306
- maybe_fmt_master_id ( f, & pk. origin ) ?;
307
- match pk. key {
308
- SinglePubKey :: FullKey ( full_key) => full_key. fmt ( f) ,
309
- SinglePubKey :: XOnly ( x_only_key) => x_only_key. fmt ( f) ,
310
- } ?;
311
- Ok ( ( ) )
312
- }
316
+ DescriptorPublicKey :: Single ( ref pk) => pk. fmt ( f) ,
313
317
DescriptorPublicKey :: XPub ( ref xpub) => xpub. fmt ( f) ,
314
318
DescriptorPublicKey :: MultiXPub ( ref xpub) => {
315
319
maybe_fmt_master_id ( f, & xpub. origin ) ?;
@@ -438,6 +442,41 @@ fn fmt_derivation_paths(f: &mut fmt::Formatter, paths: &[bip32::DerivationPath])
438
442
Ok ( ( ) )
439
443
}
440
444
445
+ impl FromStr for DescriptorSinglePublicKey {
446
+ type Err = DescriptorKeyParseError ;
447
+
448
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
449
+ let ( key_part, origin) = parse_key_origin ( s) ?;
450
+
451
+ let key = match key_part. len ( ) {
452
+ 64 => {
453
+ let x_only_key = XOnlyPublicKey :: from_str ( key_part)
454
+ . map_err ( |_| DescriptorKeyParseError ( "Error while parsing simple xonly key" ) ) ?;
455
+ SinglePubKey :: XOnly ( x_only_key)
456
+ }
457
+ 66 | 130 => {
458
+ if !( & key_part[ 0 ..2 ] == "02" || & key_part[ 0 ..2 ] == "03" || & key_part[ 0 ..2 ] == "04" )
459
+ {
460
+ return Err ( DescriptorKeyParseError (
461
+ "Only publickeys with prefixes 02/03/04 are allowed" ,
462
+ ) ) ;
463
+ }
464
+ let key = bitcoin:: PublicKey :: from_str ( key_part) . map_err ( |_| {
465
+ DescriptorKeyParseError ( "Error while parsing simple public key" )
466
+ } ) ?;
467
+ SinglePubKey :: FullKey ( key)
468
+ }
469
+ _ => {
470
+ return Err ( DescriptorKeyParseError (
471
+ "Public keys must be 64/66/130 characters in size" ,
472
+ ) )
473
+ }
474
+ } ;
475
+
476
+ Ok ( Self { key, origin } )
477
+ }
478
+ }
479
+
441
480
impl FromStr for DescriptorExtendedPublicKey {
442
481
type Err = DescriptorKeyParseError ;
443
482
@@ -489,34 +528,7 @@ impl FromStr for DescriptorPublicKey {
489
528
DescriptorExtendedPublicKey :: from_str ( s) . map ( Self :: XPub )
490
529
}
491
530
} else {
492
- let key = match key_part. len ( ) {
493
- 64 => {
494
- let x_only_key = XOnlyPublicKey :: from_str ( key_part) . map_err ( |_| {
495
- DescriptorKeyParseError ( "Error while parsing simple xonly key" )
496
- } ) ?;
497
- SinglePubKey :: XOnly ( x_only_key)
498
- }
499
- 66 | 130 => {
500
- if !( & key_part[ 0 ..2 ] == "02"
501
- || & key_part[ 0 ..2 ] == "03"
502
- || & key_part[ 0 ..2 ] == "04" )
503
- {
504
- return Err ( DescriptorKeyParseError (
505
- "Only publickeys with prefixes 02/03/04 are allowed" ,
506
- ) ) ;
507
- }
508
- let key = bitcoin:: PublicKey :: from_str ( key_part) . map_err ( |_| {
509
- DescriptorKeyParseError ( "Error while parsing simple public key" )
510
- } ) ?;
511
- SinglePubKey :: FullKey ( key)
512
- }
513
- _ => {
514
- return Err ( DescriptorKeyParseError (
515
- "Public keys must be 64/66/130 characters in size" ,
516
- ) )
517
- }
518
- } ;
519
- Ok ( DescriptorPublicKey :: Single ( SinglePub { key, origin } ) )
531
+ DescriptorSinglePublicKey :: from_str ( s) . map ( Self :: Single )
520
532
}
521
533
}
522
534
}
@@ -601,6 +613,60 @@ pub trait DescriptorKey : Clone + fmt::Debug + fmt::Display + Eq + FromStr + std
601
613
) -> Result < bitcoin:: PublicKey , ConversionError > ;
602
614
}
603
615
616
+ impl DescriptorKey for DescriptorSinglePublicKey {
617
+ fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
618
+ if let Some ( ( fingerprint, _) ) = self . origin {
619
+ fingerprint
620
+ } else {
621
+ let mut engine = XpubIdentifier :: engine ( ) ;
622
+ match self . key {
623
+ SinglePubKey :: FullKey ( pk) => {
624
+ pk. write_into ( & mut engine) . expect ( "engines don't error" )
625
+ }
626
+ SinglePubKey :: XOnly ( x_only_pk) => engine. input ( & x_only_pk. serialize ( ) ) ,
627
+ } ;
628
+ bip32:: Fingerprint :: from (
629
+ & XpubIdentifier :: from_engine ( engine) [ ..4 ]
630
+ . try_into ( )
631
+ . expect ( "4 byte slice" ) ,
632
+ )
633
+ }
634
+ }
635
+
636
+ fn full_derivation_path ( & self ) -> Option < bip32:: DerivationPath > {
637
+ Some ( if let Some ( ( _, ref path) ) = self . origin {
638
+ path. clone ( )
639
+ } else {
640
+ bip32:: DerivationPath :: from ( vec ! [ ] )
641
+ } )
642
+ }
643
+
644
+ fn has_wildcard ( & self ) -> bool {
645
+ false
646
+ }
647
+
648
+ fn at_derivation_index ( self , _index : u32 ) -> Result < DefiniteDescriptorKey , ConversionError > {
649
+ Ok (
650
+ DefiniteDescriptorKey :: new ( DescriptorPublicKey :: Single ( self ) )
651
+ . expect ( "The key should not contain any wildcards at this point" ) ,
652
+ )
653
+ }
654
+
655
+ fn is_multipath ( & self ) -> bool {
656
+ false
657
+ }
658
+
659
+ fn derive_public_key < C : Verification > (
660
+ & self ,
661
+ _secp : & Secp256k1 < C > ,
662
+ ) -> Result < bitcoin:: PublicKey , ConversionError > {
663
+ match self . key {
664
+ SinglePubKey :: FullKey ( pk) => Ok ( pk) ,
665
+ SinglePubKey :: XOnly ( xpk) => Ok ( xpk. to_public_key ( ) ) ,
666
+ }
667
+ }
668
+ }
669
+
604
670
impl DescriptorKey for DescriptorExtendedPublicKey {
605
671
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
606
672
fn master_fingerprint ( & self ) -> bip32:: Fingerprint {
@@ -703,24 +769,7 @@ impl DescriptorPublicKey {
703
769
xpub. xkey . fingerprint ( )
704
770
}
705
771
}
706
- DescriptorPublicKey :: Single ( ref single) => {
707
- if let Some ( ( fingerprint, _) ) = single. origin {
708
- fingerprint
709
- } else {
710
- let mut engine = XpubIdentifier :: engine ( ) ;
711
- match single. key {
712
- SinglePubKey :: FullKey ( pk) => {
713
- pk. write_into ( & mut engine) . expect ( "engines don't error" )
714
- }
715
- SinglePubKey :: XOnly ( x_only_pk) => engine. input ( & x_only_pk. serialize ( ) ) ,
716
- } ;
717
- bip32:: Fingerprint :: from (
718
- & XpubIdentifier :: from_engine ( engine) [ ..4 ]
719
- . try_into ( )
720
- . expect ( "4 byte slice" ) ,
721
- )
722
- }
723
- }
772
+ DescriptorPublicKey :: Single ( ref single) => single. master_fingerprint ( ) ,
724
773
}
725
774
}
726
775
@@ -734,13 +783,7 @@ impl DescriptorPublicKey {
734
783
pub fn full_derivation_path ( & self ) -> Option < bip32:: DerivationPath > {
735
784
match * self {
736
785
DescriptorPublicKey :: XPub ( ref xpub) => xpub. full_derivation_path ( ) ,
737
- DescriptorPublicKey :: Single ( ref single) => {
738
- Some ( if let Some ( ( _, ref path) ) = single. origin {
739
- path. clone ( )
740
- } else {
741
- bip32:: DerivationPath :: from ( vec ! [ ] )
742
- } )
743
- }
786
+ DescriptorPublicKey :: Single ( ref single) => single. full_derivation_path ( ) ,
744
787
DescriptorPublicKey :: MultiXPub ( _) => None ,
745
788
}
746
789
}
@@ -754,7 +797,7 @@ impl DescriptorPublicKey {
754
797
/// Whether or not the key has a wildcard
755
798
pub fn has_wildcard ( & self ) -> bool {
756
799
match * self {
757
- DescriptorPublicKey :: Single ( .. ) => false ,
800
+ DescriptorPublicKey :: Single ( ref single ) => single . has_wildcard ( ) ,
758
801
DescriptorPublicKey :: XPub ( ref xpub) => xpub. has_wildcard ( ) ,
759
802
DescriptorPublicKey :: MultiXPub ( ref xpub) => xpub. wildcard != Wildcard :: None ,
760
803
}
@@ -780,8 +823,7 @@ impl DescriptorPublicKey {
780
823
/// - If `index` is hardened.
781
824
pub fn at_derivation_index ( self , index : u32 ) -> Result < DefiniteDescriptorKey , ConversionError > {
782
825
match self {
783
- DescriptorPublicKey :: Single ( _) => Ok ( DefiniteDescriptorKey :: new ( self )
784
- . expect ( "The key should not contain any wildcards at this point" ) ) ,
826
+ DescriptorPublicKey :: Single ( single) => single. at_derivation_index ( index) ,
785
827
DescriptorPublicKey :: XPub ( xpub) => xpub. at_derivation_index ( index) ,
786
828
DescriptorPublicKey :: MultiXPub ( _) => Err ( ConversionError :: MultiKey ) ,
787
829
}
@@ -790,7 +832,7 @@ impl DescriptorPublicKey {
790
832
/// Whether or not this key has multiple derivation paths.
791
833
pub fn is_multipath ( & self ) -> bool {
792
834
match self {
793
- DescriptorPublicKey :: Single ( .. ) => false ,
835
+ DescriptorPublicKey :: Single ( single ) => single . is_multipath ( ) ,
794
836
DescriptorPublicKey :: XPub ( xpub) => xpub. is_multipath ( ) ,
795
837
DescriptorPublicKey :: MultiXPub ( _) => true ,
796
838
}
@@ -1164,10 +1206,7 @@ impl DefiniteDescriptorKey {
1164
1206
secp : & Secp256k1 < C > ,
1165
1207
) -> Result < bitcoin:: PublicKey , ConversionError > {
1166
1208
match self . 0 {
1167
- DescriptorPublicKey :: Single ( ref pk) => match pk. key {
1168
- SinglePubKey :: FullKey ( pk) => Ok ( pk) ,
1169
- SinglePubKey :: XOnly ( xpk) => Ok ( xpk. to_public_key ( ) ) ,
1170
- } ,
1209
+ DescriptorPublicKey :: Single ( ref pk) => pk. derive_public_key ( secp) ,
1171
1210
DescriptorPublicKey :: XPub ( ref xpk) => xpk. derive_public_key ( secp) ,
1172
1211
DescriptorPublicKey :: MultiXPub ( _) => {
1173
1212
unreachable ! ( "A definite key cannot contain a multipath key." )
0 commit comments