Crate bdk

Source
Expand description

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

§!! DEPRECATED !!

The bdk library is now deprecated and replaced by bdk_wallet. All projects should migrate to bdk_wallet 1.0.0 or newer as soon as possible. For migration instructions see the “Book of BDK” chapter on “Migrating from 0.x”.

The BDK team will continue to publish bdk 0.30.x bug fix releases as needed, but only for a limited time.

§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 keys
  • async-interface: async functions in bdk traits
  • keys-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 network
  • electrum: electrum client protocol for interacting with electrum servers
  • esplora: esplora client protocol for interacting with blockstream electrs servers
  • key-value-db: key value database based on sled 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
Blockchain backends
database
Database types
descriptor
Descriptors
keys
Key formats
psbt
Additional functions on the rust-bitcoin PartiallySignedTransaction structure.
wallet
Wallet

Macros§

descriptor
Macro to write full descriptors with code
fragment
Macro to write descriptor fragments with code

Structs§

Balance
Balance differentiated in various categories
BlockTime
Block height and timestamp of a block
FeeRate
Fee rate
LocalUtxo
An unspent output owned by a Wallet.
TransactionDetails
A wallet transaction
WeightedUtxo
A Utxo with its satisfaction_weight.

Enums§

Error
Errors that can be thrown by the Wallet
KeychainKind
Types of keychains
Utxo
An unspent transaction output (UTXO).

Traits§

Vbytes
Trait implemented by types that can be used to measure weight units.

Functions§

version
Get the version of BDK at runtime

Type Aliases§

ConfirmationTimeDeprecated
DEPRECATED: Confirmation time of a transaction