Skip to content

Commit 03e34c6

Browse files
committed
commit2
1 parent bd85770 commit 03e34c6

23 files changed

Lines changed: 2067 additions & 1012 deletions

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ To persist `Wallet` state use a data storage crate that reads and writes [`Chang
7979

8080
```rust,no_run
8181
use bdk_wallet::rusqlite;
82-
use bdk_wallet::{KeychainKind, Wallet};
82+
use bdk_wallet::{KeyRing, KeychainKind, Wallet};
8383
8484
// Open or create a new SQLite database for wallet data.
8585
let db_path = "my_wallet.sqlite";
@@ -92,18 +92,20 @@ let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfS
9292
let mut wallet = match Wallet::load()
9393
.descriptor(KeychainKind::External, Some(descriptor))
9494
.descriptor(KeychainKind::Internal, Some(change_descriptor))
95-
.extract_keys()
9695
.check_network(network)
9796
.load_wallet(&mut conn)?
9897
{
9998
Some(wallet) => wallet,
100-
None => Wallet::create(descriptor, change_descriptor)
101-
.network(network)
102-
.create_wallet(&mut conn)?,
99+
None => {
100+
let mut keyring = KeyRing::new(network);
101+
keyring.add_descriptor(KeychainKind::External, descriptor)?;
102+
keyring.add_descriptor(KeychainKind::Internal, change_descriptor)?;
103+
keyring.into_params()?.create_wallet(&mut conn)?
104+
}
103105
};
104106
105107
// Get a new address to receive bitcoin!
106-
let address_info = wallet.reveal_next_address(KeychainKind::External);
108+
let address_info = wallet.reveal_next_address(KeychainKind::External).expect("keychain must exist");
107109
108110
// Persist new wallet state to database.
109111
wallet.persist(&mut conn)?;

examples/bitcoind_rpc.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use bdk_bitcoind_rpc::{
22
bitcoincore_rpc::{Auth, Client, RpcApi},
33
Emitter, MempoolEvent,
44
};
5-
use bdk_wallet::rusqlite::Connection;
65
use bdk_wallet::{
76
bitcoin::{Block, Network},
87
KeychainKind, Wallet,
98
};
9+
use bdk_wallet::{rusqlite::Connection, KeyRing};
1010
use clap::{self, Parser};
1111
use std::{
1212
path::PathBuf,
@@ -97,26 +97,31 @@ fn main() -> anyhow::Result<()> {
9797
let wallet_opt = Wallet::load()
9898
.descriptor(KeychainKind::External, Some(args.descriptor.clone()))
9999
.descriptor(KeychainKind::Internal, args.change_descriptor.clone())
100-
.extract_keys()
101100
.check_network(args.network)
102101
.load_wallet(&mut db)?;
103102
let mut wallet = match wallet_opt {
104103
Some(wallet) => wallet,
105-
None => match &args.change_descriptor {
106-
Some(change_desc) => Wallet::create(args.descriptor.clone(), change_desc.clone())
107-
.network(args.network)
108-
.create_wallet(&mut db)?,
109-
None => Wallet::create_single(args.descriptor.clone())
110-
.network(args.network)
111-
.create_wallet(&mut db)?,
112-
},
104+
None => {
105+
let mut keyring = KeyRing::new(args.network);
106+
keyring.add_descriptor(KeychainKind::External, args.descriptor.clone())?;
107+
match &args.change_descriptor {
108+
Some(change_desc) => {
109+
keyring.add_descriptor(KeychainKind::Internal, change_desc.clone())?;
110+
keyring.into_params()?.create_wallet(&mut db)?
111+
}
112+
None => keyring.into_params()?.create_wallet(&mut db)?,
113+
}
114+
}
113115
};
114116
println!(
115117
"Loaded wallet in {}s",
116118
start_load_wallet.elapsed().as_secs_f32()
117119
);
118120

119-
let address = wallet.reveal_next_address(KeychainKind::External).address;
121+
let address = wallet
122+
.reveal_next_address(KeychainKind::External)
123+
.expect("keychain must exist")
124+
.address;
120125
println!("Wallet address: {address}");
121126

122127
let balance = wallet.balance();

examples/compiler.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use bitcoin::Network;
2121
use miniscript::policy::Concrete;
2222
use miniscript::Descriptor;
2323

24-
use bdk_wallet::{KeychainKind, Wallet};
24+
use bdk_wallet::{KeyRing, KeychainKind};
2525

2626
/// Miniscript policy is a high level abstraction of spending conditions. Defined in the
2727
/// rust-miniscript library here https://docs.rs/miniscript/7.0.0/miniscript/policy/index.html
@@ -56,23 +56,26 @@ fn main() -> Result<(), Box<dyn Error>> {
5656

5757
println!("Compiled into Descriptor: \n{descriptor}");
5858

59+
let mut keyring = KeyRing::new(Network::Regtest);
60+
keyring.add_descriptor(KeychainKind::External, descriptor)?;
61+
5962
// Create a new wallet from descriptors
60-
let mut wallet = Wallet::create_single(descriptor)
61-
.network(Network::Regtest)
62-
.create_wallet_no_persist()?;
63+
let mut wallet = keyring.into_params()?.create_wallet_no_persist()?;
6364

6465
println!(
6566
"First derived address from the descriptor: \n{}",
66-
wallet.next_unused_address(KeychainKind::External),
67+
wallet
68+
.next_unused_address(KeychainKind::External)
69+
.expect("keychain must exist"),
6770
);
6871

69-
// BDK also has it's own `Policy` structure to represent the spending condition in a more
70-
// human readable json format.
71-
let spending_policy = wallet.policies(KeychainKind::External)?;
72-
println!(
73-
"The BDK spending policy: \n{}",
74-
serde_json::to_string_pretty(&spending_policy)?
75-
);
72+
// // BDK also has it's own `Policy` structure to represent the spending condition in a more
73+
// // human readable json format.
74+
// let spending_policy = wallet.policies(KeychainKind::External)?;
75+
// println!(
76+
// "The BDK spending policy: \n{}",
77+
// serde_json::to_string_pretty(&spending_policy)?
78+
// );
7679

7780
Ok(())
7881
}

examples/electrum.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use bdk_wallet::bitcoin::Network;
66
use bdk_wallet::chain::collections::HashSet;
77
use bdk_wallet::psbt::PsbtUtils;
88
use bdk_wallet::rusqlite::Connection;
9+
use bdk_wallet::KeyRing;
910
use bdk_wallet::Wallet;
1011
use bdk_wallet::{KeychainKind, SignOptions};
12+
use bdk_wallet::descriptor::IntoWalletDescriptor;
1113
use std::io::Write;
1214
use std::thread::sleep;
1315
use std::time::Duration;
@@ -27,17 +29,21 @@ fn main() -> Result<(), anyhow::Error> {
2729
let wallet_opt = Wallet::load()
2830
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
2931
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
30-
.extract_keys()
3132
.check_network(NETWORK)
3233
.load_wallet(&mut db)?;
3334
let mut wallet = match wallet_opt {
3435
Some(wallet) => wallet,
35-
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
36-
.network(NETWORK)
37-
.create_wallet(&mut db)?,
36+
None => {
37+
let mut keyring = KeyRing::new(NETWORK);
38+
keyring.add_descriptor(KeychainKind::External, EXTERNAL_DESC)?;
39+
keyring.add_descriptor(KeychainKind::Internal, INTERNAL_DESC)?;
40+
keyring.into_params()?.create_wallet(&mut db)?
41+
}
3842
};
3943

40-
let address = wallet.next_unused_address(KeychainKind::External);
44+
let address = wallet
45+
.next_unused_address(KeychainKind::External)
46+
.expect("keychain must exist");
4147
wallet.persist(&mut db)?;
4248
println!("Generated Address: {address}");
4349

@@ -89,7 +95,14 @@ fn main() -> Result<(), anyhow::Error> {
8995
tx_builder.fee_rate(target_fee_rate);
9096

9197
let mut psbt = tx_builder.finish()?;
92-
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
98+
let finalized = wallet.sign_with_signers(
99+
&mut psbt,
100+
&[
101+
&get_signers(EXTERNAL_DESC, &wallet),
102+
&get_signers(INTERNAL_DESC, &wallet),
103+
],
104+
SignOptions::default(),
105+
)?;
93106
assert!(finalized);
94107
let original_fee = psbt.fee_amount().unwrap();
95108
let tx_feerate = psbt.fee_rate().unwrap();
@@ -124,7 +137,14 @@ fn main() -> Result<(), anyhow::Error> {
124137
let mut builder = wallet.build_fee_bump(txid).expect("failed to bump tx");
125138
builder.fee_rate(feerate);
126139
let mut bumped_psbt = builder.finish().unwrap();
127-
let finalize_btx = wallet.sign(&mut bumped_psbt, SignOptions::default())?;
140+
let finalize_btx = wallet.sign_with_signers(
141+
&mut bumped_psbt,
142+
&[
143+
&get_signers(EXTERNAL_DESC, &wallet),
144+
&get_signers(INTERNAL_DESC, &wallet),
145+
],
146+
SignOptions::default(),
147+
)?;
128148
assert!(finalize_btx);
129149
let new_fee = bumped_psbt.fee_amount().unwrap();
130150
let bumped_tx = bumped_psbt.extract_tx()?;
@@ -176,3 +196,14 @@ fn main() -> Result<(), anyhow::Error> {
176196

177197
Ok(())
178198
}
199+
200+
pub fn get_signers(
201+
desc: impl IntoWalletDescriptor,
202+
wallet: &Wallet<KeychainKind>
203+
) -> bdk_wallet::signer::SignersContainer {
204+
use bdk_wallet::signer::SignersContainer;
205+
206+
let (descriptor, keymap) = desc.into_wallet_descriptor(wallet.secp_ctx(), wallet.network().into())
207+
.unwrap();
208+
SignersContainer::build(keymap, &descriptor, wallet.secp_ctx())
209+
}

examples/esplora_async.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use bdk_wallet::{
33
bitcoin::{Amount, FeeRate, Network},
44
psbt::PsbtUtils,
55
rusqlite::Connection,
6-
KeychainKind, SignOptions, Wallet,
6+
KeyRing, KeychainKind, SignOptions, Wallet,
7+
descriptor::IntoWalletDescriptor,
78
};
89
use std::{collections::BTreeSet, io::Write};
910
use tokio::time::{sleep, Duration};
@@ -24,17 +25,21 @@ async fn main() -> Result<(), anyhow::Error> {
2425
let wallet_opt = Wallet::load()
2526
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
2627
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
27-
.extract_keys()
2828
.check_network(NETWORK)
2929
.load_wallet(&mut db)?;
3030
let mut wallet = match wallet_opt {
3131
Some(wallet) => wallet,
32-
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
33-
.network(NETWORK)
34-
.create_wallet(&mut db)?,
32+
None => {
33+
let mut keyring = KeyRing::new(NETWORK);
34+
keyring.add_descriptor(KeychainKind::External, EXTERNAL_DESC)?;
35+
keyring.add_descriptor(KeychainKind::Internal, INTERNAL_DESC)?;
36+
keyring.into_params()?.create_wallet(&mut db)?
37+
}
3538
};
3639

37-
let address = wallet.next_unused_address(KeychainKind::External);
40+
let address = wallet
41+
.next_unused_address(KeychainKind::External)
42+
.expect("keychain must exist");
3843
wallet.persist(&mut db)?;
3944
println!("Next unused address: ({}) {address}", address.index);
4045

@@ -83,7 +88,14 @@ async fn main() -> Result<(), anyhow::Error> {
8388
tx_builder.fee_rate(target_fee_rate);
8489

8590
let mut psbt = tx_builder.finish()?;
86-
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
91+
let finalized = wallet.sign_with_signers(
92+
&mut psbt,
93+
&[
94+
&get_signers(EXTERNAL_DESC, &wallet),
95+
&get_signers(INTERNAL_DESC, &wallet),
96+
],
97+
SignOptions::default(),
98+
)?;
8799
assert!(finalized);
88100
let original_fee = psbt.fee_amount().unwrap();
89101
let tx_feerate = psbt.fee_rate().unwrap();
@@ -117,7 +129,14 @@ async fn main() -> Result<(), anyhow::Error> {
117129
let mut builder = wallet.build_fee_bump(txid).expect("failed to bump tx");
118130
builder.fee_rate(feerate);
119131
let mut bumped_psbt = builder.finish().unwrap();
120-
let finalize_btx = wallet.sign(&mut bumped_psbt, SignOptions::default())?;
132+
let finalize_btx = wallet.sign_with_signers(
133+
&mut bumped_psbt,
134+
&[
135+
&get_signers(EXTERNAL_DESC, &wallet),
136+
&get_signers(INTERNAL_DESC, &wallet),
137+
],
138+
SignOptions::default(),
139+
)?;
121140
assert!(finalize_btx);
122141
let new_fee = bumped_psbt.fee_amount().unwrap();
123142
let bumped_tx = bumped_psbt.extract_tx()?;
@@ -185,3 +204,14 @@ async fn main() -> Result<(), anyhow::Error> {
185204

186205
Ok(())
187206
}
207+
208+
pub fn get_signers(
209+
desc: impl IntoWalletDescriptor,
210+
wallet: &Wallet<KeychainKind>
211+
) -> bdk_wallet::signer::SignersContainer {
212+
use bdk_wallet::signer::SignersContainer;
213+
214+
let (descriptor, keymap) = desc.into_wallet_descriptor(wallet.secp_ctx(), wallet.network().into())
215+
.unwrap();
216+
SignersContainer::build(keymap, &descriptor, wallet.secp_ctx())
217+
}

examples/esplora_blocking.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use bdk_wallet::rusqlite::Connection;
33
use bdk_wallet::{
44
bitcoin::{Amount, FeeRate, Network},
55
psbt::PsbtUtils,
6-
KeychainKind, SignOptions, Wallet,
6+
KeyRing, KeychainKind, SignOptions, Wallet,
7+
descriptor::IntoWalletDescriptor,
78
};
89
use std::thread::sleep;
910
use std::time::Duration;
@@ -24,17 +25,21 @@ fn main() -> Result<(), anyhow::Error> {
2425
let wallet_opt = Wallet::load()
2526
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
2627
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
27-
.extract_keys()
2828
.check_network(NETWORK)
2929
.load_wallet(&mut db)?;
3030
let mut wallet = match wallet_opt {
3131
Some(wallet) => wallet,
32-
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
33-
.network(NETWORK)
34-
.create_wallet(&mut db)?,
32+
None => {
33+
let mut keyring = KeyRing::new(NETWORK);
34+
keyring.add_descriptor(KeychainKind::External, EXTERNAL_DESC)?;
35+
keyring.add_descriptor(KeychainKind::Internal, INTERNAL_DESC)?;
36+
keyring.into_params()?.create_wallet(&mut db)?
37+
}
3538
};
3639

37-
let address = wallet.next_unused_address(KeychainKind::External);
40+
let address = wallet
41+
.next_unused_address(KeychainKind::External)
42+
.expect("keychain must exist");
3843
wallet.persist(&mut db)?;
3944
println!(
4045
"Next unused address: ({}) {}",
@@ -78,7 +83,14 @@ fn main() -> Result<(), anyhow::Error> {
7883
tx_builder.fee_rate(target_fee_rate);
7984

8085
let mut psbt = tx_builder.finish()?;
81-
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
86+
let finalized = wallet.sign_with_signers(
87+
&mut psbt,
88+
&[
89+
&get_signers(EXTERNAL_DESC, &wallet),
90+
&get_signers(INTERNAL_DESC, &wallet),
91+
],
92+
SignOptions::default(),
93+
)?;
8294
assert!(finalized);
8395
let original_fee = psbt.fee_amount().unwrap();
8496
let tx_feerate = psbt.fee_rate().unwrap();
@@ -113,7 +125,14 @@ fn main() -> Result<(), anyhow::Error> {
113125
let mut builder = wallet.build_fee_bump(txid).unwrap();
114126
builder.fee_rate(feerate);
115127
let mut new_psbt = builder.finish().unwrap();
116-
let finalize_tx = wallet.sign(&mut new_psbt, SignOptions::default())?;
128+
let finalize_tx = wallet.sign_with_signers(
129+
&mut new_psbt,
130+
&[
131+
&get_signers(EXTERNAL_DESC, &wallet),
132+
&get_signers(INTERNAL_DESC, &wallet),
133+
],
134+
SignOptions::default(),
135+
)?;
117136
assert!(finalize_tx);
118137
let new_fee = new_psbt.fee_amount().unwrap();
119138
let bumped_tx = new_psbt.extract_tx()?;
@@ -166,3 +185,14 @@ fn main() -> Result<(), anyhow::Error> {
166185

167186
Ok(())
168187
}
188+
189+
pub fn get_signers(
190+
desc: impl IntoWalletDescriptor,
191+
wallet: &Wallet<KeychainKind>
192+
) -> bdk_wallet::signer::SignersContainer {
193+
use bdk_wallet::signer::SignersContainer;
194+
195+
let (descriptor, keymap) = desc.into_wallet_descriptor(wallet.secp_ctx(), wallet.network().into())
196+
.unwrap();
197+
SignersContainer::build(keymap, &descriptor, wallet.secp_ctx())
198+
}

0 commit comments

Comments
 (0)