Skip to content

Commit fc0ef04

Browse files
Add mnemonic to descriptors example.
This was initially requested by one user but might be relevant for other users as well.
1 parent 06310f1 commit fc0ef04

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

Diff for: Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ name = "rpcwallet"
119119
path = "examples/rpcwallet.rs"
120120
required-features = ["keys-bip39", "key-value-db", "rpc", "electrsd/bitcoind_22_0"]
121121

122+
[[example]]
123+
name = "mnemonic_to_descriptors"
124+
path = "examples/mnemonic_to_descriptors.rs"
125+
required-features = ["all-keys"]
126+
122127
[workspace]
123128
members = ["macros"]
124129
[package.metadata.docs.rs]

Diff for: examples/mnemonic_to_descriptors.rs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
2+
//
3+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
4+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
6+
// You may not use this file except in accordance with one or both of these
7+
// licenses.
8+
9+
use bdk::bitcoin::secp256k1::Secp256k1;
10+
use bdk::bitcoin::util::bip32::{DerivationPath, KeySource};
11+
use bdk::bitcoin::Network;
12+
use bdk::keys::bip39::{Language, Mnemonic, WordCount};
13+
use bdk::keys::DescriptorKey::Secret;
14+
use bdk::keys::KeyError::Message;
15+
use bdk::keys::{DerivableKey, DescriptorKey, ExtendedKey, GeneratableKey, GeneratedKey};
16+
use bdk::miniscript::{miniscript, Segwitv0};
17+
use bdk::Error as BDK_Error;
18+
use std::error::Error;
19+
use std::str::FromStr;
20+
21+
/// This example demonstrates how to generate a mnemonic phrase
22+
/// using BDK and use that to generate a master extended private key.
23+
/// It then uses the master extended private key with a derivation
24+
/// path to generate child extended private and public keys. Finally,
25+
/// it uses the derivation path and these keys to get the descriptors.
26+
fn main() -> Result<(), Box<dyn Error>> {
27+
let secp = Secp256k1::new();
28+
29+
// In this example we are generating a 12 words mnemonic phrase
30+
// but it is also possible generate 15, 18, 21 and 24 words
31+
// using their respective `WordCount` variant.
32+
let mnemonic: GeneratedKey<_, miniscript::BareCtx> =
33+
Mnemonic::generate((WordCount::Words12, Language::English))
34+
.map_err(|_| BDK_Error::Generic("Mnemonic generation error".to_string()))?;
35+
36+
let mnemonic = mnemonic.into_key();
37+
let xkey: ExtendedKey = (mnemonic.clone(), None).into_extended_key()?;
38+
let master_xprv = xkey.into_xprv(Network::Testnet).ok_or_else(|| {
39+
BDK_Error::Generic("Privatekey info not found (should not happen)".to_string())
40+
})?;
41+
42+
let fingerprint = master_xprv.fingerprint(&secp);
43+
let phrase = mnemonic
44+
.word_iter()
45+
.fold("".to_string(), |phrase, w| phrase + w + " ")
46+
.trim()
47+
.to_string();
48+
49+
println!("Mnemonic phrase: {}", phrase);
50+
println!("Xprv fingerprint: {}", fingerprint);
51+
52+
// You can replace this derivation path with one of your choosing
53+
let path = DerivationPath::from_str("m/84h/0h/0h").unwrap();
54+
55+
let derived_xprv = &master_xprv.derive_priv(&secp, &path)?;
56+
57+
let origin: KeySource = (fingerprint, path);
58+
59+
let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
60+
derived_xprv.into_descriptor_key(Some(origin), DerivationPath::default())?;
61+
62+
if let Secret(desc_seckey, _, _) = derived_xprv_desc_key {
63+
let desc_pubkey = desc_seckey
64+
.as_public(&secp)
65+
.map_err(|e| BDK_Error::Generic(e.to_string()))?;
66+
println!("xpub {}", desc_pubkey.to_string());
67+
println!("xprv {}", desc_seckey.to_string());
68+
} else {
69+
return Err(Box::new(BDK_Error::Key(Message(
70+
"Invalid key variant".to_string(),
71+
))));
72+
}
73+
74+
Ok(())
75+
}

0 commit comments

Comments
 (0)