Code Monkey home page Code Monkey logo

bdk's Introduction

The Bitcoin Dev Kit

BDK

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

Crate Info MIT or Apache-2.0 Licensed CI Status Wallet API Docs Rustc Version 1.63.0+ Chat on Discord

About

The bdk libraries aims to provide well engineered and reviewed components for Bitcoin based applications. It is built upon the excellent rust-bitcoin and rust-miniscript crates.

⚠ The Bitcoin Dev Kit developers are in the process of releasing a v1.0 which is a fundamental re-write of how the library works. See for some background on this project: https://bitcoindevkit.org/blog/road-to-bdk-1/ (ignore the timeline 😁) For a release timeline see the BDK 1.0 project page.

Architecture

The project is split up into several crates in the /crates directory:

  • wallet: Contains the central high level Wallet type that is built from the low-level mechanisms provided by the other components
  • chain: Tools for storing and indexing chain data
  • persist: Types that define data persistence of a BDK wallet
  • file_store: A (experimental) persistence backend for storing chain data in a single file.
  • esplora: Extends the esplora-client crate with methods to fetch chain data from an esplora HTTP server in the form that bdk_chain and Wallet can consume.
  • electrum: Extends the electrum-client crate with methods to fetch chain data from an electrum server in the form that bdk_chain and Wallet can consume.

Fully working examples of how to use these components are in /example-crates:

  • example_cli: Library used by the example_* crates. Provides utilities for syncing, showing the balance, generating addresses and creating transactions without using the bdk_wallet Wallet.
  • example_electrum: A command line Bitcoin wallet application built on top of example_cli and the electrum crate. It shows the power of the bdk tools (chain + file_store + electrum), without depending on the main bdk_wallet library.
  • example_esplora: A command line Bitcoin wallet application built on top of example_cli and the esplora crate. It shows the power of the bdk tools (chain + file_store + esplora), without depending on the main bdk_wallet library.
  • example_bitcoind_rpc_polling: A command line Bitcoin wallet application built on top of example_cli and the bitcoind_rpc crate. It shows the power of the bdk tools (chain + file_store + bitcoind_rpc), without depending on the main bdk_wallet library.
  • wallet_esplora_blocking: Uses the Wallet to sync and spend using the Esplora blocking interface.
  • wallet_esplora_async: Uses the Wallet to sync and spend using the Esplora asynchronous interface.
  • wallet_electrum: Uses the Wallet to sync and spend using Electrum.

Minimum Supported Rust Version (MSRV)

This library should compile with any combination of features with Rust 1.63.0.

To build with the MSRV you will need to pin dependencies as follows:

# zip 0.6.3 has MSRV 1.64.0
cargo update -p zip --precise "0.6.2"
# time 0.3.21 has MSRV 1.65.0
cargo update -p time --precise "0.3.20"
# jobserver 0.1.27 has MSRV 1.66.0
cargo update -p jobserver --precise "0.1.26"
# home 0.5.9 has MSRV 1.70.0
cargo update -p home --precise "0.5.5"
# proptest 1.4.0 has MSRV 1.65.0
cargo update -p proptest --precise "1.2.0"

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.

bdk's People

Contributors

afilini avatar danielabrozzoni avatar darosior avatar davemo88 avatar eupn avatar evanlinjin avatar jumbojets avatar justinmoon avatar kafaichoi avatar laggintimes avatar llfourn avatar luckysori avatar mcroad avatar murchandamus avatar notmandatory avatar rajarshimaitra avatar rcasatta avatar rustaceanrob avatar stevenroose avatar storopoli avatar tcharding avatar thomaseizinger avatar thunderbiscuit avatar tnull avatar ulrichard avatar valuedmammal avatar vladimirfomene avatar w0xlt avatar wszdexdrf avatar yukibtc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bdk's Issues

PSBT workflow and traits

We are currently discussing in rust-bitcoin how to model the PSBT workflow in rust. Bdk seems to be the most advanced rust wallet implementation so far. Do you have any opinion on rust-bitcoin/rust-bitcoin#457 for example? From what I read in the bdk docs I figure that my wallet trait might be too simple and not capturing UTXO selection parameters very well (something I thought to be intrinsic to a certain wallet impl). Your Signer trait also seems more adapted to the real world as it differentiates between signing single inputs and whole transactions at once. Given your experience, do you think unifying the interface for PSBT handling is feasible (so that e.g. new HW wallet crates can be compatible with all PSBT aware rust software)?

Issues using descriptors with checksums

Starting with an empty ~/.magical-bitcoin, it crashes if we provide a descriptor containing a checksum:

$ magic --descriptor "pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)#gn28ywm7" policies
...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ChecksumMismatch', examples/repl.rs:71:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Furthermore, a checksum for the entire checksummed descriptor is stored in sled, which causes a conflict when we try to provide the same valid descriptor without a checksum.

