feat(etherscan): Allow `ClientBuilder` to create `Client` without API key (#2067)

Etherscan allows 1 request per 5 seconds if the API key is not defined
This commit is contained in:
Yiannis M 2023-01-22 23:08:33 +02:00 committed by GitHub
parent ea8c231834
commit 50ef8a78f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 7 deletions

View File

@ -34,7 +34,7 @@ pub struct Client {
/// Client that executes HTTP requests /// Client that executes HTTP requests
client: reqwest::Client, client: reqwest::Client,
/// Etherscan API key /// Etherscan API key
api_key: String, api_key: Option<String>,
/// Etherscan API endpoint like <https://api(-chain).etherscan.io/api> /// Etherscan API endpoint like <https://api(-chain).etherscan.io/api>
etherscan_api_url: Url, etherscan_api_url: Url,
/// Etherscan base endpoint like <https://etherscan.io> /// Etherscan base endpoint like <https://etherscan.io>
@ -235,7 +235,7 @@ impl Client {
other: T, other: T,
) -> Query<T> { ) -> Query<T> {
Query { Query {
apikey: Cow::Borrowed(&self.api_key), apikey: self.api_key.as_deref().map(Cow::Borrowed),
module: Cow::Borrowed(module), module: Cow::Borrowed(module),
action: Cow::Borrowed(action), action: Cow::Borrowed(action),
other, other,
@ -307,7 +307,7 @@ impl ClientBuilder {
/// Configures the etherscan api key /// Configures the etherscan api key
pub fn with_api_key(mut self, api_key: impl Into<String>) -> Self { pub fn with_api_key(mut self, api_key: impl Into<String>) -> Self {
self.api_key = Some(api_key.into()); self.api_key = Some(api_key.into()).filter(|s| !s.is_empty());
self self
} }
@ -321,7 +321,6 @@ impl ClientBuilder {
/// ///
/// # Errors /// # Errors
/// if required fields are missing: /// if required fields are missing:
/// - `api_key`
/// - `etherscan_api_url` /// - `etherscan_api_url`
/// - `etherscan_url` /// - `etherscan_url`
pub fn build(self) -> Result<Client> { pub fn build(self) -> Result<Client> {
@ -329,8 +328,7 @@ impl ClientBuilder {
let client = Client { let client = Client {
client: client.unwrap_or_default(), client: client.unwrap_or_default(),
api_key: api_key api_key,
.ok_or_else(|| EtherscanError::Builder("etherscan api key".to_string()))?,
etherscan_api_url: etherscan_api_url etherscan_api_url: etherscan_api_url
.ok_or_else(|| EtherscanError::Builder("etherscan api url".to_string()))?, .ok_or_else(|| EtherscanError::Builder("etherscan api url".to_string()))?,
etherscan_url: etherscan_url etherscan_url: etherscan_url
@ -434,7 +432,8 @@ pub enum ResponseData<T> {
/// The type that gets serialized as query /// The type that gets serialized as query
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
struct Query<'a, T: Serialize> { struct Query<'a, T: Serialize> {
apikey: Cow<'a, str>, #[serde(skip_serializing_if = "Option::is_none")]
apikey: Option<Cow<'a, str>>,
module: Cow<'a, str>, module: Cow<'a, str>,
action: Cow<'a, str>, action: Cow<'a, str>,
#[serde(flatten)] #[serde(flatten)]