Skip to content

Commit 4638293

Browse files
committed
Update functions
1 parent 91bb4bf commit 4638293

File tree

1 file changed

+153
-15
lines changed

1 file changed

+153
-15
lines changed

src/descriptor_handler.rs

Lines changed: 153 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use miniscript::descriptor::{DescriptorXKey, Wildcard};
1717

1818
use std::str::FromStr;
1919

20+
use miniscript::Tap;
21+
22+
2023
pub 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

Comments
 (0)