Alloy v2.0 includes several targeted improvements to the Network trait that make it significantly more ergonomic and versatile. These changes were driven in large part by Foundry's ongoing refactor towards fully generic Network and Evm abstractions, work motivated by Tempo support, which surfaced a some rough edges on workflows fully generic over Network.
NetworkWallet<N> is now generic over the Network trait, meaning EthereumWallet can be used seamlessly with custom network implementations without requiring a separate wallet type. The required bounds — N::TxEnvelope: From<Signed<N::UnsignedTx>> and N::UnsignedTx: SignableTransaction<Signature>, are placed on the impl rather than on Network itself, so existing custom network implementations are unaffected.
Non-signable transactions (such as Optimism deposit transactions) now return sealed envelopes rather than errors, removing a common source of boilerplate in OP Stack integrations.
Network::TransactionRequest now has a From<Self::TransactionResponse> bound, enabling generic round-trip conversion between RPC responses and transaction request types. This is particularly useful for transaction simulation and re-submission workflows, a pattern the Foundry refactor relied on heavily, and is now available out of the box for any Network implementation.
// Fetch a transaction and convert it back to a request
let tx: TransactionResponse = provider.get_transaction_by_hash(hash).await?;
let req: TransactionRequest = tx.into();The from field is now correctly populated via into_recovered() during conversion, fixing a subtle bug where the sender address was previously lost.
Previously, blob transaction building was split across two separate traits: TransactionBuilder4844 and TransactionBuilder7594. This created friction for anyone building generic transaction tooling that needed to support both sidecar formats introduced by Dencun and Pectra.
In v2.0, these have been unified into a single TransactionBuilder4844 trait that handles both EIP-4844 and EIP-7594 sidecar variants, simplifying bounds in blob handling contexts. Methods are now explicit about which format they target:
// Set an EIP-4844 sidecar
tx.with_blob_sidecar_4844(sidecar_4844);
// Or an EIP-7594 sidecar (PeerDAS)
tx.with_blob_sidecar_7594(sidecar_7594);
// Or work with either variant directly
tx.with_blob_sidecar(BlobTransactionSidecarVariant::Eip7594(sidecar));