Skip to main content

foundry_primitives/network/
wallet.rs

1use alloy_consensus::{Sealed, SignableTransaction};
2use alloy_network::{Ethereum, EthereumWallet, NetworkWallet, TxSigner};
3use alloy_primitives::{Address, Signature};
4use alloy_signer::{Error, Result};
5
6use crate::{FoundryNetwork, FoundryTxEnvelope, FoundryTypedTx};
7
8impl NetworkWallet<FoundryNetwork> for EthereumWallet {
9    fn default_signer_address(&self) -> Address {
10        NetworkWallet::<Ethereum>::default_signer_address(self)
11    }
12
13    fn has_signer_for(&self, address: &Address) -> bool {
14        NetworkWallet::<Ethereum>::has_signer_for(self, address)
15    }
16
17    fn signer_addresses(&self) -> impl Iterator<Item = Address> {
18        NetworkWallet::<Ethereum>::signer_addresses(self)
19    }
20
21    async fn sign_transaction_from(
22        &self,
23        sender: Address,
24        tx: FoundryTypedTx,
25    ) -> Result<FoundryTxEnvelope> {
26        match tx {
27            FoundryTypedTx::Legacy(mut tx) => {
28                let sig = sign_with_wallet(self, sender, &mut tx).await?;
29                Ok(FoundryTxEnvelope::Legacy(tx.into_signed(sig)))
30            }
31            FoundryTypedTx::Eip2930(mut tx) => {
32                let sig = sign_with_wallet(self, sender, &mut tx).await?;
33                Ok(FoundryTxEnvelope::Eip2930(tx.into_signed(sig)))
34            }
35            FoundryTypedTx::Eip1559(mut tx) => {
36                let sig = sign_with_wallet(self, sender, &mut tx).await?;
37                Ok(FoundryTxEnvelope::Eip1559(tx.into_signed(sig)))
38            }
39            FoundryTypedTx::Eip4844(mut tx) => {
40                let sig = sign_with_wallet(self, sender, &mut tx).await?;
41                Ok(FoundryTxEnvelope::Eip4844(tx.into_signed(sig)))
42            }
43            FoundryTypedTx::Eip7702(mut tx) => {
44                let sig = sign_with_wallet(self, sender, &mut tx).await?;
45                Ok(FoundryTxEnvelope::Eip7702(tx.into_signed(sig)))
46            }
47            FoundryTypedTx::Deposit(tx) => {
48                // Deposit transactions don't require signing
49                Ok(FoundryTxEnvelope::Deposit(Sealed::new(tx)))
50            }
51            FoundryTypedTx::Tempo(mut tx) => {
52                let sig = sign_with_wallet(self, sender, &mut tx).await?;
53                Ok(FoundryTxEnvelope::Tempo(tx.into_signed(sig.into())))
54            }
55        }
56    }
57}
58
59/// Helper function to sign a transaction using the wallet's signer for the given sender address.
60async fn sign_with_wallet(
61    wallet: &EthereumWallet,
62    sender: Address,
63    tx: &mut dyn SignableTransaction<Signature>,
64) -> Result<Signature> {
65    let signer = wallet
66        .signer_by_address(sender)
67        .ok_or_else(|| Error::other(format!("Signer not found for sender {sender}")))?;
68    TxSigner::sign_transaction(&signer, tx).await
69}