BDK

A modern, lightweight, descriptor-based wallet library written in Rust!

CI Status API Docs Rustc Version 1.45+ Chat on Discord

Project Homepage | Documentation

## About The `bdk` library aims to be the core building block for Bitcoin wallets of any kind. * It uses [Miniscript](https://github.com/rust-bitcoin/rust-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's built to be cross-platform: the core logic works on desktop, mobile, and even WebAssembly. * It's 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. ## Examples ### Sync the balance of a descriptor ```rust,no_run use bdk::Wallet; use bdk::database::MemoryDatabase; use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::electrum_client::Client; fn main() -> Result<(), bdk::Error> { let client = Client::new("ssl://electrum.blockstream.info:60002", None)?; let wallet = Wallet::new( "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), bitcoin::Network::Testnet, MemoryDatabase::default(), ElectrumBlockchain::from(client) )?; wallet.sync(noop_progress(), None)?; println!("Descriptor balance: {} SAT", wallet.get_balance()?); Ok(()) } ``` ### Generate a few addresses ```rust use bdk::{Wallet, OfflineWallet}; use bdk::database::MemoryDatabase; fn main() -> Result<(), bdk::Error> { let wallet: OfflineWallet<_> = Wallet::new_offline( "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_new_address()?); println!("Address #1: {}", wallet.get_new_address()?); println!("Address #2: {}", wallet.get_new_address()?); Ok(()) } ``` ### Create a transaction ```rust,no_run use bdk::{FeeRate, TxBuilder, Wallet}; use bdk::database::MemoryDatabase; use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::electrum_client::Client; use bitcoin::consensus::serialize; fn main() -> Result<(), bdk::Error> { let client = Client::new("ssl://electrum.blockstream.info:60002", None)?; let wallet = Wallet::new( "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), bitcoin::Network::Testnet, MemoryDatabase::default(), ElectrumBlockchain::from(client) )?; wallet.sync(noop_progress(), None)?; let send_to = wallet.get_new_address()?; let (psbt, details) = wallet.create_tx( TxBuilder::with_recipients(vec![(send_to.script_pubkey(), 50_000)]) .enable_rbf() .do_not_spend_change() .fee_rate(FeeRate::from_sat_per_vb(5.0)) )?; println!("Transaction details: {:#?}", details); println!("Unsigned PSBT: {}", base64::encode(&serialize(&psbt))); Ok(()) } ``` ### Sign a transaction ```rust,no_run use bdk::{Wallet, OfflineWallet}; use bdk::database::MemoryDatabase; use bitcoin::consensus::deserialize; fn main() -> Result<(), bdk::Error> { let wallet: OfflineWallet<_> = Wallet::new_offline( "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)", Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"), bitcoin::Network::Testnet, MemoryDatabase::default(), )?; let psbt = "..."; let psbt = deserialize(&base64::decode(psbt).unwrap())?; let (signed_psbt, finalized) = wallet.sign(psbt, None)?; Ok(()) } ```