diff --git a/.github/workflows/cont_integration.yml b/.github/workflows/cont_integration.yml index 9f31349e..65827328 100644 --- a/.github/workflows/cont_integration.yml +++ b/.github/workflows/cont_integration.yml @@ -23,7 +23,9 @@ jobs: - reserves,electrum - reserves,esplora-ureq - reserves,compact_filters + - reserves,rpc - rpc + - electrum,verify steps: - name: Checkout uses: actions/checkout@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 706ca4f8..ac58a1c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Re-license to dual MIT and Apache 2.0 and update project name to "Bitcoin Dev Kit" +- Update to bdk and bdk-reserves to `0.17.0` +- Add 'verify' feature flag which enables transaction verification against consensus rules during sync. ## [0.4.0] diff --git a/Cargo.lock b/Cargo.lock index e9cc31d3..aff727e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.52" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ "proc-macro2", "quote", @@ -80,14 +80,15 @@ dependencies = [ [[package]] name = "bdk" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3face7de38293a2f7e2a9f69a48b442f28e864da0fc7a6a977388e31bdc367d7" +checksum = "00fa2bcfe9debe57f32285ef56cb218b2e0dbf91e476ad22f61a745d4c032a18" dependencies = [ "async-trait", "bdk-macros", "bip39", "bitcoin", + "bitcoinconsensus", "bitcoincore-rpc", "cc", "electrum-client", @@ -109,7 +110,7 @@ dependencies = [ [[package]] name = "bdk-cli" -version = "0.4.0" +version = "0.5.0" dependencies = [ "base64 0.11.0", "bdk", @@ -140,9 +141,9 @@ dependencies = [ [[package]] name = "bdk-reserves" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85397162a769b6162033c4ed8edc6285d347006eac5299dd186dee7bd77e8c88" +checksum = "caf154487aa14256d6f3769baf6c80b56c945a0a1c825a7f3132878acbc8ede0" dependencies = [ "base64 0.11.0", "bdk", @@ -351,10 +352,11 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ + "autocfg", "cfg-if", "crossbeam-utils", "lazy_static", @@ -364,9 +366,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if", "lazy_static", @@ -603,9 +605,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -620,9 +622,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1f717ddc7b2ba36df7e871fd88db79326551d3d6f1fc406fbfd28b582ff8e" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ "bytes", "fnv", @@ -706,9 +708,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.17" +version = "0.14.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" dependencies = [ "bytes", "futures-channel", @@ -741,9 +743,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", @@ -760,9 +762,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c" [[package]] name = "itoa" @@ -814,9 +816,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" [[package]] name = "libloading" @@ -842,18 +844,19 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if", ] @@ -953,13 +956,12 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", - "version_check", ] [[package]] @@ -1073,9 +1075,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" dependencies = [ "proc-macro2", ] @@ -1139,28 +1141,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", "redox_syscall", + "thiserror", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -1175,9 +1178,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "reqwest" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525" +checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" dependencies = [ "base64 0.13.0", "bytes", @@ -1480,9 +1483,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" dependencies = [ "proc-macro2", "quote", @@ -1556,16 +1559,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -1576,20 +1579,32 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c650a8ef0cd2dd93736f033d21cbd1224c5a967aa0c258d00fcf7dafef9b9f" +checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" dependencies = [ "lazy_static", ] @@ -1890,9 +1905,9 @@ checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index 6daf25b5..0ed9caa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bdk-cli" -version = "0.4.0" +version = "0.5.0" edition = "2018" authors = ["Alekos Filini ", "Riccardo Casatta ", "Steve Myers "] homepage = "https://bitcoindevkit.org" @@ -12,7 +12,7 @@ readme = "README.md" license = "MIT" [dependencies] -bdk = { version = "0.16", default-features = false, features = ["all-keys"]} +bdk = { version = "0.17", default-features = false, features = ["all-keys"]} bdk-macros = "0.6" structopt = "^0.3" serde_json = { version = "^1.0" } @@ -27,7 +27,7 @@ dirs-next = { version = "2.0", optional = true } env_logger = { version = "0.7", optional = true } clap = { version = "2.33", optional = true } regex = { version = "1", optional = true } -bdk-reserves = { version = "0.16", optional = true} +bdk-reserves = { version = "0.17", optional = true} [features] default = ["cli", "repl"] @@ -41,6 +41,7 @@ compiler = ["bdk/compiler"] compact_filters = ["bdk/compact_filters"] rpc = ["bdk/rpc"] reserves = ["bdk-reserves"] +verify = ["bdk/verify"] [[bin]] name = "bdk-cli" diff --git a/src/bdk_cli.rs b/src/bdk_cli.rs index b094834c..93b9fd92 100644 --- a/src/bdk_cli.rs +++ b/src/bdk_cli.rs @@ -71,7 +71,7 @@ const REPL_LINE_SPLIT_REGEX: &str = r#""([^"]*)"|'([^']*)'|([\w\-]+)"#; #[structopt(name = "", setting = AppSettings::NoBinaryName, version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"), author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))] -pub enum ReplSubCommand { +enum ReplSubCommand { #[cfg(any( feature = "electrum", feature = "esplora", @@ -127,14 +127,7 @@ fn open_database(wallet_opts: &WalletOpts) -> Result { feature = "compact_filters", feature = "rpc" ))] -fn new_online_wallet( - network: Network, - wallet_opts: &WalletOpts, - database: D, -) -> Result, Error> -where - D: BatchDatabase, -{ +fn new_blockchain(_network: Network, wallet_opts: &WalletOpts) -> Result { #[cfg(feature = "electrum")] let config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { url: wallet_opts.electrum_opts.server.clone(), @@ -168,7 +161,7 @@ where AnyBlockchainConfig::CompactFilters(CompactFiltersBlockchainConfig { peers, - network, + network: _network, storage_dir: prepare_home_dir()? .into_os_string() .into_string() @@ -194,7 +187,7 @@ where let wallet_name = wallet_name_from_descriptor( &wallet_opts.descriptor[..], wallet_opts.change_descriptor.as_deref(), - network, + _network, &Secp256k1::new(), )?; @@ -204,37 +197,28 @@ where let rpc_config = RpcConfig { url: rpc_url, auth, - network, + network: _network, wallet_name, skip_blocks: wallet_opts.rpc_opts.skip_blocks, }; AnyBlockchainConfig::Rpc(rpc_config) }; - let descriptor = wallet_opts.descriptor.as_str(); - let change_descriptor = wallet_opts.change_descriptor.as_deref(); - let wallet = Wallet::new( - descriptor, - change_descriptor, - network, - database, - AnyBlockchain::from_config(&config)?, - )?; - Ok(wallet) + Ok(AnyBlockchain::from_config(&config)?) } -fn new_offline_wallet( +fn new_wallet( network: Network, wallet_opts: &WalletOpts, database: D, -) -> Result, Error> +) -> Result, Error> where D: BatchDatabase, { let descriptor = wallet_opts.descriptor.as_str(); let change_descriptor = wallet_opts.change_descriptor.as_deref(); - let wallet = Wallet::new_offline(descriptor, change_descriptor, network, database)?; + let wallet = Wallet::new(descriptor, change_descriptor, network, database)?; Ok(wallet) } @@ -294,8 +278,10 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result } => { let wallet_opts = maybe_descriptor_wallet_name(wallet_opts, network)?; let database = open_database(&wallet_opts)?; - let wallet = new_online_wallet(network, &wallet_opts, database)?; - let result = bdk_cli::handle_online_wallet_subcommand(&wallet, online_subcommand)?; + let blockchain = new_blockchain(network, &wallet_opts)?; + let wallet = new_wallet(network, &wallet_opts, database)?; + let result = + bdk_cli::handle_online_wallet_subcommand(&wallet, &blockchain, online_subcommand)?; serde_json::to_string_pretty(&result)? } CliSubCommand::Wallet { @@ -304,7 +290,7 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result } => { let wallet_opts = maybe_descriptor_wallet_name(wallet_opts, network)?; let database = open_database(&wallet_opts)?; - let wallet = new_offline_wallet(network, &wallet_opts, database)?; + let wallet = new_wallet(network, &wallet_opts, database)?; let result = bdk_cli::handle_offline_wallet_subcommand( &wallet, &wallet_opts, @@ -337,7 +323,7 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result feature = "compact_filters", feature = "rpc" ))] - let wallet = new_online_wallet(network, &wallet_opts, database)?; + let wallet = new_wallet(network, &wallet_opts, database)?; #[cfg(not(any( feature = "electrum", @@ -345,7 +331,7 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result feature = "compact_filters", feature = "rpc" )))] - let wallet = new_offline_wallet(network, &wallet_opts, database)?; + let wallet = new_wallet(network, &wallet_opts, database)?; let mut rl = Editor::<()>::new(); @@ -391,7 +377,12 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result feature = "rpc" ))] ReplSubCommand::OnlineWalletSubCommand(online_subcommand) => { - bdk_cli::handle_online_wallet_subcommand(&wallet, online_subcommand) + let blockchain = new_blockchain(network, &wallet_opts)?; + bdk_cli::handle_online_wallet_subcommand( + &wallet, + &blockchain, + online_subcommand, + ) } ReplSubCommand::OfflineWalletSubCommand(offline_subcommand) => { bdk_cli::handle_offline_wallet_subcommand( diff --git a/src/lib.rs b/src/lib.rs index 6cdb0bbe..8b106311 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,7 @@ //! //! let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet", "--descriptor", //! "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", -//! "sync", "--max_addresses", "50"]; +//! "sync"]; //! //! let cli_opts = CliOpts::from_iter(&cli_args); //! let network = cli_opts.network; @@ -61,23 +61,23 @@ //! //! let database = MemoryDatabase::new(); //! -//! let config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { -//! url: wallet_opts.electrum_opts.server, -//! socks5: wallet_opts.proxy_opts.proxy, -//! retry: wallet_opts.proxy_opts.retries, -//! timeout: None, -//! stop_gap: 10 -//! }); +//! let blockchain_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { +//! url: wallet_opts.electrum_opts.server.clone(), +//! socks5: wallet_opts.proxy_opts.proxy.clone(), +//! retry: wallet_opts.proxy_opts.retries, +//! timeout: wallet_opts.electrum_opts.timeout, +//! stop_gap: wallet_opts.electrum_opts.stop_gap, +//! }); +//! let blockchain = AnyBlockchain::from_config(&blockchain_config).expect("blockchain"); //! //! let wallet = Wallet::new( //! descriptor, //! change_descriptor, //! network, //! database, -//! AnyBlockchain::from_config(&config).unwrap(), -//! ).unwrap(); +//! ).expect("wallet"); //! -//! let result = bdk_cli::handle_online_wallet_subcommand(&wallet, online_subcommand).unwrap(); +//! let result = bdk_cli::handle_online_wallet_subcommand(&wallet, &blockchain, online_subcommand).expect("result"); //! println!("{}", serde_json::to_string_pretty(&result).unwrap()); //! } //! # } @@ -124,7 +124,15 @@ use bdk::bitcoin::secp256k1::Secp256k1; use bdk::bitcoin::util::bip32::{DerivationPath, ExtendedPrivKey, KeySource}; use bdk::bitcoin::util::psbt::PartiallySignedTransaction; use bdk::bitcoin::{Address, Network, OutPoint, Script, Txid}; -#[cfg(feature = "reserves")] +#[cfg(all( + feature = "reserves", + any( + feature = "electrum", + feature = "esplora", + feature = "compact_filters", + feature = "rpc" + ) +))] use bdk::blockchain::Capability; #[cfg(any( feature = "electrum", @@ -187,7 +195,7 @@ use bdk_reserves::reserves::ProofOfReserves; /// /// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet", /// "--descriptor", "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/44'/1'/0'/0/*)", -/// "sync", "--max_addresses", "50"]; +/// "sync"]; /// /// // to get CliOpts from the OS command line args use: /// // let cli_opts = CliOpts::from_args(); @@ -234,9 +242,7 @@ use bdk_reserves::reserves::ProofOfReserves; /// retries: 5, /// }, /// }, -/// subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync { -/// max_addresses: Some(50) -/// }), +/// subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync), /// }, /// }; /// @@ -800,11 +806,7 @@ blockchain client and network connection. ))] pub enum OnlineWalletSubCommand { /// Syncs with the chosen blockchain server - Sync { - /// max addresses to consider - #[structopt(short = "v", long = "max_addresses")] - max_addresses: Option, - }, + Sync, /// Broadcasts a transaction to the network. Takes either a raw transaction or a PSBT to extract Broadcast { /// Sets the PSBT to sign @@ -881,8 +883,8 @@ fn parse_outpoint(s: &str) -> Result { /// Execute an offline wallet sub-command /// /// Offline wallet sub-commands are described in [`OfflineWalletSubCommand`]. -pub fn handle_offline_wallet_subcommand( - wallet: &Wallet, +pub fn handle_offline_wallet_subcommand( + wallet: &Wallet, wallet_opts: &WalletOpts, offline_subcommand: OfflineWalletSubCommand, ) -> Result @@ -1082,17 +1084,25 @@ where feature = "rpc" ))] #[maybe_async] -pub fn handle_online_wallet_subcommand( - wallet: &Wallet, +pub fn handle_online_wallet_subcommand( + wallet: &Wallet, + blockchain: &B, online_subcommand: OnlineWalletSubCommand, ) -> Result where - C: Blockchain, + B: Blockchain, D: BatchDatabase, { + use bdk::SyncOptions; + match online_subcommand { - Sync { max_addresses } => { - maybe_await!(wallet.sync(log_progress(), max_addresses))?; + Sync => { + maybe_await!(wallet.sync( + blockchain, + SyncOptions { + progress: Some(Box::new(log_progress())), + } + ))?; Ok(json!({})) } Broadcast { psbt, tx } => { @@ -1106,9 +1116,8 @@ where (Some(_), Some(_)) => panic!("Both `psbt` and `tx` options not allowed"), (None, None) => panic!("Missing `psbt` and `tx` option"), }; - - let txid = maybe_await!(wallet.broadcast(&tx))?; - Ok(json!({ "txid": txid })) + maybe_await!(blockchain.broadcast(&tx))?; + Ok(json!({ "txid": tx.txid() })) } #[cfg(feature = "reserves")] ProduceProof { msg } => { @@ -1135,12 +1144,11 @@ where } => { let psbt = base64::decode(&psbt).unwrap(); let psbt: PartiallySignedTransaction = deserialize(&psbt).unwrap(); - let current_height = wallet.client().get_height()?; + let current_height = blockchain.get_height()?; let max_confirmation_height = if confirmations == 0 { None } else { - if !wallet - .client() + if !blockchain .get_capabilities() .contains(&Capability::GetAnyTx) { @@ -1420,10 +1428,8 @@ mod test { use bdk::miniscript::bitcoin::network::constants::Network::Testnet; #[cfg(all(feature = "reserves", feature = "electrum"))] use bdk::{ - blockchain::{noop_progress, ElectrumBlockchain}, - database::MemoryDatabase, - electrum_client::Client, - Wallet, + blockchain::ElectrumBlockchain, database::MemoryDatabase, electrum_client::Client, + SyncOptions, Wallet, }; use std::str::{self, FromStr}; use structopt::StructOpt; @@ -1691,7 +1697,7 @@ mod test { fn test_parse_wallet_sync() { let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet", "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)", - "sync", "--max_addresses", "50"]; + "sync"]; let cli_opts = CliOpts::from_iter(&cli_args); @@ -1736,9 +1742,7 @@ mod test { skip_blocks: None, }, }, - subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync { - max_addresses: Some(50) - }), + subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync), }, }; @@ -1965,7 +1969,7 @@ mod test { fn test_parse_wrong_network() { let cli_args = vec!["repl", "--network", "badnet", "wallet", "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)", - "sync", "--max_addresses", "50"]; + "sync"]; let cli_opts = CliOpts::from_iter_safe(&cli_args); assert!(cli_opts.is_err()); @@ -2280,16 +2284,16 @@ mod test { let message = "Those coins belong to Satoshi Nakamoto"; let client = Client::new("ssl://electrum.blockstream.info:60002").unwrap(); + let blockchain = ElectrumBlockchain::from(client); let wallet = Wallet::new( &descriptor, None, Network::Testnet, MemoryDatabase::default(), - ElectrumBlockchain::from(client), ) .unwrap(); - wallet.sync(noop_progress(), None).unwrap(); + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); let balance = wallet.get_balance().unwrap(); let addr = wallet.get_address(bdk::wallet::AddressIndex::New).unwrap(); @@ -2318,7 +2322,7 @@ mod test { } => online_subcommand, _ => panic!("unexpected subcommand"), }; - let result = handle_online_wallet_subcommand(&wallet, wallet_subcmd).unwrap(); + let result = handle_online_wallet_subcommand(&wallet, &blockchain, wallet_subcmd).unwrap(); let psbt: PartiallySignedTransaction = serde_json::from_str(&result.as_object().unwrap().get("psbt").unwrap().to_string()) .unwrap(); @@ -2356,7 +2360,7 @@ mod test { } => online_subcommand, _ => panic!("unexpected subcommand"), }; - let result = handle_online_wallet_subcommand(&wallet, wallet_subcmd).unwrap(); + let result = handle_online_wallet_subcommand(&wallet, &blockchain, wallet_subcmd).unwrap(); let spendable = result .as_object() .unwrap()