ethers_middleware/
builder.rs

1use crate::{
2    gas_oracle::{GasOracle, GasOracleMiddleware},
3    NonceManagerMiddleware, SignerMiddleware,
4};
5use ethers_core::types::Address;
6use ethers_providers::Middleware;
7use ethers_signers::Signer;
8
9/// A builder trait to compose different [`Middleware`] layers and then build a composed
10/// [`Provider`](ethers_providers::Provider) architecture.
11///
12/// [`Middleware`] composition acts in a wrapping fashion. Adding a new layer results in wrapping
13/// its predecessor.
14///
15/// ```rust
16/// use ethers_providers::{Middleware, Provider, Http};
17/// use std::sync::Arc;
18/// use std::convert::TryFrom;
19/// use ethers_signers::{LocalWallet, Signer};
20/// use ethers_middleware::{*, gas_escalator::*, gas_oracle::*};
21///
22/// fn builder_example() {
23///     let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
24///     let signer = key.parse::<LocalWallet>().unwrap();
25///     let address = signer.address();
26///     let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
27///     let gas_oracle = GasNow::new();
28///
29///     let provider = Provider::<Http>::try_from("http://localhost:8545")
30///         .unwrap()
31///         .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
32///         .gas_oracle(gas_oracle)
33///         .with_signer(signer)
34///         .nonce_manager(address); // Outermost layer
35/// }
36///
37/// fn builder_example_raw_wrap() {
38///     let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
39///     let signer = key.parse::<LocalWallet>().unwrap();
40///     let address = signer.address();
41///     let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
42///
43///     let provider = Provider::<Http>::try_from("http://localhost:8545")
44///         .unwrap()
45///         .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
46///         .wrap_into(|p| SignerMiddleware::new(p, signer))
47///         .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
48///         .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer
49/// }
50/// ```
51pub trait MiddlewareBuilder: Middleware + Sized + 'static {
52    /// Wraps `self` inside a new [`Middleware`].
53    ///
54    /// `f` Consumes `self`. Must be used to return a new [`Middleware`] wrapping `self`.
55    fn wrap_into<F, T>(self, f: F) -> T
56    where
57        F: FnOnce(Self) -> T,
58        T: Middleware,
59    {
60        f(self)
61    }
62
63    /// Wraps `self` inside a [`SignerMiddleware`].
64    fn with_signer<S>(self, s: S) -> SignerMiddleware<Self, S>
65    where
66        S: Signer,
67    {
68        SignerMiddleware::new(self, s)
69    }
70
71    /// Wraps `self` inside a [`NonceManagerMiddleware`].
72    fn nonce_manager(self, address: Address) -> NonceManagerMiddleware<Self> {
73        NonceManagerMiddleware::new(self, address)
74    }
75
76    /// Wraps `self` inside a [`GasOracleMiddleware`].
77    fn gas_oracle<G>(self, gas_oracle: G) -> GasOracleMiddleware<Self, G>
78    where
79        G: GasOracle,
80    {
81        GasOracleMiddleware::new(self, gas_oracle)
82    }
83}
84
85impl<M> MiddlewareBuilder for M where M: Middleware + Sized + 'static {}