Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,23 @@ name = "esplora_blocking"

[[example]]
name = "bitcoind_rpc"

[[example]]
name = "multi_keychain_address_generation"
path = "examples/multi_keychain/address_generation.rs"

[[example]]
name = "multi_keychain_wallet"
path = "examples/multi_keychain/wallet.rs"

[[example]]
name = "multi_keychain_balance_tracking"
path = "examples/multi_keychain/balance_tracking.rs"

[[example]]
name = "multi_keychain_migration_guide"
path = "examples/multi_keychain/migration_guide.rs"

[[example]]
name = "multi_keychain_persistence"
path = "examples/multi_keychain/persistence.rs"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ To persist `Wallet` state use a data storage crate that reads and writes [`Chang
* [`bdk_file_store`]: Stores wallet changes in a simple flat file.
* `rusqlite`: Stores wallet changes in a SQLite database.

**Example**
<!-- **Example**

```rust,no_run
use bdk_wallet::rusqlite;
Expand Down Expand Up @@ -110,7 +110,7 @@ wallet.persist(&mut conn)?;

println!("Next receive address: {}", address_info.address);
Ok::<_, anyhow::Error>(())
```
``` -->

## Minimum Supported Rust Version (MSRV)

Expand Down
50 changes: 33 additions & 17 deletions examples/bitcoind_rpc.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#![allow(unused)]
use bdk_bitcoind_rpc::{
bitcoincore_rpc::{Auth, Client, RpcApi},
Emitter, MempoolEvent,
};
use bdk_wallet::rusqlite::Connection;
use bdk_wallet::{
bitcoin::{Block, Network},
KeychainKind, Wallet,
keyring::KeyRing,
KeychainKind, LoadParams, PersistedWallet, Wallet,
};
use clap::{self, Parser};
use std::{
Expand Down Expand Up @@ -94,29 +96,43 @@ fn main() -> anyhow::Result<()> {

let start_load_wallet = Instant::now();
let mut db = Connection::open(args.db_path)?;
let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(args.descriptor.clone()))
.descriptor(KeychainKind::Internal, args.change_descriptor.clone())
.extract_keys()
.check_network(args.network)
.load_wallet(&mut db)?;
let mut wallet = match wallet_opt {

let mut params = LoadParams::new()
.check_descriptor(KeychainKind::External, Some(args.descriptor.clone()))
.check_genesis_hash(bitcoin::constants::genesis_block(args.network).block_hash())
.check_network(args.network);

if let Some(desc) = &args.change_descriptor {
params = params.check_descriptor(KeychainKind::Internal, Some(desc.clone()));
}

let mut wallet = match params.load_wallet(&mut db).unwrap() {
Some(wallet) => wallet,
None => match &args.change_descriptor {
Some(change_desc) => Wallet::create(args.descriptor.clone(), change_desc.clone())
.network(args.network)
.create_wallet(&mut db)?,
None => Wallet::create_single(args.descriptor.clone())
.network(args.network)
.create_wallet(&mut db)?,
},
None => {
let mut keyring: KeyRing<KeychainKind> = KeyRing::new(
args.network,
KeychainKind::External,
args.descriptor.clone(),
)
.unwrap();
if let Some(desc) = &args.change_descriptor {
keyring
.add_descriptor(KeychainKind::Internal, desc.clone())
.unwrap();
}
Wallet::create(keyring).create_wallet(&mut db)?
}
};

println!(
"Loaded wallet in {}s",
start_load_wallet.elapsed().as_secs_f32()
);

let address = wallet.reveal_next_address(KeychainKind::External).address;
let address = wallet
.next_unused_address(KeychainKind::External)
.unwrap()
.address;
println!("Wallet address: {address}");

let balance = wallet.balance();
Expand Down
81 changes: 43 additions & 38 deletions examples/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
// You may not use this file except in accordance with one or both of these
// licenses.

#![allow(unused)]
extern crate bdk_wallet;
extern crate bitcoin;
extern crate miniscript;
extern crate serde_json;
// extern crate bitcoin;
// extern crate miniscript;
// extern crate serde_json;

use std::error::Error;
use std::str::FromStr;
Expand All @@ -32,47 +32,52 @@ use bdk_wallet::{KeychainKind, Wallet};
/// This example demonstrates the interaction between a bdk wallet and miniscript policy.
#[allow(clippy::print_stdout)]
fn main() -> Result<(), Box<dyn Error>> {
// We start with a miniscript policy string
let policy_str = "or(
10@thresh(4,
pk(029ffbe722b147f3035c87cb1c60b9a5947dd49c774cc31e94773478711a929ac0),pk(025f05815e3a1a8a83bfbb03ce016c9a2ee31066b98f567f6227df1d76ec4bd143),pk(025625f41e4a065efc06d5019cbbd56fe8c07595af1231e7cbc03fafb87ebb71ec),pk(02a27c8b850a00f67da3499b60562673dcf5fdfb82b7e17652a7ac54416812aefd),pk(03e618ec5f384d6e19ca9ebdb8e2119e5bef978285076828ce054e55c4daf473e2)
),1@and(
older(4209713),
thresh(2,
pk(03deae92101c790b12653231439f27b8897264125ecb2f46f48278603102573165),pk(033841045a531e1adf9910a6ec279589a90b3b8a904ee64ffd692bd08a8996c1aa),pk(02aebf2d10b040eb936a6f02f44ee82f8b34f5c1ccb20ff3949c2b28206b7c1068)
)
)
)"
.replace(&[' ', '\n', '\t'][..], "");
// // We start with a miniscript policy string
// let policy_str = "or(
// 10@thresh(4,
// pk(029ffbe722b147f3035c87cb1c60b9a5947dd49c774cc31e94773478711a929ac0),
// pk(025f05815e3a1a8a83bfbb03ce016c9a2ee31066b98f567f6227df1d76ec4bd143),
// pk(025625f41e4a065efc06d5019cbbd56fe8c07595af1231e7cbc03fafb87ebb71ec),
// pk(02a27c8b850a00f67da3499b60562673dcf5fdfb82b7e17652a7ac54416812aefd),
// pk(03e618ec5f384d6e19ca9ebdb8e2119e5bef978285076828ce054e55c4daf473e2) ),1@and(
// older(4209713),
// thresh(2,
//
// pk(03deae92101c790b12653231439f27b8897264125ecb2f46f48278603102573165),
// pk(033841045a531e1adf9910a6ec279589a90b3b8a904ee64ffd692bd08a8996c1aa),
// pk(02aebf2d10b040eb936a6f02f44ee82f8b34f5c1ccb20ff3949c2b28206b7c1068) )
// )
// )"
// .replace(&[' ', '\n', '\t'][..], "");

println!("Compiling policy: \n{policy_str}");
// println!("Compiling policy: \n{policy_str}");

// Parse the string as a [`Concrete`] type miniscript policy.
let policy = Concrete::<String>::from_str(&policy_str)?;
// // Parse the string as a [`Concrete`] type miniscript policy.
// let policy = Concrete::<String>::from_str(&policy_str)?;

// Create a `wsh` type descriptor from the policy.
// `policy.compile()` returns the resulting miniscript from the policy.
let descriptor = Descriptor::new_wsh(policy.compile()?)?.to_string();
// // Create a `wsh` type descriptor from the policy.
// // `policy.compile()` returns the resulting miniscript from the policy.
// let descriptor = Descriptor::new_wsh(policy.compile()?)?.to_string();

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

// Create a new wallet from descriptors
let mut wallet = Wallet::create_single(descriptor)
.network(Network::Regtest)
.create_wallet_no_persist()?;
// // Create a new wallet from descriptors
// let mut wallet = Wallet::create_single(descriptor)
// .network(Network::Regtest)
// .create_wallet_no_persist()?;

println!(
"First derived address from the descriptor: \n{}",
wallet.next_unused_address(KeychainKind::External),
);
// println!(
// "First derived address from the descriptor: \n{}",
// wallet.next_unused_address(KeychainKind::External),
// );

// BDK also has it's own `Policy` structure to represent the spending condition in a more
// human readable json format.
let spending_policy = wallet.policies(KeychainKind::External)?;
println!(
"The BDK spending policy: \n{}",
serde_json::to_string_pretty(&spending_policy)?
);
// // BDK also has it's own `Policy` structure to represent the spending condition in a more
// // human readable json format.
// let spending_policy = wallet.policies(KeychainKind::External)?;
// println!(
// "The BDK spending policy: \n{}",
// serde_json::to_string_pretty(&spending_policy)?
// );

Ok(())
}
Loading