$ magic --descriptor "pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)" policies
...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ChecksumMismatch', examples/repl.rs:71:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If we delete ~/.magical-bitcoin and re-run the last command it will work.

I believe this line should check to see if the descriptor already contains a valid checksum.

Test Compact Block Filters supported backend

Test all the backends with the #[bdk_blockchain_tests] proc macro like we do with electrum in the CI. This could be done while transitioning to GitHub Actions (see #59).

I would use nigiri to have an electrs/esplora local instance, then a btcd node for compact filters.

Currently the CI downloads and runs the full node but that's pretty slow, we could make docker containers with everything preinstalled for it.

A docker image for electrs was added here: 98803b2

Eclipse attack protection

Generally need to think about how to prevent eclipse attacks for light clients that sync block headers from peers. Some ideas of strategies that can be borrowed from Bitcoin Core:

  • general core heuristics: feeler connections, new/tried nodes tables, test-before-evict, etc.
  • using ASMAP table information (https://bitcoincore.reviews/16702.html)
  • reverse header lookup strategies and banning peers that give bad headers

Coin control & UTXO blacklisting

Two related privacy features I'd like to see implemented in the future:

  1. per-UTXO coin control during transaction construction
  2. blacklisting of individual UTXO(s) to combat dusting attacks

Integrate with LDK

BDK should be able to provide blockchain and key services for the Lightning Development Kit (LDK). The LDK traits that need to be implemented by BDK are:

  • lightning::chain::keysinterface::KeysInterface
  • lightning::chain::chaininterface::BroadcasterInterface
  • lightning::chain::chaininterface::FeeEstimator
  • lightning::chain::Filter
  • lightning::chain::Confirm
  • lightning::chain::Access
  • lightning::chain::Watch

Taproot / Schnorr

This is a tracking issue for other issues and PRs related to supporting Taproot in BDK.

Dependencies

Overall rust-bitcoin org tracking project

rust-bitcoin/rust-bitcoin

rust-bitcoin/rust-miniscript

Send to Single Signature TR Address

Create Single Signature TR Descriptor Wallet

Create Multi Signature TR Descriptor Wallet

Light client library to monitor mempool

Suggestion from @moneyball. Create a library that allows a light client to use the p2p network to monitor the mempool. today, the only way you can do this is with Core, which implies running a fully validating node. however, there is no reason you need to do IBD or validation in order to just monitor the mempool. why would a light client want to monitor the mempool?

  1. self sovereign improved fee estimation
  2. self sovereign watchtower (for LN or various other L2/custody protocols that have been proposed which require monitoring for certain txn and responding)
  3. perhaps certain analytical tools (would be awesome if devs could focus on the analytical tool and utilize BDK to deal with all the details vs. write from scratch)

Compact block filter Blockchain backend

This is an overview issue (based on same issue for murmel) for discussion and tracking the addition of a fully functional compact filters Blockchain backend to bdk. Ideally we'll have additional issues and/or PRs for each missing feature to link to this issue and we check off each feature as it's completed.

The below BIP-157/158 protocol features are based on the BIP-157 Client Operation section. Please suggest additions and corrections in the comments.

Missing protocol features for bdk are indicated below with an unchecked box [ ], completed features with a checked box [x].

Terminology

  • peer: bitcoin full node peer
  • block header: bitcoin standard block header
  • filter header: BIP-157 compact block filter header
  • block filter: BIP-157/158 compact block filter

Peer Discovery

    • Allow user to specify peer addresses
    • Receive peer addresses via [addr] messages from connected peers
    • Store new peer addresses
    • If no provided or previously stored peers, find seed peer addresses via DNS

Connect to Peers

    • Allow user to specify number of peers to connect to
    • Allow user to specify minimum number of BIP-157 peers to connect to
    • Connect to peers and request signalling bits via [version] message
    • Keep track of peers signalling service bit NODE_COMPACT_FILTERS
    • Connect to specified number of peers
    • Connect to minimum number of BIP-157 peers

Request Block Headers

    • Request block headers via [getheaders] message to connected peers
    • Request block headers from genesis to most work block, 1 to 2000 blocks per request
    • Optional: Request block headers from stored checkpoint block instead of genesis block

Receive Block Headers

    • Receive block headers [headers] from peers
    • Build chain of block headers from stored and received new block headers
    • Store new block headers and new block header tip
    • Disconnect peers whose longest chain has significantly less work than known tip
    • Request block filter headers from all peers for any new block header received

Request Filter Headers

    • Allow user to specify start block height for block filter sync
    • Request filter headers via [getcfheaders] message to peers
    • Request from start block height to end block hash (1-1000 per request)
    • Request filter headers for the same block from more than one peer
    • Optional: First request filter headers at intervals of 1000 via [getcfcheckpt] message

Receive Filter Headers

    • Receive filter headers [cfheaders] from peers
    • Verify filter headers from multiple peers are the same
    • If any received filter headers for a block are different,
      • request full block and compute correct block filter and filter header
      • ban peers that provided incorrect filter header
    • Build chain of filter headers from stored and received new filter headers
    • Store verified filter headers, at least to depth of 100
    • Request block filter for any new verified filter header
    • Optional: store more than 100 verified filter headers

Request Block Filters

    • Request block filters after all filter headers are received and verified
    • Request block filters from start block via [getcfilters] message to peers
    • Request from start block height to end block hash (1-1000 per request)
    • Optional: Check if filter header is for empty block filter if so skip request
    • Optional: Request different block filters in parallel from multiple peers

Receive Block Filters

    • Receive block filter [cfilter] from peers
    • Verify block filters sequentially, must link to corresponding filter header
    • Ban any peer that sends an invalid block filter
    • Check block filters for relevance
      • Previous output scripts for transaction inputs
      • ScriptPubKey for transaction outputs

Fetch Full Blocks

    • If fetching full blocks, download from random peers
    • Fetch full blocks from peers even if they don’t support compact block filters
    • Fetch full blocks that correspond to relevant block filters

Adding outputs to a wallet at runtime

In several of the more cutting edge Bitcoin protocols you end up in a situation where there is a 2-of-2(A,B) where Alice and Bob own the two keys respectively. Later on, one of the parties (let's say Alice) learns the secret key for B through the execution of the protocol. Now Alice owns the output but needs to store and recall the secret key for B and the details of the output.

I was thinking it would be nice for magical to manage this for me. What I think I want is to be able to add some kind of auxiliary descriptors to a wallet. The wallet could store it in its database and treat it like any of its other unspent outputs. Here are some considerations that come to mind:

  1. You would probably want a coin selection policy that spends these higher priority than outputs derived from your main descriptor (because they are lost if you lose database backup).
  2. When doing things like get_balance you're probably going to want to see how much of your balance is derived from the main descriptor and how much is from these transient descriptors. Likely you will want to "sweep" all of these in one go back to the main wallet descriptor.
  3. Sometimes these outputs have a pending tx that may spend from it in the future (e.g. revoked lightning commitment transactions) so the user needs to spend from it right away. Although it should be the application's job to make sure this happens, it would be cool if you could mark the auxiliary descriptor with a block height or time for which it must be spent before.

I was thinking about trying to implement something like this myself but wanted to check if you had an existing vision for this.

Error parsing multisig descriptor

Example:

use magical_bitcoin_wallet::descriptor::ExtendedDescriptor;
use std::str::FromStr;

fn main() {
    let desc_str = "wsh(multi(1,[9d033c9d/48'/1'/0'/2']tpubDEHKJA6XKc6QaRvc5gunJY9T9cst9m1y8o2owqrvUmXK69ZjWySB7hgB6HvFdTp5MamaKYumSGxL49VUiEjWrhDE8N8BympFWDknLBEPG38/0/*,[6bb3d403/48'/1'/0'/2']tpubDDw2d4rKFtn5ECCq4KQ6GTi73YUQt3Wz2gqyv19kLAPJQKKKzNvEESi9v44sG4Fc6DsBuDgo5FQ9ZxbzQfV2X7jRvsBcT7N5s6g57xS4aUM/0/*))";
    ExtendedDescriptor::from_str(&desc_str).unwrap();
}

Output:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Miniscript(Unexpected("multi(3 args) while parsing Miniscript"))', examples/magical.rs:6:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Here is where the error is being created in rust-miniscript. You can see a couple lines above that is where multi should be handled, but it seems there hasn't been a rust-miniscript release since it was added.

Test the descriptor module

  • Test the ToWalletDescriptor trait
    • From &str with and without checksum appended
    • From &str with keys from the right/wrong network
    • From the output of the descriptor!() macro

Moved to #193
- [ ] Test the ExtractPolicy trait
- [ ] Simple descriptors like wpkh(), sh(multi())
- [ ] Both with extended and single keys
- [ ] More complicated descriptor that contains timelocks too in a thresh()
- [ ] Mixed timelocks should fail
- [ ] Multiple timelocks of the same type should be correctly merged together

  • Test the get_checksum() function. It should return the same value as Bitcoin Core's getdescriptorinfo

  • Test the descriptor!() macro

    • Ideally at least one of each "type" of operator should be tested (i.e. one modifier, one "leaf_opcode", one "leaf_opcode_value", etc)
    • Test mixing up key types that implement ToDescriptorKey in multi() or thresh()
    • Test that the valid_networks returned is correctly computed based on the keys present in the descriptor
    • Test that the key_maps are correctly merged together
    • Test that the ScriptContext is correctly validated (i.e. passing a type that only impl ToDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
  • Test the existing descriptor templates, make sure they are expanded to the right descriptors

Mobile hardware security

  • Secure enclave key storage and signing
  • Hardware wallet / HWI
  • HSM runtime support like the nShield

This may need to be moved or companion issues created in bdk-jni (and future bdk-ios) repos

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.