From 7931dbd62e04afa540d5d8c4f1a5b97081c1a99b Mon Sep 17 00:00:00 2001 From: Rahamath-Unnisa Date: Mon, 20 Oct 2025 14:45:29 +0000 Subject: [PATCH 1/5] Added validate_domain in electrum option --- src/commands.rs | 14 +++++++++++--- src/handlers.rs | 10 ++++++---- src/utils.rs | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 62a6a2d..3086228 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -12,7 +12,8 @@ //! All optional args are defined in the structs below. //! All subcommands are defined in the below enums. -#![allow(clippy::large_enum_variant)] + +#[allow(clippy::large_enum_variant)] use bdk_wallet::bitcoin::{ Address, Network, OutPoint, ScriptBuf, @@ -186,6 +187,10 @@ pub struct WalletOpts { #[cfg(feature = "electrum")] #[arg(env = "ELECTRUM_BATCH_SIZE", short = 'b', long, default_value = "10")] pub batch_size: usize, + ///Electrum validate domain option. + #[cfg(feature = "electrum")] + #[arg(env="VALIDATE_DOMAIN",long = "validate-domain", action = clap::ArgAction::Set, default_value_t = true)] + pub validate_domain: bool, /// Esplora parallel requests. #[cfg(feature = "esplora")] #[arg( @@ -396,8 +401,11 @@ pub enum OnlineWalletSubCommand { stop_gap: usize, }, /// Syncs with the chosen blockchain server. - Sync, - /// Broadcasts a transaction to the network. Takes either a raw transaction or a PSBT to extract. + Sync { + #[command(flatten)] + wallet_opts: WalletOpts, + }, + Broadcast { /// Sets the PSBT to sign. #[arg( diff --git a/src/handlers.rs b/src/handlers.rs index 941c550..ce34da5 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -9,7 +9,7 @@ //! Command Handlers //! //! This module describes all the command handling logic used by bdk-cli. - + use crate::debug; use crate::commands::OfflineWalletSubCommand::*; use crate::commands::*; use crate::error::BDKCliError as Error; @@ -619,7 +619,7 @@ pub(crate) async fn handle_online_wallet_subcommand( }); match client { #[cfg(feature = "electrum")] - Electrum { client, batch_size } => { + Electrum { client, batch_size,validate_domain } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client @@ -694,15 +694,16 @@ pub(crate) async fn handle_online_wallet_subcommand( let pc = (100 * progress.consumed()) as f32 / progress.total() as f32; eprintln!("[ SCANNING {pc:03.0}% ] {item}"); }); + match client { #[cfg(feature = "electrum")] - Electrum { client, batch_size } => { + Electrum { client, batch_size, validate_domain } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client .populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx)); - let update = client.sync(request, batch_size, false)?; + let update = client.sync(request, batch_size, validate_domain)?; wallet.apply_update(update)?; } #[cfg(feature = "esplora")] @@ -788,6 +789,7 @@ pub(crate) async fn handle_online_wallet_subcommand( Electrum { client, batch_size: _, + validate_domain, } => client .transaction_broadcast(&tx) .map_err(|e| Error::Generic(e.to_string()))?, diff --git a/src/utils.rs b/src/utils.rs index cb81074..7bcc69d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -127,6 +127,7 @@ pub(crate) enum BlockchainClient { Electrum { client: Box>, batch_size: usize, + validate_domain: bool, }, #[cfg(feature = "esplora")] Esplora { @@ -164,6 +165,7 @@ pub(crate) fn new_blockchain_client( BlockchainClient::Electrum { client: Box::new(client), batch_size: wallet_opts.batch_size, + validate_domain: wallet_opts.validate_domain, } } #[cfg(feature = "esplora")] From a2f59544388de97be65d081f4833ca7d32429a58 Mon Sep 17 00:00:00 2001 From: Rahamath-Unnisa Date: Thu, 23 Oct 2025 10:44:43 +0000 Subject: [PATCH 2/5] Clean up commands.rs and handlers.rs per review comments --- src/commands.rs | 6 ++---- src/handlers.rs | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 3086228..2f21af2 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -12,9 +12,7 @@ //! All optional args are defined in the structs below. //! All subcommands are defined in the below enums. - -#[allow(clippy::large_enum_variant)] - +#![allow(clippy::large_enum_variant)] use bdk_wallet::bitcoin::{ Address, Network, OutPoint, ScriptBuf, bip32::{DerivationPath, Xpriv}, @@ -401,7 +399,7 @@ pub enum OnlineWalletSubCommand { stop_gap: usize, }, /// Syncs with the chosen blockchain server. - Sync { + Sync { #[command(flatten)] wallet_opts: WalletOpts, }, diff --git a/src/handlers.rs b/src/handlers.rs index ce34da5..78138fd 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -9,7 +9,6 @@ //! Command Handlers //! //! This module describes all the command handling logic used by bdk-cli. - use crate::debug; use crate::commands::OfflineWalletSubCommand::*; use crate::commands::*; use crate::error::BDKCliError as Error; @@ -619,7 +618,11 @@ pub(crate) async fn handle_online_wallet_subcommand( }); match client { #[cfg(feature = "electrum")] - Electrum { client, batch_size,validate_domain } => { + Electrum { + client, + batch_size, + validate_domain: _, + } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client @@ -686,7 +689,7 @@ pub(crate) async fn handle_online_wallet_subcommand( } Ok(serde_json::to_string_pretty(&json!({}))?) } - Sync => { + sync => { #[cfg(any(feature = "electrum", feature = "esplora"))] let request = wallet .start_sync_with_revealed_spks() @@ -697,13 +700,17 @@ pub(crate) async fn handle_online_wallet_subcommand( match client { #[cfg(feature = "electrum")] - Electrum { client, batch_size, validate_domain } => { + Electrum { + client, + batch_size, + validate_domain, + } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client .populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx)); - let update = client.sync(request, batch_size, validate_domain)?; + let update = client.sync(request, batch_size, false)?; wallet.apply_update(update)?; } #[cfg(feature = "esplora")] From 80e132ff6320d89ca5901546cf3452992daf69a7 Mon Sep 17 00:00:00 2001 From: Rahamath-Unnisa Date: Sat, 25 Oct 2025 16:26:02 +0000 Subject: [PATCH 3/5] Added validate-domain option config in utils.rs and made changes required to that. --- Cargo.lock | 1 + Cargo.toml | 1 + src/utils.rs | 14 +++++++------- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ff8e29..e6a476d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,7 @@ dependencies = [ "clap", "cli-table", "dirs", + "electrum-client", "env_logger", "log", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d5767f3..c063c30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ bdk_redb = { version = "0.1.0", optional = true } shlex = { version = "1.3.0", optional = true } tracing = "0.1.41" tracing-subscriber = "0.3.20" +electrum-client = "0.24.0" [features] default = ["repl", "sqlite"] diff --git a/src/utils.rs b/src/utils.rs index 7bcc69d..25a036b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -9,19 +9,18 @@ //! Utility Tools //! //! This module includes all the utility tools used by the App. -use crate::error::BDKCliError as Error; -use std::fmt::Display; -use std::str::FromStr; - -use std::path::{Path, PathBuf}; - use crate::commands::WalletOpts; +use crate::error::BDKCliError as Error; #[cfg(feature = "cbf")] use bdk_kyoto::{ BuilderExt, Info, LightClient, Receiver, ScanType::Sync, UnboundedReceiver, Warning, builder::Builder, }; use bdk_wallet::bitcoin::{Address, Network, OutPoint, ScriptBuf}; +use electrum_client::ConfigBuilder; +use std::fmt::Display; +use std::path::{Path, PathBuf}; +use std::str::FromStr; #[cfg(any( feature = "electrum", @@ -160,7 +159,8 @@ pub(crate) fn new_blockchain_client( let client = match wallet_opts.client_type { #[cfg(feature = "electrum")] ClientType::Electrum => { - let client = bdk_electrum::electrum_client::Client::new(url) + let config = ConfigBuilder::new().validate_domain(true).build(); + let client = bdk_electrum::electrum_client::Client::from_config(url, config) .map(bdk_electrum::BdkElectrumClient::new)?; BlockchainClient::Electrum { client: Box::new(client), From 31a3fbf4223c9458d15a2213524faafe6bb31c72 Mon Sep 17 00:00:00 2001 From: Rahamath-Unnisa Date: Tue, 28 Oct 2025 12:32:07 +0000 Subject: [PATCH 4/5] modified utils.rs to add configurations --- src/utils.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils.rs b/src/utils.rs index 25a036b..8ae39ce 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -159,7 +159,9 @@ pub(crate) fn new_blockchain_client( let client = match wallet_opts.client_type { #[cfg(feature = "electrum")] ClientType::Electrum => { - let config = ConfigBuilder::new().validate_domain(true).build(); + let config = ConfigBuilder::new() + .validate_domain(wallet_opts.validate_domain) + .build(); let client = bdk_electrum::electrum_client::Client::from_config(url, config) .map(bdk_electrum::BdkElectrumClient::new)?; BlockchainClient::Electrum { From 818a744bb09b2b8cb1ef5c85379ee5da2aeb6d74 Mon Sep 17 00:00:00 2001 From: Rahamath-Unnisa Date: Mon, 3 Nov 2025 15:17:19 +0000 Subject: [PATCH 5/5] fix(electrum): always enable domain validation internally Signed-off-by: Rahamath-Unnisa --- Cargo.lock | 1 - Cargo.toml | 6 ++---- src/commands.rs | 4 ---- src/handlers.rs | 13 ++----------- src/utils.rs | 8 ++------ 5 files changed, 6 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6a476d..4ff8e29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,7 +190,6 @@ dependencies = [ "clap", "cli-table", "dirs", - "electrum-client", "env_logger", "log", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index c063c30..f31d3be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,18 +21,16 @@ serde_json = "1.0" thiserror = "2.0.11" tokio = { version = "1", features = ["full"] } cli-table = "0.5.0" - +bdk_electrum = { version = "0.23.0", optional = true } # Optional dependencies bdk_bitcoind_rpc = { version = "0.21.0", features = ["std"], optional = true } -bdk_electrum = { version = "0.23.0", optional = true } + bdk_esplora = { version = "0.22.1", features = ["async-https", "tokio"], optional = true } bdk_kyoto = { version = "0.15.1", optional = true } bdk_redb = { version = "0.1.0", optional = true } shlex = { version = "1.3.0", optional = true } tracing = "0.1.41" tracing-subscriber = "0.3.20" -electrum-client = "0.24.0" - [features] default = ["repl", "sqlite"] diff --git a/src/commands.rs b/src/commands.rs index 2f21af2..545b0e0 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -185,10 +185,6 @@ pub struct WalletOpts { #[cfg(feature = "electrum")] #[arg(env = "ELECTRUM_BATCH_SIZE", short = 'b', long, default_value = "10")] pub batch_size: usize, - ///Electrum validate domain option. - #[cfg(feature = "electrum")] - #[arg(env="VALIDATE_DOMAIN",long = "validate-domain", action = clap::ArgAction::Set, default_value_t = true)] - pub validate_domain: bool, /// Esplora parallel requests. #[cfg(feature = "esplora")] #[arg( diff --git a/src/handlers.rs b/src/handlers.rs index 78138fd..b6e401b 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -618,11 +618,7 @@ pub(crate) async fn handle_online_wallet_subcommand( }); match client { #[cfg(feature = "electrum")] - Electrum { - client, - batch_size, - validate_domain: _, - } => { + Electrum { client, batch_size } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client @@ -700,11 +696,7 @@ pub(crate) async fn handle_online_wallet_subcommand( match client { #[cfg(feature = "electrum")] - Electrum { - client, - batch_size, - validate_domain, - } => { + Electrum { client, batch_size } => { // Populate the electrum client's transaction cache so it doesn't re-download transaction we // already have. client @@ -796,7 +788,6 @@ pub(crate) async fn handle_online_wallet_subcommand( Electrum { client, batch_size: _, - validate_domain, } => client .transaction_broadcast(&tx) .map_err(|e| Error::Generic(e.to_string()))?, diff --git a/src/utils.rs b/src/utils.rs index 8ae39ce..a2961ed 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -11,13 +11,13 @@ //! This module includes all the utility tools used by the App. use crate::commands::WalletOpts; use crate::error::BDKCliError as Error; +use bdk_electrum::electrum_client::ConfigBuilder; #[cfg(feature = "cbf")] use bdk_kyoto::{ BuilderExt, Info, LightClient, Receiver, ScanType::Sync, UnboundedReceiver, Warning, builder::Builder, }; use bdk_wallet::bitcoin::{Address, Network, OutPoint, ScriptBuf}; -use electrum_client::ConfigBuilder; use std::fmt::Display; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -126,7 +126,6 @@ pub(crate) enum BlockchainClient { Electrum { client: Box>, batch_size: usize, - validate_domain: bool, }, #[cfg(feature = "esplora")] Esplora { @@ -159,15 +158,12 @@ pub(crate) fn new_blockchain_client( let client = match wallet_opts.client_type { #[cfg(feature = "electrum")] ClientType::Electrum => { - let config = ConfigBuilder::new() - .validate_domain(wallet_opts.validate_domain) - .build(); + let config = ConfigBuilder::new().build(); let client = bdk_electrum::electrum_client::Client::from_config(url, config) .map(bdk_electrum::BdkElectrumClient::new)?; BlockchainClient::Electrum { client: Box::new(client), batch_size: wallet_opts.batch_size, - validate_domain: wallet_opts.validate_domain, } } #[cfg(feature = "esplora")]