Merge commit 'refs/pull/365/head' of github.com:bitcoindevkit/bdk into release/0.8.0

This commit is contained in:
Alekos Filini 2021-06-09 16:05:16 +02:00
commit 9205295332
No known key found for this signature in database
GPG Key ID: 431401E4A4530061
6 changed files with 119 additions and 104 deletions

View File

@ -162,7 +162,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Set default toolchain - name: Set default toolchain
run: rustup default 1.51.0 # STABLE run: rustup default nightly
- name: Set profile - name: Set profile
run: rustup set profile minimal run: rustup set profile minimal
- name: Add rustfmt - name: Add rustfmt
@ -170,4 +170,4 @@ jobs:
- name: Update toolchain - name: Update toolchain
run: rustup update run: rustup update
- name: Check fmt - name: Check fmt
run: cargo fmt --all -- --check run: cargo fmt --all -- --config format_code_in_doc_comments=true --check

View File

@ -37,7 +37,7 @@ pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
/// ///
/// ``` /// ```
/// use bdk::descriptor::error::Error as DescriptorError; /// use bdk::descriptor::error::Error as DescriptorError;
/// use bdk::keys::{KeyError, IntoDescriptorKey}; /// use bdk::keys::{IntoDescriptorKey, KeyError};
/// use bdk::miniscript::Legacy; /// use bdk::miniscript::Legacy;
/// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut}; /// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
/// ///

View File

@ -192,7 +192,7 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ``` /// ```
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// ///
/// use bdk::keys::{DescriptorKey, KeyError, ScriptContext, IntoDescriptorKey}; /// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
/// pubkey: PublicKey, /// pubkey: PublicKey,
@ -211,8 +211,8 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// ///
/// use bdk::keys::{ /// use bdk::keys::{
/// mainnet_network, DescriptorKey, DescriptorPublicKey, DescriptorSinglePub, KeyError, /// mainnet_network, DescriptorKey, DescriptorPublicKey, DescriptorSinglePub,
/// ScriptContext, IntoDescriptorKey, /// IntoDescriptorKey, KeyError, ScriptContext,
/// }; /// };
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
@ -237,7 +237,7 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ``` /// ```
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// ///
/// use bdk::keys::{DescriptorKey, ExtScriptContext, KeyError, ScriptContext, IntoDescriptorKey}; /// use bdk::keys::{DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext};
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
/// is_legacy: bool, /// is_legacy: bool,
@ -266,7 +266,7 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// use std::str::FromStr; /// use std::str::FromStr;
/// ///
/// use bdk::keys::{DescriptorKey, KeyError, IntoDescriptorKey}; /// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
/// ///
/// pub struct MySegwitOnlyKeyType { /// pub struct MySegwitOnlyKeyType {
/// pubkey: PublicKey, /// pubkey: PublicKey,

View File

