ethers-middleware

Your ethers application interacts with the blockchain through a Provider abstraction. Provider is a special type of Middleware that can be composed with others to obtain a layered architecture. This approach promotes "Open Closed Principle", "Single Responsibility" and composable patterns. The building process happens in a wrapping fashion, and starts from a Provider being the first element in the stack. This process continues having new middlewares being pushed on top of a layered data structure.

For more information, please refer to the book.

Available Middleware

Examples

Each Middleware implements the trait MiddlewareBuilder. This trait helps a developer to compose a custom Middleware stack.

The following example shows how to build a composed Middleware starting from a Provider:

```rust

use ethers_providers::{Middleware, Provider, Http};

use ethers_signers::{LocalWallet, Signer};

use ethersmiddleware::{gasoracle::GasNow, MiddlewareBuilder};

let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; let signer = key.parse::()?; let address = signer.address(); let gas_oracle = GasNow::new();

let provider = Provider::::tryfrom("http://localhost:8545")? .gasoracle(gasoracle) .withsigner(signer) .nonce_manager(address); // Outermost layer

Ok::<_, Box>(())

```

The wrap_into function can be used to wrap Middleware layers explicitly. This is useful when pushing Middlewares not directly handled by the builder interface.

```rust,no_run

use ethers_providers::{Middleware, Provider, Http};

use std::convert::TryFrom;

use ethers_signers::{LocalWallet, Signer};

use ethersmiddleware::{*,gasescalator::,gas_oracle::};

let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; let signer = key.parse::()?; let address = signer.address(); let escalator = GeometricGasPrice::new(1.125, 60_u64, None::);

let provider = Provider::::tryfrom("http://localhost:8545")? .wrapinto(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) .wrapinto(|p| SignerMiddleware::new(p, signer)) .wrapinto(|p| GasOracleMiddleware::new(p, GasNow::new())) .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer

Ok::<_, Box>(())

```

A Middleware stack can be also constructed manually. This is achieved by explicitly wrapping layers.

```rust,no_run

use ethers_providers::{Provider, Http};

use ethers_signers::{LocalWallet, Signer};

use ethers_middleware::{

gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},

gas_oracle::{GasOracleMiddleware, GasCategory, GasNow},

signer::SignerMiddleware,

nonce_manager::NonceManagerMiddleware,

};

// Start the stack let provider = Provider::::try_from("http://localhost:8545")?;

// Escalate gas prices let escalator = GeometricGasPrice::new(1.125, 60u64, None::); let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock);

// Sign transactions with a private key let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; let signer = key.parse::()?; let address = signer.address(); let provider = SignerMiddleware::new(provider, signer);

// Use GasNow as the gas oracle let gasoracle = GasNow::new(); let provider = GasOracleMiddleware::new(provider, gasoracle);

// Manage nonces locally let provider = NonceManagerMiddleware::new(provider, address);

Ok::<_, Box>(())

```