Alekos Filini 7201e09db9
Merge bitcoindevkit/bdk#599: Fix typo in docs for TxBuilder allow_shrinking method
4628a10191f451a7b0ade674e9f8568bf695e49c Fix typo in docs for TxBuilder allow_shrinking method (thunderbiscuit)

Pull request description:

  ### Description
  This PR fixes a small typo in the documentation for the `allow_shrinking()` method on the `TxBuilder`.

  ### Notes to the reviewers
  The sentence
  ```txt
  Explicitly tells the wallet that it is allowed to reduce the fee of the output matching this `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet will attempt to find a change output to shrink instead.
  ```
  was changed for
  ```txt
  Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet will attempt to find a change output to shrink instead.
  ```

  To reflect the fact that it's the _amount_ of the output that is being reduced in order to leave more for the fees.

  ### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

ACKs for top commit:
  notmandatory:
    ACK 4628a10191f451a7b0ade674e9f8568bf695e49c

Tree-SHA512: ca135764d78144295fdbdb4673ca6dec153c6f83ee7fb5d7d3051e0d46b04d23b2f3c3fd66e44491da842c778e72b52f8996d00e4c20986d7ccb11587f0d7d27
2022-05-06 10:27:00 +02:00
2022-05-04 17:29:07 +02:00
2022-05-04 17:29:07 +02:00
2021-09-30 11:24:01 -07:00
2020-11-16 12:09:14 +01:00
2022-04-20 10:31:31 -07:00
2022-05-04 17:29:07 +02:00
2022-05-04 17:29:07 +02:00

BDK

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

Crate Info MIT or Apache-2.0 Licensed CI Status API Docs Rustc Version 1.56+ 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 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

use bdk::Wallet;
use bdk::database::MemoryDatabase;
use bdk::blockchain::ElectrumBlockchain;
use bdk::SyncOptions;

use bdk::electrum_client::Client;

fn main() -> Result<(), bdk::Error> {
    let blockchain = ElectrumBlockchain::from(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(),
    )?;

    wallet.sync(&blockchain, SyncOptions::default())?;

    println!("Descriptor balance: {} SAT", wallet.get_balance()?);

    Ok(())
}

Generate a few addresses

use bdk::{Wallet, 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 bdk::wallet::AddressIndex::New;

use bitcoin::consensus::serialize;

fn main() -> Result<(), bdk::Error> {
    let blockchain = ElectrumBlockchain::from(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(),
    )?;

    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: {}", base64::encode(&serialize(&psbt)));

    Ok(())
}

Sign a transaction

use bdk::{Wallet, SignOptions, database::MemoryDatabase};

use bitcoin::consensus::deserialize;

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 = deserialize(&base64::decode(psbt).unwrap())?;

    let finalized = wallet.sign(&mut psbt, SignOptions::default())?;

    Ok(())
}

Testing

Unit testing

cargo test

Integration testing

Integration testing require testing features, for example:

cargo test --features test-electrum

The other options are test-esplora or test-rpc. Note that electrs and bitcoind binaries are automatically downloaded (on mac and linux), to specify you already have installed binaries you must use --no-default-features and provide BITCOIND_EXE and ELECTRS_EXE as environment variables.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Languages
Rust 99.9%