From d5df3d0c739e1022006aef8c52a4562aa5fc6852 Mon Sep 17 00:00:00 2001 From: benthecarman Date: Fri, 18 Jul 2025 13:34:47 -0500 Subject: [PATCH] Add option to include headers in Esplora config This is useful if the esplora server has a form of authentication in front of it --- src/builder.rs | 44 ++++++++++++++++++++++++++++++++++++++++++-- src/chain/mod.rs | 18 ++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 66b160e31..30a1649d2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -87,6 +87,7 @@ const LSPS_HARDENED_CHILD_INDEX: u32 = 577; enum ChainDataSourceConfig { Esplora { server_url: String, + headers: HashMap, sync_config: Option, }, Electrum { @@ -294,9 +295,28 @@ impl NodeBuilder { /// information. pub fn set_chain_source_esplora( &mut self, server_url: String, sync_config: Option, + ) -> &mut Self { + self.chain_data_source_config = Some(ChainDataSourceConfig::Esplora { + server_url, + headers: Default::default(), + sync_config, + }); + self + } + + /// Configures the [`Node`] instance to source its chain data from the given Esplora server. + /// + /// The given `headers` will be included in all requests to the Esplora server, typically used for + /// authentication purposes. + /// + /// If no `sync_config` is given, default values are used. See [`EsploraSyncConfig`] for more + /// information. + pub fn set_chain_source_esplora_with_headers( + &mut self, server_url: String, headers: HashMap, + sync_config: Option, ) -> &mut Self { self.chain_data_source_config = - Some(ChainDataSourceConfig::Esplora { server_url, sync_config }); + Some(ChainDataSourceConfig::Esplora { server_url, headers, sync_config }); self } @@ -754,6 +774,24 @@ impl ArcedNodeBuilder { self.inner.write().unwrap().set_chain_source_esplora(server_url, sync_config); } + /// Configures the [`Node`] instance to source its chain data from the given Esplora server. + /// + /// The given `headers` will be included in all requests to the Esplora server, typically used for + /// authentication purposes. + /// + /// If no `sync_config` is given, default values are used. See [`EsploraSyncConfig`] for more + /// information. + pub fn set_chain_source_esplora_with_headers( + &self, server_url: String, headers: HashMap, + sync_config: Option, + ) { + self.inner.write().unwrap().set_chain_source_esplora_with_headers( + server_url, + headers, + sync_config, + ); + } + /// Configures the [`Node`] instance to source its chain data from the given Electrum server. /// /// If no `sync_config` is given, default values are used. See [`ElectrumSyncConfig`] for more @@ -1117,10 +1155,11 @@ fn build_with_store_internal( )); let chain_source = match chain_data_source_config { - Some(ChainDataSourceConfig::Esplora { server_url, sync_config }) => { + Some(ChainDataSourceConfig::Esplora { server_url, headers, sync_config }) => { let sync_config = sync_config.unwrap_or(EsploraSyncConfig::default()); Arc::new(ChainSource::new_esplora( server_url.clone(), + headers.clone(), sync_config, Arc::clone(&wallet), Arc::clone(&fee_estimator), @@ -1187,6 +1226,7 @@ fn build_with_store_internal( let sync_config = EsploraSyncConfig::default(); Arc::new(ChainSource::new_esplora( server_url.clone(), + HashMap::new(), sync_config, Arc::clone(&wallet), Arc::clone(&fee_estimator), diff --git a/src/chain/mod.rs b/src/chain/mod.rs index c3d5fdedc..2f8eeaac4 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -233,21 +233,31 @@ pub(crate) enum ChainSource { impl ChainSource { pub(crate) fn new_esplora( - server_url: String, sync_config: EsploraSyncConfig, onchain_wallet: Arc, - fee_estimator: Arc, tx_broadcaster: Arc, - kv_store: Arc, config: Arc, logger: Arc, - node_metrics: Arc>, + server_url: String, headers: HashMap, sync_config: EsploraSyncConfig, + onchain_wallet: Arc, fee_estimator: Arc, + tx_broadcaster: Arc, kv_store: Arc, config: Arc, + logger: Arc, node_metrics: Arc>, ) -> Self { // FIXME / TODO: We introduced this to make `bdk_esplora` work separately without updating // `lightning-transaction-sync`. We should revert this as part of of the upgrade to LDK 0.2. let mut client_builder_0_11 = esplora_client_0_11::Builder::new(&server_url); client_builder_0_11 = client_builder_0_11.timeout(DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS); + + for (header_name, header_value) in &headers { + client_builder_0_11 = client_builder_0_11.header(header_name, header_value); + } + let esplora_client_0_11 = client_builder_0_11.build_async().unwrap(); let tx_sync = Arc::new(EsploraSyncClient::from_client(esplora_client_0_11, Arc::clone(&logger))); let mut client_builder = esplora_client::Builder::new(&server_url); client_builder = client_builder.timeout(DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS); + + for (header_name, header_value) in &headers { + client_builder = client_builder.header(header_name, header_value); + } + let esplora_client = client_builder.build_async().unwrap(); let onchain_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);