-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab8b5f6
commit db7d30c
Showing
4 changed files
with
155 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "examples-layers" | ||
|
||
publish.workspace = true | ||
version.workspace = true | ||
edition.workspace = true | ||
rust-version.workspace = true | ||
authors.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
|
||
[dev-dependencies] | ||
alloy-network.workspace = true | ||
alloy-node-bindings.workspace = true | ||
alloy-primitives.workspace = true | ||
alloy-provider.workspace = true | ||
alloy-rpc-client.workspace = true | ||
alloy-rpc-types.workspace = true | ||
alloy-signer-wallet.workspace = true | ||
alloy-transport-http.workspace = true | ||
|
||
reqwest.workspace = true | ||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
//! Example of using the `ManagedNonceLayer` in the provider. | ||
use alloy_network::EthereumSigner; | ||
use alloy_node_bindings::Anvil; | ||
use alloy_primitives::{address, U256, U64}; | ||
use alloy_provider::{layers::ManagedNonceLayer, Provider, ProviderBuilder, RootProvider}; | ||
use alloy_rpc_client::RpcClient; | ||
use alloy_rpc_types::request::TransactionRequest; | ||
use alloy_signer_wallet::LocalWallet; | ||
use alloy_transport_http::Http; | ||
use reqwest::Client; | ||
|
||
/// In Ethereum, the nonce of a transaction is a number that represents the number of transactions | ||
/// that have been sent from a particular account. The nonce is used to ensure that transactions are | ||
/// processed in the order they are intended, and to prevent the same transaction from being | ||
/// processed multiple times. | ||
/// | ||
/// The nonce manager in Alloy is a layer that helps you manage the nonce | ||
/// of transactions by keeping track of the current nonce for a given account and automatically | ||
/// incrementing it as needed. This can be useful if you want to ensure that transactions are sent | ||
/// in the correct order, or if you want to avoid having to manually manage the nonce yourself. | ||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Spin up a local Anvil node. | ||
// Ensure `anvil` is available in $PATH | ||
let anvil = Anvil::new().spawn(); | ||
|
||
// Set up the wallets. | ||
let wallet: LocalWallet = anvil.keys()[0].clone().into(); | ||
let from = wallet.address(); | ||
|
||
// Create a provider with a signer and the network. | ||
let http = Http::<Client>::new(anvil.endpoint().parse()?); | ||
let provider = ProviderBuilder::new() | ||
.layer(ManagedNonceLayer) | ||
.signer(EthereumSigner::from(wallet)) | ||
.provider(RootProvider::new(RpcClient::new(http, true))); | ||
|
||
let tx = TransactionRequest { | ||
from: Some(from), | ||
value: Some(U256::from(100)), | ||
to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), | ||
gas_price: Some(U256::from(20e9)), | ||
gas: Some(U256::from(21000)), | ||
..Default::default() | ||
}; | ||
|
||
let pending = provider.send_transaction(tx.clone()).await?; | ||
let tx_hash = pending.watch().await?; | ||
let mined_tx = provider.get_transaction_by_hash(tx_hash).await?; | ||
assert_eq!(mined_tx.nonce, U64::from(0)); | ||
|
||
println!("Transaction sent with nonce: {}", mined_tx.nonce); | ||
|
||
let pending = provider.send_transaction(tx).await?; | ||
let tx_hash = pending.watch().await?; | ||
let mined_tx = provider.get_transaction_by_hash(tx_hash).await?; | ||
assert_eq!(mined_tx.nonce, U64::from(1)); | ||
|
||
println!("Transaction sent with nonce: {}", mined_tx.nonce); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//! Example of using the `SignerLayer` in the provider. | ||
use alloy_network::EthereumSigner; | ||
use alloy_node_bindings::Anvil; | ||
use alloy_primitives::{address, b256, U256, U64}; | ||
use alloy_provider::{Provider, ProviderBuilder, RootProvider}; | ||
use alloy_rpc_client::RpcClient; | ||
use alloy_rpc_types::request::TransactionRequest; | ||
use alloy_signer_wallet::LocalWallet; | ||
use alloy_transport_http::Http; | ||
use reqwest::Client; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Spin up a local Anvil node. | ||
// Ensure `anvil` is available in $PATH | ||
let anvil = Anvil::new().spawn(); | ||
|
||
// Set up the wallets. | ||
let wallet: LocalWallet = anvil.keys()[0].clone().into(); | ||
|
||
// Create a provider with a signer and the network. | ||
let http = Http::<Client>::new(anvil.endpoint().parse()?); | ||
let provider = ProviderBuilder::new() | ||
.signer(EthereumSigner::from(wallet)) | ||
.provider(RootProvider::new(RpcClient::new(http, true))); | ||
|
||
let tx = TransactionRequest { | ||
nonce: Some(U64::from(0)), | ||
value: Some(U256::from(100)), | ||
to: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into(), | ||
gas_price: Some(U256::from(20e9)), | ||
gas: Some(U256::from(21000)), | ||
..Default::default() | ||
}; | ||
|
||
let builder = provider.send_transaction(tx).await?; | ||
let node_hash = *builder.tx_hash(); | ||
|
||
println!( | ||
"Node hash matches expected hash: {}", | ||
node_hash == b256!("eb56033eab0279c6e9b685a5ec55ea0ff8d06056b62b7f36974898d4fbb57e64") | ||
); | ||
|
||
let pending = builder.register().await?; | ||
let pending_transaction_hash = *pending.tx_hash(); | ||
|
||
println!( | ||
"Pending transaction hash matches node hash: {}", | ||
pending_transaction_hash == node_hash | ||
); | ||
|
||
let transaction_hash = pending.await?; | ||
assert_eq!(transaction_hash, node_hash); | ||
|
||
println!("Transaction hash matches node hash: {}", transaction_hash == node_hash); | ||
|
||
let receipt = | ||
provider.get_transaction_receipt(transaction_hash).await.unwrap().expect("no receipt"); | ||
let receipt_hash = receipt.transaction_hash.expect("no receipt hash"); | ||
|
||
println!("Receipt hash matches node hash: {}", receipt_hash == node_hash); | ||
|
||
Ok(()) | ||
} |