espresso_contract_deployer/
impersonate_filler.rs

1use alloy::{
2    network::{Network, TransactionBuilder},
3    primitives::Address,
4    providers::{
5        Provider, SendableTx,
6        fillers::{FillerControlFlow, TxFiller},
7    },
8    transports::TransportResult,
9};
10
11/// A filler that sets the `from` field on transactions to impersonate a specific address.
12/// This is useful when using Anvil's impersonation features to send transactions from
13/// accounts that we don't have the private key for.
14///
15/// Avoids having to manually set the `from` field on transactions.
16#[derive(Clone, Debug, Default)]
17pub struct ImpersonateFiller {
18    from: Address,
19}
20
21impl ImpersonateFiller {
22    pub fn new(from: Address) -> Self {
23        Self { from }
24    }
25}
26
27#[derive(Clone, Debug)]
28pub struct ImpersonateFillable {
29    pub from: Address,
30}
31
32impl<N: Network> TxFiller<N> for ImpersonateFiller {
33    type Fillable = ImpersonateFillable;
34
35    fn status(&self, tx: &N::TransactionRequest) -> FillerControlFlow {
36        if tx.from().is_none() {
37            FillerControlFlow::Ready
38        } else {
39            FillerControlFlow::Finished
40        }
41    }
42
43    async fn prepare<P: Provider<N>>(
44        &self,
45        _provider: &P,
46        _tx: &N::TransactionRequest,
47    ) -> TransportResult<Self::Fillable> {
48        Ok(ImpersonateFillable { from: self.from })
49    }
50
51    async fn fill(
52        &self,
53        fillable: Self::Fillable,
54        mut tx: SendableTx<N>,
55    ) -> TransportResult<SendableTx<N>> {
56        if let Some(builder) = tx.as_mut_builder() {
57            builder.set_from(fillable.from);
58        }
59        Ok(tx)
60    }
61
62    fn fill_sync(&self, tx: &mut SendableTx<N>) {
63        if let Some(builder) = tx.as_mut_builder() {
64            builder.set_from(self.from);
65        }
66    }
67}