From 0245a4e1ff5ee7d173ee18c610909d4dad46b265 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 7 Nov 2024 23:20:23 +0530 Subject: [PATCH] feat(`network`): `AnyNetworkWallet` (#1631) --- crates/network/src/ethereum/wallet.rs | 32 ++++++++++++++++++++++++++- crates/provider/Cargo.toml | 1 + crates/provider/src/provider/trait.rs | 28 ++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/crates/network/src/ethereum/wallet.rs b/crates/network/src/ethereum/wallet.rs index 045f9643add..05fa75bac69 100644 --- a/crates/network/src/ethereum/wallet.rs +++ b/crates/network/src/ethereum/wallet.rs @@ -1,8 +1,10 @@ -use crate::{Network, NetworkWallet, TxSigner}; +use crate::{AnyNetwork, AnyTxEnvelope, AnyTypedTransaction, Network, NetworkWallet, TxSigner}; use alloy_consensus::{SignableTransaction, TxEnvelope, TypedTransaction}; use alloy_primitives::{map::AddressHashMap, Address, PrimitiveSignature as Signature}; use std::sync::Arc; +use super::Ethereum; + /// A wallet capable of signing any transaction for the Ethereum network. #[derive(Clone, Default)] pub struct EthereumWallet { @@ -139,3 +141,31 @@ where } } } + +impl NetworkWallet for EthereumWallet { + fn default_signer_address(&self) -> Address { + self.default + } + + fn has_signer_for(&self, address: &Address) -> bool { + self.signers.contains_key(address) + } + + fn signer_addresses(&self) -> impl Iterator { + self.signers.keys().copied() + } + + #[doc(alias = "sign_tx_from")] + async fn sign_transaction_from( + &self, + sender: Address, + tx: AnyTypedTransaction, + ) -> alloy_signer::Result { + match tx { + AnyTypedTransaction::Ethereum(t) => Ok(AnyTxEnvelope::Ethereum( + NetworkWallet::::sign_transaction_from(self, sender, t).await?, + )), + _ => Err(alloy_signer::Error::other("cannot sign UnknownTypedTransaction")), + } + } +} diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index fd9c656e1a7..9f0bd927883 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -77,6 +77,7 @@ alloy-sol-types.workspace = true alloy-signer.workspace = true alloy-signer-local.workspace = true alloy-transport-http = { workspace = true, features = ["reqwest", "jwt-auth"] } +alloy-serde.workspace = true itertools.workspace = true reqwest.workspace = true diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 45cdd09a38e..99d0d3cf649 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1085,11 +1085,12 @@ mod tests { use super::*; use crate::{builder, ProviderBuilder, WalletProvider}; use alloy_consensus::Transaction; - use alloy_network::AnyNetwork; + use alloy_network::{AnyNetwork, EthereumWallet, TransactionBuilder}; use alloy_node_bindings::Anvil; use alloy_primitives::{address, b256, bytes, keccak256}; use alloy_rpc_client::BuiltInConnectionString; use alloy_rpc_types_eth::{request::TransactionRequest, Block}; + use alloy_signer_local::PrivateKeySigner; // For layer transport tests #[cfg(feature = "hyper")] use alloy_transport_http::{ @@ -1729,6 +1730,31 @@ mod tests { } } + #[tokio::test] + async fn any_network_wallet_filler() { + use alloy_serde::WithOtherFields; + let anvil = Anvil::new().spawn(); + let signer: PrivateKeySigner = + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".parse().unwrap(); + let wallet = EthereumWallet::from(signer); + + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .network::() + .wallet(wallet) + .on_http(anvil.endpoint_url()); + + let tx = TransactionRequest::default() + .with_to(address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")) + .value(U256::from(325235)); + + let tx = WithOtherFields::new(tx); + + let builder = provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap(); + + assert!(builder.status()); + } + #[tokio::test] async fn builtin_connect_boxed() { let anvil = Anvil::new().spawn();