2020-08-31 11:26:36 +02:00
// Magical Bitcoin Library
// Written in 2020 by
// Alekos Filini <alekos.filini@gmail.com>
//
// Copyright (c) 2020 Magical Bitcoin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
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-09-07 11:16:41 +02:00
// only enables the nightly `external_doc` feature when
// `test-md-docs` is enabled
#![ cfg_attr(feature = " test-md-docs " , feature(external_doc)) ]
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.
//! The default features include a simple key-value database ([`sled`](crate::sled)) to cache
//! blockchain data and an [electrum](https://docs.rs/electrum-client/) blockchain client to
//! interact with the bitcoin P2P network.
//!
//! ```toml
//! bdk = "0.2.0"
//! ```
//!
//! ## Sync the balance of a descriptor
//!
//! ### Example
//! ```ignore
//! 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(())
//! }
//! ```
//!
//! ## Generate a few addresses
//!
//! ### Example
//! ```
//! 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
//!
//! ### Example
//! ```ignore
//! use base64::decode;
//! 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")?;
//! 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
//!
//! ### Example
//! ```ignore
//! use base64::decode;
//! 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(())
//! }
//! ```
//!
//! # 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
//! * `cli-utils`: utilities for creating a command line interface wallet
//! * `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 ;
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
#[ macro_use ]
extern crate lazy_static ;
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 = " esplora " ) ]
pub extern crate reqwest ;
#[ 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
2020-05-08 23:30:45 +02:00
#[ cfg(feature = " cli-utils " ) ]
pub mod cli ;
2020-10-28 15:34:46 -07:00
#[ allow(unused_imports) ]
2020-08-10 10:49:34 +02:00
#[ cfg(test) ]
#[ macro_use ]
extern crate testutils ;
2020-10-28 15:34:46 -07:00
#[ allow(unused_imports) ]
2020-08-10 10:49:34 +02:00
#[ cfg(test) ]
#[ macro_use ]
extern crate testutils_macros ;
2020-10-28 15:34:46 -07:00
#[ allow(unused_imports) ]
2020-08-10 10:49:34 +02:00
#[ cfg(test) ]
#[ macro_use ]
extern crate serial_test ;
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 ;
2020-12-07 18:23:14 -08:00
#[ allow(missing_docs) ] // TODO add missing docs and remove this allow
2020-08-31 10:49:44 +02:00
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 ;
2020-09-04 11:44:49 +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 ;
2020-08-07 11:23:01 +02:00
pub use wallet ::tx_builder ::TxBuilder ;
pub use wallet ::{ OfflineWallet , Wallet } ;