2021-03-03 13:22:05 -08:00
// Bitcoin Dev Kit
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
2020-08-31 11:26:36 +02:00
//
2021-03-03 13:22:05 -08:00
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
2020-08-31 11:26:36 +02:00
//
2021-03-03 13:22:05 -08:00
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <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.
2020-08-31 11:26:36 +02:00
2020-12-07 18:23:14 -08:00
// rustdoc will warn if there are missing docs
#![ warn(missing_docs) ]
2020-08-31 11:26:36 +02:00
// only enables the `doc_cfg` feature when
// the `docsrs` configuration attribute is defined
2020-08-31 10:49:44 +02:00
#![ cfg_attr(docsrs, feature(doc_cfg)) ]
2020-08-31 11:26:36 +02:00
2020-12-07 18:23:14 -08:00
//! 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](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 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.
2020-12-16 12:10:40 +01:00
//! The default features include a simple key-value database ([`sled`](sled)) to cache
2020-12-07 18:23:14 -08:00
//! blockchain data and an [electrum](https://docs.rs/electrum-client/) blockchain client to
//! interact with the bitcoin P2P network.
//!
//! ```toml
2021-09-04 10:45:18 -07:00
//! bdk = "0.11.0"
2020-12-07 18:23:14 -08:00
//! ```
2021-05-11 11:10:54 +10:00
#![ cfg_attr(
feature = " electrum " ,
doc = r ##"
## Sync the balance of a descriptor
### Example
` ` ` 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 " ) ? ;
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 ( ( ) )
}
` ` `
" ##
) ]
2020-12-07 18:23:14 -08:00
//!
//! ## Generate a few addresses
//!
//! ### Example
//! ```
2020-12-23 13:48:17 +11:00
//! use bdk::{Wallet};
2020-12-07 18:23:14 -08:00
//! use bdk::database::MemoryDatabase;
2021-03-08 16:17:10 -08:00
//! use bdk::wallet::AddressIndex::New;
2020-12-07 18:23:14 -08:00
//!
//! fn main() -> Result<(), bdk::Error> {
2021-03-08 16:17:10 -08:00
//! let wallet = Wallet::new_offline(
2020-12-07 18:23:14 -08:00
//! "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
//! Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
//! bitcoin::Network::Testnet,
//! MemoryDatabase::default(),
//! )?;
//!
2021-03-08 16:17:10 -08:00
//! println!("Address #0: {}", wallet.get_address(New)?);
//! println!("Address #1: {}", wallet.get_address(New)?);
//! println!("Address #2: {}", wallet.get_address(New)?);
2020-12-07 18:23:14 -08:00
//!
//! Ok(())
//! }
//! ```
2021-05-11 11:10:54 +10:00
#![ cfg_attr(
feature = " electrum " ,
doc = r ##"
## Create a transaction
### Example
` ` ` no_run
use bdk ::{ FeeRate , Wallet } ;
use bdk ::database ::MemoryDatabase ;
use bdk ::blockchain ::{ noop_progress , 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 ( ) ,
ElectrumBlockchain ::from ( client )
) ? ;
wallet . sync ( noop_progress ( ) , None ) ? ;
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 ) ;
2021-06-10 15:14:00 +02:00
println! ( " Unsigned PSBT: {} " , & psbt ) ;
2021-05-11 11:10:54 +10:00
Ok ( ( ) )
}
` ` `
" ##
) ]
2020-12-07 18:23:14 -08:00
//!
//! ## Sign a transaction
//!
//! ### Example
2021-05-11 11:10:54 +10:00
//! ```no_run
2021-06-10 15:14:00 +02:00
//! use std::str::FromStr;
//!
//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
2020-12-07 18:23:14 -08:00
//!
2021-05-11 11:10:54 +10:00
//! use bdk::{Wallet, SignOptions};
//! use bdk::database::MemoryDatabase;
//!
2020-12-07 18:23:14 -08:00
//! fn main() -> Result<(), bdk::Error> {
2020-12-23 13:48:17 +11:00
//! let wallet = Wallet::new_offline(
2020-12-07 18:23:14 -08:00
//! "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
//! Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
//! bitcoin::Network::Testnet,
//! MemoryDatabase::default(),
//! )?;
//!
//! let psbt = "...";
2021-06-10 15:14:00 +02:00
//! let mut psbt = Psbt::from_str(psbt)?;
2020-12-07 18:23:14 -08:00
//!
2021-05-11 11:10:54 +10:00
//! let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
2020-12-07 18:23:14 -08:00
//!
//! Ok(())
//! }
//! ```
//!
//! # Feature flags
//!
//! BDK uses a set of [feature flags](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section)
//! 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](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) 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`](crate::blockchain::compact_filters) client protocol for interacting with the bitcoin P2P network
//! * `electrum`: [`electrum`](crate::blockchain::electrum) client protocol for interacting with electrum servers
//! * `esplora`: [`esplora`](crate::blockchain::esplora) client protocol for interacting with blockstream [electrs](https://github.com/Blockstream/electrs) servers
//! * `key-value-db`: key value [`database`](crate::database) based on [`sled`](crate::sled) for caching blockchain data
2020-01-27 22:02:55 +01:00
pub extern crate bitcoin ;
extern crate log ;
pub extern crate miniscript ;
extern crate serde ;
2020-02-05 11:59:02 +01:00
#[ macro_use ]
2020-01-27 22:02:55 +01:00
extern crate serde_json ;
2021-06-01 16:36:09 +10:00
#[ cfg(all(feature = " reqwest " , feature = " ureq " )) ]
compile_error! ( " Features reqwest and ureq are mutually exclusive and cannot be enabled together " ) ;
2021-02-03 17:29:24 +11:00
#[ cfg(all(feature = " async-interface " , feature = " electrum " )) ]
compile_error! (
" Features async-interface and electrum are mutually exclusive and cannot be enabled together "
) ;
2021-06-01 16:36:09 +10:00
#[ cfg(all(feature = " async-interface " , feature = " ureq " )) ]
compile_error! (
" Features async-interface and ureq are mutually exclusive and cannot be enabled together "
) ;
#[ cfg(all(feature = " async-interface " , feature = " compact_filters " )) ]
compile_error! (
" Features async-interface and compact_filters are mutually exclusive and cannot be enabled together "
) ;
2020-10-13 10:57:40 +02:00
#[ cfg(feature = " keys-bip39 " ) ]
extern crate bip39 ;
2020-08-10 11:41:19 +02:00
#[ cfg(any(target_arch = " wasm32 " , feature = " async-interface " )) ]
2020-07-20 15:51:57 +02:00
#[ macro_use ]
extern crate async_trait ;
#[ macro_use ]
2020-09-14 14:25:38 +02:00
extern crate bdk_macros ;
2020-07-20 15:51:57 +02:00
2020-10-07 14:18:50 -07:00
#[ cfg(feature = " compact_filters " ) ]
2020-02-06 12:17:28 +01:00
extern crate lazy_static ;
2021-05-17 17:20:32 +02:00
#[ cfg(feature = " rpc " ) ]
2021-08-17 17:52:07 +02:00
pub extern crate core_rpc ;
2021-05-17 17:20:32 +02:00
2020-05-07 15:14:05 +02:00
#[ cfg(feature = " electrum " ) ]
2020-02-07 23:22:28 +01:00
pub extern crate electrum_client ;
2020-05-07 15:14:05 +02:00
#[ cfg(feature = " key-value-db " ) ]
2020-02-07 23:22:28 +01:00
pub extern crate sled ;
2020-02-05 11:59:02 +01:00
2021-06-17 16:03:33 +02:00
#[ allow(unused_imports) ]
2020-02-04 11:05:54 +01:00
#[ macro_use ]
2020-09-04 11:44:49 +02:00
pub ( crate ) mod error ;
2020-05-03 16:15:11 +02:00
pub mod blockchain ;
2020-02-05 11:59:02 +01:00
pub mod database ;
2020-02-04 11:05:54 +01:00
pub mod descriptor ;
2020-09-07 11:16:41 +02:00
#[ cfg(feature = " test-md-docs " ) ]
mod doctest ;
2020-09-18 16:31:03 +02:00
pub mod keys ;
2020-08-31 10:49:44 +02:00
pub ( crate ) mod psbt ;
pub ( crate ) mod types ;
2020-02-07 23:22:28 +01:00
pub mod wallet ;
2020-09-22 16:12:09 +02:00
pub use descriptor ::template ;
2021-03-30 16:33:07 +02:00
pub use descriptor ::HdKeyPaths ;
2020-08-31 10:49:44 +02:00
pub use error ::Error ;
pub use types ::* ;
pub use wallet ::address_validator ;
pub use wallet ::signer ;
2021-04-19 14:16:39 +02:00
pub use wallet ::signer ::SignOptions ;
2020-08-07 11:23:01 +02:00
pub use wallet ::tx_builder ::TxBuilder ;
2020-12-23 13:48:17 +11:00
pub use wallet ::Wallet ;
2021-01-25 15:13:45 -05:00
/// Get the version of BDK at runtime
pub fn version ( ) -> & 'static str {
env! ( " CARGO_PKG_VERSION " , " unknown " )
}
2021-05-19 13:04:32 +10:00
2021-05-19 16:09:01 +10:00
// We should consider putting this under a feature flag but we need the macro in doctets so we need
// to wait until https://github.com/rust-lang/rust/issues/67295 is fixed.
//
// Stuff in here is too rough to document atm
#[ doc(hidden) ]
2021-05-19 13:04:32 +10:00
pub mod testutils ;