]> Untitled Git - bdk/commitdiff
Make doctests work
authorLLFourn <lloyd.fourn@gmail.com>
Tue, 21 Feb 2023 01:38:16 +0000 (12:38 +1100)
committerDaniela Brozzoni <danielabrozzoni@protonmail.com>
Thu, 2 Mar 2023 09:55:14 +0000 (10:55 +0100)
18 files changed:
README.md
examples/compiler.rs
examples/electrum_backend.rs [deleted file]
examples/esplora.rs [deleted file]
examples/esplora_backend_asynchronous.rs [deleted file]
examples/esplora_backend_synchronous.rs [deleted file]
examples/hardware_signer.rs
examples/psbt_signer.rs [deleted file]
examples/utils/mod.rs
src/descriptor/dsl.rs
src/descriptor/template.rs
src/lib.rs
src/wallet/coin_selection.rs
src/wallet/export.rs
src/wallet/hardwaresigner.rs
src/wallet/mod.rs
src/wallet/signer.rs
src/wallet/tx_builder.rs

index 0f15de96e865207e36d5634298a10b008a491e36..95ce43153fb6e819a302fa2c174701879af4f181 100644 (file)
--- a/README.md
+++ b/README.md
@@ -40,7 +40,6 @@ The `bdk` library aims to be the core building block for Bitcoin wallets of any
 
 ```rust,no_run
 use bdk::Wallet;
-use bdk::database::MemoryDatabase;
 use bdk::blockchain::ElectrumBlockchain;
 use bdk::SyncOptions;
 use bdk::electrum_client::Client;
@@ -52,7 +51,6 @@ fn main() -> Result<(), bdk::Error> {
         "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
         Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
         Network::Testnet,
-        MemoryDatabase::default(),
     )?;
 
     wallet.sync(&blockchain, SyncOptions::default())?;
@@ -66,16 +64,15 @@ fn main() -> Result<(), bdk::Error> {
 ### Generate a few addresses
 
 ```rust
