alloy_provider/provider/
wallet.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use crate::{
    fillers::{FillProvider, JoinFill, TxFiller, WalletFiller},
    Provider,
};
use alloy_network::{Ethereum, Network, NetworkWallet};
use alloy_primitives::Address;
use alloy_transport::Transport;

/// Trait for Providers, Fill stacks, etc, which contain [`NetworkWallet`].
pub trait WalletProvider<N: Network = Ethereum> {
    /// The underlying [`NetworkWallet`] type contained in this stack.
    type Wallet: NetworkWallet<N>;

    /// Get a reference to the underlying wallet.
    fn wallet(&self) -> &Self::Wallet;

    /// Get a mutable reference to the underlying wallet.
    fn wallet_mut(&mut self) -> &mut Self::Wallet;

    /// Get the default signer address.
    fn default_signer_address(&self) -> Address {
        self.wallet().default_signer_address()
    }

    /// Check if the signer can sign for the given address.
    fn has_signer_for(&self, address: &Address) -> bool {
        self.wallet().has_signer_for(address)
    }

    /// Get an iterator of all signer addresses. Note that because the signer
    /// always has at least one address, this iterator will always have at least
    /// one element.
    fn signer_addresses(&self) -> impl Iterator<Item = Address> {
        self.wallet().signer_addresses()
    }
}

impl<W, N> WalletProvider<N> for WalletFiller<W>
where
    W: NetworkWallet<N> + Clone,
    N: Network,
{
    type Wallet = W;

    #[inline(always)]
    fn wallet(&self) -> &Self::Wallet {
        self.as_ref()
    }

    #[inline(always)]
    fn wallet_mut(&mut self) -> &mut Self::Wallet {
        self.as_mut()
    }
}

impl<L, R, N> WalletProvider<N> for JoinFill<L, R>
where
    R: WalletProvider<N>,
    N: Network,
{
    type Wallet = R::Wallet;

    #[inline(always)]
    fn wallet(&self) -> &Self::Wallet {
        self.right().wallet()
    }

    #[inline(always)]
    fn wallet_mut(&mut self) -> &mut Self::Wallet {
        self.right_mut().wallet_mut()
    }
}

impl<F, P, T, N> WalletProvider<N> for FillProvider<F, P, T, N>
where
    F: TxFiller<N> + WalletProvider<N>,
    P: Provider<T, N>,
    T: Transport + Clone,
    N: Network,
{
    type Wallet = F::Wallet;

    #[inline(always)]
    fn wallet(&self) -> &Self::Wallet {
        self.filler.wallet()
    }

    #[inline(always)]
    fn wallet_mut(&mut self) -> &mut Self::Wallet {
        self.filler.wallet_mut()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::ProviderBuilder;
    use itertools::Itertools;

    #[test]
    fn basic_usage() {
        let provider = ProviderBuilder::new().on_anvil_with_wallet();

        assert!(provider.signer_addresses().contains(&provider.default_signer_address()));
    }

    #[test]
    fn bubbles_through_fillers() {
        let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet();

        assert!(provider.signer_addresses().contains(&provider.default_signer_address()));
    }
}