@ -14,9 +14,6 @@
// only enables the `doc_cfg` feature when // only enables the `doc_cfg` feature when
// the `docsrs` configuration attribute is defined // the `docsrs` configuration attribute is defined
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
// only enables the nightly `external_doc` feature when
// `test-md-docs` is enabled
#![cfg_attr(feature = "test-md-docs", feature(external_doc))]
//! A modern, lightweight, descriptor-based wallet library written in Rust. //! A modern, lightweight, descriptor-based wallet library written in Rust.
//! //!
@ -45,34 +42,37 @@
//! ```toml //! ```toml
//! bdk = "0.7.0" //! bdk = "0.7.0"
//! ``` //! ```
//! #![cfg_attr(
//! ## Sync the balance of a descriptor feature = "electrum",
//! doc = r##"
//! ### Example ## Sync the balance of a descriptor
//! ```ignore
//! use bdk::Wallet; ### Example
//! use bdk::database::MemoryDatabase; ```no_run
//! use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::Wallet;
//! use bdk::database::MemoryDatabase;
//! use bdk::electrum_client::Client; 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")?; fn main() -> Result<(), bdk::Error> {
//! let wallet = Wallet::new( let client = Client::new("ssl://electrum.blockstream.info:60002")?;
//! "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", let wallet = Wallet::new(
//! Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
//! bitcoin::Network::Testnet, Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
//! MemoryDatabase::default(), bitcoin::Network::Testnet,
//! ElectrumBlockchain::from(client) MemoryDatabase::default(),
//! )?; ElectrumBlockchain::from(client)
//! )?;
//! wallet.sync(noop_progress(), None)?;
//! wallet.sync(noop_progress(), None)?;
//! println!("Descriptor balance: {} SAT", wallet.get_balance()?);
//! println!("Descriptor balance: {} SAT", wallet.get_balance()?);
//! Ok(())
//! } Ok(())
//! ``` }
```
"##
)]
//! //!
//! ## Generate a few addresses //! ## Generate a few addresses
//! //!
@ -97,61 +97,65 @@
//! Ok(()) //! Ok(())
//! } //! }
//! ``` //! ```
//! #![cfg_attr(
//! ## Create a transaction feature = "electrum",
//! doc = r##"
//! ### Example ## Create a transaction
//! ```ignore
//! use base64::decode; ### Example
//! use bdk::{FeeRate, Wallet}; ```no_run
//! use bdk::database::MemoryDatabase; use base64::decode;
//! use bdk::blockchain::{noop_progress, ElectrumBlockchain};
//! use bdk::{FeeRate, Wallet};
//! use bdk::electrum_client::Client; use bdk::database::MemoryDatabase;
//! use bdk::blockchain::{noop_progress, ElectrumBlockchain};
//! use bitcoin::consensus::serialize; use bdk::electrum_client::Client;
//! use bdk::wallet::AddressIndex::New;
//! use bitcoin::consensus::serialize;
//! fn main() -> Result<(), bdk::Error> { use bdk::wallet::AddressIndex::New;
//! let client = Client::new("ssl://electrum.blockstream.info:60002")?;
//! let wallet = Wallet::new( fn main() -> Result<(), bdk::Error> {
//! "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", let client = Client::new("ssl://electrum.blockstream.info:60002")?;
//! Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), let wallet = Wallet::new(
//! bitcoin::Network::Testnet, "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
//! MemoryDatabase::default(), Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
//! ElectrumBlockchain::from(client) bitcoin::Network::Testnet,
//! )?; MemoryDatabase::default(),
//! ElectrumBlockchain::from(client)
//! wallet.sync(noop_progress(), None)?; )?;
//!
//! let send_to = wallet.get_address(New)?; wallet.sync(noop_progress(), None)?;
//! let (psbt, details) = {
//! let mut builder = wallet.build_tx(); let send_to = wallet.get_address(New)?;
//! builder let (psbt, details) = {
//! .add_recipient(send_to.script_pubkey(), 50_000) let mut builder = wallet.build_tx();
//! .enable_rbf() builder
//! .do_not_spend_change() .add_recipient(send_to.script_pubkey(), 50_000)
//! .fee_rate(FeeRate::from_sat_per_vb(5.0)) .enable_rbf()
//! builder.finish()? .do_not_spend_change()
//! }; .fee_rate(FeeRate::from_sat_per_vb(5.0));
//! builder.finish()?
//! println!("Transaction details: {:#?}", details); };
//! println!("Unsigned PSBT: {}", base64::encode(&serialize(&psbt)));
//! println!("Transaction details: {:#?}", details);
//! Ok(()) println!("Unsigned PSBT: {}", base64::encode(&serialize(&psbt)));
//! }
//! ``` Ok(())
}
```
"##
)]
//! //!
//! ## Sign a transaction //! ## Sign a transaction
//! //!
//! ### Example //! ### Example
//! ```ignore //! ```no_run
//! use base64::decode; //! use base64::decode;
//! use bdk::{Wallet};
//! use bdk::database::MemoryDatabase;
//!
//! use bitcoin::consensus::deserialize; //! use bitcoin::consensus::deserialize;
//! //!
//! use bdk::{Wallet, SignOptions};
//! use bdk::database::MemoryDatabase;
//!
//! fn main() -> Result<(), bdk::Error> { //! fn main() -> Result<(), bdk::Error> {
//! let wallet = Wallet::new_offline( //! let wallet = Wallet::new_offline(
//! "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)", //! "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
@ -163,7 +167,7 @@
//! let psbt = "..."; //! let psbt = "...";
//! let mut psbt = deserialize(&base64::decode(psbt).unwrap())?; //! let mut psbt = deserialize(&base64::decode(psbt).unwrap())?;
//! //!
//! let finalized = wallet.sign(&mut psbt, None)?; //! let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }

