Expand description
A modern, lightweight, descriptor-based wallet library written in Rust.
About
The BDK library aims to be the core building block for Bitcoin wallets of any kind.
- It uses Miniscript to support descriptors with generalized conditions. This exact same library can be used to build single-sig wallets, multisigs, timelocked contracts and more.
- It supports multiple blockchain backends and databases, allowing developers to choose exactly what’s right for their projects.
- It is built to be cross-platform: the core logic works on desktop, mobile, and even WebAssembly.
- It is very easy to extend: developers can implement customized logic for blockchain backends, databases, signers, coin selection, and more, without having to fork and modify this library.
A Tour of BDK
BDK consists of a number of modules that provide a range of functionality essential for implementing descriptor based Bitcoin wallet applications in Rust. In this section, we will take a brief tour of BDK, summarizing the major APIs and their uses.
The easiest way to get started is to add bdk to your dependencies with the default features.
The default features include a simple key-value database (sled
) to cache
blockchain data and an electrum blockchain client to
interact with the bitcoin P2P network.
Examples
Sync the balance of a descriptor
use bdk::{Wallet, SyncOptions};
use bdk::database::MemoryDatabase;
use bdk::blockchain::ElectrumBlockchain;
use bdk::electrum_client::Client;
fn main() -> Result<(), bdk::Error> {
let client = Client::new("ssl://electrum.blockstream.info:60002")?;
let blockchain = ElectrumBlockchain::from(client);
let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
bitcoin::Network::Testnet,
MemoryDatabase::default(),
)?;
wallet.sync(&blockchain, SyncOptions::default())?;
println!("Descriptor balance: {} SAT", wallet.get_balance()?);
Ok(())
}
Generate a few addresses
Example
use bdk::{Wallet};
use bdk::database::MemoryDatabase;
use bdk::wallet::AddressIndex::New;
fn main() -> Result<(), bdk::Error> {
let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
bitcoin::Network::Testnet,
MemoryDatabase::default(),
)?;
println!("Address #0: {}", wallet.get_address(New)?);
println!("Address #1: {}", wallet.get_address(New)?);
println!("Address #2: {}", wallet.get_address(New)?);
Ok(())
}
Create a transaction
use bdk::{FeeRate, Wallet, SyncOptions};
use bdk::database::MemoryDatabase;
use bdk::blockchain::ElectrumBlockchain;
use bdk::electrum_client::Client;
use bitcoin::consensus::serialize;
use bdk::wallet::AddressIndex::New;
fn main() -> Result<(), bdk::Error> {
let client = Client::new("ssl://electrum.blockstream.info:60002")?;
let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
bitcoin::Network::Testnet,
MemoryDatabase::default(),
)?;
let blockchain = ElectrumBlockchain::from(client);
wallet.sync(&blockchain, SyncOptions::default())?;
let send_to = wallet.get_address(New)?;
let (psbt, details) = {
let mut builder = wallet.build_tx();
builder
.add_recipient(send_to.script_pubkey(), 50_000)
.enable_rbf()
.do_not_spend_change()
.fee_rate(FeeRate::from_sat_per_vb(5.0));
builder.finish()?
};
println!("Transaction details: {:#?}", details);
println!("Unsigned PSBT: {}", &psbt);
Ok(())
}
Sign a transaction
use std::str::FromStr;
use bitcoin::psbt::PartiallySignedTransaction as Psbt;
use bdk::{Wallet, SignOptions};
use bdk::database::MemoryDatabase;
fn main() -> Result<(), bdk::Error> {
let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
bitcoin::Network::Testnet,
MemoryDatabase::default(),
)?;
let psbt = "...";
let mut psbt = Psbt::from_str(psbt)?;
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
Ok(())
}
Feature flags
BDK uses a set of feature flags
to reduce the amount of compiled code by allowing projects to only enable the features they need.
By default, BDK enables two internal features, key-value-db
and electrum
.
If you are new to BDK we recommended that you use the default features which will enable
basic descriptor wallet functionality. More advanced users can disable the default
features
(--no-default-features
) and build the BDK library with only the features you need.
Below is a list of the available feature flags and the additional functionality they provide.
all-keys
: all features for working with bitcoin keysasync-interface
: async functions in bdk traitskeys-bip39
: BIP-39 mnemonic codes for generating deterministic keys
Internal features
These features do not expose any new API, but influence internal implementation aspects of BDK.
compact_filters
:compact_filters
client protocol for interacting with the bitcoin P2P networkelectrum
:electrum
client protocol for interacting with electrum serversesplora
:esplora
client protocol for interacting with blockstream electrs serverskey-value-db
: key valuedatabase
based onsled
for caching blockchain data
Re-exports
pub extern crate bitcoin;
pub extern crate bitcoincore_rpc;
pub extern crate electrum_client;
pub extern crate esplora_client;
pub extern crate hwi;
pub extern crate miniscript;
pub extern crate rusqlite;
pub extern crate sled;
pub use descriptor::template;
pub use descriptor::HdKeyPaths;
pub use wallet::signer;
pub use wallet::signer::SignOptions;
pub use wallet::tx_builder::TxBuilder;
pub use wallet::SyncOptions;
pub use wallet::Wallet;
Modules
- Blockchain backends
- Database types
- Descriptors
- Key formats
- Additional functions on the
rust-bitcoin
PartiallySignedTransaction
structure. - Wallet
Macros
- Macro to write full descriptors with code
- Macro to write descriptor fragments with code
Structs
- Balance differentiated in various categories
- Block height and timestamp of a block
- Fee rate
- An unspent output owned by a
Wallet
. - A wallet transaction
- A
Utxo
with itssatisfaction_weight
.
Enums
- Errors that can be thrown by the
Wallet
- Types of keychains
- An unspent transaction output (UTXO).
Traits
- Trait implemented by types that can be used to measure weight units.
Functions
- Get the version of BDK at runtime
Type Aliases
- ConfirmationTimeDeprecatedDEPRECATED: Confirmation time of a transaction