From 4d111af337d29bced2d4f32a8d72fedc473bb423 Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:29:56 +0200 Subject: [PATCH] feat(contracts): update to `cb95183` and add `with_recommended_fillers()` to examples where appropriate (#50) * upgrade to cd5a2c7 * start updating examples * fix examples * fix clippy and ordering * requires signer and from, not sure why it is not inheriting from the provider * upgrade to cb95183 * fix broken examples * update layer -> singer, add gas_signer and improve documentation --- Cargo.toml | 2 +- README.md | 9 +-- .../anvil/examples/deploy_contract_anvil.rs | 36 +++++------ .../examples/deploy_from_artifact.rs | 3 +- .../examples/deploy_from_contract.rs | 3 +- .../contracts/examples/interact_with_abi.rs | 2 +- examples/{layers => fillers}/Cargo.toml | 0 .../examples/gas_filler.rs} | 21 ++++--- .../examples/nonce_management_filler.rs} | 24 ++++---- .../fillers/examples/recommended_fillers.rs | 60 +++++++++++++++++++ .../examples/signer_filler.rs} | 16 ++--- examples/providers/examples/builder.rs | 17 +++--- examples/providers/examples/http.rs | 2 +- .../examples/query_contract_storage.rs | 3 +- .../examples/query_deployed_bytecode.rs | 2 +- examples/queries/examples/query_logs.rs | 2 +- .../transactions/examples/gas_price_usd.rs | 14 +++-- examples/transactions/examples/trace_call.rs | 21 +++---- .../examples/trace_transaction.rs | 4 +- .../transactions/examples/transfer_erc20.rs | 16 ++--- .../transactions/examples/transfer_eth.rs | 10 +++- examples/wallets/examples/keystore_signer.rs | 25 ++++---- examples/wallets/examples/ledger_signer.rs | 27 +++++---- .../wallets/examples/private_key_signer.rs | 25 ++++---- examples/wallets/examples/trezor_signer.rs | 27 +++++---- examples/wallets/examples/yubi_signer.rs | 24 ++++---- 26 files changed, 226 insertions(+), 169 deletions(-) rename examples/{layers => fillers}/Cargo.toml (100%) rename examples/{layers/examples/recommended_layers.rs => fillers/examples/gas_filler.rs} (76%) rename examples/{layers/examples/nonce_layer.rs => fillers/examples/nonce_management_filler.rs} (79%) create mode 100644 examples/fillers/examples/recommended_fillers.rs rename examples/{layers/examples/signer_layer.rs => fillers/examples/signer_filler.rs} (81%) diff --git a/Cargo.toml b/Cargo.toml index 6a97c8ee..044c09bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ unnecessary_struct_initialization = "allow" use_self = "allow" [workspace.dependencies] -alloy = { git = "https://github.com/alloy-rs/alloy", rev = "bfd0fda", features = [ +alloy = { git = "https://github.com/alloy-rs/alloy", rev = "cb95183", features = [ "contract", "network", "node-bindings", diff --git a/README.md b/README.md index 7b06345e..038007f4 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,11 @@ This repository contains the following examples: - [x] [Deploy from artifact](./examples/contracts/examples/deploy_from_artifact.rs) - [x] [Deploy from contract](./examples/contracts/examples/deploy_from_contract.rs) - [x] [Interact with ABI](./examples/contracts/examples/interact_with_abi.rs) -- [x] Layers (Middleware) - - [x] [Recommended layers](./examples/layers/examples/recommended_layers.rs) - - [x] [Nonce manager](./examples/layers/examples/nonce_layer.rs) - - [x] [Signature manager](./examples/layers/examples/signer_layer.rs) +- [x] Fillers (Middleware) + - [x] [Gas filler](./examples/fillers/examples/gas_filler.rs) + - [x] [Nonce management filler](./examples/fillers/examples/nonce_filler.rs) + - [x] [Recommended fillers](./examples/fillers/examples/recommended_fillers.rs) + - [x] [Signer management filler](./examples/fillers/examples/signer_filler.rs) - [x] Subscriptions - [x] [Subscribe and watch blocks](./examples/subscriptions/examples/subscribe_blocks.rs) - [x] [Subscribe to contract events and watch logs](./examples/subscriptions/examples/watch_contract_event.rs) diff --git a/examples/anvil/examples/deploy_contract_anvil.rs b/examples/anvil/examples/deploy_contract_anvil.rs index 678c7d98..60479790 100644 --- a/examples/anvil/examples/deploy_contract_anvil.rs +++ b/examples/anvil/examples/deploy_contract_anvil.rs @@ -1,12 +1,8 @@ //! Example of deploying a contract to Anvil and interacting with it. use alloy::{ - network::EthereumSigner, - node_bindings::Anvil, - primitives::U256, - providers::{Provider, ProviderBuilder}, - signers::wallet::LocalWallet, - sol, + network::EthereumSigner, node_bindings::Anvil, primitives::U256, providers::ProviderBuilder, + signers::wallet::LocalWallet, sol, }; use eyre::Result; @@ -36,36 +32,32 @@ async fn main() -> Result<()> { // Set up signer from the first default Anvil account (Alice). let signer: LocalWallet = anvil.keys()[0].clone().into(); + let from = signer.address(); // Create a provider with a signer and the network. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; println!("Anvil running at `{}`", anvil.endpoint()); - // Get the base fee for the block. - let base_fee = provider.get_gas_price().await?; - // Deploy the contract. - let contract_builder = Counter::deploy_builder(&provider); - let estimate = contract_builder.estimate_gas().await?; - let contract_address = - contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; - - println!("Deployed contract at address: {contract_address:?}"); + let contract_builder = Counter::deploy_builder(&provider).from(from); + let contract_address = contract_builder.deploy().await?; + let contract = Counter::new(contract_address, provider); - let contract = Counter::new(contract_address, &provider); + println!("Deployed contract at address: {:?}", contract.address()); - let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?; - let builder = contract.setNumber(U256::from(42)).nonce(1).gas(estimate).gas_price(base_fee); + // Set the number to 42. + let builder = contract.setNumber(U256::from(42)).from(from); let receipt = builder.send().await?.get_receipt().await?; println!("Set number to 42: {:?}", receipt.transaction_hash); // Increment the number to 43. - let estimate = contract.increment().estimate_gas().await?; - let builder = contract.increment().nonce(2).gas(estimate).gas_price(base_fee); + let builder = contract.increment().from(from); let receipt = builder.send().await?.get_receipt().await?; println!("Incremented number: {:?}", receipt.transaction_hash); diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index 12f23344..fea47b60 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -29,8 +29,7 @@ async fn main() -> Result<()> { // Create a provider with a signer. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_http(rpc_url)?; println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 0064b4bc..536f6864 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -39,8 +39,7 @@ async fn main() -> Result<()> { // Create a provider with a signer. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_http(rpc_url)?; println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/contracts/examples/interact_with_abi.rs b/examples/contracts/examples/interact_with_abi.rs index 35f182d5..13bac73e 100644 --- a/examples/contracts/examples/interact_with_abi.rs +++ b/examples/contracts/examples/interact_with_abi.rs @@ -19,7 +19,7 @@ async fn main() -> Result<()> { // Create a provider. let rpc_url = anvil.endpoint().parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Create a contract instance. let contract = IERC20::new("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?, provider); diff --git a/examples/layers/Cargo.toml b/examples/fillers/Cargo.toml similarity index 100% rename from examples/layers/Cargo.toml rename to examples/fillers/Cargo.toml diff --git a/examples/layers/examples/recommended_layers.rs b/examples/fillers/examples/gas_filler.rs similarity index 76% rename from examples/layers/examples/recommended_layers.rs rename to examples/fillers/examples/gas_filler.rs index c6a6d9a4..cbaba2f9 100644 --- a/examples/layers/examples/recommended_layers.rs +++ b/examples/fillers/examples/gas_filler.rs @@ -1,4 +1,4 @@ -//! Example of using the `.with_recommended_layers()` method in the provider. +//! Example of using the `GasFiller` in the provider. use alloy::{ network::{EthereumSigner, TransactionBuilder}, @@ -26,21 +26,21 @@ async fn main() -> Result<()> { // Create a provider with the signer. let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - // Adds the `GasEstimatorLayer` and the `NonceManagerLayer` layers. - .with_recommended_layers() - // Alternatively, you can add the layers individually: - // .with_gas_estimation() - // .with_nonce_management() + // Add the `GasFiller` to the provider. + // It is generally recommended to use the `.with_recommended_fillers()` method, which + // includes the `GasFiller`. + .with_gas_estimation() .signer(EthereumSigner::from(signer)) - .on_reqwest_http(rpc_url)?; + .on_http(rpc_url)?; // Create an EIP-1559 type transaction. - // Notice that the `nonce` field is set by the `NonceManagerLayer`. - // Notice that without the `GasEstimatorLayer`, you need to set the gas related fields. let tx = TransactionRequest::default() .with_from(alice) .with_to(vitalik.into()) .with_value(U256::from(100)) + // Notice that without the `NonceFiller`, you need to set `nonce` field. + .with_nonce(0) + // Notice that without the `ChainIdFiller`, you need to set the `chain_id` field. .with_chain_id(anvil.chain_id()); // Send the transaction, the nonce (0) is automatically managed by the provider. @@ -51,6 +51,9 @@ async fn main() -> Result<()> { println!("Transaction sent with nonce: {}", pending_tx.nonce); + // Update the nonce and send the transaction again. + let tx = tx.with_nonce(1); + // Send the transaction, the nonce (1) is automatically managed by the provider. let builder = provider.send_transaction(tx).await?; let node_hash = *builder.tx_hash(); diff --git a/examples/layers/examples/nonce_layer.rs b/examples/fillers/examples/nonce_management_filler.rs similarity index 79% rename from examples/layers/examples/nonce_layer.rs rename to examples/fillers/examples/nonce_management_filler.rs index 01b0f360..343bc7ba 100644 --- a/examples/layers/examples/nonce_layer.rs +++ b/examples/fillers/examples/nonce_management_filler.rs @@ -1,10 +1,10 @@ -//! Example of using the `NonceManagerLayer` in the provider. +//! Example of using the `NonceFiller` in the provider. use alloy::{ network::{EthereumSigner, TransactionBuilder}, node_bindings::Anvil, primitives::{address, U256}, - providers::{layers::NonceManagerLayer, Provider, ProviderBuilder}, + providers::{Provider, ProviderBuilder}, rpc::types::eth::request::TransactionRequest, signers::wallet::LocalWallet, }; @@ -35,23 +35,23 @@ async fn main() -> Result<()> { // Create a provider with the signer. let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - // Add the `NonceManagerLayer` to the provider. - // It is generally recommended to use the `.with_recommended_layers()` method, which - // includes the `NonceManagerLayer`. - .layer(NonceManagerLayer) + // Add the `NonceFiller` to the provider. + // It is generally recommended to use the `.with_recommended_fillers()` method, which + // includes the `NonceFiller`. + .with_nonce_management() .signer(EthereumSigner::from(signer)) - .on_reqwest_http(rpc_url)?; + .on_http(rpc_url)?; // Create an EIP-1559 type transaction. let tx = TransactionRequest::default() .with_from(alice) .with_to(vitalik.into()) .with_value(U256::from(100)) - // Notice that without the `GasEstimatorLayer`, you need to set the gas related fields. - .with_gas_limit(U256::from(21000)) - .with_max_fee_per_gas(U256::from(20e9)) - .with_max_priority_fee_per_gas(U256::from(1e9)) - // It is required to set the chain_id for EIP-1559 transactions. + // Notice that without the `GasFiller`, you need to set the gas related fields. + .with_gas_limit(21_000) + .with_max_fee_per_gas(20_000_000_000) + .with_max_priority_fee_per_gas(1_000_000_000) + // Notice that without the `ChainIdFiller`, you need to set the `chain_id` field. .with_chain_id(anvil.chain_id()); // Send the transaction, the nonce (0) is automatically managed by the provider. diff --git a/examples/fillers/examples/recommended_fillers.rs b/examples/fillers/examples/recommended_fillers.rs new file mode 100644 index 00000000..005f0b83 --- /dev/null +++ b/examples/fillers/examples/recommended_fillers.rs @@ -0,0 +1,60 @@ +//! Example of using the `.with_recommended_fillers()` method in the provider. + +use alloy::{ + network::{EthereumSigner, TransactionBuilder}, + node_bindings::Anvil, + primitives::{address, U256}, + providers::{Provider, ProviderBuilder}, + rpc::types::eth::request::TransactionRequest, + signers::wallet::LocalWallet, +}; +use eyre::Result; + +#[tokio::main] +async fn main() -> Result<()> { + // Spin up a local Anvil node. + // Ensure `anvil` is available in $PATH. + let anvil = Anvil::new().try_spawn()?; + + // Set up signer from the first default Anvil account (Alice). + let signer: LocalWallet = anvil.keys()[0].clone().into(); + + // Create two users, Alice and Vitalik. + let alice = signer.address(); + let vitalik = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); + + // Create a provider with the signer. + let rpc_url = anvil.endpoint().parse()?; + let provider = ProviderBuilder::new() + // Adds the `ChainIdFiller`, `GasFiller` and the `NonceFiller` layers. + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; + + // Build a EIP-1559 type transaction. + // Notice that the `nonce` field is set by the `NonceFiller`. + // Notice that the gas related fields are set by the `GasFiller`. + // Notice that the `chain_id` field is set by the `ChainIdFiller`. + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(vitalik.into()) + .with_value(U256::from(100)); + + // Send the transaction, the nonce (0) is automatically managed by the provider. + let builder = provider.send_transaction(tx.clone()).await?; + let node_hash = *builder.tx_hash(); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 0); + + println!("Transaction sent with nonce: {}", pending_tx.nonce); + + // Send the transaction, the nonce (1) is automatically managed by the provider. + let builder = provider.send_transaction(tx).await?; + let node_hash = *builder.tx_hash(); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 1); + + println!("Transaction sent with nonce: {}", pending_tx.nonce); + + Ok(()) +} diff --git a/examples/layers/examples/signer_layer.rs b/examples/fillers/examples/signer_filler.rs similarity index 81% rename from examples/layers/examples/signer_layer.rs rename to examples/fillers/examples/signer_filler.rs index 44188ece..eb4b9652 100644 --- a/examples/layers/examples/signer_layer.rs +++ b/examples/fillers/examples/signer_filler.rs @@ -1,4 +1,4 @@ -//! Example of using the `SignerLayer` in the provider. +//! Example of using the `SignerFiller` in the provider. use alloy::{ network::{EthereumSigner, TransactionBuilder}, @@ -26,20 +26,20 @@ async fn main() -> Result<()> { // Create a provider with the signer. let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - // Add the `SignerLayer` to the provider + // Add the `SignerFiller` to the provider .signer(EthereumSigner::from(signer)) - .on_reqwest_http(rpc_url)?; + .on_http(rpc_url)?; - // Create a legacy type transaction. + // Build a legacy type transaction to send 100 wei to Vitalik. let tx = TransactionRequest::default() .with_from(alice) - // Notice that without the `NonceManagerLayer`, you need to manually set the nonce field. + // Notice that without the `NonceFiller`, you need to manually set the nonce field. .with_nonce(0) .with_to(vitalik.into()) .with_value(U256::from(100)) - // Notice that without the `GasEstimatorLayer`, you need to set the gas related fields. - .with_gas_price(U256::from(20e9)) - .with_gas_limit(U256::from(21000)); + // Notice that without the `GasFiller`, you need to set the gas related fields. + .with_gas_price(20_000_000_000) + .with_gas_limit(21_000); let builder = provider.send_transaction(tx).await?; let node_hash = *builder.tx_hash(); diff --git a/examples/providers/examples/builder.rs b/examples/providers/examples/builder.rs index 4d5c42b8..645db9d4 100644 --- a/examples/providers/examples/builder.rs +++ b/examples/providers/examples/builder.rs @@ -25,17 +25,16 @@ async fn main() -> Result<()> { // Set up the HTTP provider with the `reqwest` crate. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(wallet)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(wallet)) + .on_http(rpc_url)?; // Create a transaction. - let mut tx = TransactionRequest::default() - .to(Some(bob)) - .value(U256::from(100)) - .nonce(0) - .gas_limit(U256::from(21000)); - - tx.set_gas_price(U256::from(20e9)); + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(bob.into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let pending_tx = provider.send_transaction(tx).await?; diff --git a/examples/providers/examples/http.rs b/examples/providers/examples/http.rs index c379ba47..486e5b8c 100644 --- a/examples/providers/examples/http.rs +++ b/examples/providers/examples/http.rs @@ -9,7 +9,7 @@ async fn main() -> Result<()> { let rpc_url = "https://eth.merkle.io".parse()?; // Create a provider with the HTTP transport using the `reqwest` crate. - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Get latest block number. let latest_block = provider.get_block_number().await?; diff --git a/examples/queries/examples/query_contract_storage.rs b/examples/queries/examples/query_contract_storage.rs index 2122499a..817e692d 100644 --- a/examples/queries/examples/query_contract_storage.rs +++ b/examples/queries/examples/query_contract_storage.rs @@ -3,6 +3,7 @@ use alloy::{ primitives::{address, U256}, providers::{Provider, ProviderBuilder}, + rpc::types::eth::BlockId, }; use eyre::Result; @@ -15,7 +16,7 @@ async fn main() -> Result<()> { // Get storage slot 0 from the Uniswap V3 USDC-ETH pool on Ethereum mainnet. let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"); let storage_slot = U256::from(0); - let storage = provider.get_storage_at(pool_address, storage_slot, None).await?; + let storage = provider.get_storage_at(pool_address, storage_slot, BlockId::latest()).await?; println!("Slot 0: {storage:?}"); diff --git a/examples/queries/examples/query_deployed_bytecode.rs b/examples/queries/examples/query_deployed_bytecode.rs index 4711b06d..547fa8c5 100644 --- a/examples/queries/examples/query_deployed_bytecode.rs +++ b/examples/queries/examples/query_deployed_bytecode.rs @@ -11,7 +11,7 @@ use eyre::Result; async fn main() -> Result<()> { // Create a provider. let rpc_url = "https://eth.merkle.io".parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Get the bytecode of the Uniswap V3 USDC-ETH pool on Ethereum mainnet. let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"); diff --git a/examples/queries/examples/query_logs.rs b/examples/queries/examples/query_logs.rs index 08b84ad0..1f594c9d 100644 --- a/examples/queries/examples/query_logs.rs +++ b/examples/queries/examples/query_logs.rs @@ -11,7 +11,7 @@ use eyre::Result; async fn main() -> Result<()> { // Create a provider. let rpc_url = "https://eth.merkle.io".parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Get logs from the latest block let latest_block = provider.get_block_number().await?; diff --git a/examples/transactions/examples/gas_price_usd.rs b/examples/transactions/examples/gas_price_usd.rs index 9a62d23a..00ed9633 100644 --- a/examples/transactions/examples/gas_price_usd.rs +++ b/examples/transactions/examples/gas_price_usd.rs @@ -1,10 +1,11 @@ //! Example of how to get the gas price in USD using the Chainlink ETH/USD feed. use alloy::{ + network::TransactionBuilder, node_bindings::Anvil, primitives::{address, utils::format_units, Address, Bytes, U256}, providers::{Provider, ProviderBuilder}, - rpc::types::eth::TransactionRequest, + rpc::types::eth::{BlockId, TransactionRequest}, sol, sol_types::SolCall, }; @@ -30,15 +31,16 @@ async fn main() -> Result<()> { // Create a provider. let rpc_url = anvil.endpoint().parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Create a call to get the latest answer from the Chainlink ETH/USD feed. let call = latestAnswerCall {}.abi_encode(); let input = Bytes::from(call); // Call the Chainlink ETH/USD feed contract. - let tx = TransactionRequest::default().to(Some(ETH_USD_FEED)).input(Some(input).into()); - let response = provider.call(&tx, None).await?; + let tx = TransactionRequest::default().with_to(ETH_USD_FEED.into()).with_input(input); + + let response = provider.call(&tx, BlockId::latest()).await?; let result = U256::from_str(&response.to_string())?; // Get the gas price of the network. @@ -54,9 +56,9 @@ async fn main() -> Result<()> { Ok(()) } -fn get_usd_value(amount: U256, price_usd: U256) -> Result { +fn get_usd_value(amount: u128, price_usd: U256) -> Result { let base = U256::from(10).pow(U256::from(ETH_DECIMALS)); - let value = amount * price_usd / base; + let value = U256::from(amount) * price_usd / base; let formatted = format_units(value, ETH_USD_FEED_DECIMALS)?.parse::()?; Ok(formatted) diff --git a/examples/transactions/examples/trace_call.rs b/examples/transactions/examples/trace_call.rs index 9d8e9e99..fd288311 100644 --- a/examples/transactions/examples/trace_call.rs +++ b/examples/transactions/examples/trace_call.rs @@ -1,10 +1,11 @@ //! Example of how to trace a transaction using `trace_call`. use alloy::{ + network::TransactionBuilder, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, rpc::types::{ - eth::{BlockId, BlockNumberOrTag, TransactionRequest}, + eth::{BlockId, TransactionRequest}, trace::parity::TraceType, }, }; @@ -14,25 +15,21 @@ use eyre::Result; async fn main() -> Result<()> { // Create a provider. let rpc_url = "https://eth.merkle.io".parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Create two users, Alice and Bob. let alice = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); let bob = address!("70997970C51812dc3A010C7d01b50e0d17dc79C8"); - // Create a transaction to send 100 wei from Alice to Bob. - let tx = TransactionRequest { - from: Some(alice), - to: Some(bob), - value: Some(U256::from(100)), - ..Default::default() - }; + // Build a transaction to send 100 wei from Alice to Bob. + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(bob.into()) + .with_value(U256::from(100)); // Trace the transaction on top of the latest block. let trace_type = [TraceType::Trace]; - let result = provider - .trace_call(&tx, &trace_type, Some(BlockId::Number(BlockNumberOrTag::Latest))) - .await?; + let result = provider.trace_call(&tx, &trace_type, BlockId::latest()).await?; println!("{:?}", result.trace); diff --git a/examples/transactions/examples/trace_transaction.rs b/examples/transactions/examples/trace_transaction.rs index c21f63b5..ae6d8977 100644 --- a/examples/transactions/examples/trace_transaction.rs +++ b/examples/transactions/examples/trace_transaction.rs @@ -3,7 +3,7 @@ use alloy::{ node_bindings::Anvil, primitives::b256, - providers::{Provider, ProviderBuilder}, + providers::{debug::DebugApi, ProviderBuilder}, rpc::types::trace::geth::{ GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingOptions, GethDefaultTracingOptions, @@ -19,7 +19,7 @@ async fn main() -> Result<()> { // Create a provider. let rpc_url = anvil.endpoint().parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Hash of the tx we want to trace let hash = b256!("97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7"); diff --git a/examples/transactions/examples/transfer_erc20.rs b/examples/transactions/examples/transfer_erc20.rs index 79029c1e..4b9a464c 100644 --- a/examples/transactions/examples/transfer_erc20.rs +++ b/examples/transactions/examples/transfer_erc20.rs @@ -1,11 +1,11 @@ //! Example of how to transfer ERC20 tokens from one account to another. use alloy::{ - network::Ethereum, + network::{Ethereum, TransactionBuilder}, node_bindings::Anvil, primitives::{Address, Bytes, U256}, providers::{Provider, ProviderBuilder, ReqwestProvider}, - rpc::types::eth::TransactionRequest, + rpc::types::eth::{BlockId, TransactionRequest}, sol, sol_types::SolCall, }; @@ -26,7 +26,7 @@ async fn main() -> Result<()> { // Create a provider. let rpc_url = anvil.endpoint().parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Create two users, Alice and Bob. let alice = anvil.addresses()[0]; @@ -97,15 +97,11 @@ async fn balance_of( let call = ERC20Example::balanceOfCall { account }.abi_encode(); let input = Bytes::from(call); - // Create a transaction. - let tx = TransactionRequest { - to: Some(contract_address), - input: Some(input).into(), - ..Default::default() - }; + // Build a transaction to call the contract with the input. + let tx = TransactionRequest::default().with_to(contract_address.into()).with_input(input); // Call the contract. - let result = provider.call(&tx, None).await?; + let result = provider.call(&tx, BlockId::latest()).await?; // Decode the result. let result = ERC20Example::balanceOfCall::abi_decode_returns(&result, true)?._0; diff --git a/examples/transactions/examples/transfer_eth.rs b/examples/transactions/examples/transfer_eth.rs index d3d03600..4936f3dd 100644 --- a/examples/transactions/examples/transfer_eth.rs +++ b/examples/transactions/examples/transfer_eth.rs @@ -1,6 +1,7 @@ //! Example of how to transfer ETH from one account to another. use alloy::{ + network::TransactionBuilder, node_bindings::Anvil, primitives::U256, providers::{Provider, ProviderBuilder}, @@ -16,14 +17,17 @@ async fn main() -> Result<()> { // Create a provider. let rpc_url = anvil.endpoint().parse()?; - let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new().on_http(rpc_url)?; // Create two users, Alice and Bob. let alice = anvil.addresses()[0]; let bob = anvil.addresses()[1]; - // Create a transaction to transfer 1 wei from Alice to Bob. - let tx = TransactionRequest::default().from(alice).value(U256::from(1)).to(Some(bob)); + // Build a transaction to send 100 wei from Alice to Bob. + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(bob.into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let pending_tx = provider.send_transaction(tx).await?; diff --git a/examples/wallets/examples/keystore_signer.rs b/examples/wallets/examples/keystore_signer.rs index 67672cf2..2aa4f880 100644 --- a/examples/wallets/examples/keystore_signer.rs +++ b/examples/wallets/examples/keystore_signer.rs @@ -1,7 +1,7 @@ //! Example of using a keystore wallet to sign and send a transaction. use alloy::{ - network::EthereumSigner, + network::{EthereumSigner, TransactionBuilder}, node_bindings::Anvil, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, @@ -24,21 +24,20 @@ async fn main() -> Result<()> { let keystore_file_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?).join("examples/keystore/alice.json"); let signer = Wallet::decrypt_keystore(keystore_file_path, password)?; + let alice = signer.address(); // Create a provider with the signer. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; - - // Create a transaction. - let tx = TransactionRequest { - value: Some(U256::from(100)), - to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), - nonce: Some(0), - gas_price: Some(U256::from(20e9)), - gas: Some(U256::from(21000)), - ..Default::default() - }; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; + + // Build a transaction to send 100 wei to Vitalik from Alice. + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.get_receipt().await?; diff --git a/examples/wallets/examples/ledger_signer.rs b/examples/wallets/examples/ledger_signer.rs index 39fa04fd..3fefa2b5 100644 --- a/examples/wallets/examples/ledger_signer.rs +++ b/examples/wallets/examples/ledger_signer.rs @@ -1,11 +1,14 @@ //! Example of signing and sending a transaction using a Ledger device. use alloy::{ - network::EthereumSigner, + network::{EthereumSigner, TransactionBuilder}, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, rpc::types::eth::request::TransactionRequest, - signers::ledger::{HDPath, LedgerSigner}, + signers::{ + ledger::{HDPath, LedgerSigner}, + Signer, + }, }; use eyre::Result; @@ -13,20 +16,20 @@ use eyre::Result; async fn main() -> Result<()> { // Instantiate the application by acquiring a lock on the Ledger device. let signer = LedgerSigner::new(HDPath::LedgerLive(0), Some(1)).await?; + let from = signer.address(); // Create a provider with the signer. let rpc_url = "http://localhost:8545".parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; - // Create a transaction. - let tx = TransactionRequest { - value: Some(U256::from(100)), - to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), - gas_price: Some(U256::from(20e9)), - gas: Some(U256::from(21000)), - ..Default::default() - }; + // Build a transaction to send 100 wei to Vitalik. + let tx = TransactionRequest::default() + .with_from(from) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let receipt = diff --git a/examples/wallets/examples/private_key_signer.rs b/examples/wallets/examples/private_key_signer.rs index 18dcd476..00e043da 100644 --- a/examples/wallets/examples/private_key_signer.rs +++ b/examples/wallets/examples/private_key_signer.rs @@ -1,7 +1,7 @@ //! Example of using a local wallet to sign and send a transaction. use alloy::{ - network::EthereumSigner, + network::{EthereumSigner, TransactionBuilder}, node_bindings::Anvil, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, @@ -17,21 +17,20 @@ async fn main() -> Result<()> { // Set up signer from the first default Anvil account (Alice). let signer: LocalWallet = anvil.keys()[0].clone().into(); + let alice = signer.address(); // Create a provider with the signer. let rpc_url = anvil.endpoint().parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; - - // Create a transaction. - let tx = TransactionRequest { - value: Some(U256::from(100)), - to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), - nonce: Some(0), - gas_price: Some(U256::from(20e9)), - gas: Some(U256::from(21000)), - ..Default::default() - }; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; + + // Build a transaction to send 100 wei to Vitalik. + let tx = TransactionRequest::default() + .with_from(alice) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.get_receipt().await?; diff --git a/examples/wallets/examples/trezor_signer.rs b/examples/wallets/examples/trezor_signer.rs index 61e50210..7403ebaf 100644 --- a/examples/wallets/examples/trezor_signer.rs +++ b/examples/wallets/examples/trezor_signer.rs @@ -1,11 +1,14 @@ //! Example of signing and sending a transaction using a Trezor device. use alloy::{ - network::EthereumSigner, + network::{EthereumSigner, TransactionBuilder}, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, rpc::types::eth::request::TransactionRequest, - signers::trezor::{HDPath, TrezorSigner}, + signers::{ + trezor::{HDPath, TrezorSigner}, + Signer, + }, }; use eyre::Result; @@ -13,20 +16,20 @@ use eyre::Result; async fn main() -> Result<()> { // Instantiate the application by acquiring a lock on the Trezor device. let signer = TrezorSigner::new(HDPath::TrezorLive(0), Some(1)).await?; + let from = signer.address(); // Create a provider with the signer. let rpc_url = "http://localhost:8545".parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; - // Create a transaction. - let tx = TransactionRequest { - value: Some(U256::from(100)), - to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), - gas_price: Some(U256::from(20e9)), - gas: Some(U256::from(21000)), - ..Default::default() - }; + // Build a transaction to send 100 wei to Vitalik. + let tx = TransactionRequest::default() + .with_from(from) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let receipt = diff --git a/examples/wallets/examples/yubi_signer.rs b/examples/wallets/examples/yubi_signer.rs index f8c6462f..d4578b9c 100644 --- a/examples/wallets/examples/yubi_signer.rs +++ b/examples/wallets/examples/yubi_signer.rs @@ -1,7 +1,7 @@ //! Example of signing and sending a transaction using a Yubi device. use alloy::{ - network::EthereumSigner, + network::{EthereumSigner, TransactionBuilder}, primitives::{address, U256}, providers::{Provider, ProviderBuilder}, rpc::types::eth::request::TransactionRequest, @@ -22,20 +22,20 @@ async fn main() -> Result<()> { // `from_key` method to upload a key you already have, or the `new` method // to generate a new keypair. let signer = YubiWallet::connect(connector, Credentials::default(), 0); + let from = signer.address(); // Create a provider with the signer. let rpc_url = "http://localhost:8545".parse()?; - let provider = - ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?; - - // Create a transaction. - let tx = TransactionRequest { - value: Some(U256::from(100)), - to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), - gas_price: Some(U256::from(20e9)), - gas: Some(U256::from(21000)), - ..Default::default() - }; + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .signer(EthereumSigner::from(signer)) + .on_http(rpc_url)?; + + // Build a transaction to send 100 wei to Vitalik. + let tx = TransactionRequest::default() + .with_from(from) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)); // Send the transaction and wait for the receipt. let receipt =