@@ -23,19 +23,21 @@ use bdk_wallet::bitcoin::script::PushBytesBuf;
2323use bdk_wallet:: bitcoin:: Network ;
2424use bdk_wallet:: bitcoin:: { secp256k1:: Secp256k1 , Txid } ;
2525use bdk_wallet:: bitcoin:: { Amount , FeeRate , Psbt , Sequence } ;
26- use bdk_wallet:: descriptor:: Segwitv0 ;
26+ use bdk_wallet:: descriptor:: { Descriptor , Segwitv0 } ;
2727use bdk_wallet:: keys:: bip39:: WordCount ;
2828#[ cfg( feature = "sqlite" ) ]
2929use bdk_wallet:: rusqlite:: Connection ;
3030#[ cfg( feature = "compiler" ) ]
3131use bdk_wallet:: {
32- descriptor:: { Descriptor , Legacy , Miniscript } ,
32+ descriptor:: { Legacy , Miniscript } ,
3333 miniscript:: policy:: Concrete ,
3434} ;
3535use bdk_wallet:: { KeychainKind , SignOptions , Wallet } ;
3636
3737use bdk_wallet:: keys:: DescriptorKey :: Secret ;
38- use bdk_wallet:: keys:: { DerivableKey , DescriptorKey , ExtendedKey , GeneratableKey , GeneratedKey } ;
38+ use bdk_wallet:: keys:: {
39+ DerivableKey , DescriptorKey , DescriptorPublicKey , ExtendedKey , GeneratableKey , GeneratedKey ,
40+ } ;
3941use bdk_wallet:: miniscript:: miniscript;
4042use serde_json:: { json, Value } ;
4143use std:: collections:: BTreeMap ;
@@ -901,9 +903,11 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
901903 }
902904 Ok ( "" . to_string ( ) )
903905 }
904- CliSubCommand :: Descriptor ( args) => {
906+ CliSubCommand :: Descriptor {
907+ subcommand : descriptor_subcommand,
908+ } => {
905909 let network = cli_opts. network ;
906- let descriptor = generate_descriptor_from_args ( args . clone ( ) , network )
910+ let descriptor = handle_descriptor_subcommand ( network , descriptor_subcommand )
907911 . map_err ( |e| Error :: Generic ( e. to_string ( ) ) ) ?;
908912 let json = serde_json:: to_string_pretty ( & descriptor) ?;
909913 Ok ( json)
@@ -979,49 +983,71 @@ fn readline() -> Result<String, Error> {
979983 Ok ( buffer)
980984}
981985
982- pub fn generate_descriptor_from_args (
983- args : GenerateDescriptorArgs ,
986+ pub fn handle_descriptor_subcommand (
984987 network : Network ,
985- ) -> Result < serde_json:: Value , Error > {
986- let descriptor_type = match args. r#type {
987- 44 => DescriptorType :: Bip44 ,
988- 49 => DescriptorType :: Bip49 ,
989- 84 => DescriptorType :: Bip84 ,
990- 86 => DescriptorType :: Bip86 ,
991- _ => {
992- return Err ( Error :: Generic ( format ! (
993- "Unsupported script type {}" ,
994- args. r#type
995- ) ) )
996- }
997- } ;
998- if args. multipath && args. path . is_some ( ) {
999- return Err ( Error :: InvalidArguments (
1000- "Path can not be called here" . to_string ( ) ,
1001- ) ) ;
1002- }
1003- if args. path . is_some ( ) && args. key . is_none ( ) {
1004- return Err ( Error :: InvalidArguments (
1005- "Custom path requires a key" . to_string ( ) ,
1006- ) ) ;
1007- }
1008- match ( args. multipath , args. key . as_ref ( ) ) {
1009- ( true , Some ( key) ) => generate_multipath_descriptor ( & network, args. r#type , key) ,
1010- ( false , Some ( key) ) => {
1011- if let Some ( path) = args. path . as_ref ( ) {
1012- // Use descriptor from custom derivation path
1013- generate_bip_descriptor_from_key ( & network, key, path, descriptor_type)
1014- } else {
1015- generate_standard_descriptor ( & network, args. r#type , key)
988+ subcommand : DescriptorSubCommand ,
989+ ) -> Result < Value , Error > {
990+ match subcommand {
991+ DescriptorSubCommand :: Generate {
992+ r#type,
993+ multipath,
994+ key,
995+ } => {
996+ let ( descriptor_type, derivation_path_str) = match r#type {
997+ 44 => ( DescriptorType :: Bip44 , "m/44'/1'/0'" ) ,
998+ 49 => ( DescriptorType :: Bip49 , "m/49'/1'/0'" ) ,
999+ 84 => ( DescriptorType :: Bip84 , "m/84'/1'/0'" ) ,
1000+ 86 => ( DescriptorType :: Bip86 , "m/86'/1'/0'" ) ,
1001+ _ => {
1002+ return Err ( Error :: Generic ( format ! (
1003+ "Unsupported script type {}" ,
1004+ r#type
1005+ ) ) )
1006+ }
1007+ } ;
1008+
1009+ match ( multipath, key. as_ref ( ) ) {
1010+ ( true , Some ( k) ) => generate_multipath_descriptor ( & network, r#type, k) ,
1011+ ( false , Some ( k) ) => {
1012+ if is_mnemonic ( k) {
1013+ generate_descriptor_from_mnemonic_string (
1014+ k,
1015+ network,
1016+ derivation_path_str,
1017+ descriptor_type,
1018+ )
1019+ } else {
1020+ generate_standard_descriptor ( & network, r#type, k)
1021+ }
1022+ }
1023+ ( false , None ) => generate_new_descriptor_with_mnemonic ( network, descriptor_type) ,
1024+ _ => Err ( Error :: InvalidArguments (
1025+ "Invalid arguments: provide a key or weak string" . to_string ( ) ,
1026+ ) ) ,
10161027 }
10171028 }
1018- ( false , None ) => {
1019- // Generate from fresh mnemonic
1020- generate_new_descriptor_with_mnemonic ( network, descriptor_type)
1029+ DescriptorSubCommand :: Info { descriptor } => {
1030+ let parsed: Descriptor < DescriptorPublicKey > = descriptor
1031+ . parse ( )
1032+ . map_err ( |e| Error :: Generic ( format ! ( "Failed to parse descriptor: {}" , e) ) ) ?;
1033+
1034+ let checksum = parsed. to_string ( ) ;
1035+ let script_type = match parsed {
1036+ Descriptor :: Wpkh ( _) => "wpkh" ,
1037+ Descriptor :: Pkh ( _) => "pkh" ,
1038+ Descriptor :: Sh ( _) => "sh" ,
1039+ Descriptor :: Tr ( _) => "tr" ,
1040+ _ => "other" ,
1041+ } ;
1042+
1043+ let json = json ! ( {
1044+ "descriptor" : checksum,
1045+ "type" : script_type,
1046+ "is_multipath" : descriptor. contains( "/*" ) ,
1047+ } ) ;
1048+
1049+ Ok ( json)
10211050 }
1022- _ => Err ( Error :: InvalidArguments (
1023- "Invalid arguments: please provide a key or a weak string" . to_string ( ) ,
1024- ) ) ,
10251051 }
10261052}
10271053
0 commit comments