From 5d0503603248d81ad1e0ee3e7995d1f1a79a8449 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Tue, 26 Mar 2024 11:59:59 +0000 Subject: [PATCH 1/2] add recommended layers example and additional comments to mark the differences --- Cargo.toml | 2 +- README.md | 1 + examples/layers/examples/nonce_layer.rs | 6 +- .../layers/examples/recommended_layers.rs | 60 +++++++++++++++++++ examples/layers/examples/signer_layer.rs | 2 + 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 examples/layers/examples/recommended_layers.rs diff --git a/Cargo.toml b/Cargo.toml index 55a00649..0894c2c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ publish = false exclude = ["examples/"] [workspace.dependencies] -alloy = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [ +alloy = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ # "dyn-abi", # "json-abi", # "json", diff --git a/README.md b/README.md index 0d5284ef..14f94db3 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ cargo run --example mnemonic_signer - [x] [Deploy from contract](./examples/contracts/examples/deploy_from_contract.rs) - [x] [Generate](./examples/contracts/examples/generate.rs) - [x] Layers + - [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] Subscriptions diff --git a/examples/layers/examples/nonce_layer.rs b/examples/layers/examples/nonce_layer.rs index a2378fd8..0e6b1864 100644 --- a/examples/layers/examples/nonce_layer.rs +++ b/examples/layers/examples/nonce_layer.rs @@ -32,7 +32,9 @@ async fn main() -> Result<()> { // Create a provider with the signer. let http = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - // Add the `ManagedNonceLayer` to the provider + // Add the `ManagedNonceLayer` to the provider. + // It is generally recommended to use the `.with_recommended_layers()` method, which + // includes the `ManagedNonceLayer`. .layer(ManagedNonceLayer) .signer(EthereumSigner::from(wallet)) .on_client(RpcClient::new_http(http)); @@ -42,9 +44,11 @@ async fn main() -> Result<()> { .with_from(from) .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").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. .with_chain_id(anvil.chain_id()); // Send the transaction, the nonce (0) is automatically managed by the provider. diff --git a/examples/layers/examples/recommended_layers.rs b/examples/layers/examples/recommended_layers.rs new file mode 100644 index 00000000..1efb549c --- /dev/null +++ b/examples/layers/examples/recommended_layers.rs @@ -0,0 +1,60 @@ +//! Example of using the `ManagedNonceLayer` in the provider. + +use alloy::{ + network::{EthereumSigner, TransactionBuilder}, + node_bindings::Anvil, + primitives::{address, U256}, + providers::{Provider, ProviderBuilder}, + rpc::{client::RpcClient, 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 the wallets. + let wallet: LocalWallet = anvil.keys()[0].clone().into(); + let from = wallet.address(); + + // Create a provider with the signer. + let http = anvil.endpoint().parse()?; + let provider = ProviderBuilder::new() + // Adds the `GasEstimatorLayer` and the `ManagedNonceLayer` layers. + .with_recommended_layers() + // Alternatively, you can add the layers individually: + // .with_gas_estimation() + // .with_nonce_management() + .signer(EthereumSigner::from(wallet)) + .on_client(RpcClient::new_http(http)); + + // Create an EIP-1559 type transaction. + // Notice that the `nonce` field is set by the `ManagedNonceLayer`. + // Notice that without the `GasEstimatorLayer`, you need to set the gas related fields. + let tx = TransactionRequest::default() + .with_from(from) + .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .with_value(U256::from(100)) + .with_chain_id(anvil.chain_id()); + + // 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_transaction = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_transaction.nonce, 0); + + println!("Transaction sent with nonce: {}", pending_transaction.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_transaction = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_transaction.nonce, 1); + + println!("Transaction sent with nonce: {}", pending_transaction.nonce); + + Ok(()) +} diff --git a/examples/layers/examples/signer_layer.rs b/examples/layers/examples/signer_layer.rs index 46a4b82f..82fb4fa8 100644 --- a/examples/layers/examples/signer_layer.rs +++ b/examples/layers/examples/signer_layer.rs @@ -29,10 +29,12 @@ async fn main() -> Result<()> { // Create a legacy type transaction. let tx = TransactionRequest::default() + // Notice that without the `ManagedNonceLayer`, you need to manually set the nonce field. .with_nonce(0) .with_from(from) .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").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)); From fff6a814e66573ac4c17bc72947a02590529d4a0 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Tue, 26 Mar 2024 12:04:28 +0000 Subject: [PATCH 2/2] update to f7333c4 --- examples/providers/Cargo.toml | 4 ++-- examples/subscriptions/Cargo.toml | 4 ++-- examples/transactions/examples/transfer_erc20.rs | 2 +- examples/wallets/examples/ledger_signer.rs | 3 ++- examples/wallets/examples/trezor_signer.rs | 3 ++- examples/wallets/examples/yubi_signer.rs | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/providers/Cargo.toml b/examples/providers/Cargo.toml index 77070624..52f37ca3 100644 --- a/examples/providers/Cargo.toml +++ b/examples/providers/Cargo.toml @@ -13,10 +13,10 @@ repository.workspace = true [dev-dependencies] alloy.workspace = true # Temp dependency fix to enable relevant features - Ref: https://github.com/alloy-rs/examples/pull/3#discussion_r1537842062 -alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [ +alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ "pubsub", ] } -alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [ +alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ "pubsub", "ws", ] } diff --git a/examples/subscriptions/Cargo.toml b/examples/subscriptions/Cargo.toml index e37af35e..cd7a213c 100644 --- a/examples/subscriptions/Cargo.toml +++ b/examples/subscriptions/Cargo.toml @@ -13,11 +13,11 @@ repository.workspace = true [dev-dependencies] alloy.workspace = true # Temp fix for enabling features. Ref: https://github.com/alloy-rs/examples/pull/3/#discussion_r1537842062 -alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [ +alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ "pubsub", "ws", ] } -alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [ +alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ "pubsub", ] } # alloy-contract.workspace = true diff --git a/examples/transactions/examples/transfer_erc20.rs b/examples/transactions/examples/transfer_erc20.rs index b030b68a..a826db50 100644 --- a/examples/transactions/examples/transfer_erc20.rs +++ b/examples/transactions/examples/transfer_erc20.rs @@ -43,7 +43,7 @@ async fn main() -> Result<()> { println!("Transfer tx: {:?}", pending_tx.tx_hash()); // Wait for confirmation - let _ = pending_tx.with_confirmations(1); + let _ = pending_tx.with_required_confirmations(1); let to_bal = balance_of(&provider, to, contract_address).await?; let from_bal = balance_of(&provider, from, contract_address).await?; diff --git a/examples/wallets/examples/ledger_signer.rs b/examples/wallets/examples/ledger_signer.rs index 2efb4d25..1b7a238b 100644 --- a/examples/wallets/examples/ledger_signer.rs +++ b/examples/wallets/examples/ledger_signer.rs @@ -30,7 +30,8 @@ async fn main() -> Result<()> { }; // Broadcast the transaction and wait for the receipt. - let receipt = provider.send_transaction(tx).await?.with_confirmations(3).get_receipt().await?; + let receipt = + provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?; println!("Send transaction: {:?}", receipt.transaction_hash); diff --git a/examples/wallets/examples/trezor_signer.rs b/examples/wallets/examples/trezor_signer.rs index 73cf13e5..4884e1b2 100644 --- a/examples/wallets/examples/trezor_signer.rs +++ b/examples/wallets/examples/trezor_signer.rs @@ -30,7 +30,8 @@ async fn main() -> Result<()> { }; // Broadcast the transaction and wait for the receipt. - let receipt = provider.send_transaction(tx).await?.with_confirmations(3).get_receipt().await?; + let receipt = + provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?; println!("Send transaction: {:?}", receipt.transaction_hash); diff --git a/examples/wallets/examples/yubi_signer.rs b/examples/wallets/examples/yubi_signer.rs index 35823920..d1ebb908 100644 --- a/examples/wallets/examples/yubi_signer.rs +++ b/examples/wallets/examples/yubi_signer.rs @@ -39,7 +39,8 @@ async fn main() -> Result<()> { }; // Broadcast the transaction and wait for the receipt. - let receipt = provider.send_transaction(tx).await?.with_confirmations(3).get_receipt().await?; + let receipt = + provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?; println!("Send transaction: {:?}", receipt.transaction_hash);