use super::{GasCategory, GasOracle, GasOracleError, Result};
use async_trait::async_trait;
use ethers_core::types::U256;
use ethers_etherscan::Client;
use std::ops::{Deref, DerefMut};
#[derive(Clone, Debug)]
#[must_use]
pub struct Etherscan {
client: Client,
gas_category: GasCategory,
}
impl Deref for Etherscan {
type Target = Client;
fn deref(&self) -> &Self::Target {
&self.client
}
}
impl DerefMut for Etherscan {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.client
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl GasOracle for Etherscan {
async fn fetch(&self) -> Result<U256> {
match self.gas_category {
GasCategory::SafeLow | GasCategory::Standard | GasCategory::Fast => {}
GasCategory::Fastest => return Err(GasOracleError::GasCategoryNotSupported),
}
let result = self.query().await?;
let gas_price = match self.gas_category {
GasCategory::SafeLow => result.safe_gas_price,
GasCategory::Standard => result.propose_gas_price,
GasCategory::Fast => result.fast_gas_price,
_ => unreachable!(),
};
Ok(gas_price)
}
async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> {
Err(GasOracleError::Eip1559EstimationNotSupported)
}
}
impl Etherscan {
pub fn new(client: Client) -> Self {
Etherscan { client, gas_category: GasCategory::Standard }
}
pub fn category(mut self, gas_category: GasCategory) -> Self {
self.gas_category = gas_category;
self
}
pub async fn query(&self) -> Result<ethers_etherscan::gas::GasOracle> {
Ok(self.client.gas_oracle().await?)
}
}