#钱包 #比特币钱包 #描述符 #psbt

no-std jitash-bdk

一个现代化的、轻量级的基于描述符的钱包库

2 个版本

0.28.1 2023 年 7 月 26 日
0.28.0 2023 年 7 月 14 日

#4#bitcoin-wallet


ord-lite 使用

MIT/Apache

1MB
21K SLoC

BDK

用 Rust 编写的现代化、轻量级基于描述符的钱包库!

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

项目主页 | 文档

关于

bdk 库旨在成为任何类型比特币钱包的核心构建模块。

  • 它使用 Miniscript 支持具有通用条件的描述符。这个库可以用来构建单签钱包、多重签名钱包、定时锁定合约等。
  • 它支持多个区块链后端和数据库,允许开发者选择最适合其项目的选项。
  • 它设计为跨平台:核心逻辑在桌面、移动设备甚至 WebAssembly 上都能工作。
  • 它非常容易扩展:开发者可以为区块链后端、数据库、签名者、选币等实现自定义逻辑,而无需分叉和修改此库。

示例

同步描述符的余额

use jitash_bdk::Wallet;
use jitash_bdk::database::MemoryDatabase;
use jitash_bdk::blockchain::ElectrumBlockchain;
use jitash_bdk::SyncOptions;
use jitash_bdk::electrum_client::Client;
use jitash_bdk::bitcoin::Network;

fn main() -> Result<(), jitash_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/*)"),
        Network::Testnet,
        MemoryDatabase::default(),
    )?;

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

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

    Ok(())
}

生成一些地址

use jitash_bdk::{Wallet, database::MemoryDatabase};
use jitash_bdk::wallet::AddressIndex::New;
use jitash_bdk::bitcoin::Network;

fn main() -> Result<(), jitash_bdk::Error> {
    let wallet = Wallet::new(
        "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
        Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
        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(())
}

创建一笔交易

use jitash_bdk::{FeeRate, Wallet, SyncOptions};
use jitash_bdk::database::MemoryDatabase;
use jitash_bdk::blockchain::ElectrumBlockchain;

use jitash_bdk::electrum_client::Client;
use jitash_bdk::wallet::AddressIndex::New;

use base64;
use jitash_bdk::bitcoin::consensus::serialize;
use jitash_bdk::bitcoin::Network;

fn main() -> Result<(), jitash_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/*)"),
        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(())
}

签名交易

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

use base64;
use jitash_bdk::bitcoin::consensus::deserialize;
use jitash_bdk::bitcoin::Network;

fn main() -> Result<(), jitash_bdk::Error> {
    let wallet = Wallet::new(
        "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
        Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
        Network::Testnet,
        MemoryDatabase::default(),
    )?;

    let psbt = "...";
    let mut psbt = deserialize(&base64::decode(psbt).unwrap())?;

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

    Ok(())
}

测试

单元测试

cargo test

集成测试

集成测试需要测试功能,例如

cargo test --features test-electrum

其他选项包括 test-esploratest-rpctest-rpc-legacy,它针对较旧版本的Bitcoin Core运行。注意,electrsbitcoind 二进制文件会自动下载(在mac和linux上),若要指定已安装的二进制文件,必须使用 --no-default-features 并将 BITCOIND_EXEELECTRS_EXE 作为环境变量提供。

在WASM下运行

如果您想在WASM下运行此库,您可能需要将以下行添加到您的 Cargo.toml

[dependencies]
getrandom = { version = "0.2", features = ["js"] }

这使 rand 包在JavaScript可用的环境中工作。有关更多信息,请参阅 此链接

许可证

根据您的选择,许可协议为以下之一

贡献

除非您明确声明,否则您根据Apache-2.0许可证定义的任何有意提交以包含在作品中的贡献,将按上述方式双许可,不附加任何额外条款或条件。

依赖项

~12–37MB
~529K SLoC