View File

@ -46,17 +46,25 @@
//! let mut selected_amount = 0; //! let mut selected_amount = 0;
//! let mut additional_weight = 0; //! let mut additional_weight = 0;
//! let all_utxos_selected = required_utxos //! let all_utxos_selected = required_utxos
//! .into_iter().chain(optional_utxos) //! .into_iter()
//! .scan((&mut selected_amount, &mut additional_weight), |(selected_amount, additional_weight), weighted_utxo| { //! .chain(optional_utxos)
//! **selected_amount += weighted_utxo.utxo.txout().value; //! .scan(
//! **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight; //! (&mut selected_amount, &mut additional_weight),
//! Some(weighted_utxo.utxo) //! |(selected_amount, additional_weight), weighted_utxo| {
//! }) //! **selected_amount += weighted_utxo.utxo.txout().value;
//! **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
//! Some(weighted_utxo.utxo)
//! },
//! )
//! .collect::<Vec<_>>(); //! .collect::<Vec<_>>();
//! let additional_fees = additional_weight as f32 * fee_rate.as_sat_vb() / 4.0; //! let additional_fees = additional_weight as f32 * fee_rate.as_sat_vb() / 4.0;
//! let amount_needed_with_fees = (fee_amount + additional_fees).ceil() as u64 + amount_needed; //! let amount_needed_with_fees =
//! if amount_needed_with_fees > selected_amount { //! (fee_amount + additional_fees).ceil() as u64 + amount_needed;
//! return Err(bdk::Error::InsufficientFunds{ needed: amount_needed_with_fees, available: selected_amount }); //! if amount_needed_with_fees > selected_amount {
//! return Err(bdk::Error::InsufficientFunds {
//! needed: amount_needed_with_fees,
//! available: selected_amount,
//! });
//! } //! }
//! //!
//! Ok(CoinSelectionResult { //! Ok(CoinSelectionResult {
@ -72,8 +80,7 @@
//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap(); //! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
//! let (psbt, details) = { //! let (psbt, details) = {
//! let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything); //! let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
//! builder //! builder.add_recipient(to_address.script_pubkey(), 50_000);
//! .add_recipient(to_address.script_pubkey(), 50_000);
//! builder.finish()? //! builder.finish()?
//! }; //! };
//! //!

View File

@ -87,9 +87,9 @@ impl TxBuilderContext for BumpFee {}
/// let (psbt1, details) = { /// let (psbt1, details) = {
/// let mut builder = wallet.build_tx(); /// let mut builder = wallet.build_tx();
/// builder /// builder
/// .ordering(TxOrdering::Untouched) /// .ordering(TxOrdering::Untouched)
/// .add_recipient(addr1.script_pubkey(), 50_000) /// .add_recipient(addr1.script_pubkey(), 50_000)
/// .add_recipient(addr2.script_pubkey(), 50_000); /// .add_recipient(addr2.script_pubkey(), 50_000);
/// builder.finish()? /// builder.finish()?
/// }; /// };
/// ///
@ -103,7 +103,10 @@ impl TxBuilderContext for BumpFee {}
/// builder.finish()? /// builder.finish()?
/// }; /// };
/// ///
/// assert_eq!(psbt1.global.unsigned_tx.output[..2], psbt2.global.unsigned_tx.output[..2]); /// assert_eq!(
/// psbt1.global.unsigned_tx.output[..2],
/// psbt2.global.unsigned_tx.output[..2]
/// );
/// # Ok::<(), bdk::Error>(()) /// # Ok::<(), bdk::Error>(())
/// ``` /// ```
/// ///
@ -246,7 +249,8 @@ impl<'a, B, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderConte
/// let mut path = BTreeMap::new(); /// let mut path = BTreeMap::new();
/// path.insert("aabbccdd".to_string(), vec![0, 1]); /// path.insert("aabbccdd".to_string(), vec![0, 1]);
/// ///
/// let builder = wallet.build_tx() /// let builder = wallet
/// .build_tx()
/// .add_recipient(to_address.script_pubkey(), 50_000) /// .add_recipient(to_address.script_pubkey(), 50_000)
/// .policy_path(path, KeychainKind::External); /// .policy_path(path, KeychainKind::External);
/// ///