ethers_middleware/gas_oracle/
mod.rs1pub mod blocknative;
2pub use blocknative::BlockNative;
3
4pub mod eth_gas_station;
5#[allow(deprecated)]
6pub use eth_gas_station::EthGasStation;
7
8pub mod etherchain;
9pub use etherchain::Etherchain;
10
11#[cfg(feature = "etherscan")]
12pub mod etherscan;
13#[cfg(feature = "etherscan")]
14pub use etherscan::Etherscan;
15
16pub mod middleware;
17pub use middleware::{GasOracleMiddleware, MiddlewareError};
18
19pub mod median;
20pub use median::Median;
21
22pub mod cache;
23pub use cache::Cache;
24
25pub mod polygon;
26pub use polygon::Polygon;
27
28pub mod gas_now;
29pub use gas_now::GasNow;
30
31pub mod provider_oracle;
32pub use provider_oracle::ProviderOracle;
33
34use async_trait::async_trait;
35use auto_impl::auto_impl;
36use ethers_core::types::U256;
37use reqwest::Error as ReqwestError;
38use std::{error::Error, fmt::Debug};
39use thiserror::Error;
40
41pub(crate) const GWEI_TO_WEI: u64 = 1_000_000_000;
42pub(crate) const GWEI_TO_WEI_U256: U256 = U256([GWEI_TO_WEI, 0, 0, 0]);
43
44pub type Result<T, E = GasOracleError> = std::result::Result<T, E>;
45
46#[derive(Clone, Copy, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
48pub enum GasCategory {
49 SafeLow,
50 #[default]
51 Standard,
52 Fast,
53 Fastest,
54}
55
56#[derive(Debug, Error)]
58pub enum GasOracleError {
59 #[error(transparent)]
62 HttpClientError(#[from] ReqwestError),
63
64 #[error(transparent)]
66 SerdeJsonError(#[from] serde_json::Error),
67
68 #[error("invalid oracle response")]
70 InvalidResponse,
71
72 #[error(transparent)]
75 #[cfg(feature = "etherscan")]
76 EtherscanError(#[from] ethers_etherscan::errors::EtherscanError),
77
78 #[error("gas category not supported")]
81 GasCategoryNotSupported,
82
83 #[error("EIP-1559 gas estimation not supported")]
84 Eip1559EstimationNotSupported,
85
86 #[error("None of the oracles returned a value")]
87 NoValues,
88
89 #[error("Chain is not supported by the oracle")]
90 UnsupportedChain,
91
92 #[error("Provider error: {0}")]
94 ProviderError(#[from] Box<dyn Error + Send + Sync>),
95 #[error("Failed to parse gas values: {0}")]
96 ConversionError(#[from] ethers_core::utils::ConversionError),
97}
98
99#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
115#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
116#[auto_impl(&, Box, Arc)]
117pub trait GasOracle: Send + Sync + Debug {
118 async fn fetch(&self) -> Result<U256>;
135
136 async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)>;
154}
155
156#[inline]
157#[doc(hidden)]
158pub fn from_gwei_f64(gwei: f64) -> U256 {
159 U256::from((gwei * GWEI_TO_WEI as f64).ceil() as u64)
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn test_gwei_wei_constants() {
168 let as_u256: U256 = GWEI_TO_WEI.into();
169 assert_eq!(as_u256, GWEI_TO_WEI_U256);
170 assert_eq!(GWEI_TO_WEI_U256.as_u64(), GWEI_TO_WEI);
171 }
172
173 #[test]
174 fn test_gwei_conversion() {
175 let max_priority_fee: f64 = 1.8963421368;
176
177 let result = from_gwei_f64(max_priority_fee);
178 assert_eq!(result, U256::from(1896342137));
179 }
180}