]> Untitled Git - bdk-cli/commitdiff
Add ElectrumOpts and EsploraOpts structops; set no default dependencies
authorSteve Myers <steve@notmandatory.org>
Tue, 9 Feb 2021 03:16:01 +0000 (19:16 -0800)
committerSteve Myers <steve@notmandatory.org>
Tue, 9 Feb 2021 03:22:14 +0000 (19:22 -0800)
.github/workflows/cont_integration.yml
Cargo.toml
README.md
src/bdk_cli.rs
src/lib.rs

index c5e7536f539b28bc7d407e75a50a1937f521040e..d1c5203cfe9295d74bd5d377f0feae888e832364 100644 (file)
@@ -14,7 +14,10 @@ jobs:
           - 1.45.0 # MSRV
         features:
           - default
-          - default,esplora
+          - repl
+          - electrum
+          - esplora
+          - repl,electrum,esplora
     steps:
       - name: Checkout
         uses: actions/checkout@v2
index 1e09f81ac390d000224fbec70a6b12d544d12694..056f5121db39463b9d724b5d5091430656658039 100644 (file)
@@ -12,7 +12,7 @@ readme = "README.md"
 license = "MIT"
 
 [dependencies]
-bdk = { git = "https://github.com/bitcoindevkit/bdk.git", rev = "c4f2179", features = ["all-keys"]}
+bdk = { git = "https://github.com/bitcoindevkit/bdk.git", rev = "c4f2179", default-features = false, features = ["all-keys"]}
 bdk-macros = { git = "https://github.com/bitcoindevkit/bdk.git", rev = "c4f2179" }
 structopt = "^0.3"
 serde_json = { version = "^1.0" }
@@ -28,8 +28,8 @@ clap = { version = "2.33", optional = true }
 regex = {version = "1", optional = true }
 
 [features]
-default = ["repl", "electrum"]
-repl = ["async-trait", "rustyline", "dirs-next", "env_logger", "clap", "regex"]
+default = []
+repl = ["async-trait", "bdk/key-value-db", "clap", "dirs-next", "env_logger", "regex", "rustyline"]
 electrum = ["bdk/electrum"]
 esplora = ["bdk/esplora"]
 compiler = ["bdk/compiler"]
@@ -37,4 +37,7 @@ compiler = ["bdk/compiler"]
 [[bin]]
 name = "bdk-cli"
 path = "src/bdk_cli.rs"
-required-features = ["repl"]
+required-features = ["repl", "electrum"]
+
+[package.metadata.docs.rs]
+all-features = true
index 46deea397c881705dc342a2a15097b31ae581c5a..e5d4886bfdd54e658055d2e9ad5b3c44d0622097 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,23 +14,32 @@ To get usage information for the `bdk-cli` bin use the below command which retur
 available wallet options and commands:
 
 ```shell
-cargo run
+cargo run --features repl,electrum
 ```
 
 To sync a wallet to the default electrum server:
 
 ```shell
-cargo run -- wallet --descriptor "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)" sync
+cargo run --features repl,electrum,esplora -- wallet --descriptor "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)" sync
 ```
 
 To get a wallet balance with customized logging:
 
 ```shell
-RUST_LOG=debug,sled=info,rustls=info cargo run -- wallet --descriptor "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)" get_balance
+RUST_LOG=debug,sled=info,rustls=info cargo run --features repl,electrum,esplora -- wallet --descriptor "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)" get_balance
 ```
 
 To generate a new extended master key, suitable for using in a descriptor:
 
 ```shell
-cargo run -- key generate
+cargo run --features repl,electrum -- key generate
+```
+
+To install dev version of `bdk-cli` from local git repo:
+
+```shell
+cd <bdk-cli git repo directory>
+cargo install --path . --features repl,electrum,esplora
+
+bdk-cli help # to verify it worked
 ```
