Sqlite,
}
-#[cfg(any(feature = "electrum", feature = "esplora",))]
+#[cfg(any(feature = "electrum", feature = "esplora", feature = "rpc"))]
#[derive(Clone, ValueEnum, Debug, Eq, PartialEq)]
pub enum ClientType {
#[cfg(feature = "electrum")]
Electrum,
#[cfg(feature = "esplora")]
Esplora,
+ #[cfg(feature = "rpc")]
+ RPC,
}
/// Config options wallet operations can take.
/// Sets the descriptor to use for internal/change addresses.
#[arg(env = "INT_DESCRIPTOR", short = 'i', long)]
pub int_descriptor: Option<String>,
- #[cfg(any(feature = "electrum", feature = "esplora",))]
+ #[cfg(any(feature = "electrum", feature = "esplora", feature = "rpc"))]
#[arg(env = "CLIENT_TYPE", short = 'c', long, value_enum, required = true)]
pub client_type: ClientType,
#[cfg(any(feature = "sqlite",))]
#[arg(env = "DATABASE_TYPE", short = 'd', long, value_enum, required = true)]
pub database_type: DatabaseType,
/// Sets the server url.
- #[cfg(any(feature = "electrum", feature = "esplora",))]
+ #[cfg(any(feature = "electrum", feature = "esplora", feature = "rpc"))]
#[arg(env = "SERVER_URL", short = 'u', long, required = true)]
pub url: String,
/// Electrum batch size.
- #[cfg(any(feature = "electrum"))]
+ #[cfg(feature = "electrum")]
#[arg(env = "ELECTRUM_BATCH_SIZE", short = 'b', long, default_value = "10")]
pub batch_size: usize,
/// Esplora parallel requests.
- #[cfg(any(feature = "esplora"))]
+ #[cfg(feature = "esplora")]
#[arg(
env = "ESPLORA_PARALLEL_REQUESTS",
short = 'p',
default_value = "5"
)]
pub parallel_requests: usize,
+ #[cfg(feature = "rpc")]
+ /// Sets the rpc basic authentication.
+ #[arg(
+ env = "USER:PASSWD",
+ short = 'a',
+ long,
+ value_parser = parse_proxy_auth,
+ default_value = "user:password",
+ )]
+ pub basic_auth: (String, String),
+
+ #[cfg(feature = "rpc")]
+ /// Sets an optional cookie authentication.
+ #[arg(name = "COOKIE", long)]
+ pub cookie: Option<String>
}
/// Options to configure a SOCKS5 proxy for a blockchain client connection.
pub skip_blocks: usize,
}
-/// Options to configure a bitcoin core rpc backend.
-#[cfg(feature = "rpc")]
-#[derive(Debug, Args, Clone, PartialEq, Eq)]
-pub struct RpcOpts {
- /// Sets the full node address for rpc connection.
- #[arg(
- env = "ADDRESS:PORT",
- long = "rpc-node",
- default_value = "127.0.0.1:18443"
- )]
- pub address: String,
-
- /// Sets the rpc basic authentication.
- #[arg(
- env = "USER:PASSWD",
- short = 'a',
- long = "rpc-basic-auth",
- value_parser = parse_proxy_auth,
- default_value = "user:password",
- )]
- pub basic_auth: (String, String),
-
- /// Sets an optional cookie authentication.
- #[arg(name = "COOKIE", short = 'c', long = "rpc-cookie")]
- pub cookie: Option<String>,
-
- /// Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
- #[arg(env = "RPC_START_TIME", long = "rpc-start-time", default_value = "0")]
- pub start_time: u64,
-}
-
-/// Options to configure electrum backend.
-#[cfg(feature = "electrum")]
-#[derive(Debug, Args, Clone, PartialEq, Eq)]
-pub struct ElectrumOpts {
- /// Sets the Electrum server to use.
- #[arg(
- env = "ELECTRUM_URL",
- short = 'e',
- long = "electrum",
- default_value = "ssl://electrum.blockstream.info:60002"
- )]
- pub server: String,
-
- /// Stop searching addresses for transactions after finding an unused gap of this length.
- #[arg(env = "ELECTRUM_BATCH_SIZE", long = "batch_size", default_value = "10")]
- pub batch_size: usize,
-}
-
-/// Options to configure Esplora backend.
-#[cfg(feature = "esplora")]
-#[derive(Debug, Args, Clone, PartialEq, Eq)]
-pub struct EsploraOpts {
- /// Use the esplora server if given as parameter.
- #[arg(
- env = "ESPLORA_URL",
- short = 's',
- long = "esplora",
- default_value = "https://blockstream.info/testnet/api/"
- )]
- pub server: String,
-
- /// Socket timeout.
- #[arg(env = "TIMEOUT", long = "timeout", default_value = "5")]
- pub timeout: u64,
-
- /// Number of parallel requests sent to the esplora service.
- #[arg(env = "CONCURRENCY", long = "esplora-conc", default_value = "4")]
- pub conc: u8,
-}
-
/// Wallet subcommands that can be issued without a blockchain backend.
#[derive(Debug, Subcommand, Clone, PartialEq)]
#[command(rename_all = "snake")]
/// Exit REPL loop.
Exit,
}
-
-// #[cfg(test)]
-// mod test {
-// use super::*;
-// #[cfg(feature = "compiler")]
-// use crate::handlers::handle_compile_subcommand;
-// use crate::handlers::handle_key_subcommand;
-// use bdk_wallet::bitcoin::bip32::{DerivationPath, Xpriv};
-// use bdk_wallet::bitcoin::{Address, Network, OutPoint};
-// use bdk_wallet::miniscript::bitcoin::network::Network::Testnet;
-// use std::str::{self, FromStr};
-//
-// use super::OfflineWalletSubCommand::{BumpFee, CreateTx, GetNewAddress};
-// #[cfg(any(
-// feature = "electrum",
-// feature = "esplora",
-// feature = "cbf",
-// feature = "rpc"
-// ))]
-// use super::OnlineWalletSubCommand::{Broadcast, Sync};
-// use super::WalletSubCommand::OfflineWalletSubCommand;
-// #[cfg(any(
-// feature = "electrum",
-// feature = "esplora",
-// feature = "cbf",
-// feature = "rpc"
-// ))]
-// use super::WalletSubCommand::OnlineWalletSubCommand;
-// #[cfg(feature = "repl")]
-// use regex::Regex;
-//
-// #[test]
-// fn test_clap_args() {
-// use clap::CommandFactory;
-// CliOpts::command().debug_assert();
-// }
-//
-// #[test]
-// fn test_parse_wallet_get_new_address() {
-// let cli_args = vec!["bdk-cli", "--network", "bitcoin", "wallet",
-// "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "get_new_address"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// #[cfg(feature = "electrum")]
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// #[cfg(feature = "esplora")]
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// #[cfg(feature = "cbf")]
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// #[cfg(any(feature="compact_filters", feature="electrum", feature="esplora"))]
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// #[cfg(feature = "rpc")]
-// rpc_opts: RpcOpts {
-// address: "127.0.0.1:18443".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: None,
-// start_time: 0,
-// },
-// },
-// subcommand: OfflineWalletSubCommand(GetNewAddress),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(feature = "electrum")]
-// #[test]
-// fn test_parse_wallet_electrum() {
-// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
-// "--proxy", "127.0.0.1:9150", "--retries", "3", "--timeout", "10",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "--server","ssl://electrum.blockstream.info:50002",
-// "--stop_gap", "20",
-// "get_new_address"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// electrum_opts: ElectrumOpts {
-// timeout: Some(10),
-// server: "ssl://electrum.blockstream.info:50002".to_string(),
-// stop_gap: 20
-// },
-// proxy_opts: ProxyOpts{
-// proxy: Some("127.0.0.1:9150".to_string()),
-// proxy_auth: None,
-// retries: 3,
-// },
-// },
-// subcommand: OfflineWalletSubCommand(GetNewAddress),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(feature = "esplora")]
-// #[test]
-// fn test_parse_wallet_esplora() {
-// let cli_args = vec!["bdk-cli", "--network", "bitcoin", "wallet",
-// "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "--server", "https://blockstream.info/api/",
-// "--conc", "10",
-// "--stop_gap", "20",
-// "get_new_address"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/api/".to_string(),
-// conc: 10,
-// stop_gap: 20,
-// timeout: 5,
-// },
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// }
-// },
-// subcommand: OfflineWalletSubCommand(GetNewAddress),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(feature = "rpc")]
-// #[test]
-// fn test_parse_wallet_rpc() {
-// let cli_args = vec!["bdk-cli", "--network", "bitcoin", "wallet",
-// "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "--node", "125.67.89.101:56678",
-// "--basic-auth", "user:password",
-// "--cookie", "/home/user/.bitcoin/regtest/.cookie",
-// "--start-time", "123456",
-// "get_new_address"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// rpc_opts: RpcOpts {
-// address: "125.67.89.101:56678".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: Some("/home/user/.bitcoin/regtest/.cookie".to_string()),
-// start_time: 123456,
-// },
-// },
-// subcommand: OfflineWalletSubCommand(GetNewAddress),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(feature = "cbf")]
-// #[test]
-// fn test_parse_wallet_compact_filters() {
-// let cli_args = vec!["bdk-cli", "--network", "bitcoin", "wallet",
-// "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "--proxy", "127.0.0.1:9005",
-// "--proxy_auth", "random_user:random_passwd",
-// "--node", "127.0.0.1:18444",
-// "--conn_count", "4",
-// "--skip_blocks", "5",
-// "get_new_address"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 5,
-// },
-// proxy_opts: ProxyOpts{
-// proxy: Some("127.0.0.1:9005".to_string()),
-// proxy_auth: Some(("random_user".to_string(), "random_passwd".to_string())),
-// retries: 5,
-// }
-// },
-// subcommand: OfflineWalletSubCommand(GetNewAddress),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(any(
-// feature = "electrum",
-// feature = "esplora",
-// feature = "cbf",
-// feature = "rpc"
-// ))]
-// #[test]
-// fn test_parse_wallet_sync() {
-// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "sync"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: None,
-// #[cfg(feature = "electrum")]
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// #[cfg(feature = "esplora")]
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// #[cfg(feature = "cbf")]
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// #[cfg(any(feature="compact_filters", feature="electrum", feature="esplora"))]
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// #[cfg(feature = "rpc")]
-// rpc_opts: RpcOpts {
-// address: "127.0.0.1:18443".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: None,
-// start_time: 0,
-// },
-// },
-// subcommand: OnlineWalletSubCommand(Sync),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[test]
-// fn test_parse_wallet_create_tx() {
-// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "create_tx", "--to", "n2Z3YNXtceeJhFkTknVaNjT1mnCGWesykJ:123456", "--to", "mjDZ34icH4V2k9GmC8niCrhzVuR3z8Mgkf:78910",
-// "--utxos","87345e46bfd702d24d54890cc094d08a005f773b27c8f965dfe0eb1e23eef88e:1",
-// "--utxos","87345e46bfd702d24d54890cc094d08a005f773b27c8f965dfe0eb1e23eef88e:2",
-// "--add_string","Hello BDK",
-// ];
-//
-// let cli_opts = CliOpts::parse_from(&cli_args);
-//
-// let script1 = Address::from_str("n2Z3YNXtceeJhFkTknVaNjT1mnCGWesykJ")
-// .unwrap()
-// .assume_checked()
-// .script_pubkey();
-//
-// let script2 = Address::from_str("mjDZ34icH4V2k9GmC8niCrhzVuR3z8Mgkf")
-// .unwrap()
-// .assume_checked()
-// .script_pubkey();
-//
-// let outpoint1 = OutPoint::from_str(
-// "87345e46bfd702d24d54890cc094d08a005f773b27c8f965dfe0eb1e23eef88e:1",
-// )
-// .unwrap();
-// let outpoint2 = OutPoint::from_str(
-// "87345e46bfd702d24d54890cc094d08a005f773b27c8f965dfe0eb1e23eef88e:2",
-// )
-// .unwrap();
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// #[cfg(feature = "electrum")]
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// #[cfg(feature = "esplora")]
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// #[cfg(feature = "cbf")]
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// #[cfg(any(feature="compact_filters", feature="electrum", feature="esplora"))]
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// #[cfg(feature = "rpc")]
-// rpc_opts: RpcOpts {
-// address: "127.0.0.1:18443".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: None,
-// start_time: 0,
-// },
-// },
-// subcommand: WalletSubCommand::OfflineWalletSubCommand(CreateTx {
-// recipients: vec![(script1, 123456), (script2, 78910)],
-// send_all: false,
-// enable_rbf: true,
-// offline_signer: false,
-// utxos: Some(vec!(outpoint1, outpoint2)),
-// unspendable: None,
-// fee_rate: None,
-// external_policy: None,
-// internal_policy: None,
-// add_data: None,
-// add_string: Some("Hello BDK".to_string()),
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[test]
-// fn test_parse_wallet_bump_fee() {
-// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "--change_descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
-// "bump_fee", "--fee_rate", "6.1",
-// "--txid","35aab0d0213f8996f9e236a28630319b93109754819e8abf48a0835708d33506",
-// "--shrink","tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt"];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: Some("wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-// #[cfg(feature = "electrum")]
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// #[cfg(feature = "esplora")]
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// #[cfg(feature = "cbf")]
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// #[cfg(feature = "rpc")]
-// rpc_opts: RpcOpts {
-// address: "127.0.0.1:18443".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: None,
-// start_time: 0,
-// },
-// #[cfg(any(feature="compact_filters", feature="electrum", feature="esplora"))]
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// }
-// },
-// subcommand: OfflineWalletSubCommand(BumpFee {
-// txid: "35aab0d0213f8996f9e236a28630319b93109754819e8abf48a0835708d33506".to_string(),
-// shrink_address: Some(Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap().assume_checked()),
-// offline_signer: false,
-// utxos: None,
-// unspendable: None,
-// fee_rate: 6.1
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(any(
-// feature = "electrum",
-// feature = "esplora",
-// feature = "cbf",
-// feature = "rpc"
-// ))]
-// #[test]
-// fn test_parse_wallet_broadcast() {
-// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "broadcast",
-// "--psbt", "cHNidP8BAEICAAAAASWhGE1AhvtO+2GjJHopssFmgfbq+WweHd8zN/DeaqmDAAAAAAD/////AQAAAAAAAAAABmoEAAECAwAAAAAAAAA="];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
-// change_descriptor: None,
-// #[cfg(feature = "electrum")]
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// #[cfg(feature = "esplora")]
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// #[cfg(feature = "cbf")]
-// cbf_opts: CompactFilterOpts{
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// #[cfg(any(feature="compact_filters", feature="electrum", feature="esplora"))]
-// proxy_opts: ProxyOpts{
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// #[cfg(feature = "rpc")]
-// rpc_opts: RpcOpts {
-// address: "127.0.0.1:18443".to_string(),
-// basic_auth: ("user".to_string(), "password".to_string()),
-// cookie: None,
-// start_time: 0,
-// },
-// },
-// subcommand: OnlineWalletSubCommand(Broadcast {
-// psbt: Some("cHNidP8BAEICAAAAASWhGE1AhvtO+2GjJHopssFmgfbq+WweHd8zN/DeaqmDAAAAAAD/////AQAAAAAAAAAABmoEAAECAwAAAAAAAAA=".to_string()),
-// tx: None
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[test]
-// fn test_parse_wrong_network() {
-// let cli_args = vec!["repl", "--network", "badnet", "wallet",
-// "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
-// "sync"];
-//
-// let cli_opts = CliOpts::from_iter_safe(&cli_args);
-// assert!(cli_opts.is_err());
-// }
-//
-// #[test]
-// fn test_key_generate() {
-// let network = Testnet;
-// let key_generate_cmd = KeySubCommand::Generate {
-// word_count: 12,
-// password: Some("test123".to_string()),
-// };
-//
-// let result = handle_key_subcommand(network, key_generate_cmd).unwrap();
-// let result_obj = result.as_object().unwrap();
-//
-// let mnemonic = result_obj.get("mnemonic").unwrap().as_str().unwrap();
-// let mnemonic: Vec<&str> = mnemonic.split(' ').collect();
-// let xprv = result_obj.get("xprv").unwrap().as_str().unwrap();
-//
-// assert_eq!(mnemonic.len(), 12);
-// assert_eq!(&xprv[0..4], "tprv");
-// }
-//
-// #[test]
-// fn test_key_restore() {
-// let network = Testnet;
-// let key_generate_cmd = KeySubCommand::Restore {
-// mnemonic: "payment battle unit sword token broccoli era violin purse trip blood hire"
-// .to_string(),
-// password: Some("test123".to_string()),
-// };
-//
-// let result = handle_key_subcommand(network, key_generate_cmd).unwrap();
-// let result_obj = result.as_object().unwrap();
-//
-// let fingerprint = result_obj.get("fingerprint").unwrap().as_str().unwrap();
-// let xprv = result_obj.get("xprv").unwrap().as_str().unwrap();
-//
-// assert_eq!(&fingerprint, &"828af366");
-// assert_eq!(&xprv, &"tprv8ZgxMBicQKsPd18TeiFknZKqaZFwpdX9tvvKh8eeHSSPBQi5g9xPHztBg411o78G8XkrhQb6Q1cVvBJ1a9xuFHpmWgvQsvkJkNxBjfGoqhK");
-// }
-//
-// #[test]
-// fn test_key_derive() {
-// let network = Testnet;
-// let key_generate_cmd = KeySubCommand::Derive {
-// xprv: Xpriv::from_str("tprv8ZgxMBicQKsPfQjJy8ge2cvBfDjLxJSkvNLVQiw7BQ5gTjKadG2rrcQB5zjcdaaUTz5EDNJaS77q4DzjqjogQBfMsaXFFNP3UqoBnwt2kyT").unwrap(),
-// path: DerivationPath::from_str("m/84'/1'/0'/0").unwrap(),
-// };
-//
-// let result = handle_key_subcommand(network, key_generate_cmd).unwrap();
-// let result_obj = result.as_object().unwrap();
-//
-// let xpub = result_obj.get("xpub").unwrap().as_str().unwrap();
-// let xprv = result_obj.get("xprv").unwrap().as_str().unwrap();
-//
-// assert_eq!(&xpub, &"[566844c5/84'/1'/0'/0]tpubDFeqiDkfwR1tAhPxsXSZMfEmfpDhwhLyhLKZgmeBvuBkZQusoWeL62oGg2oTNGcENeKdwuGepAB85eMvyLemabYe9PSqv6cr5mFXktHc3Ka/*");
-// assert_eq!(&xprv, &"[566844c5/84'/1'/0'/0]tprv8ixoZoiRo3LDHENAysmxxFaf6nhmnNA582inQFbtWdPMivf7B7pjuYBQVuLC5bkM7tJZEDbfoivENsGZPBnQg1n52Kuc1P8X2Ei3XJuJX7c/*");
-// }
-//
-// #[cfg(feature = "compiler")]
-// #[test]
-// fn test_parse_compile() {
-// let cli_args = vec![
-// "bdk-cli",
-// "compile",
-// "thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))",
-// "--type",
-// "sh-wsh",
-// ];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Testnet,
-// datadir: None,
-// subcommand: CliSubCommand::Compile {
-// policy: "thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))".to_string(),
-// script_type: "sh-wsh".to_string(),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(feature = "compiler")]
-// #[test]
-// fn test_compile() {
-// let result = handle_compile_subcommand(
-// Network::Testnet,
-// "thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))".to_string(),
-// "sh-wsh".to_string(),
-// )
-// .unwrap();
-// let result_obj = result.as_object().unwrap();
-//
-// let descriptor = result_obj.get("descriptor").unwrap().as_str().unwrap();
-// assert_eq!(
-// &descriptor,
-// &"sh(wsh(thresh(3,pk(Alice),s:pk(Bob),s:pk(Carol),snl:older(2))))#rmef3s78"
-// );
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "cbf"))]
-// #[test]
-// fn test_parse_produce_proof() {
-// let message = "Those coins belong to Satoshi Nakamoto";
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "wallet",
-// "--descriptor",
-// "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)",
-// "produce_proof",
-// "--message",
-// message.clone(),
-// ];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
-// .to_string(),
-// change_descriptor: None,
-// cbf_opts: CompactFilterOpts {
-// address: vec!["127.0.0.1:18444".to_string()],
-// conn_count: 4,
-// skip_blocks: 0,
-// },
-// proxy_opts: ProxyOpts {
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// },
-// subcommand: OnlineWalletSubCommand(ProduceProof {
-// msg: message.to_string(),
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "esplora-ureq"))]
-// #[test]
-// fn test_parse_verify_proof_internal() {
-// let psbt = r#"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"#;
-// let message = "Those coins belong to Satoshi Nakamoto";
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "wallet",
-// "--descriptor",
-// "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)",
-// "verify_proof",
-// "--psbt",
-// psbt.clone(),
-// "--message",
-// message.clone(),
-// ];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
-// .to_string(),
-// change_descriptor: None,
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// proxy_opts: ProxyOpts {
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// },
-// subcommand: OnlineWalletSubCommand(OnlineWalletSubCommand::VerifyProof {
-// psbt: psbt.to_string(),
-// msg: message.to_string(),
-// confirmations: 6,
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "esplora-ureq"))]
-// #[test]
-// fn test_parse_verify_proof_internal_confirmation() {
-// let psbt = r#"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"#;
-// let message = "Those coins belong to Satoshi Nakamoto";
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "wallet",
-// "--descriptor",
-// "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)",
-// "verify_proof",
-// "--psbt",
-// psbt.clone(),
-// "--message",
-// message.clone(),
-// "--confirmations",
-// "0",
-// ];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::Wallet {
-// wallet_opts: WalletOpts {
-// wallet: None,
-// verbose: false,
-// descriptor: "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
-// .to_string(),
-// change_descriptor: None,
-// esplora_opts: EsploraOpts {
-// server: "https://blockstream.info/testnet/api/".to_string(),
-// timeout: 5,
-// stop_gap: 10,
-// conc: 4,
-// },
-// proxy_opts: ProxyOpts {
-// proxy: None,
-// proxy_auth: None,
-// retries: 5,
-// },
-// },
-// subcommand: OnlineWalletSubCommand(OnlineWalletSubCommand::VerifyProof {
-// psbt: psbt.to_string(),
-// msg: message.to_string(),
-// confirmations: 0,
-// }),
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "electrum"))]
-// #[test]
-// fn test_parse_verify_proof_external() {
-// let psbt = r#"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"#.to_string();
-// let address = "tb1qanjjv4cs20dgv32vncrxw702l8g4qtn2m9wn7d".to_string();
-// let message = "Those coins belong to Satoshi Nakamoto".to_string();
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "external_reserves",
-// &message,
-// &psbt,
-// "6",
-// &address,
-// "--server",
-// "ssl://electrum.blockstream.info:60002",
-// ];
-//
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let expected_cli_opts = CliOpts {
-// network: Network::Bitcoin,
-// datadir: None,
-// subcommand: CliSubCommand::ExternalReserves {
-// message,
-// psbt,
-// confirmations: 6,
-// addresses: [address].to_vec(),
-// electrum_opts: ElectrumOpts {
-// timeout: None,
-// server: "ssl://electrum.blockstream.info:60002".to_string(),
-// stop_gap: 10,
-// },
-// },
-// };
-//
-// assert_eq!(expected_cli_opts, cli_opts);
-// }
-//
-// /// Encodes a partially signed transaction as base64 and returns the bytes of the resulting string.
-// #[cfg(all(feature = "reserves", feature = "electrum"))]
-// fn encode_psbt(psbt: Psbt) -> Vec<u8> {
-// let mut encoded = Vec::<u8>::new();
-// psbt.consensus_encode(&mut encoded).unwrap();
-// let base64_psbt = base64::encode(&encoded);
-//
-// base64_psbt.as_bytes().to_vec()
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "electrum"))]
-// #[test]
-// fn test_proof_of_reserves_wallet() {
-// let descriptor = "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string();
-// 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(),
-// )
-// .unwrap();
-//
-// wallet.sync(&blockchain, SyncOptions::default()).unwrap();
-// let balance = wallet.get_balance().unwrap();
-//
-// let addr = wallet
-// .get_address(bdk_wallet::wallet::AddressIndex::New)
-// .unwrap();
-// assert_eq!(
-// "tb1qanjjv4cs20dgv32vncrxw702l8g4qtn2m9wn7d",
-// addr.to_string()
-// );
-//
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "wallet",
-// "--descriptor",
-// &descriptor,
-// "produce_proof",
-// "--message",
-// message.clone(),
-// ];
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let wallet_subcmd = match cli_opts.subcommand {
-// CliSubCommand::Wallet {
-// wallet_opts: _,
-// subcommand: OnlineWalletSubCommand(online_subcommand),
-// } => online_subcommand,
-// _ => panic!("unexpected subcommand"),
-// };
-// 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();
-// let psbt = encode_psbt(psbt);
-// let psbt = str::from_utf8(&psbt).unwrap();
-// assert_eq!(format!("{}", psbt), "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");
-//
-// let psbt_b64 = &result
-// .as_object()
-// .unwrap()
-// .get("psbt_base64")
-// .unwrap()
-// .to_string();
-// assert_eq!(&format!("{}", psbt), psbt_b64.trim_matches('\"'));
-//
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "wallet",
-// "--descriptor",
-// &descriptor,
-// "verify_proof",
-// "--psbt",
-// psbt,
-// "--message",
-// message.clone(),
-// ];
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let wallet_subcmd = match cli_opts.subcommand {
-// CliSubCommand::Wallet {
-// wallet_opts: _,
-// subcommand: OnlineWalletSubCommand(online_subcommand),
-// } => online_subcommand,
-// _ => panic!("unexpected subcommand"),
-// };
-// let result = handle_online_wallet_subcommand(&wallet, &blockchain, wallet_subcmd).unwrap();
-// let spendable = result
-// .as_object()
-// .unwrap()
-// .get("spendable")
-// .unwrap()
-// .as_u64()
-// .unwrap();
-// assert_eq!(spendable, balance.get_spendable());
-// }
-//
-// #[cfg(all(feature = "reserves", feature = "electrum"))]
-// #[test]
-// fn test_proof_of_reserves_veryfy() {
-// let message = "Those coins belong to Satoshi Nakamoto";
-// let address = "tb1qanjjv4cs20dgv32vncrxw702l8g4qtn2m9wn7d";
-// let psbt = "cHNidP8BAKcBAAAAA9A7AuVMuwIrkAuXtKDqw3BruovK2PH7E90MzCbyaAMlAAAAAAD/////sq+79fxJ+5F8951Xcbp8N5VYVJoesG1zd3AxStcGwPYAAAAAAP/////AUS4n/SkO9SSvIv8MI2Xdm3xdn77Sud6uX5PyqCganAEAAAAA/////wGwrQEAAAAAABl2qRSff9CW037SwOP38M/JJL7vT/zraIisAAAAAAABAQoAAAAAAAAAAAFRAQcAAAEBHxAnAAAAAAAAFgAU7OUmVxBT2oZFTJ4GZ3nq+dFQLmoiAgMrBVgHi+w4aUqEkz1lkwPiV12ufpFoWRFFQRW/1kSH40gwRQIhAPgByvkajQrNeQDSGik2gnxpo/P/owiEHR+0nWefkXurAiBgrAlDvwuTiaGEEWQW/Kd7L7u7YOQnqvrd46DR0A8yPgEBBwABCGwCSDBFAiEA+AHK+RqNCs15ANIaKTaCfGmj8/+jCIQdH7SdZ5+Re6sCIGCsCUO/C5OJoYQRZBb8p3svu7tg5Ceq+t3joNHQDzI+ASEDKwVYB4vsOGlKhJM9ZZMD4lddrn6RaFkRRUEVv9ZEh+MAAQEfoIYBAAAAAAAWABTs5SZXEFPahkVMngZneer50VAuaiICAysFWAeL7DhpSoSTPWWTA+JXXa5+kWhZEUVBFb/WRIfjRzBEAiBSfiX0qP7vR+2Qx/mRJS8pwma8nTfOWKerzo6c0iSAfwIgEfX4Wt7YXd8MkKUEY627GWYCmKfMsJGcIC0U1wgc1vUBAQcAAQhrAkcwRAIgUn4l9Kj+70ftkMf5kSUvKcJmvJ03zlinq86OnNIkgH8CIBH1+Fre2F3fDJClBGOtuxlmApinzLCRnCAtFNcIHNb1ASEDKwVYB4vsOGlKhJM9ZZMD4lddrn6RaFkRRUEVv9ZEh+MAAA==";
-//
-// let cli_args = vec![
-// "bdk-cli",
-// "--network",
-// "bitcoin",
-// "external_reserves",
-// message,
-// psbt,
-// "6",
-// address,
-// address, // passing the address twice on purpose, to test passing of multiple addresses
-// "--server",
-// "ssl://electrum.blockstream.info:60002",
-// ];
-// let cli_opts = CliOpts::from_iter(&cli_args);
-//
-// let (message, psbt, confirmations, addresses, electrum_opts) = match cli_opts.subcommand {
-// CliSubCommand::ExternalReserves {
-// message,
-// psbt,
-// confirmations,
-// addresses,
-// electrum_opts,
-// } => (message, psbt, confirmations, addresses, electrum_opts),
-// _ => panic!("unexpected subcommand"),
-// };
-// let result = handle_ext_reserves_subcommand(
-// Network::Bitcoin,
-// message,
-// psbt,
-// confirmations,
-// addresses,
-// electrum_opts,
-// )
-// .unwrap();
-// let spendable = result
-// .as_object()
-// .unwrap()
-// .get("spendable")
-// .unwrap()
-// .as_u64()
-// .unwrap();
-// assert!(spendable > 0);
-// }
-//
-// #[cfg(feature = "repl")]
-// #[test]
-// fn test_regex_double_quotes() {
-// let split_regex = Regex::new(crate::REPL_LINE_SPLIT_REGEX).unwrap();
-// let line = r#"restore -m "word1 word2 word3" -p 'test! 123 -test' "#;
-// let split_line: Vec<&str> = split_regex
-// .captures_iter(&line)
-// .map(|c| {
-// c.get(1)
-// .or_else(|| c.get(2))
-// .or_else(|| c.get(3))
-// .unwrap()
-// .as_str()
-// })
-// .collect();
-// assert_eq!(
-// vec!(
-// "restore",
-// "-m",
-// "word1 word2 word3",
-// "-p",
-// "test! 123 -test"
-// ),
-// split_line
-// );
-// }
-//
-// #[cfg(feature = "repl")]
-// #[test]
-// fn test_regex_single_quotes() {
-// let split_regex = Regex::new(crate::REPL_LINE_SPLIT_REGEX).unwrap();
-// let line = r#"restore -m 'word1 word2 word3' -p "test *123 -test" "#;
-// let split_line: Vec<&str> = split_regex
-// .captures_iter(&line)
-// .map(|c| {
-// c.get(1)
-// .or_else(|| c.get(2))
-// .or_else(|| c.get(3))
-// .unwrap()
-// .as_str()
-// })
-// .collect();
-// assert_eq!(
-// vec!(
-// "restore",
-// "-m",
-// "word1 word2 word3",
-// "-p",
-// "test *123 -test"
-// ),
-// split_line
-// );
-// }
-// }