Skip to content

Commit 2d67e10

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 dfeb08f commit 2d67e10

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ name = "psbt_signer"
124124
path = "examples/psbt_signer.rs"
125125
required-features = ["electrum"]
126126

127+
[[example]]
128+
name = "mnemonic_to_descriptors"
129+
path = "examples/mnemonic_to_descriptors.rs"
130+
required-features = ["all-keys"]
131+
127132
[workspace]
128133
members = ["macros"]
129134
[package.metadata.docs.rs]

examples/mnemonic_to_descriptors.rs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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;
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::{
16+
DerivableKey, DescriptorKey, ExtendedKey, GeneratableKey, GeneratedKey, IntoDescriptorKey,
17+
};
18+
use bdk::miniscript::Segwitv0;
19+
use bdk::Error as BDK_Error;
20+
use std::error::Error;
21+
use std::str::FromStr;
22+
23+
/// This example demonstrates how to generate a mnemonic phrase
24+
/// using BDK and use that to generate a master extended private key.
25+
/// It then uses the master extended private key with a derivation
26+
/// path to generate child extended private and public keys. Finally,
27+
/// it uses the derivation path and these keys to get the descriptors.
28+
fn main() -> Result<(), Box<dyn Error>> {
29+
let secp = Secp256k1::new();
30+
31+
// In this example we are generating a 12 words mnemonic phrase
32+
// but it is also possible generate 15, 18, 21 and 24 words
33+
// using their respective `WordCount` variant.
34+
let mnemonic: GeneratedKey<_, Segwitv0> =
35+
Mnemonic::generate((WordCount::Words12, Language::English))
36+
.map_err(|_| BDK_Error::Generic("Mnemonic generation error".to_string()))?;
37+
38+
let mnemonic = mnemonic.into_key();
39+
40+
// We don't want a passphrase on the mnemonic so we use None
41+
let xkey: ExtendedKey = (mnemonic.clone(), None).into_extended_key()?;
42+
let master_xprv = xkey.into_xprv(Network::Testnet).ok_or_else(|| {
43+
BDK_Error::Generic("Privatekey info not found (should not happen)".to_string())
44+
})?;
45+
46+
let fingerprint = master_xprv.fingerprint(&secp);
47+
let phrase = mnemonic.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+
// The second item in the mnemonic tuple represents the passphrase.
56+
let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
57+
((mnemonic, None), path).into_descriptor_key()?;
58+
59+
if let Secret(desc_seckey, _, _) = derived_xprv_desc_key {
60+
let desc_pubkey = desc_seckey
61+
.as_public(&secp)
62+
.map_err(|e| BDK_Error::Generic(e.to_string()))?;
63+
println!("xpub {}", desc_pubkey);
64+
println!("xprv {}", desc_seckey);
65+
} else {
66+
return Err(Box::new(BDK_Error::Key(Message(
67+
"Invalid key variant".to_string(),
68+
))));
69+
}
70+
71+
Ok(())
72+
}

0 commit comments

Comments
 (0)