@@ -50,7 +50,17 @@ impl fmt::Display for Key {
5050 match self {
5151 Key :: Slip77 ( data) => write ! ( f, "slip77({})" , data) ,
5252 Key :: Bare ( pk) => fmt:: Display :: fmt ( pk, f) ,
53- Key :: View ( sk) => fmt:: Display :: fmt ( sk, f) ,
53+ Key :: View ( sk) => {
54+ if let DescriptorSecretKey :: Single ( sk) = sk {
55+ crate :: descriptor:: maybe_fmt_master_id ( f, & sk. origin ) ?;
56+ for byte in & sk. key . inner . secret_bytes ( ) {
57+ write ! ( f, "{:02x}" , byte) ?;
58+ }
59+ Ok ( ( ) )
60+ } else {
61+ fmt:: Display :: fmt ( sk, f)
62+ }
63+ }
5464 }
5565 }
5666}
@@ -211,7 +221,7 @@ impl_from_str!(
211221 "slip77() must have exactly one argument" . to_owned( )
212222 ) ) ,
213223 _ => expression:: terminal( keyexpr, DescriptorPublicKey :: from_str) . map( Key :: Bare )
214- . or_else( |_| expression:: terminal( keyexpr, DescriptorSecretKey :: from_str ) . map( Key :: View ) ) ?,
224+ . or_else( |_| expression:: terminal( keyexpr, |s : & str | DescriptorSecretKey :: from_str_inner ( s , true ) ) . map( Key :: View ) ) ?,
215225 } ,
216226 descriptor: crate :: Descriptor :: from_tree( & top. args[ 1 ] ) ?,
217227 } )
@@ -420,6 +430,10 @@ mod tests {
420430 "ct(pk(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623),elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#nvax6rau" ,
421431 "unexpected «pk»" ,
422432 ) ,
433+ (
434+ "ct(L3jXxwef3fpB7hcrFozcWgHeJCPSAFiZ1Ji2YJMPxceaGvy3PC1q,elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#gcy6hcfz" ,
435+ "unexpected «Error while parsing xkey.»" ,
436+ ) ,
423437 ] ;
424438
425439 /*
@@ -470,6 +484,26 @@ mod tests {
470484 test. check ( & secp) ;
471485 }
472486
487+ #[ test]
488+ fn view_single_key_descriptor ( ) {
489+ let secp = secp256k1_zkp:: Secp256k1 :: new ( ) ;
490+ let view_key = "c25deb86fa11e49d651d7eae27c220ef930fbd86ea023eebfa73e54875647963" ;
491+ let ct_key = "0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90" ;
492+ let pk = "021a8fb6bd5a653b021b98a2a785725b8ddacfe3687bc043aa7f4d25d3a48d40b5" ;
493+ let addr_conf = "el1qq265u4g3k3m3qpyxjwpdrtnm293wuxgvs9xzmzcs2ck0mv5rx23w4d7xfsednsmmxrszfe7s9rs0c6cvf3dfyqwa4jj40uffq" ;
494+ let addr_unconf = "ert1qklrycvkecdanpcpyulgz3c8udvxyck5jkzxddw" ;
495+
496+ for desc_str in [
497+ format ! ( "ct({view_key},elwpkh({pk}))#c2kx9zll" ) ,
498+ format ! ( "ct({ct_key},elwpkh({pk}))#m5mvyh29" ) ,
499+ ] {
500+ let desc = Descriptor :: < DefiniteDescriptorKey > :: from_str ( & desc_str) . unwrap ( ) ;
501+ assert_eq ! ( desc. to_string( ) , desc_str) ;
502+ assert_eq ! ( addr_conf, & desc. address( & secp, & elements:: AddressParams :: ELEMENTS ) . unwrap( ) . to_string( ) ) ;
503+ assert_eq ! ( addr_unconf, & desc. unconfidential_address( & elements:: AddressParams :: ELEMENTS ) . unwrap( ) . to_string( ) ) ;
504+ }
505+ }
506+
473507 #[ test]
474508 fn descriptor_wildcard ( ) {
475509 let secp = secp256k1_zkp:: Secp256k1 :: new ( ) ;
0 commit comments