-use bdk::{Wallet, database::MemoryDatabase};
+use bdk::Wallet;
 use bdk::wallet::AddressIndex::New;
 use bdk::bitcoin::Network;
 
 fn main() -> Result<(), bdk::Error> {
-    let wallet = Wallet::new(
+    let wallet = Wallet::new_no_persist(
         "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));
@@ -90,7 +87,6 @@ fn main() -> Result<(), bdk::Error> {
 
 ```rust,no_run
 use bdk::{FeeRate, Wallet, SyncOptions};
-use bdk::database::MemoryDatabase;
 use bdk::blockchain::ElectrumBlockchain;
 
 use bdk::electrum_client::Client;
@@ -102,11 +98,10 @@ use bdk::bitcoin::Network;
 
 fn main() -> Result<(), bdk::Error> {
     let blockchain = ElectrumBlockchain::from(Client::new("ssl://electrum.blockstream.info:60002")?);
-    let wallet = Wallet::new(
+    let wallet = Wallet::new_no_persist(
         "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
         Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
         Network::Testnet,
-        MemoryDatabase::default(),
     )?;
 
     wallet.sync(&blockchain, SyncOptions::default())?;
@@ -132,18 +127,17 @@ fn main() -> Result<(), bdk::Error> {
 ### Sign a transaction
 
 ```rust,no_run
-use bdk::{Wallet, SignOptions, database::MemoryDatabase};
+use bdk::{Wallet, SignOptions};
 
 use base64;
 use bdk::bitcoin::consensus::deserialize;
 use bdk::bitcoin::Network;
 
 fn main() -> Result<(), bdk::Error> {
-    let wallet = Wallet::new(
+    let wallet = Wallet::new_no_persist(
         "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
         Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
         Network::Testnet,
-        MemoryDatabase::default(),
     )?;
 
     let psbt = "...";
index 98f433941c10ef30c9bc7c01956b16e6e6e6ea95..f8918895cee2dc170586d31cbda28dbe446244e4 100644 (file)
@@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn Error>> {
     info!("Compiled into following Descriptor: \n{}", descriptor);
 
     // Create a new wallet from this descriptor
-    let wallet = Wallet::new(&format!("{}", descriptor), None, Network::Regtest)?;
+    let mut wallet = Wallet::new_no_persist(&format!("{}", descriptor), None, Network::Regtest)?;
 
     info!(
         "First derived address from the descriptor: \n{}",
diff --git a/examples/electrum_backend.rs b/examples/electrum_backend.rs
deleted file mode 100644 (file)
index 5259865..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-use std::str::FromStr;
-
-use bdk::bitcoin::util::bip32::ExtendedPrivKey;
-use bdk::bitcoin::Network;
-use bdk::blockchain::{Blockchain, ElectrumBlockchain};
-use bdk::database::MemoryDatabase;
-use bdk::template::Bip84;
-use bdk::wallet::export::FullyNodedExport;
-use bdk::{KeychainKind, SyncOptions, Wallet};
-
-use bdk::electrum_client::Client;
-use bdk::wallet::AddressIndex;
-use bitcoin::util::bip32;
-
-pub mod utils;
-
-use crate::utils::tx::build_signed_tx;
-
-/// This will create a wallet from an xpriv and get the balance by connecting to an Electrum server.
-/// If enough amount is available, this will send a transaction to an address.
-/// Otherwise, this will display a wallet address to receive funds.
-///
-/// This can be run with `cargo run --example electrum_backend` in the root folder.
-fn main() {
-    let network = Network::Testnet;
-
-    let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
-
-    let electrum_url = "ssl://electrum.blockstream.info:60002";
-
-    run(&network, electrum_url, xpriv);
-}
-
-fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
-    Wallet::new(
-        Bip84(*xpriv, KeychainKind::External),
-        Some(Bip84(*xpriv, KeychainKind::Internal)),
-        *network,
-        MemoryDatabase::default(),
-    )
-    .unwrap()
-}
-
-fn run(network: &Network, electrum_url: &str, xpriv: &str) {
-    let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
-
-    // Apparently it works only with Electrs (not EletrumX)
-    let blockchain = ElectrumBlockchain::from(Client::new(electrum_url).unwrap());
-
-    let wallet = create_wallet(network, &xpriv);
-
-    wallet.sync(&blockchain, SyncOptions::default()).unwrap();
-
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    println!("address: {}", address);
-
-    let balance = wallet.get_balance().unwrap();
-
-    println!("Available coins in BDK wallet : {} sats", balance);
-
-    if balance.confirmed > 6500 {
-        // the wallet sends the amount to itself.
-        let recipient_address = wallet
-            .get_address(AddressIndex::New)
-            .unwrap()
-            .address
-            .to_string();
-
-        let amount = 5359;
-
-        let tx = build_signed_tx(&wallet, &recipient_address, amount);
-
-        blockchain.broadcast(&tx).unwrap();
-
-        println!("tx id: {}", tx.txid());
-    } else {
-        println!("Insufficient Funds. Fund the wallet with the address above");
-    }
-
-    let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
-        .map_err(ToString::to_string)
-        .map_err(bdk::Error::Generic)
-        .unwrap();
-
-    println!("------\nWallet Backup: {}", export.to_string());
-}
diff --git a/examples/esplora.rs b/examples/esplora.rs
deleted file mode 100644 (file)
index 1659666..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-use bdk::{
-    blockchain::esplora::{esplora_client, BlockingClientExt},
-    wallet::AddressIndex,
-    Wallet,
-};
-use bdk_test_client::{RpcApi, TestClient};
-use bitcoin::{Amount, Network};
-use rand::Rng;
-use std::error::Error;
-
-fn main() -> Result<(), Box<dyn Error>> {
-    let _ = env_logger::init();
-    const DESCRIPTOR: &'static str ="tr([73c5da0a/86'/0'/0']tprv8cSrHfiTQQWzKVejDHvBcvW4pdLEDLMvtVdbUXFfceQ4kbZKMsuFWbd3LUN3omNrQfafQaPwXUFXtcofkE9UjFZ3i9deezBHQTGvYV2xUzz/0/*)";
-    const CHANGE_DESCRIPTOR: &'static str = "tr(tprv8ZgxMBicQKsPeQe98SGJ53vEJ7MNEFkQ4CkZmrr6PNom3vn6GqxuyoE78smkzpuP347zR9MXPg38PoZ8tbxLqSx4CufufHAGbQ9Hf7yTTwn/44'/0'/0'/1/*)#pxy2d75a";
-
-    let mut test_client = TestClient::default();
-    let esplora_url = format!(
-        "http://{}",
-        test_client.electrsd.esplora_url.as_ref().unwrap()
-    );
-    let client = esplora_client::Builder::new(&esplora_url).build_blocking()?;
-
-    let wallet = Wallet::new(DESCRIPTOR, Some(CHANGE_DESCRIPTOR), Network::Regtest)
-        .expect("parsing descriptors failed");
-    // note we don't *need* the Mutex for this example but it helps to show when the wallet does and
-    // doesn't need to be mutablek
-    let wallet = std::sync::Mutex::new(wallet);
-    let n_initial_transactions = 10;
-
-    let addresses = {
-        // we need it to be mutable to get a new address.
-        // This incremenents the derivatoin index of the keychain.
-        let mut wallet = wallet.lock().unwrap();
-        core::iter::repeat_with(|| wallet.get_address(AddressIndex::New))
-            .filter(|_| rand::thread_rng().gen_bool(0.5))
-            .take(n_initial_transactions)
-            .collect::<Vec<_>>()
-    };
-
-    // get some coins for the internal node
-    test_client.generate(100, None);
-
-    for address in addresses {
-        let exp_txid = test_client
-            .send_to_address(
-                &address,
-                Amount::from_sat(10_000),
-                None,
-                None,
-                None,
-                None,
-                None,
-                None,
-            )
-            .expect("tx should send");
-        eprintln!(
-            "💸 sending some coins to: {} (index {}) in tx {}",
-            address, address.index, exp_txid
-        );
-        // sometimes generate a block after we send coins to the address
-        if rand::thread_rng().gen_bool(0.3) {
-            let height = test_client.generate(1, None);
-            eprintln!("📦 created a block at height {}", height);
-        }
-    }
-
-    let wait_for_esplora_sync = std::time::Duration::from_secs(5);
-
-    println!("⏳ waiting {}s for esplora to catch up..", wait_for_esplora_sync.as_secs());
-    std::thread::sleep(wait_for_esplora_sync);
-
-
-    let wallet_scan_input = {
-        let wallet = wallet.lock().unwrap();
-        wallet.start_wallet_scan()
-    };
-
-    let start = std::time::Instant::now();
-    let stop_gap = 5;
-    eprintln!(
-        "🔎 startig scanning all keychains with stop gap of {}",
-        stop_gap
-    );
-    let wallet_scan = client.wallet_scan(wallet_scan_input, stop_gap, &Default::default(), 5)?;
-
-    // we've got an update so briefly take a lock the wallet to apply it
-    {
-        let mut wallet = wallet.lock().unwrap();
-        match wallet.apply_wallet_scan(wallet_scan) {
-            Ok(changes) => {
-                eprintln!("🎉 success! ({}ms)", start.elapsed().as_millis());
-                eprintln!("wallet balance after: {:?}", wallet.get_balance());
-                //XXX: esplora is not indexing mempool transactions right now (or not doing it fast enough)
-                eprintln!(
-                    "wallet found {} new transactions",
-                    changes.tx_additions().count(),
-                );
-                if changes.tx_additions().count() != n_initial_transactions {
-                    eprintln!(
-                        "(it should have found {} but maybe stop gap wasn't large enough?)",
-                        n_initial_transactions
-                    );
-                }
-            }
-            Err(reason) => {
-                eprintln!("❌ esplora produced invalid wallet scan {}", reason);
-            }
-        }
-    }
-
-    Ok(())
-}
diff --git a/examples/esplora_backend_asynchronous.rs b/examples/esplora_backend_asynchronous.rs
deleted file mode 100644 (file)
index 4aa149b..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-use std::str::FromStr;
-
-use bdk::blockchain::Blockchain;
-use bdk::{
-    blockchain::esplora::EsploraBlockchain,
-    database::MemoryDatabase,
-    template::Bip84,
-    wallet::{export::FullyNodedExport, AddressIndex},
-    KeychainKind, SyncOptions, Wallet,
-};
-use bitcoin::{
-    util::bip32::{self, ExtendedPrivKey},
-    Network,
-};
-
-pub mod utils;
-
-use crate::utils::tx::build_signed_tx;
-
-/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server,
-/// using non blocking asynchronous calls with `reqwest`.
-/// If enough amount is available, this will send a transaction to an address.
-/// Otherwise, this will display a wallet address to receive funds.
-///
-/// This can be run with `cargo run --no-default-features --features="use-esplora-reqwest, reqwest-default-tls, async-interface" --example esplora_backend_asynchronous`
-/// in the root folder.
-#[tokio::main(flavor = "current_thread")]
-async fn main() {
-    let network = Network::Signet;
-
-    let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
-
-    let esplora_url = "https://explorer.bc-2.jp/api";
-
-    run(&network, esplora_url, xpriv).await;
-}
-
-fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
-    Wallet::new(
-        Bip84(*xpriv, KeychainKind::External),
-        Some(Bip84(*xpriv, KeychainKind::Internal)),
-        *network,
-        MemoryDatabase::default(),
-    )
-    .unwrap()
-}
-
-async fn run(network: &Network, esplora_url: &str, xpriv: &str) {
-    let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
-
-    let blockchain = EsploraBlockchain::new(esplora_url, 20);
-
-    let wallet = create_wallet(network, &xpriv);
-
-    wallet
-        .sync(&blockchain, SyncOptions::default())
-        .await
-        .unwrap();
-
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    println!("address: {}", address);
-
-    let balance = wallet.get_balance().unwrap();
-
-    println!("Available coins in BDK wallet : {} sats", balance);
-
-    if balance.confirmed > 10500 {
-        // the wallet sends the amount to itself.
-        let recipient_address = wallet
-            .get_address(AddressIndex::New)
-            .unwrap()
-            .address
-            .to_string();
-
-        let amount = 9359;
-
-        let tx = build_signed_tx(&wallet, &recipient_address, amount);
-
-        let _ = blockchain.broadcast(&tx);
-
-        println!("tx id: {}", tx.txid());
-    } else {
-        println!("Insufficient Funds. Fund the wallet with the address above");
-    }
-
-    let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
-        .map_err(ToString::to_string)
-        .map_err(bdk::Error::Generic)
-        .unwrap();
-
-    println!("------\nWallet Backup: {}", export.to_string());
-}
diff --git a/examples/esplora_backend_synchronous.rs b/examples/esplora_backend_synchronous.rs
deleted file mode 100644 (file)
index 31907f8..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-use std::str::FromStr;
-
-use bdk::blockchain::Blockchain;
-use bdk::{
-    blockchain::esplora::EsploraBlockchain,
-    database::MemoryDatabase,
-    template::Bip84,
-    wallet::{export::FullyNodedExport, AddressIndex},
-    KeychainKind, SyncOptions, Wallet,
-};
-use bitcoin::{
-    util::bip32::{self, ExtendedPrivKey},
-    Network,
-};
-
-pub mod utils;
-
-use crate::utils::tx::build_signed_tx;
-
-/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server,
-/// using blocking calls with `ureq`.
-/// If enough amount is available, this will send a transaction to an address.
-/// Otherwise, this will display a wallet address to receive funds.
-///
-/// This can be run with `cargo run --features=use-esplora-ureq --example esplora_backend_synchronous`
-/// in the root folder.
-fn main() {
-    let network = Network::Signet;
-
-    let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
-
-    let esplora_url = "https://explorer.bc-2.jp/api";
-
-    run(&network, esplora_url, xpriv);
-}
-
-fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
-    Wallet::new(
-        Bip84(*xpriv, KeychainKind::External),
-        Some(Bip84(*xpriv, KeychainKind::Internal)),
-        *network,
-        MemoryDatabase::default(),
-    )
-    .unwrap()
-}
-
-fn run(network: &Network, esplora_url: &str, xpriv: &str) {
-    let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
-
-    let blockchain = EsploraBlockchain::new(esplora_url, 20);
-
-    let wallet = create_wallet(network, &xpriv);
-
-    wallet.sync(&blockchain, SyncOptions::default()).unwrap();
-
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    println!("address: {}", address);
-
-    let balance = wallet.get_balance().unwrap();
-
-    println!("Available coins in BDK wallet : {} sats", balance);
-
-    if balance.confirmed > 10500 {
-        // the wallet sends the amount to itself.
-        let recipient_address = wallet
-            .get_address(AddressIndex::New)
-            .unwrap()
-            .address
-            .to_string();
-
-        let amount = 9359;
-
-        let tx = build_signed_tx(&wallet, &recipient_address, amount);
-
-        blockchain.broadcast(&tx).unwrap();
-
-        println!("tx id: {}", tx.txid());
-    } else {
-        println!("Insufficient Funds. Fund the wallet with the address above");
-    }
-
-    let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
-        .map_err(ToString::to_string)
-        .map_err(bdk::Error::Generic)
-        .unwrap();
-
-    println!("------\nWallet Backup: {}", export.to_string());
-}
index 514f99a64de6c061a78e93f4316fa05b3c92d3d6..afaf1948480927495cd706d75b9476d3b0151a18 100644 (file)
@@ -1,6 +1,5 @@
 use bdk::bitcoin::{Address, Network};
 use bdk::blockchain::{Blockchain, ElectrumBlockchain};
-use bdk::database::MemoryDatabase;
 use bdk::hwi::{types::HWIChain, HWIClient};
 use bdk::miniscript::{Descriptor, DescriptorPublicKey};
 use bdk::signer::SignerOrdering;
@@ -42,7 +41,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     // Creating a custom signer from the device
     let custom_signer = HWISigner::from_device(&first_device, HWIChain::Test)?;
-    let mut wallet = Wallet::new(
+    let mut wallet = Wallet::new_no_persist(
         descriptors.receive[0].clone(),
         Some(descriptors.internal[0].clone()),
         Network::Testnet,
diff --git a/examples/psbt_signer.rs b/examples/psbt_signer.rs
deleted file mode 100644 (file)
index c7d4156..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2020-2022 Bitcoin Dev Kit Developers
-//
-// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
-// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
-// You may not use this file except in accordance with one or both of these
-// licenses.
-
-use bdk::blockchain::{Blockchain, ElectrumBlockchain};
-use bdk::database::MemoryDatabase;
-use bdk::wallet::AddressIndex;
-use bdk::{descriptor, SyncOptions};
-use bdk::{FeeRate, SignOptions, Wallet};
-use bitcoin::secp256k1::Secp256k1;
-use bitcoin::{Address, Network};
-use electrum_client::Client;
-use miniscript::descriptor::DescriptorSecretKey;
-use std::error::Error;
-use std::str::FromStr;
-
-/// This example shows how to sign and broadcast the transaction for a PSBT (Partially Signed
-/// Bitcoin Transaction) for a single key, witness public key hash (WPKH) based descriptor wallet.
-/// The electrum protocol is used to sync blockchain data from the testnet bitcoin network and
-/// wallet data is stored in an ephemeral in-memory database. The process steps are:
-/// 1. Create a "signing" wallet and a "watch-only" wallet based on the same private keys.
-/// 2. Deposit testnet funds into the watch only wallet.
-/// 3. Sync the watch only wallet and create a spending transaction to return all funds to the testnet faucet.
-/// 4. Sync the signing wallet and sign and finalize the PSBT created by the watch only wallet.
-/// 5. Broadcast the transactions from the finalized PSBT.
-fn main() -> Result<(), Box<dyn Error>> {
-    // test key created with `bdk-cli key generate` and `bdk-cli key derive` commands
-    let external_secret_xkey = DescriptorSecretKey::from_str("[e9824965/84'/1'/0']tprv8fvem7qWxY3SGCQczQpRpqTKg455wf1zgixn6MZ4ze8gRfHjov5gXBQTadNfDgqs9ERbZZ3Bi1PNYrCCusFLucT39K525MWLpeURjHwUsfX/0/*").unwrap();
-    let internal_secret_xkey = DescriptorSecretKey::from_str("[e9824965/84'/1'/0']tprv8fvem7qWxY3SGCQczQpRpqTKg455wf1zgixn6MZ4ze8gRfHjov5gXBQTadNfDgqs9ERbZZ3Bi1PNYrCCusFLucT39K525MWLpeURjHwUsfX/1/*").unwrap();
-
-    let secp = Secp256k1::new();
-    let external_public_xkey = external_secret_xkey.to_public(&secp).unwrap();
-    let internal_public_xkey = internal_secret_xkey.to_public(&secp).unwrap();
-
-    let signing_external_descriptor = descriptor!(wpkh(external_secret_xkey)).unwrap();
-    let signing_internal_descriptor = descriptor!(wpkh(internal_secret_xkey)).unwrap();
-
-    let watch_only_external_descriptor = descriptor!(wpkh(external_public_xkey)).unwrap();
-    let watch_only_internal_descriptor = descriptor!(wpkh(internal_public_xkey)).unwrap();
-
-    // create client for Blockstream's testnet electrum server
-    let blockchain =
-        ElectrumBlockchain::from(Client::new("ssl://electrum.blockstream.info:60002")?);
-
-    // create watch only wallet
-    let watch_only_wallet: Wallet = Wallet::new(
-        watch_only_external_descriptor,
-        Some(watch_only_internal_descriptor),
-        Network::Testnet,
-    )?;
-
-    // create signing wallet
-    let signing_wallet: Wallet = Wallet::new(
-        signing_external_descriptor,
-        Some(signing_internal_descriptor),
-        Network::Testnet,
-    )?;
-
-    println!("Syncing watch only wallet.");
-    watch_only_wallet.sync(&blockchain, SyncOptions::default())?;
-
-    // get deposit address
-    let deposit_address = watch_only_wallet.get_address(AddressIndex::New);
-
-    let balance = watch_only_wallet.get_balance()?;
-    println!("Watch only wallet balances in SATs: {}", balance);
-
-    if balance.get_total() < 10000 {
-        println!(
-            "Send at least 10000 SATs (0.0001 BTC) from the u01.net testnet faucet to address '{addr}'.\nFaucet URL: https://bitcoinfaucet.uo1.net/?to={addr}",
-            addr = deposit_address.address
-        );
-    } else if balance.get_spendable() < 10000 {
-        println!(
-            "Wait for at least 10000 SATs of your wallet transactions to be confirmed...\nBe patient, this could take 10 mins or longer depending on how testnet is behaving."
-        );
-        for tx_details in watch_only_wallet
-            .transactions()
-            .iter()
-            .filter(|txd| txd.received > 0 && txd.confirmation_time.is_none())
-        {
-            println!(
-                "See unconfirmed tx for {} SATs: https://mempool.space/testnet/tx/{}",
-                tx_details.received, tx_details.txid
-            );
-        }
-    } else {
-        println!("Creating a PSBT sending 9800 SATs plus fee to the u01.net testnet faucet return address 'tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt'.");
-        let return_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?;
-        let mut builder = watch_only_wallet.build_tx();
-        builder
-            .add_recipient(return_address.script_pubkey(), 9_800)
-            .enable_rbf()
-            .fee_rate(FeeRate::from_sat_per_vb(1.0));
-
-        let (mut psbt, details) = builder.finish()?;
-        println!("Transaction details: {:#?}", details);
-        println!("Unsigned PSBT: {}", psbt);
-
-        // Sign and finalize the PSBT with the signing wallet
-        let finalized = signing_wallet.sign(&mut psbt, SignOptions::default())?;
-        assert!(finalized, "The PSBT was not finalized!");
-        println!("The PSBT has been signed and finalized.");
-
-        // Broadcast the transaction
-        let raw_transaction = psbt.extract_tx();
-        let txid = raw_transaction.txid();
-
-        blockchain.broadcast(&raw_transaction)?;
-        println!("Transaction broadcast! TXID: {txid}.\nExplorer URL: https://mempool.space/testnet/tx/{txid}", txid = txid);
-    }
-
-    Ok(())
-}
index 25249fa7e31af6cde33caa8c4e5ad868ec9e4737..c7f032e90ae13833be78c11a90eb9fd255584786 100644 (file)
@@ -2,11 +2,11 @@ pub(crate) mod tx {
 
     use std::str::FromStr;
 
-    use bdk::{database::BatchDatabase, SignOptions, Wallet};
+    use bdk::{SignOptions, Wallet, persist};
     use bitcoin::{Address, Transaction};
 
-    pub fn build_signed_tx<D: BatchDatabase>(
-        wallet: &Wallet<D>,
+    pub fn build_signed_tx<()>(
+        wallet: &Wallet<()>,
         recipient_address: &str,
         amount: u64,
     ) -> Transaction {
@@ -15,6 +15,7 @@ pub(crate) mod tx {
 
         let to_address = Address::from_str(recipient_address).unwrap();
 
+
         // Set recipient of the transaction
         tx_builder.set_recipients(vec![(to_address.script_pubkey(), amount)]);
 
index fdd78a46d4f7d117163a88c945d7a9661d69d362..e689a540afea463b531985a1cb02746794ea3970 100644 (file)
@@ -203,8 +203,8 @@ macro_rules! impl_node_opcode_two {
                 a_keymap.extend(b_keymap.into_iter());
 
                 let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
-                    alloc::sync::Arc::new(a_minisc),
-                    alloc::sync::Arc::new(b_minisc),
+                    $crate::alloc::sync::Arc::new(a_minisc),
+                    $crate::alloc::sync::Arc::new(b_minisc),
                 ))?;
 
                 minisc.check_miniscript()?;
@@ -234,9 +234,9 @@ macro_rules! impl_node_opcode_three {
                 let networks = $crate::keys::merge_networks(&networks, &c_networks);
 
                 let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
-                    alloc::sync::Arc::new(a_minisc),
-                    alloc::sync::Arc::new(b_minisc),
-                    alloc::sync::Arc::new(c_minisc),
+                    $crate::alloc::sync::Arc::new(a_minisc),
+                    $crate::alloc::sync::Arc::new(b_minisc),
+                    $crate::alloc::sync::Arc::new(c_minisc),
                 ))?;
 
                 minisc.check_miniscript()?;
@@ -263,7 +263,7 @@ macro_rules! impl_sortedmulti {
             )*
         ];
 
-        keys.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
+        keys.into_iter().collect::<Result<$crate::alloc::vec::Vec<_>, _>>()
             .map_err($crate::descriptor::DescriptorError::Key)
             .and_then(|keys| $crate::keys::make_sortedmulti($thresh, keys, $build_desc, &secp))
     });
@@ -274,7 +274,7 @@ macro_rules! impl_sortedmulti {
 #[macro_export]
 macro_rules! parse_tap_tree {
     ( @merge $tree_a:expr, $tree_b:expr) => {{
-        use alloc::sync::Arc;
+        use $crate::alloc::sync::Arc;
         use $crate::miniscript::descriptor::TapTree;
 
         $tree_a
@@ -318,7 +318,7 @@ macro_rules! parse_tap_tree {
 
     // Single leaf
     ( $op:ident ( $( $minisc:tt )* ) ) => {{
-        use alloc::sync::Arc;
+        use $crate::alloc::sync::Arc;
         use $crate::miniscript::descriptor::TapTree;
 
         $crate::fragment!( $op ( $( $minisc )* ) )
@@ -337,7 +337,7 @@ macro_rules! apply_modifier {
             .and_then(|(minisc, keymap, networks)| {
                 let minisc = $crate::miniscript::Miniscript::from_ast(
                     $crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
-                        alloc::sync::Arc::new(minisc),
+                        $crate::alloc::sync::Arc::new(minisc),
                     ),
                 )?;
 
@@ -374,8 +374,8 @@ macro_rules! apply_modifier {
         $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
             $crate::impl_leaf_opcode_value_two!(
                 AndV,
-                alloc::sync::Arc::new(a_minisc),
-                alloc::sync::Arc::new($crate::fragment!(true).unwrap().0)
+                $crate::alloc::sync::Arc::new(a_minisc),
+                $crate::alloc::sync::Arc::new($crate::fragment!(true).unwrap().0)
             )
             .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
         })
@@ -384,8 +384,8 @@ macro_rules! apply_modifier {
         $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
             $crate::impl_leaf_opcode_value_two!(
                 OrI,
-                alloc::sync::Arc::new($crate::fragment!(false).unwrap().0),
-                alloc::sync::Arc::new(a_minisc)
+                $crate::alloc::sync::Arc::new($crate::fragment!(false).unwrap().0),
+                $crate::alloc::sync::Arc::new(a_minisc)
             )
             .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
         })
@@ -394,8 +394,8 @@ macro_rules! apply_modifier {
         $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
             $crate::impl_leaf_opcode_value_two!(
                 OrI,
-                alloc::sync::Arc::new(a_minisc),
-                alloc::sync::Arc::new($crate::fragment!(false).unwrap().0)
+                $crate::alloc::sync::Arc::new(a_minisc),
+                $crate::alloc::sync::Arc::new($crate::fragment!(false).unwrap().0)
             )
             .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
         })
@@ -599,7 +599,7 @@ macro_rules! group_multi_keys {
             )*
         ];
 
-        keys.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
+        keys.into_iter().collect::<Result<$crate::alloc::vec::Vec<_>, _>>()
             .map_err($crate::descriptor::DescriptorError::Key)
     }};
 }
@@ -744,8 +744,8 @@ macro_rules! fragment {
     ( thresh_vec ( $thresh:expr, $items:expr ) ) => ({
         use $crate::miniscript::descriptor::KeyMap;
 
-        let (items, key_maps_networks): (alloc::vec::Vec<_>, alloc::vec::Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip();
-        let items = items.into_iter().map(alloc::sync::Arc::new).collect();
+        let (items, key_maps_networks): ($crate::alloc::vec::Vec<_>, $crate::alloc::vec::Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip();
+        let items = items.into_iter().map($crate::alloc::sync::Arc::new).collect();
 
         let (key_maps, valid_networks) = key_maps_networks.into_iter().fold((KeyMap::default(), $crate::keys::any_network()), |(mut keys_acc, net_acc), (key, net)| {
             keys_acc.extend(key.into_iter());
@@ -760,7 +760,7 @@ macro_rules! fragment {
     ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
         let items = $crate::fragment_internal!( @v $( $inner )* );
 
-        items.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
+        items.into_iter().collect::<Result<$crate::alloc::vec::Vec<_>, _>>()
             .and_then(|items| $crate::fragment!(thresh_vec($thresh, items)))
     });
     ( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
index d6697becc0b07fec1f169ef5ecb6cd29a60e47c4..cf0296c912b19b9ab00e42f58814fbf42b2ac3dd 100644 (file)
@@ -73,19 +73,13 @@ impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
 ///
 /// ```
 /// # use bdk::bitcoin::{PrivateKey, Network};
-/// # use bdk::{Wallet};
-/// # use bdk::database::MemoryDatabase;
+/// # use bdk::Wallet;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::P2Pkh;
 ///
 /// let key =
 ///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
-/// let wallet = Wallet::new(
-///     P2Pkh(key),
-///     None,
-///     Network::Testnet,
-///     MemoryDatabase::default(),
-/// )?;
+/// let mut wallet = Wallet::new_no_persist(P2Pkh(key), None, Network::Testnet)?;
 ///
 /// assert_eq!(
 ///     wallet.get_address(New).to_string(),
@@ -107,22 +101,16 @@ impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
 ///
 /// ```
 /// # use bdk::bitcoin::{PrivateKey, Network};
-/// # use bdk::{Wallet};
-/// # use bdk::database::MemoryDatabase;
-/// # use bdk::wallet::AddressIndex::New;
+/// # use bdk::Wallet;
 /// use bdk::template::P2Wpkh_P2Sh;
+/// use bdk::wallet::AddressIndex;
 ///
 /// let key =
 ///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
-/// let wallet = Wallet::new(
-///     P2Wpkh_P2Sh(key),
-///     None,
-///     Network::Testnet,
-///     MemoryDatabase::default(),
-/// )?;
+/// let mut wallet = Wallet::new_no_persist(P2Wpkh_P2Sh(key), None, Network::Testnet)?;
 ///
 /// assert_eq!(
-///     wallet.get_address(New).to_string(),
+///     wallet.get_address(AddressIndex::New).to_string(),
 ///     "2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5"
 /// );
 /// # Ok::<_, Box<dyn std::error::Error>>(())
@@ -143,18 +131,12 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
 /// ```
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet};
-/// # use bdk::database::MemoryDatabase;
-/// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::P2Wpkh;
+/// use bdk::wallet::AddressIndex::New;
 ///
 /// let key =
 ///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
-/// let wallet = Wallet::new(
-///     P2Wpkh(key),
-///     None,
-///     Network::Testnet,
-///     MemoryDatabase::default(),
-/// )?;
+/// let mut wallet = Wallet::new_no_persist(P2Wpkh(key), None, Network::Testnet)?;
 ///
 /// assert_eq!(
 ///     wallet.get_address(New).to_string(),
@@ -182,20 +164,18 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip44(key.clone(), KeychainKind::External),
 ///     Some(Bip44(key, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
@@ -221,21 +201,19 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44Public;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
 /// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip44Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#xgaaevjx");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#cfhumdqz");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
@@ -261,20 +239,18 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip49(key.clone(), KeychainKind::External),
 ///     Some(Bip49(key, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
@@ -300,21 +276,19 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49Public;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
 /// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip49Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#gsmdv4xr");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#3tka9g0q");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
@@ -340,20 +314,18 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip84(key.clone(), KeychainKind::External),
 ///     Some(Bip84(key, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
@@ -379,21 +351,19 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
 /// # use std::str::FromStr;
 /// # use bdk::bitcoin::{PrivateKey, Network};
 /// # use bdk::{Wallet,  KeychainKind};
-/// # use bdk::database::MemoryDatabase;
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84Public;
 ///
 /// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
 /// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
-/// let wallet = Wallet::new(
+/// let mut wallet = Wallet::new_no_persist(
 ///     Bip84Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
 ///     Network::Testnet,
-///     MemoryDatabase::default()
 /// )?;
 ///
 /// assert_eq!(wallet.get_address(New).to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7");
-/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#nkk5dtkg");
+/// assert_eq!(wallet.public_descriptor(KeychainKind::External).unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#dhu402yv");
 /// # Ok::<_, Box<dyn std::error::Error>>(())
 /// ```
 pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
index 6a208919c0ddb3424ea9b7fc64182d28722e77e9..f4d73caafe90f313bb8550154392d41ad0f7d636 100644 (file)
 //! * 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`](sled)) to cache
-//! blockchain data and an [electrum](https://docs.rs/electrum-client/) blockchain client to
-//! interact with the bitcoin P2P network.
-//!
-//! # Examples
-#![cfg_attr(
-    feature = "electrum",
-    doc = r##"
-## Sync the balance of a descriptor
-
-```no_run
-use bdk::{Wallet, SyncOptions};
-use bdk::database::MemoryDatabase;
-use bdk::blockchain::ElectrumBlockchain;
-use bdk::electrum_client::Client;
-
-fn main() -> Result<(), bdk::Error> {
-    let client = Client::new("ssl://electrum.blockstream.info:60002")?;
-    let blockchain = ElectrumBlockchain::from(client);
-    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
 //!
 //! ### Example
 //! ```
 //! use bdk::{Wallet};
-//! use bdk::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(),
+//!     let mut wallet = Wallet::new_no_persist(
+//!          "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
+//!          Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
+//!          bitcoin::Network::Testnet,
 //!     )?;
 //!
 //!     println!("Address #0: {}", wallet.get_address(New));
@@ -98,52 +52,6 @@ fn main() -> Result<(), bdk::Error> {
 //!     Ok(())
 //! }
 //! ```
-#![cfg_attr(
-    feature = "electrum",
-    doc = r##"
-## Create a transaction
-
-```no_run
-use bdk::{FeeRate, Wallet, SyncOptions};
-use bdk::database::MemoryDatabase;
-use bdk::blockchain::ElectrumBlockchain;
-use bdk::electrum_client::Client;
-
-use bitcoin::consensus::serialize;
-use bdk::wallet::AddressIndex::New;
-
-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(),
-    )?;
-    let blockchain = ElectrumBlockchain::from(client);
-
-    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: {}", &psbt);
-
-    Ok(())
-}
-```
-"##
-)]
-//!
 //! ## Sign a transaction
 //!
 //! ```no_run
@@ -152,14 +60,12 @@ fn main() -> Result<(), bdk::Error> {
 //! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
 //!
 //! use bdk::{Wallet, SignOptions};
-//! use bdk::database::MemoryDatabase;
 //!
 //! fn main() -> Result<(), bdk::Error> {
-//!     let wallet = Wallet::new(
+//!     let wallet = Wallet::new_no_persist(
 //!         "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
 //!         Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
 //!         bitcoin::Network::Testnet,
-//!         MemoryDatabase::default(),
 //!     )?;
 //!
 //!     let psbt = "...";
@@ -193,8 +99,9 @@ fn main() -> Result<(), bdk::Error> {
 #[macro_use]
 extern crate std;
 
+#[doc(hidden)]
 #[macro_use]
-extern crate alloc;
+pub extern crate alloc;
 
 pub extern crate bitcoin;
 #[cfg(feature = "hardware-signer")]
index 12c89a7b9c489f0315a5b9dbfb04361eba87b73d..736b7319e2d1e835181744a1533591c8f7606111 100644 (file)
@@ -27,7 +27,6 @@
 //! # use std::str::FromStr;
 //! # use bitcoin::*;
 //! # use bdk::wallet::{self, coin_selection::*};
-//! # use bdk::database::Database;
 //! # use bdk::*;
 //! # use bdk::wallet::coin_selection::decide_change;
 //! # const TXIN_BASE_WEIGHT: usize = (32 + 4 + 4) * 4;
@@ -37,7 +36,6 @@
 //! impl CoinSelectionAlgorithm for AlwaysSpendEverything {
 //!     fn coin_select(
 //!         &self,
-//!         database: &D,
 //!         required_utxos: Vec<WeightedUtxo>,
 //!         optional_utxos: Vec<WeightedUtxo>,
 //!         fee_rate: FeeRate,
@@ -79,7 +77,7 @@
 //!     }
 //! }
 //!
-//! # let wallet = doctest_wallet!();
+//! # let mut wallet = doctest_wallet!();
 //! // create wallet, sync, ...
 //!
 //! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
index 469a50ac97b498e03c4d2a1ffb6f6f110852cec9..3ec43d2b9ea5752d38a857b0e977950739974def 100644 (file)
@@ -20,7 +20,6 @@
 //! ```
 //! # use std::str::FromStr;
 //! # use bitcoin::*;
-//! # use bdk::database::*;
 //! # use bdk::wallet::export::*;
 //! # use bdk::*;
 //! let import = r#"{
 //! }"#;
 //!
 //! let import = FullyNodedExport::from_str(import)?;
-//! let wallet = Wallet::new(
+//! let wallet = Wallet::new_no_persist(
 //!     &import.descriptor(),
 //!     import.change_descriptor().as_ref(),
 //!     Network::Testnet,
-//!     MemoryDatabase::default(),
 //! )?;
 //! # Ok::<_, bdk::Error>(())
 //! ```
 //! ### Export a `Wallet`
 //! ```
 //! # use bitcoin::*;
-//! # use bdk::database::*;
 //! # use bdk::wallet::export::*;
 //! # use bdk::*;
-//! let wallet = Wallet::new(
+//! let wallet = Wallet::new_no_persist(
 //!     "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)",
 //!     Some("wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/1/*)"),
 //!     Network::Testnet,
-//!     MemoryDatabase::default()
 //! )?;
 //! let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
 //!     .map_err(ToString::to_string)
@@ -232,7 +228,7 @@ mod test {
         change_descriptor: Option<&str>,
         network: Network,
     ) -> Wallet<()> {
-        let mut wallet = Wallet::new(descriptor, change_descriptor, (), network).unwrap();
+        let mut wallet = Wallet::new_no_persist(descriptor, change_descriptor, network).unwrap();
         let transaction = Transaction {
             input: vec![],
             output: vec![],
index 230cd4cf0380c9def6d591aa55c2354c7bf0749a..b014bb5398c5407054c10408f5e28b52494e2d93 100644 (file)
@@ -15,7 +15,6 @@
 //! used with hardware wallets.
 //! ```no_run
 //! # use bdk::bitcoin::Network;
-//! # use bdk::database::MemoryDatabase;
 //! # use bdk::signer::SignerOrdering;
 //! # use bdk::wallet::hardwaresigner::HWISigner;
 //! # use bdk::wallet::AddressIndex::New;
 //! let first_device = devices.remove(0)?;
 //! let custom_signer = HWISigner::from_device(&first_device, HWIChain::Test)?;
 //!
-//! # let mut wallet = Wallet::new(
+//! # let mut wallet = Wallet::new_no_persist(
 //! #     "",
 //! #     None,
 //! #     Network::Testnet,
-//! #     MemoryDatabase::default(),
 //! # )?;
 //! #
 //! // Adding the hardware signer to the BDK wallet
index 0f00dba98700d6b6e994a1248da581fe4c5ebe2e..d4dd571f408137e30a3c7f1aadf68784c2b92081 100644 (file)
@@ -25,17 +25,15 @@ use bdk_chain::{
     keychain::{KeychainChangeSet, KeychainScan, KeychainTracker},
     sparse_chain, BlockId, ConfirmationTime, IntoOwned,
 };
-use bitcoin::secp256k1::Secp256k1;
-use core::fmt;
-use core::ops::Deref;
-
 use bitcoin::consensus::encode::serialize;
+use bitcoin::secp256k1::Secp256k1;
 use bitcoin::util::psbt;
 use bitcoin::{
     Address, BlockHash, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script,
     Sequence, Transaction, TxOut, Txid, Witness,
 };
-
+use core::fmt;
+use core::ops::Deref;
 use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
 
 #[allow(unused_imports)]
@@ -79,10 +77,8 @@ const COINBASE_MATURITY: u32 = 100;
 /// Its main components are:
 ///
 /// 1. output *descriptors* from which it can derive addresses.
-/// 2. A [`Database`] where it tracks transactions and utxos related to the descriptors.
-/// 3. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors.
+/// 2. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors.
 ///
-/// [`Database`]: crate::database::Database
 /// [`signer`]: crate::signer
 #[derive(Debug)]
 pub struct Wallet<D = ()> {
@@ -573,8 +569,7 @@ impl<D> Wallet<D> {
     /// ```
     /// # use bdk::{Wallet, KeychainKind};
     /// # use bdk::bitcoin::Network;
-    /// # use bdk::database::MemoryDatabase;
-    /// let wallet = Wallet::new_no_persist("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
+    /// let wallet = Wallet::new_no_persist("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet)?;
     /// for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
     ///     // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
     ///     println!("secret_key: {}", secret_key);
@@ -599,9 +594,8 @@ impl<D> Wallet<D> {
     /// # use std::str::FromStr;
     /// # use bitcoin::*;
     /// # use bdk::*;
-    /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
-    /// # let wallet = doctest_wallet!();
+    /// # let mut wallet = doctest_wallet!();
     /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
     /// let (psbt, details) = {
     ///    let mut builder =  wallet.build_tx();
@@ -1006,9 +1000,8 @@ impl<D> Wallet<D> {
     /// # use std::str::FromStr;
     /// # use bitcoin::*;
     /// # use bdk::*;
-    /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
-    /// # let wallet = doctest_wallet!();
+    /// # let mut wallet = doctest_wallet!();
     /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
@@ -1168,9 +1161,8 @@ impl<D> Wallet<D> {
     /// # use std::str::FromStr;
     /// # use bitcoin::*;
     /// # use bdk::*;
-    /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
-    /// # let wallet = doctest_wallet!();
+    /// # let mut wallet = doctest_wallet!();
     /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
@@ -1380,7 +1372,6 @@ impl<D> Wallet<D> {
     /// Informs the wallet that you no longer intend to broadcast a tx that was built from it.
     ///
     /// This frees up the change address used when creating the tx for use in future transactions.
-    ///
     // TODO: Make this free up reserved utxos when that's implemented
     pub fn cancel_tx(&mut self, tx: &Transaction) {
         let txout_index = &mut self.keychain_tracker.txout_index;
@@ -1397,7 +1388,7 @@ impl<D> Wallet<D> {
         if keychain == KeychainKind::Internal
             && self.public_descriptor(KeychainKind::Internal).is_none()
         {
-            return KeychainKind::External;
+            KeychainKind::External
         } else {
             keychain
         }
@@ -1765,3 +1756,40 @@ where
 
     Ok(wallet_name)
 }
+
+#[macro_export]
+#[doc(hidden)]
+/// Macro for getting a wallet for use in a doctest
+macro_rules! doctest_wallet {
+    () => {{
+        use $crate::bitcoin::{BlockHash, Transaction, PackedLockTime, TxOut, Network, hashes::Hash};
+        use $crate::chain::{ConfirmationTime, BlockId};
+        use $crate::wallet::{AddressIndex, Wallet};
+        let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)";
+        let change_descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/1/*)";
+
+        let mut wallet = Wallet::new_no_persist(
+            descriptor,
+            Some(change_descriptor),
+            Network::Regtest,
+        )
+        .unwrap();
+        let address = wallet.get_address(AddressIndex::New).address;
+        let tx = Transaction {
+            version: 1,
+            lock_time: PackedLockTime(0),
+            input: vec![],
+            output: vec![TxOut {
+                value: 500_000,
+                script_pubkey: address.script_pubkey(),
+            }],
+        };
+        let _ = wallet.insert_checkpoint(BlockId { height: 1_000, hash: BlockHash::all_zeros() });
+        let _ = wallet.insert_tx(tx.clone(), ConfirmationTime::Confirmed {
+            height: 500,
+            time: 50_000
+        });
+
+        wallet
+    }}
+}
index 51106d02e2896f9abb76348e9eb080e199d7b0f0..68dc464509fb0d8e1bcc363fe4e4f06004e27982 100644 (file)
@@ -21,7 +21,6 @@
 //! # use bitcoin::*;
 //! # use bitcoin::util::psbt;
 //! # use bdk::signer::*;
-//! # use bdk::database::*;
 //! # use bdk::*;
 //! # #[derive(Debug)]
 //! # struct CustomHSM;
@@ -70,7 +69,7 @@
 //! let custom_signer = CustomSigner::connect();
 //!
 //! let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
-//! let mut wallet = Wallet::new(descriptor, None, Network::Testnet, MemoryDatabase::default())?;
+//! let mut wallet = Wallet::new_no_persist(descriptor, None, Network::Testnet)?;
 //! wallet.add_signer(
 //!     KeychainKind::External,
 //!     SignerOrdering(200),
index d4d34cdc25cd5138e4a6367e258ae62f7aacd0d7..c5492c5052fdb1647e79a74bd60a1c7ecc9f2c2f 100644 (file)
@@ -19,7 +19,7 @@
 //! # use bdk::*;
 //! # use bdk::wallet::tx_builder::CreateTx;
 //! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
-//! # let wallet = doctest_wallet!();
+//! # let mut wallet = doctest_wallet!();
 //! // create a TxBuilder from a wallet
 //! let mut tx_builder = wallet.build_tx();
 //!
@@ -80,7 +80,7 @@ impl TxBuilderContext for BumpFee {}
 /// # use bdk::wallet::tx_builder::*;
 /// # use bitcoin::*;
 /// # use core::str::FromStr;
-/// # let wallet = doctest_wallet!();
+/// # let mut wallet = doctest_wallet!();
 /// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
 /// # let addr2 = addr1.clone();
 /// // chaining
@@ -242,7 +242,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
     /// # use bitcoin::*;
     /// # use bdk::*;
     /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
-    /// # let wallet = doctest_wallet!();
+    /// # let mut wallet = doctest_wallet!();
     /// let mut path = BTreeMap::new();
     /// path.insert("aabbccdd".to_string(), vec![0, 1]);
     ///
@@ -623,7 +623,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
     /// # use bdk::*;
     /// # use bdk::wallet::tx_builder::CreateTx;
     /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
-    /// # let wallet = doctest_wallet!();
+    /// # let mut wallet = doctest_wallet!();
     /// let mut tx_builder = wallet.build_tx();
     ///
     /// tx_builder