\ No newline at end of file
index 80661c77c5631171c4e4d88ee309bc0f3f018e79..4e63b1a51bc6eec0b87a2a2362a21eb910d9c2f3 100644 (file)
@@ -100,8 +100,8 @@ where
     // Try to use Esplora config if "esplora" feature is enabled
     #[cfg(feature = "esplora")]
     let config_esplora: Option<AnyBlockchainConfig> = {
-        let esplora_concurrency = wallet_opts.esplora_concurrency;
-        wallet_opts.esplora.clone().map(|base_url| {
+        let esplora_concurrency = wallet_opts.esplora_opts.esplora_concurrency;
+        wallet_opts.esplora_opts.esplora.clone().map(|base_url| {
             AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
                 base_url,
                 concurrency: Some(esplora_concurrency),
@@ -112,10 +112,10 @@ where
     let config_esplora = None;
 
     let config_electrum = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
-        url: wallet_opts.electrum.clone(),
-        socks5: wallet_opts.proxy.clone(),
-        retry: wallet_opts.retries,
-        timeout: wallet_opts.timeout,
+        url: wallet_opts.electrum_opts.electrum.clone(),
+        socks5: wallet_opts.electrum_opts.proxy.clone(),
+        retry: wallet_opts.electrum_opts.retries,
+        timeout: wallet_opts.electrum_opts.timeout,
     });
 
     // Fall back to Electrum config if Esplora config isn't provided
index 75089f4c7c80a74b584ec3a80027d1ed5e76cdbc..7eaab7275720fca3bbd12cd70d1c70c6c288a931 100644 (file)
@@ -40,7 +40,9 @@
 //!
 //! # Example
 //!
-//! ```
+//! ```no_run
+//! # #[cfg(feature = "electrum")]
+//! # {
 //! # use bdk::bitcoin::Network;
 //! # use bdk::blockchain::{AnyBlockchain, ConfigurableBlockchain};
 //! # use bdk::blockchain::{AnyBlockchainConfig, ElectrumBlockchainConfig};
@@ -72,8 +74,8 @@
 //!     let database = MemoryDatabase::new();
 //!
 //!     let config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
-//!                 url: wallet_opts.electrum,
-//!                 socks5: wallet_opts.proxy,
+//!                 url: wallet_opts.electrum_opts.electrum,
+//!                 socks5: wallet_opts.electrum_opts.proxy,
 //!                 retry: 3,
 //!                 timeout: None,
 //!             });
@@ -89,6 +91,7 @@
 //!     let result = bdk_cli::handle_online_wallet_subcommand(&wallet, online_subcommand).unwrap();
 //!     println!("{}", serde_json::to_string_pretty(&result).unwrap());
 //! }
+//! # }
 //! ```
 
 pub extern crate bdk;
@@ -131,6 +134,10 @@ use bdk::{FeeRate, KeychainKind, Wallet};
 /// # use bdk::bitcoin::Network;
 /// # use structopt::StructOpt;
 /// # use bdk_cli::{CliOpts, WalletOpts, CliSubCommand, WalletSubCommand};
+/// # #[cfg(feature = "electrum")]
+/// # use bdk_cli::ElectrumOpts;
+/// # #[cfg(feature = "esplora")]
+/// # use bdk_cli::EsploraOpts;
 /// # use bdk_cli::OnlineWalletSubCommand::Sync;
 ///
 /// let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
@@ -148,18 +155,18 @@ use bdk::{FeeRate, KeychainKind, Wallet};
 ///                     wallet: "main".to_string(),
 ///                     descriptor: "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/44'/1'/0'/0/*)".to_string(),
 ///                     change_descriptor: None,
-///                     #[cfg(feature = "electrum")]
-///                     proxy: None,
-///                     #[cfg(feature = "electrum")]
-///                     retries: 5,
-///                     #[cfg(feature = "electrum")]
-///                     timeout: None,
-///                     #[cfg(feature = "electrum")]
-///                     electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-///                     #[cfg(feature = "esplora")]
-///                     esplora: None,
-///                     #[cfg(feature = "esplora")]
-///                     esplora_concurrency: 4,
+///               #[cfg(feature = "electrum")]
+///               electrum_opts: ElectrumOpts {
+///                   proxy: None,
+///                   retries: 5,
+///                   timeout: None,
+///                   electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+///               },
+///               #[cfg(feature = "esplora")]
+///               esplora_opts: EsploraOpts {               
+///                   esplora: None,
+///                   esplora_concurrency: 4,
+///               }
 ///                 },
 ///                 subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync {
 ///                     max_addresses: Some(50)
@@ -237,7 +244,7 @@ pub enum WalletSubCommand {
 /// Wallet options
 ///
 /// The wallet options required for all [`CliSubCommand::Wallet`] or [`CliSubCommand::Repl`]
-/// sub-commands. These options capture wallet descriptor and blockchain client information. The \
+/// sub-commands. These options capture wallet descriptor and blockchain client information. The
 /// blockchain client details are only used for [`OnlineWalletSubCommand`]s.   
 ///
 /// # Example
@@ -245,7 +252,11 @@ pub enum WalletSubCommand {
 /// ```
 /// # use bdk::bitcoin::Network;
 /// # use structopt::StructOpt;
-/// # use bdk_cli:: WalletOpts;
+/// # use bdk_cli::WalletOpts;
+/// # #[cfg(feature = "electrum")]
+/// # use bdk_cli::ElectrumOpts;
+/// # #[cfg(feature = "esplora")]
+/// # use bdk_cli::EsploraOpts;
 ///
 /// let cli_args = vec!["wallet",
 ///                     "--descriptor", "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/44'/1'/0'/0/*)"];
@@ -260,17 +271,17 @@ pub enum WalletSubCommand {
 ///               descriptor: "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/44'/1'/0'/0/*)".to_string(),
 ///               change_descriptor: None,
 ///               #[cfg(feature = "electrum")]
-///               proxy: None,
-///               #[cfg(feature = "electrum")]
-///               retries: 5,
-///               #[cfg(feature = "electrum")]
-///               timeout: None,
-///               #[cfg(feature = "electrum")]
-///               electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-///               #[cfg(feature = "esplora")]               
-///               esplora: None,
+///               electrum_opts: ElectrumOpts {
+///                   proxy: None,
+///                   retries: 5,
+///                   timeout: None,
+///                   electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+///               },
 ///               #[cfg(feature = "esplora")]
-///               esplora_concurrency: 4,
+///               esplora_opts: EsploraOpts {               
+///                   esplora: None,
+///                   esplora_concurrency: 4,
+///               }
 /// };
 ///
 /// assert_eq!(expected_wallet_opts, wallet_opts);
@@ -291,12 +302,24 @@ pub struct WalletOpts {
     /// Sets the descriptor to use for internal addresses
     #[structopt(name = "CHANGE_DESCRIPTOR", short = "c", long = "change_descriptor")]
     pub change_descriptor: Option<String>,
-    /// Sets the SOCKS5 proxy for the Electrum client
     #[cfg(feature = "electrum")]
+    #[structopt(flatten)]
+    pub electrum_opts: ElectrumOpts,
+    #[cfg(feature = "esplora")]
+    #[structopt(flatten)]
+    pub esplora_opts: EsploraOpts,
+}
+
+/// Electrum options
+///
+/// Electrum blockchain client information used by [`OnlineWalletSubCommand`]s.
+#[cfg(feature = "electrum")]
+#[derive(Debug, StructOpt, Clone, PartialEq)]
+pub struct ElectrumOpts {
+    /// Sets the SOCKS5 proxy for the Electrum client
     #[structopt(name = "PROXY_SERVER:PORT", short = "p", long = "proxy")]
     pub proxy: Option<String>,
     /// Sets the SOCKS5 proxy retries for the Electrum client
-    #[cfg(feature = "electrum")]
     #[structopt(
         name = "PROXY_RETRIES",
         short = "r",
@@ -305,11 +328,9 @@ pub struct WalletOpts {
     )]
     pub retries: u8,
     /// Sets the SOCKS5 proxy timeout for the Electrum client
-    #[cfg(feature = "electrum")]
     #[structopt(name = "PROXY_TIMEOUT", short = "t", long = "timeout")]
     pub timeout: Option<u8>,
     /// Sets the Electrum server to use
-    #[cfg(feature = "electrum")]
     #[structopt(
         name = "SERVER:PORT",
         short = "s",
@@ -317,12 +338,18 @@ pub struct WalletOpts {
         default_value = "ssl://electrum.blockstream.info:60002"
     )]
     pub electrum: String,
+}
+
+/// Esplora options
+///
+/// Esplora blockchain client information used by [`OnlineWalletSubCommand`]s.
+#[cfg(feature = "esplora")]
+#[derive(Debug, StructOpt, Clone, PartialEq)]
+pub struct EsploraOpts {
     /// Use the esplora server if given as parameter
-    #[cfg(feature = "esplora")]
     #[structopt(name = "ESPLORA_URL", short = "e", long = "esplora")]
     pub esplora: Option<String>,
     /// Concurrency of requests made to the esplora server
-    #[cfg(feature = "esplora")]
     #[structopt(
         name = "ESPLORA_CONCURRENCY",
         long = "esplora_concurrency",
@@ -359,6 +386,11 @@ To capture wallet sub-commands from a string vector without a preceeding binary
 create a custom struct the includes the `NoBinaryName` clap setting and wraps the WalletSubCommand
 enum. See also the [`bdk-cli`](https://github.com/bitcoindevkit/bdk-cli/blob/master/src/bdkcli.rs)
 example app.
+"#
+)]
+#[cfg_attr(
+    all(doc, feature = "repl"),
+    doc = r#"
 
 # Example
 ```
@@ -836,9 +868,14 @@ pub fn handle_key_subcommand(
 #[cfg(test)]
 mod test {
     use super::{CliOpts, WalletOpts};
+    #[cfg(feature = "electrum")]
+    use crate::ElectrumOpts;
+    #[cfg(feature = "esplora")]
+    use crate::EsploraOpts;
     use crate::OfflineWalletSubCommand::{CreateTx, GetNewAddress};
     use crate::OnlineWalletSubCommand::{Broadcast, Sync};
     use crate::{handle_key_subcommand, CliSubCommand, KeySubCommand, WalletSubCommand};
+
     use bdk::bitcoin::{Address, Network, OutPoint};
     use bdk::miniscript::bitcoin::network::constants::Network::Testnet;
     use std::str::FromStr;
@@ -861,17 +898,17 @@ mod test {
                     descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
                     #[cfg(feature = "electrum")]
-                    proxy: None,
-                    #[cfg(feature = "electrum")]
-                    retries: 5,
-                    #[cfg(feature = "electrum")]
-                    timeout: None,
-                    #[cfg(feature = "electrum")]
-                    electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-                    #[cfg(feature = "esplora")]
-                    esplora: None,
+                    electrum_opts: ElectrumOpts {
+                        proxy: None,
+                        retries: 5,
+                        timeout: None,
+                        electrum: "ssl://electrum.blockstream.info:60002".to_string()
+                    },
                     #[cfg(feature = "esplora")]
-                    esplora_concurrency: 4
+                    esplora_opts: EsploraOpts {
+                        esplora: None,
+                        esplora_concurrency: 4
+                    },
                 },
                 subcommand: WalletSubCommand::OfflineWalletSubCommand(GetNewAddress),
             },
@@ -899,14 +936,18 @@ mod test {
                     wallet: "main".to_string(),
                     descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: Some("wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
-                    proxy: Some("127.0.0.1:9150".to_string()),
-                    retries: 3,
-                    timeout: Some(10),
-                    electrum: "ssl://electrum.blockstream.info:50002".to_string(),
-                    #[cfg(feature = "esplora")]
-                    esplora: None,
+                    #[cfg(feature = "electrum")]
+                    electrum_opts: ElectrumOpts {
+                        proxy: Some("127.0.0.1:9150".to_string()),
+                        retries: 3,
+                        timeout: Some(10),
+                        electrum: "ssl://electrum.blockstream.info:50002".to_string(),
+                    },
                     #[cfg(feature = "esplora")]
-                    esplora_concurrency: 4,
+                    esplora_opts: EsploraOpts {
+                        esplora: None,
+                        esplora_concurrency: 4,
+                    }
                 },
                 subcommand: WalletSubCommand::OfflineWalletSubCommand(GetNewAddress),
             },
@@ -935,15 +976,17 @@ mod test {
                     descriptor: "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: Some("wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
                     #[cfg(feature = "electrum")]
-                    proxy: None,
-                    #[cfg(feature = "electrum")]
-                    retries: 5,
-                    #[cfg(feature = "electrum")]
-                    timeout: None,
-                    #[cfg(feature = "electrum")]
-                    electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-                    esplora: Some("https://blockstream.info/api/".to_string()),
-                    esplora_concurrency: 5,
+                    electrum_opts: ElectrumOpts {
+                        proxy: None,
+                        retries: 5,
+                        timeout: None,
+                        electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+                    },
+                    #[cfg(feature = "esplora")]
+                    esplora_opts: EsploraOpts {
+                        esplora: Some("https://blockstream.info/api/".to_string()),
+                        esplora_concurrency: 5,
+                    }
                 },
                 subcommand: WalletSubCommand::OfflineWalletSubCommand(GetNewAddress),
             },
@@ -968,17 +1011,17 @@ mod test {
                     descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: None,
                     #[cfg(feature = "electrum")]
-                    proxy: None,
-                    #[cfg(feature = "electrum")]
-                    retries: 5,
-                    #[cfg(feature = "electrum")]
-                    timeout: None,
-                    #[cfg(feature = "electrum")]
-                    electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-                    #[cfg(feature = "esplora")]
-                    esplora: None,
+                    electrum_opts: ElectrumOpts {
+                        proxy: None,
+                        retries: 5,
+                        timeout: None,
+                        electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+                    },
                     #[cfg(feature = "esplora")]
-                    esplora_concurrency: 4,
+                    esplora_opts: EsploraOpts {
+                        esplora: None,
+                        esplora_concurrency: 4,
+                    }
                 },
                 subcommand: WalletSubCommand::OnlineWalletSubCommand(Sync {
                     max_addresses: Some(50)
@@ -1023,17 +1066,17 @@ mod test {
                     descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: Some("wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)".to_string()),
                     #[cfg(feature = "electrum")]
-                    proxy: None,
-                    #[cfg(feature = "electrum")]
-                    retries: 5,
-                    #[cfg(feature = "electrum")]
-                    timeout: None,
-                    #[cfg(feature = "electrum")]
-                    electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-                    #[cfg(feature = "esplora")]
-                    esplora: None,
+                    electrum_opts: ElectrumOpts {
+                        proxy: None,
+                        retries: 5,
+                        timeout: None,
+                        electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+                    },
                     #[cfg(feature = "esplora")]
-                    esplora_concurrency: 4,
+                    esplora_opts: EsploraOpts {
+                        esplora: None,
+                        esplora_concurrency: 4,
+                    }
                 },
                 subcommand: WalletSubCommand::OfflineWalletSubCommand(CreateTx {
                     recipients: vec![(script1, 123456), (script2, 78910)],
@@ -1069,17 +1112,17 @@ mod test {
                     descriptor: "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)".to_string(),
                     change_descriptor: None,
                     #[cfg(feature = "electrum")]
-                    proxy: None,
-                    #[cfg(feature = "electrum")]
-                    retries: 5,
-                    #[cfg(feature = "electrum")]
-                    timeout: None,
-                    #[cfg(feature = "electrum")]
-                    electrum: "ssl://electrum.blockstream.info:60002".to_string(),
-                    #[cfg(feature = "esplora")]
-                    esplora: None,
+                    electrum_opts: ElectrumOpts {
+                        proxy: None,
+                        retries: 5,
+                        timeout: None,
+                        electrum: "ssl://electrum.blockstream.info:60002".to_string(),
+                    },
                     #[cfg(feature = "esplora")]
-                    esplora_concurrency: 4,
+                    esplora_opts: EsploraOpts {
+                        esplora: None,
+                        esplora_concurrency: 4,
+                    }
                 },
                 subcommand: WalletSubCommand::OnlineWalletSubCommand(Broadcast {
                     psbt: Some("cHNidP8BAEICAAAAASWhGE1AhvtO+2GjJHopssFmgfbq+WweHd8zN/DeaqmDAAAAAAD/////AQAAAAAAAAAABmoEAAECAwAAAAAAAAA=".to_string()),