parent
cb46b1afed
commit
b96c73ac3b
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
### Unreleased
|
### Unreleased
|
||||||
|
|
||||||
|
- Removes GasNow as a gas price oracle [#508](https://github.com/gakonst/ethers-rs/pull/508)
|
||||||
|
|
||||||
### 0.5.3
|
### 0.5.3
|
||||||
|
|
||||||
- Added Time Lagged middleware [#457](https://github.com/gakonst/ethers-rs/pull/457)
|
- Added Time Lagged middleware [#457](https://github.com/gakonst/ethers-rs/pull/457)
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub enum Frequency {
|
||||||
/// use ethers_providers::{Provider, Http};
|
/// use ethers_providers::{Provider, Http};
|
||||||
/// use ethers_middleware::{
|
/// use ethers_middleware::{
|
||||||
/// gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
|
/// gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
|
||||||
/// gas_oracle::{GasNow, GasCategory, GasOracleMiddleware},
|
/// gas_oracle::{EthGasStation, GasCategory, GasOracleMiddleware},
|
||||||
/// };
|
/// };
|
||||||
/// use std::{convert::TryFrom, time::Duration, sync::Arc};
|
/// use std::{convert::TryFrom, time::Duration, sync::Arc};
|
||||||
///
|
///
|
||||||
|
@ -61,7 +61,7 @@ pub enum Frequency {
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// // ... proceed to wrap it in other middleware
|
/// // ... proceed to wrap it in other middleware
|
||||||
/// let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
|
/// let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow);
|
||||||
/// let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
/// let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
||||||
/// ```
|
/// ```
|
||||||
pub struct GasEscalatorMiddleware<M, E> {
|
pub struct GasEscalatorMiddleware<M, E> {
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
use ethers_core::types::U256;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use reqwest::Client;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError};
|
|
||||||
|
|
||||||
const GAS_NOW_URL: &str = "https://www.gasnow.org/api/v3/gas/price";
|
|
||||||
|
|
||||||
/// A client over HTTP for the [GasNow](https://www.gasnow.org/api/v1/gas/price) gas tracker API
|
|
||||||
/// that implements the `GasOracle` trait
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct GasNow {
|
|
||||||
client: Client,
|
|
||||||
url: Url,
|
|
||||||
gas_category: GasCategory,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for GasNow {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct GasNowResponseWrapper {
|
|
||||||
data: GasNowResponse,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd)]
|
|
||||||
pub struct GasNowResponse {
|
|
||||||
pub rapid: u64,
|
|
||||||
pub fast: u64,
|
|
||||||
pub standard: u64,
|
|
||||||
pub slow: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GasNow {
|
|
||||||
/// Creates a new [GasNow](https://gasnow.org) gas price oracle.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let url = Url::parse(GAS_NOW_URL).expect("invalid url");
|
|
||||||
|
|
||||||
Self {
|
|
||||||
client: Client::new(),
|
|
||||||
url,
|
|
||||||
gas_category: GasCategory::Standard,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the gas price category to be used when fetching the gas price.
|
|
||||||
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
|
||||||
self.gas_category = gas_category;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn query(&self) -> Result<GasNowResponse, GasOracleError> {
|
|
||||||
let res = self
|
|
||||||
.client
|
|
||||||
.get(self.url.as_ref())
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.json::<GasNowResponseWrapper>()
|
|
||||||
.await?;
|
|
||||||
Ok(res.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
|
||||||
impl GasOracle for GasNow {
|
|
||||||
async fn fetch(&self) -> Result<U256, GasOracleError> {
|
|
||||||
let res = self.query().await?;
|
|
||||||
let gas_price = match self.gas_category {
|
|
||||||
GasCategory::SafeLow => U256::from(res.slow),
|
|
||||||
GasCategory::Standard => U256::from(res.standard),
|
|
||||||
GasCategory::Fast => U256::from(res.fast),
|
|
||||||
GasCategory::Fastest => U256::from(res.rapid),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(gas_price)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> {
|
|
||||||
Err(GasOracleError::Eip1559EstimationNotSupported)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,9 +7,6 @@ pub use etherchain::Etherchain;
|
||||||
mod etherscan;
|
mod etherscan;
|
||||||
pub use etherscan::Etherscan;
|
pub use etherscan::Etherscan;
|
||||||
|
|
||||||
mod gas_now;
|
|
||||||
pub use gas_now::GasNow;
|
|
||||||
|
|
||||||
mod middleware;
|
mod middleware;
|
||||||
pub use middleware::{GasOracleMiddleware, MiddlewareError};
|
pub use middleware::{GasOracleMiddleware, MiddlewareError};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
//! use ethers_signers::{LocalWallet, Signer};
|
//! use ethers_signers::{LocalWallet, Signer};
|
||||||
//! use ethers_middleware::{
|
//! use ethers_middleware::{
|
||||||
//! gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
|
//! gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
|
||||||
//! gas_oracle::{GasOracleMiddleware, GasNow, GasCategory},
|
//! gas_oracle::{GasOracleMiddleware, EthGasStation, GasCategory},
|
||||||
//! signer::SignerMiddleware,
|
//! signer::SignerMiddleware,
|
||||||
//! nonce_manager::NonceManagerMiddleware,
|
//! nonce_manager::NonceManagerMiddleware,
|
||||||
//! };
|
//! };
|
||||||
|
@ -43,8 +43,8 @@
|
||||||
//! let address = signer.address();
|
//! let address = signer.address();
|
||||||
//! let provider = SignerMiddleware::new(provider, signer);
|
//! let provider = SignerMiddleware::new(provider, signer);
|
||||||
//!
|
//!
|
||||||
//! // Use GasNow as the gas oracle
|
//! // Use EthGasStation as the gas oracle
|
||||||
//! let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
|
//! let gas_oracle = EthGasStation::new(None);
|
||||||
//! let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
//! let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
||||||
//!
|
//!
|
||||||
//! // Manage nonces locally
|
//! // Manage nonces locally
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![cfg(not(target_arch = "wasm32"))]
|
#![cfg(not(target_arch = "wasm32"))]
|
||||||
use ethers_core::{types::*, utils::Ganache};
|
use ethers_core::{types::*, utils::Ganache};
|
||||||
use ethers_middleware::gas_oracle::{
|
use ethers_middleware::gas_oracle::{
|
||||||
EthGasStation, Etherchain, Etherscan, GasCategory, GasNow, GasOracle, GasOracleMiddleware,
|
EthGasStation, Etherchain, Etherscan, GasCategory, GasOracle, GasOracleMiddleware,
|
||||||
};
|
};
|
||||||
use ethers_providers::{Http, Middleware, Provider};
|
use ethers_providers::{Http, Middleware, Provider};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -16,7 +16,7 @@ async fn using_gas_oracle() {
|
||||||
let provider = Provider::<Http>::try_from(ganache.endpoint()).unwrap();
|
let provider = Provider::<Http>::try_from(ganache.endpoint()).unwrap();
|
||||||
|
|
||||||
// assign a gas oracle to use
|
// assign a gas oracle to use
|
||||||
let gas_oracle = GasNow::new().category(GasCategory::Fastest);
|
let gas_oracle = EthGasStation::new(None);
|
||||||
let expected_gas_price = gas_oracle.fetch().await.unwrap();
|
let expected_gas_price = gas_oracle.fetch().await.unwrap();
|
||||||
|
|
||||||
let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
let provider = GasOracleMiddleware::new(provider, gas_oracle);
|
||||||
|
@ -65,11 +65,3 @@ async fn etherchain() {
|
||||||
let data = etherchain_oracle.fetch().await;
|
let data = etherchain_oracle.fetch().await;
|
||||||
assert!(data.is_ok());
|
assert!(data.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn gas_now() {
|
|
||||||
// initialize and fetch gas estimates from SparkPool
|
|
||||||
let gas_now_oracle = GasNow::new().category(GasCategory::Fastest);
|
|
||||||
let data = gas_now_oracle.fetch().await;
|
|
||||||
assert!(data.is_ok());
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod tests {
|
||||||
use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Ganache};
|
use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Ganache};
|
||||||
use ethers_middleware::{
|
use ethers_middleware::{
|
||||||
gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice},
|
gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice},
|
||||||
gas_oracle::{GasCategory, GasNow, GasOracleMiddleware},
|
gas_oracle::{EthGasStation, GasCategory, GasOracleMiddleware},
|
||||||
nonce_manager::NonceManagerMiddleware,
|
nonce_manager::NonceManagerMiddleware,
|
||||||
signer::SignerMiddleware,
|
signer::SignerMiddleware,
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,7 @@ mod tests {
|
||||||
let (provider, mock) = Provider::mocked();
|
let (provider, mock) = Provider::mocked();
|
||||||
|
|
||||||
// add a bunch of middlewares
|
// add a bunch of middlewares
|
||||||
let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
|
let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow);
|
||||||
let signer = LocalWallet::new(&mut thread_rng());
|
let signer = LocalWallet::new(&mut thread_rng());
|
||||||
let address = signer.address();
|
let address = signer.address();
|
||||||
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
|
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
|
||||||
|
@ -53,7 +53,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn can_stack_middlewares() {
|
async fn can_stack_middlewares() {
|
||||||
let ganache = Ganache::new().block_time(5u64).spawn();
|
let ganache = Ganache::new().block_time(5u64).spawn();
|
||||||
let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
|
let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow);
|
||||||
let signer: LocalWallet = ganache.keys()[0].clone().into();
|
let signer: LocalWallet = ganache.keys()[0].clone().into();
|
||||||
let address = signer.address();
|
let address = signer.address();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue