From ce0619f80322424a9b27736a8e0329a7d106866a Mon Sep 17 00:00:00 2001 From: valued mammal Date: Sat, 7 Dec 2024 12:51:24 -0500 Subject: [PATCH] test: example wallet esplora --- .../example_wallet_esplora_async/Cargo.toml | 2 +- .../example_wallet_esplora_async/src/main.rs | 75 ++++++++++--------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/example-crates/example_wallet_esplora_async/Cargo.toml b/example-crates/example_wallet_esplora_async/Cargo.toml index 38458b782..593be6f85 100644 --- a/example-crates/example_wallet_esplora_async/Cargo.toml +++ b/example-crates/example_wallet_esplora_async/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bdk_wallet = { path = "../../crates/wallet", features = ["rusqlite"] } +bdk_wallet = { path = "../../crates/wallet", features = ["rusqlite", "test-utils"] } bdk_esplora = { path = "../../crates/esplora", features = ["async-https", "tokio"] } tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } anyhow = "1" diff --git a/example-crates/example_wallet_esplora_async/src/main.rs b/example-crates/example_wallet_esplora_async/src/main.rs index b6ab5d6dc..6783d20b0 100644 --- a/example-crates/example_wallet_esplora_async/src/main.rs +++ b/example-crates/example_wallet_esplora_async/src/main.rs @@ -1,21 +1,25 @@ +#![allow(unused)] use std::{collections::BTreeSet, io::Write}; use anyhow::Ok; use bdk_esplora::{esplora_client, EsploraAsyncExt}; use bdk_wallet::{ - bitcoin::{Amount, Network}, + bitcoin::{Amount, Network, ScriptBuf}, rusqlite::Connection, KeychainKind, SignOptions, Wallet, }; +use bdk_wallet::test_utils::*; + const SEND_AMOUNT: Amount = Amount::from_sat(5000); const STOP_GAP: usize = 5; -const PARALLEL_REQUESTS: usize = 5; +const PARALLEL_REQUESTS: usize = 1; -const DB_PATH: &str = "bdk-example-esplora-async.sqlite"; +const DB_PATH: &str = ".bdk-example-esplora-async.sqlite"; const NETWORK: Network = Network::Signet; -const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)"; -const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)"; +const EXTERNAL_DESC: &str = "tr(tprv8ZgxMBicQKsPczwfSDDHGpmNeWzKaMajLtkkNUdBoisixK3sW3YTC8subMCsTJB7sM4kaJJ7K1cNVM37aZoJ7dMBt2HRYLQzoFPqPMC8cTr/86'/1'/0'/0/*)"; +const INTERNAL_DESC: &str = "tr(tprv8ZgxMBicQKsPczwfSDDHGpmNeWzKaMajLtkkNUdBoisixK3sW3YTC8subMCsTJB7sM4kaJJ7K1cNVM37aZoJ7dMBt2HRYLQzoFPqPMC8cTr/86'/1'/0'/1/*)"; + const ESPLORA_URL: &str = "http://signet.bitcoindevkit.net"; #[tokio::main] @@ -35,16 +39,8 @@ async fn main() -> Result<(), anyhow::Error> { .create_wallet(&mut conn)?, }; - let address = wallet.next_unused_address(KeychainKind::External); - wallet.persist(&mut conn)?; - println!("Next unused address: ({}) {}", address.index, address); - - let balance = wallet.balance(); - println!("Wallet balance before syncing: {}", balance.total()); - - print!("Syncing..."); + // Sync let client = esplora_client::Builder::new(ESPLORA_URL).build_async()?; - let request = wallet.start_full_scan().inspect({ let mut stdout = std::io::stdout(); let mut once = BTreeSet::::new(); @@ -53,39 +49,48 @@ async fn main() -> Result<(), anyhow::Error> { print!("\nScanning keychain [{:?}]", keychain); } print!(" {:<3}", spk_i); - stdout.flush().expect("must flush") + stdout.flush().unwrap(); } }); - let update = client .full_scan(request, STOP_GAP, PARALLEL_REQUESTS) .await?; - wallet.apply_update(update)?; wallet.persist(&mut conn)?; println!(); + let old_balance = wallet.balance(); + println!("Balance after sync: {}", old_balance.total()); + + // Build tx that sends all to a foreign recipient + let recip = ScriptBuf::from_hex("0014446906a6560d8ad760db3156706e72e171f3a2aa")?; + let mut b = wallet.build_tx(); + b.drain_to(recip).drain_wallet(); + let mut psbt = b.finish()?; + assert!(wallet.sign(&mut psbt, SignOptions::default())?); + let tx = psbt.extract_tx()?; + let txid = tx.compute_txid(); + insert_tx(&mut wallet, tx.clone()); + wallet.persist(&mut conn)?; - let balance = wallet.balance(); - println!("Wallet balance after syncing: {}", balance.total()); - - if balance.total() < SEND_AMOUNT { - println!( - "Please send at least {} to the receiving address", - SEND_AMOUNT - ); - std::process::exit(0); - } + println!("Balance after send: {}", wallet.balance().total()); + assert_eq!(wallet.balance().total(), Amount::ZERO); - let mut tx_builder = wallet.build_tx(); - tx_builder.add_recipient(address.script_pubkey(), SEND_AMOUNT); + // Cancel spend + wallet.cancel_tx(&tx); + assert_eq!(wallet.balance(), old_balance); + println!("Balance after cancel: {}", wallet.balance().total()); + wallet.persist(&mut conn)?; - let mut psbt = tx_builder.finish()?; - let finalized = wallet.sign(&mut psbt, SignOptions::default())?; - assert!(finalized); + // Load one more time + wallet = Wallet::load() + .load_wallet(&mut conn)? + .expect("must load existing"); - let tx = psbt.extract_tx()?; - client.broadcast(&tx).await?; - println!("Tx broadcasted! Txid: {}", tx.compute_txid()); + assert_eq!( + wallet.balance(), + old_balance, + "balance did not match original" + ); Ok(()) }