Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions crates/explorers/block-explorers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ pub struct ClientBuilder {
etherscan_url: Option<Url>,
/// Path to where ABI files should be cached
cache: Option<Cache>,
/// Whether to disable system proxy detection in the default HTTP client.
/// Ignored when a custom client is set via [`with_client`](Self::with_client).
no_proxy: bool,
}

// === impl ClientBuilder ===
Expand Down Expand Up @@ -300,6 +303,19 @@ impl ClientBuilder {
self
}

/// Disables automatic system proxy detection in the default HTTP client.
///
/// Mirrors [`reqwest::ClientBuilder::no_proxy`]. Useful in sandboxed
/// environments where `reqwest`'s system proxy lookup can panic (for
/// example on macOS when `SCDynamicStore` returns NULL).
///
/// Has no effect when a custom client is supplied via
/// [`with_client`](Self::with_client).
pub fn no_proxy(mut self) -> Self {
self.no_proxy = true;
self
}

/// Configures the Etherscan api url
///
/// # Errors
Expand Down Expand Up @@ -330,10 +346,17 @@ impl ClientBuilder {
/// - `etherscan_api_url`
/// - `etherscan_url`
pub fn build(self) -> Result<Client> {
let ClientBuilder { client, api_key, etherscan_api_url, etherscan_url, cache } = self;
let ClientBuilder { client, api_key, etherscan_api_url, etherscan_url, cache, no_proxy } =
self;

let client = match client {
Some(c) => c,
None if no_proxy => reqwest::Client::builder().no_proxy().build()?,
Comment thread
mablr marked this conversation as resolved.
None => reqwest::Client::default(),
};

let client = Client {
client: client.unwrap_or_default(),
client,
api_key,
etherscan_api_url: etherscan_api_url
.clone()
Expand Down Expand Up @@ -568,6 +591,12 @@ mod tests {
assert!(matches!(err, EtherscanError::LocalNetworksNotSupported));
}

#[test]
fn builder_no_proxy_builds() {
let client = Client::builder().chain(Chain::mainnet()).unwrap().no_proxy().build().unwrap();
assert_eq!(client.etherscan_url.as_str(), "https://etherscan.io/");
}

#[test]
fn can_parse_etherscan_mainnet_invalid_api_key() {
let err = serde_json::json!({
Expand Down
Loading