@@ -17,6 +17,9 @@ use miniscript::descriptor::{DescriptorXKey, Wildcard};
1717
1818 use std:: str:: FromStr ;
1919
20+ use miniscript:: Tap ;
21+
22+
2023pub fn generate_descriptor_from_args ( args : GenerateDescriptorArgs ) -> Result < Value , anyhow:: Error > {
2124 match ( args. multipath , args. key . as_ref ( ) ) {
2225 ( true , Some ( key) ) => {
@@ -169,13 +172,58 @@ pub fn generate_bip86_descriptor_from_key(
169172 network : & Network ,
170173 key : & str ,
171174) -> Result < Value , anyhow:: Error > {
172- let external = format ! ( "tr([{}/86'/1'/0']{}/0/*)" , "00000000" , key) ;
173- let internal = format ! ( "tr([{}/86'/1'/0']{}/1/*)" , "00000000" , key) ;
175+ let secp = Secp256k1 :: new ( ) ;
176+ let derivation_path: DerivationPath = "m/86h/1h/0h" . parse ( ) ?;
177+ let xprv: Xpriv = key. parse ( ) . map_err ( |e| anyhow ! ( "Invalid xprv: {e}" ) ) ?;
178+ let fingerprint = xprv. fingerprint ( & secp) ;
179+
180+ let make_desc_key = |branch : u32 | -> Result < ( String , String ) > {
181+ let branch_path: DerivationPath = DerivationPath :: from_str ( & format ! ( "{branch}" ) ) ?;
182+
183+ let desc_xprv = DescriptorXKey {
184+ origin : Some ( ( fingerprint, derivation_path. clone ( ) ) ) , // only account-level path
185+ xkey : xprv,
186+ derivation_path : branch_path, // just the change (0 for external, 1 for internal)
187+ wildcard : Wildcard :: Unhardened ,
188+ } ;
189+
190+
191+ let desc_secret = DescriptorSecretKey :: XPrv ( desc_xprv) ;
192+
193+ // Use the BDK extract() to get both descriptor and keymap
194+ let ( desc_key, keymap, _) = IntoDescriptorKey :: < Tap > :: into_descriptor_key ( desc_secret. clone ( ) ) ?
195+ . extract ( & secp) ?;
196+
197+ // Create the public descriptor from the public key
198+ let public_descriptor = Descriptor :: new_tr ( desc_key. clone ( ) , None ) ?;
199+
200+ // Here, we need to ensure that `desc_secret` is a valid descriptor type
201+ // for the private descriptor; we must use DescriptorPublicKey
202+ let private_descriptor = Descriptor :: new_tr ( desc_key, None ) ?;
203+
204+ // Convert both to string representations
205+ let public_descriptor_str = public_descriptor. to_string ( ) ;
206+ let private_descriptor_str = private_descriptor. to_string_with_secret ( & keymap) ;
207+
208+ Ok ( ( public_descriptor_str, private_descriptor_str) )
209+ } ;
210+
211+
174212
175- Ok ( json ! ( {
213+ let ( external_pub, external_priv) = make_desc_key ( 0 ) ?;
214+ let ( internal_pub, internal_priv) = make_desc_key ( 1 ) ?;
215+
216+ Ok ( serde_json:: json!( {
176217 "type" : "bip86" ,
177- "external" : external,
178- "internal" : internal,
218+ "external" : {
219+ "public" : external_pub,
220+ "private" : external_priv,
221+ } ,
222+ "internal" : {
223+ "public" : internal_pub,
224+ "private" : internal_priv,
225+ } ,
226+ "fingerprint" : fingerprint. to_string( ) ,
179227 "network" : network. to_string( )
180228 } ) )
181229}
@@ -185,13 +233,58 @@ pub fn generate_bip49_descriptor_from_key(
185233 network : & Network ,
186234 key : & str ,
187235) -> Result < Value , anyhow:: Error > {
188- let external = format ! ( "sh(wpkh([{}/49'/1'/0']{}/0/*))" , "00000000" , key) ;
189- let internal = format ! ( "sh(wpkh([{}/49'/1'/0']{}/1/*))" , "00000000" , key) ;
236+ let secp = Secp256k1 :: new ( ) ;
237+ let derivation_path: DerivationPath = "m/49h/1h/0h" . parse ( ) ?;
238+ let xprv: Xpriv = key. parse ( ) . map_err ( |e| anyhow ! ( "Invalid xprv: {e}" ) ) ?;
239+ let fingerprint = xprv. fingerprint ( & secp) ;
240+
241+ let make_desc_key = |branch : u32 | -> Result < ( String , String ) > {
242+ let branch_path: DerivationPath = DerivationPath :: from_str ( & format ! ( "{branch}" ) ) ?;
243+
244+ let desc_xprv = DescriptorXKey {
245+ origin : Some ( ( fingerprint, derivation_path. clone ( ) ) ) , // only account-level path
246+ xkey : xprv,
247+ derivation_path : branch_path, // just the change (0 for external, 1 for internal)
248+ wildcard : Wildcard :: Unhardened ,
249+ } ;
250+
251+
252+ let desc_secret = DescriptorSecretKey :: XPrv ( desc_xprv) ;
253+
254+ // Use the BDK extract() to get both descriptor and keymap
255+ let ( desc_key, keymap, _) = IntoDescriptorKey :: < Segwitv0 > :: into_descriptor_key ( desc_secret. clone ( ) ) ?
256+ . extract ( & secp) ?;
257+
258+ // Create the public descriptor from the public key
259+ let public_descriptor = Descriptor :: new_sh_wpkh ( desc_key. clone ( ) ) ?;
260+
261+ // Here, we need to ensure that `desc_secret` is a valid descriptor type
262+ // for the private descriptor; we must use DescriptorPublicKey
263+ let private_descriptor = Descriptor :: new_sh_wpkh ( desc_key) ?;
264+
265+ // Convert both to string representations
266+ let public_descriptor_str = public_descriptor. to_string ( ) ;
267+ let private_descriptor_str = private_descriptor. to_string_with_secret ( & keymap) ;
268+
269+ Ok ( ( public_descriptor_str, private_descriptor_str) )
270+ } ;
271+
272+
273+
274+ let ( external_pub, external_priv) = make_desc_key ( 0 ) ?;
275+ let ( internal_pub, internal_priv) = make_desc_key ( 1 ) ?;
190276
191- Ok ( json ! ( {
277+ Ok ( serde_json :: json!( {
192278 "type" : "bip49" ,
193- "external" : external,
194- "internal" : internal,
279+ "external" : {
280+ "public" : external_pub,
281+ "private" : external_priv,
282+ } ,
283+ "internal" : {
284+ "public" : internal_pub,
285+ "private" : internal_priv,
286+ } ,
287+ "fingerprint" : fingerprint. to_string( ) ,
195288 "network" : network. to_string( )
196289 } ) )
197290}
@@ -200,13 +293,58 @@ pub fn generate_bip44_descriptor_from_key(
200293 network : & Network ,
201294 key : & str ,
202295) -> Result < Value , anyhow:: Error > {
203- let external = format ! ( "pkh([{}/44'/1'/0']{}/0/*)" , "00000000" , key) ;
204- let internal = format ! ( "pkh([{}/44'/1'/0']{}/1/*)" , "00000000" , key) ;
296+ let secp = Secp256k1 :: new ( ) ;
297+ let derivation_path: DerivationPath = "m/44h/1h/0h" . parse ( ) ?;
298+ let xprv: Xpriv = key. parse ( ) . map_err ( |e| anyhow ! ( "Invalid xprv: {e}" ) ) ?;
299+ let fingerprint = xprv. fingerprint ( & secp) ;
205300
206- Ok ( json ! ( {
301+ let make_desc_key = |branch : u32 | -> Result < ( String , String ) > {
302+ let branch_path: DerivationPath = DerivationPath :: from_str ( & format ! ( "{branch}" ) ) ?;
303+
304+ let desc_xprv = DescriptorXKey {
305+ origin : Some ( ( fingerprint, derivation_path. clone ( ) ) ) , // only account-level path
306+ xkey : xprv,
307+ derivation_path : branch_path, // just the change (0 for external, 1 for internal)
308+ wildcard : Wildcard :: Unhardened ,
309+ } ;
310+
311+
312+ let desc_secret = DescriptorSecretKey :: XPrv ( desc_xprv) ;
313+
314+ // Use the BDK extract() to get both descriptor and keymap
315+ let ( desc_key, keymap, _) = IntoDescriptorKey :: < Segwitv0 > :: into_descriptor_key ( desc_secret. clone ( ) ) ?
316+ . extract ( & secp) ?;
317+
318+ // Create the public descriptor from the public key
319+ let public_descriptor = Descriptor :: new_pkh ( desc_key. clone ( ) ) ?;
320+
321+ // Here, we need to ensure that `desc_secret` is a valid descriptor type
322+ // for the private descriptor; we must use DescriptorPublicKey
323+ let private_descriptor = Descriptor :: new_pkh ( desc_key) ?;
324+
325+ // Convert both to string representations
326+ let public_descriptor_str = public_descriptor. to_string ( ) ;
327+ let private_descriptor_str = private_descriptor. to_string_with_secret ( & keymap) ;
328+
329+ Ok ( ( public_descriptor_str, private_descriptor_str) )
330+ } ;
331+
332+
333+
334+ let ( external_pub, external_priv) = make_desc_key ( 0 ) ?;
335+ let ( internal_pub, internal_priv) = make_desc_key ( 1 ) ?;
336+
337+ Ok ( serde_json:: json!( {
207338 "type" : "bip44" ,
208- "external" : external,
209- "internal" : internal,
339+ "external" : {
340+ "public" : external_pub,
341+ "private" : external_priv,
342+ } ,
343+ "internal" : {
344+ "public" : internal_pub,
345+ "private" : internal_priv,
346+ } ,
347+ "fingerprint" : fingerprint. to_string( ) ,
210348 "network" : network. to_string( )
211349 } ) )
212350}
0 commit comments