From b3510b7c8f81309fb5f10c7a9e832eed5ae414e4 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 17:43:21 +0200 Subject: [PATCH 1/8] enhance trace --- crates/block-explorers/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index dcd896a..417c3d6 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -196,6 +196,8 @@ impl Client { if self.chain_id.is_some() && !self.url_contains_chainid() { post_query.insert("chainid", self.chain_id.unwrap()); + + trace!(target: "etherscan", "QUERY {:?}", post_query); } let response = self From 22b825f061d2ebb34092ec2a4f2c9711791c06dd Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 17:59:59 +0200 Subject: [PATCH 2/8] only insert chain id as query parameter if Etherscan --- crates/block-explorers/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 417c3d6..58f4a99 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -192,9 +192,15 @@ impl Client { async fn post(&self, form: &F) -> Result { trace!(target: "etherscan", "POST {}", self.etherscan_api_url); + let is_etherscan = Url::parse(ETHERSCAN_V2_API_BASE_URL) + .map_err(|_| EtherscanError::Builder("Bad URL Parse".into()))?; + let mut post_query = HashMap::new(); - if self.chain_id.is_some() && !self.url_contains_chainid() { + if self.etherscan_api_url == is_etherscan + && self.chain_id.is_some() + && !self.url_contains_chainid() + { post_query.insert("chainid", self.chain_id.unwrap()); trace!(target: "etherscan", "QUERY {:?}", post_query); From 4198763c488d64edeaa351b1e2ea2e6f3546772f Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 18:02:17 +0200 Subject: [PATCH 3/8] nit --- crates/block-explorers/src/lib.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 58f4a99..7874b5d 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -192,15 +192,9 @@ impl Client { async fn post(&self, form: &F) -> Result { trace!(target: "etherscan", "POST {}", self.etherscan_api_url); - let is_etherscan = Url::parse(ETHERSCAN_V2_API_BASE_URL) - .map_err(|_| EtherscanError::Builder("Bad URL Parse".into()))?; - let mut post_query = HashMap::new(); - if self.etherscan_api_url == is_etherscan - && self.chain_id.is_some() - && !self.url_contains_chainid() - { + if self.is_etherscan() && self.chain_id.is_some() && !self.url_contains_chainid() { post_query.insert("chainid", self.chain_id.unwrap()); trace!(target: "etherscan", "QUERY {:?}", post_query); @@ -265,6 +259,10 @@ impl Client { } } + fn is_etherscan(&self) -> bool { + self.etherscan_api_url == Url::parse(ETHERSCAN_V2_API_BASE_URL).unwrap() + } + fn url_contains_chainid(&self) -> bool { self.etherscan_api_url.query_pairs().any(|(key, _)| key.eq_ignore_ascii_case("chainid")) } From ab990121c487f624627449b9ca595ccb93b79e79 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 18:04:47 +0200 Subject: [PATCH 4/8] nit --- crates/block-explorers/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 7874b5d..0ef19e9 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -260,7 +260,10 @@ impl Client { } fn is_etherscan(&self) -> bool { - self.etherscan_api_url == Url::parse(ETHERSCAN_V2_API_BASE_URL).unwrap() + Url::parse(ETHERSCAN_V2_API_BASE_URL) + .ok() + .map(|url| self.etherscan_api_url == url) + .unwrap_or(false) } fn url_contains_chainid(&self) -> bool { From 967a002350c8336b9b077df5dec6136f69f5a8f8 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 18:10:12 +0200 Subject: [PATCH 5/8] nits --- crates/block-explorers/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 0ef19e9..2d4324f 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -197,7 +197,7 @@ impl Client { if self.is_etherscan() && self.chain_id.is_some() && !self.url_contains_chainid() { post_query.insert("chainid", self.chain_id.unwrap()); - trace!(target: "etherscan", "QUERY {:?}", post_query); + trace!(target: "etherscan", "POST QUERY {:?}", post_query); } let response = self @@ -260,10 +260,7 @@ impl Client { } fn is_etherscan(&self) -> bool { - Url::parse(ETHERSCAN_V2_API_BASE_URL) - .ok() - .map(|url| self.etherscan_api_url == url) - .unwrap_or(false) + self.etherscan_api_url.as_str().contains(ETHERSCAN_V2_API_BASE_URL) } fn url_contains_chainid(&self) -> bool { From df2c46c040ee1fd647adb5eefef4f03290c874ca Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 28 Aug 2025 18:23:23 +0200 Subject: [PATCH 6/8] etherscan_api_urls are now postfixed with chainid in alloy-chains --- crates/block-explorers/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 2d4324f..4b14ec8 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -300,17 +300,14 @@ impl ClientBuilder { ) -> (reqwest::Result, reqwest::Result) { (api.into_url(), url.into_url()) } - let (_, etherscan_url) = chain + let (etherscan_api_url, etherscan_url) = chain .named() .ok_or_else(|| EtherscanError::ChainNotSupported(chain))? .etherscan_urls() .map(urls) .ok_or_else(|| EtherscanError::ChainNotSupported(chain))?; - let etherscan_api_url = Url::parse(ETHERSCAN_V2_API_BASE_URL) - .map_err(|_| EtherscanError::Builder("Bad URL Parse".into()))?; - - self.with_chain_id(chain).with_api_url(etherscan_api_url)?.with_url(etherscan_url?) + self.with_chain_id(chain).with_api_url(etherscan_api_url?)?.with_url(etherscan_url?) } /// Configures the Etherscan url From 3ed2567097a17cbea3032f37db38a9a3b05e0cf6 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Fri, 29 Aug 2025 13:21:03 +0200 Subject: [PATCH 7/8] drop chain_id, it is now consistently part of alloy-chains etherscan urls --- crates/block-explorers/src/lib.rs | 42 ++----------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 4b14ec8..74c4c3c 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -24,7 +24,6 @@ use reqwest::{header, IntoUrl, Url}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{ borrow::Cow, - collections::HashMap, io::Write, path::PathBuf, time::{Duration, SystemTime, UNIX_EPOCH}, @@ -61,8 +60,6 @@ pub struct Client { etherscan_url: Url, /// Path to where ABI files should be cached cache: Option, - /// Chain ID - chain_id: Option, } impl Client { @@ -192,19 +189,10 @@ impl Client { async fn post(&self, form: &F) -> Result { trace!(target: "etherscan", "POST {}", self.etherscan_api_url); - let mut post_query = HashMap::new(); - - if self.is_etherscan() && self.chain_id.is_some() && !self.url_contains_chainid() { - post_query.insert("chainid", self.chain_id.unwrap()); - - trace!(target: "etherscan", "POST QUERY {:?}", post_query); - } - let response = self .client .post(self.etherscan_api_url.clone()) .form(form) - .query(&post_query) .send() .await? .text() @@ -254,18 +242,9 @@ impl Client { apikey: self.api_key.as_deref().map(Cow::Borrowed), module: Cow::Borrowed(module), action: Cow::Borrowed(action), - chain_id: if self.url_contains_chainid() { None } else { self.chain_id }, other, } } - - fn is_etherscan(&self) -> bool { - self.etherscan_api_url.as_str().contains(ETHERSCAN_V2_API_BASE_URL) - } - - fn url_contains_chainid(&self) -> bool { - self.etherscan_api_url.query_pairs().any(|(key, _)| key.eq_ignore_ascii_case("chainid")) - } } #[derive(Clone, Debug, Default)] @@ -280,8 +259,6 @@ pub struct ClientBuilder { etherscan_url: Option, /// Path to where ABI files should be cached cache: Option, - /// Chain ID - chain_id: Option, } // === impl ClientBuilder === @@ -307,7 +284,7 @@ impl ClientBuilder { .map(urls) .ok_or_else(|| EtherscanError::ChainNotSupported(chain))?; - self.with_chain_id(chain).with_api_url(etherscan_api_url?)?.with_url(etherscan_url?) + self.with_api_url(etherscan_api_url?)?.with_url(etherscan_url?) } /// Configures the Etherscan url @@ -348,17 +325,6 @@ impl ClientBuilder { self } - /// Configures the chain id for Etherscan verification: - pub fn with_chain_id(mut self, chain: Chain) -> Self { - self.chain_id = Some(chain.id()); - self - } - - /// Returns the chain the client is built on. - pub fn get_chain(&self) -> Option { - self.chain_id.map(Chain::from_id) - } - /// Returns a Client that uses this ClientBuilder configuration. /// /// # Errors @@ -367,8 +333,7 @@ impl ClientBuilder { /// - `etherscan_api_url` /// - `etherscan_url` pub fn build(self) -> Result { - let ClientBuilder { client, api_key, etherscan_api_url, etherscan_url, cache, chain_id } = - self; + let ClientBuilder { client, api_key, etherscan_api_url, etherscan_url, cache } = self; let client = Client { client: client.unwrap_or_default(), @@ -379,7 +344,6 @@ impl ClientBuilder { etherscan_url: etherscan_url .ok_or_else(|| EtherscanError::Builder("etherscan url".to_string()))?, cache, - chain_id, }; Ok(client) } @@ -507,8 +471,6 @@ struct Query<'a, T: Serialize> { apikey: Option>, module: Cow<'a, str>, action: Cow<'a, str>, - #[serde(rename = "chainId", skip_serializing_if = "Option::is_none")] - chain_id: Option, #[serde(flatten)] other: T, } From c5b9dcffa5a13c258d627d215ec1263a7ae30d6c Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Fri, 29 Aug 2025 14:31:21 +0200 Subject: [PATCH 8/8] fix test, goerli was deprecated: ref https://github.com/alloy-rs/chains/pull/196; use sepolia instead - note the inclusion of chainid parameter in returned url --- crates/block-explorers/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 74c4c3c..15fa365 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -530,9 +530,12 @@ mod tests { #[test] fn test_api_paths() { - let client = Client::new(Chain::goerli(), "").unwrap(); - assert_eq!(client.etherscan_api_url.as_str(), "https://api.etherscan.io/v2/api"); - assert_eq!(client.block_url(100), "https://goerli.etherscan.io/block/100"); + let client = Client::new(Chain::sepolia(), "").unwrap(); + assert_eq!( + client.etherscan_api_url.as_str(), + "https://api.etherscan.io/v2/api?chainid=11155111" + ); + assert_eq!(client.block_url(100), "https://sepolia.etherscan.io/block/100"); } #[test]