@@ -22,9 +22,22 @@ use bdk_wallet::bitcoin::consensus::encode::serialize_hex;
2222use bdk_wallet:: bitcoin:: script:: PushBytesBuf ;
2323use bdk_wallet:: bitcoin:: Network ;
2424use bdk_wallet:: bitcoin:: { secp256k1:: Secp256k1 , Txid } ;
25- use bdk_wallet:: bitcoin:: { Amount , FeeRate , Psbt , Sequence } ;
2625use bdk_wallet:: descriptor:: Segwitv0 ;
2726use bdk_wallet:: keys:: bip39:: WordCount ;
27+ use bdk_wallet:: keys:: { GeneratableKey , GeneratedKey } ;
28+ use bdk_wallet:: serde:: ser:: Error as SerdeErrorTrait ;
29+ use serde_json:: json;
30+ use serde_json:: Error as SerdeError ;
31+ use serde_json:: Value ;
32+
33+ #[ cfg( any(
34+ feature = "electrum" ,
35+ feature = "esplora" ,
36+ feature = "cbf" ,
37+ feature = "rpc"
38+ ) ) ]
39+ use bdk_wallet:: bitcoin:: Transaction ;
40+ use bdk_wallet:: bitcoin:: { Amount , FeeRate , Psbt , Sequence } ;
2841#[ cfg( feature = "sqlite" ) ]
2942use bdk_wallet:: rusqlite:: Connection ;
3043#[ cfg( feature = "compiler" ) ]
@@ -33,18 +46,18 @@ use bdk_wallet::{
3346 miniscript:: policy:: Concrete ,
3447} ;
3548use bdk_wallet:: { KeychainKind , SignOptions , Wallet } ;
49+ use std:: fmt;
50+ use std:: str:: FromStr ;
3651
3752use bdk_wallet:: keys:: DescriptorKey :: Secret ;
38- use bdk_wallet:: keys:: { DerivableKey , DescriptorKey , ExtendedKey , GeneratableKey , GeneratedKey } ;
53+ use bdk_wallet:: keys:: { DerivableKey , DescriptorKey , ExtendedKey } ;
3954use bdk_wallet:: miniscript:: miniscript;
40- use serde_json:: json;
4155use std:: collections:: BTreeMap ;
4256#[ cfg( any( feature = "electrum" , feature = "esplora" ) ) ]
4357use std:: collections:: HashSet ;
4458use std:: convert:: TryFrom ;
4559#[ cfg( any( feature = "repl" , feature = "electrum" , feature = "esplora" ) ) ]
4660use std:: io:: Write ;
47- use std:: str:: FromStr ;
4861
4962#[ cfg( feature = "electrum" ) ]
5063use crate :: utils:: BlockchainClient :: Electrum ;
@@ -61,7 +74,7 @@ use tokio::select;
6174) ) ]
6275use {
6376 crate :: commands:: OnlineWalletSubCommand :: * ,
64- bdk_wallet:: bitcoin:: { consensus:: Decodable , hex:: FromHex , Transaction } ,
77+ bdk_wallet:: bitcoin:: { consensus:: Decodable , hex:: FromHex } ,
6578} ;
6679#[ cfg( feature = "esplora" ) ]
6780use { crate :: utils:: BlockchainClient :: Esplora , bdk_esplora:: EsploraAsyncExt } ;
@@ -900,6 +913,13 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
900913 }
901914 Ok ( "" . to_string ( ) )
902915 }
916+ CliSubCommand :: Descriptor ( args) => {
917+ let network = cli_opts. network ;
918+ let descriptor = generate_descriptor_from_args ( args. clone ( ) , network)
919+ . map_err ( |e| SerdeError :: custom ( e. to_string ( ) ) ) ?;
920+ let json = serde_json:: to_string_pretty ( & descriptor) ?;
921+ Ok ( json)
922+ }
903923 } ;
904924 result. map_err ( |e| e. into ( ) )
905925}
@@ -971,6 +991,57 @@ fn readline() -> Result<String, Error> {
971991 Ok ( buffer)
972992}
973993
994+ pub fn generate_descriptor_from_args (
995+ args : GenerateDescriptorArgs ,
996+ network : Network ,
997+ ) -> Result < serde_json:: Value , Error > {
998+ match ( args. multipath , args. key . as_ref ( ) ) {
999+ ( true , Some ( key) ) => generate_multipath_descriptor ( & network, args. r#type , key) ,
1000+ ( false , Some ( key) ) => generate_standard_descriptor ( & network, args. r#type , key) ,
1001+ ( false , None ) => {
1002+ // New default: generate descriptor from fresh mnemonic (for script_type 84 only)
1003+ if args. r#type == 84 {
1004+ generate_new_bip84_descriptor_with_mnemonic ( network)
1005+ } else {
1006+ Err ( Error :: Generic (
1007+ "Only script type 84 is supported for mnemonic-based generation" . to_string ( ) ,
1008+ ) )
1009+ }
1010+ }
1011+ _ => Err ( Error :: InvalidArguments (
1012+ "Invalid arguments: please provide a key or a weak string" . to_string ( ) ,
1013+ ) ) ,
1014+ }
1015+ }
1016+
1017+ pub fn generate_standard_descriptor (
1018+ network : & Network ,
1019+ script_type : u8 ,
1020+ key : & str ,
1021+ ) -> Result < Value , Error > {
1022+ let descriptor_type = match script_type {
1023+ 44 => DescriptorType :: Bip44 ,
1024+ 49 => DescriptorType :: Bip49 ,
1025+ 84 => DescriptorType :: Bip84 ,
1026+ 86 => DescriptorType :: Bip86 ,
1027+ _ => return Err ( Error :: UnsupportedScriptType ( script_type) ) ,
1028+ } ;
1029+
1030+ generate_descriptor_from_key_by_type ( network, key, descriptor_type)
1031+ }
1032+
1033+ impl fmt:: Display for DescriptorType {
1034+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1035+ let s = match self {
1036+ DescriptorType :: Bip44 => "bip44" ,
1037+ DescriptorType :: Bip49 => "bip49" ,
1038+ DescriptorType :: Bip84 => "bip84" ,
1039+ DescriptorType :: Bip86 => "bip86" ,
1040+ } ;
1041+ write ! ( f, "{}" , s)
1042+ }
1043+ }
1044+
9741045#[ cfg( any(
9751046 feature = "electrum" ,
9761047 feature = "esplora" ,
0 commit comments