async-interface = ["async-trait"]
electrum = ["electrum-client"]
# MUST ALSO USE `--no-default-features`.
-use-esplora-reqwest = ["esplora", "reqwest", "futures"]
-use-esplora-ureq = ["esplora", "ureq"]
+use-esplora-reqwest = ["esplora", "reqwest", "reqwest/socks", "futures"]
+use-esplora-ureq = ["esplora", "ureq", "ureq/socks"]
# Typical configurations will not need to use `esplora` feature directly.
esplora = []
///
/// eg. `https://blockstream.info/api/`
pub base_url: String,
+ /// Optional URL of the proxy to use to make requests to the Esplora server
+ ///
+ /// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
+ ///
+ /// Note that the format of this value and the supported protocols change slightly between the
+ /// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
+ /// details check with the documentation of the two crates. Both of them are compiled with
+ /// the `socks` feature enabled.
+ ///
+ /// The proxy is ignored when targeting `wasm32`.
+ pub proxy: Option<String>,
/// Number of parallel requests sent to the esplora service (default: 4)
pub concurrency: Option<u8>,
/// Stop searching addresses for transactions after finding an unused gap of this length.
type Config = EsploraBlockchainConfig;
fn from_config(config: &Self::Config) -> Result<Self, Error> {
+ let map_e = |e: reqwest::Error| Error::Esplora(Box::new(e.into()));
+
let mut blockchain = EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap);
if let Some(concurrency) = config.concurrency {
blockchain.url_client.concurrency = concurrency;
- };
+ }
+ #[cfg(not(target_arch = "wasm32"))]
+ if let Some(proxy) = &config.proxy {
+ blockchain.url_client.client = Client::builder()
+ .proxy(reqwest::Proxy::all(proxy).map_err(map_e)?)
+ .build()
+ .map_err(map_e)?;
+ }
Ok(blockchain)
}
}
#[allow(unused_imports)]
use log::{debug, error, info, trace};
-use ureq::{Agent, Response};
+use ureq::{Agent, Proxy, Response};
use bitcoin::consensus::{deserialize, serialize};
use bitcoin::hashes::hex::{FromHex, ToHex};
}
impl EsploraBlockchain {
- /// Create a new instance of the client from a base URL and `stop_gap`.
+ /// Create a new instance of the client from a base URL and the `stop_gap`.
pub fn new(base_url: &str, stop_gap: usize) -> Self {
EsploraBlockchain {
url_client: UrlClient {
pub struct EsploraBlockchainConfig {
/// Base URL of the esplora service eg. `https://blockstream.info/api/`
pub base_url: String,
+ /// Optional URL of the proxy to use to make requests to the Esplora server
+ ///
+ /// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
+ ///
+ /// Note that the format of this value and the supported protocols change slightly between the
+ /// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
+ /// details check with the documentation of the two crates. Both of them are compiled with
+ /// the `socks` feature enabled.
+ ///
+ /// The proxy is ignored when targeting `wasm32`.
+ pub proxy: Option<String>,
/// Socket read timeout.
pub timeout_read: u64,
/// Socket write timeout.
type Config = EsploraBlockchainConfig;
fn from_config(config: &Self::Config) -> Result<Self, Error> {
- let agent: Agent = ureq::AgentBuilder::new()
+ let mut agent_builder = ureq::AgentBuilder::new()
.timeout_read(Duration::from_secs(config.timeout_read))
- .timeout_write(Duration::from_secs(config.timeout_write))
- .build();
- Ok(EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap).with_agent(agent))
+ .timeout_write(Duration::from_secs(config.timeout_write));
+
+ if let Some(proxy) = &config.proxy {
+ agent_builder = agent_builder
+ .proxy(Proxy::new(proxy).map_err(|e| Error::Esplora(Box::new(e.into())))?);
+ }
+
+ Ok(
+ EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap)
+ .with_agent(agent_builder.build()),
+ )
}
}