diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..e2cefa70 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,33 @@ + + + + +## Motivation + + + +## Solution + + + +## PR Checklist + +- [ ] Added Documentation +- [ ] Breaking changes \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f18c94e..8924ccce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -125,11 +125,13 @@ less work from you. This section lists some commonly needed commands. ```sh -cargo check --all-features +cargo check --examples --all-features +cargo build --examples --all-features cargo +nightly fmt --all -cargo build --all-features -cargo test --all-features -cargo +nightly clippy --all-features +cargo +nightly clippy \ + --examples \ + --all-features \ + -- -D warnings ``` ### Tests diff --git a/Cargo.toml b/Cargo.toml index cc56a751..4eb6470b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,50 @@ repository = "https://github.com/alloy-rs/examples" publish = false exclude = ["examples/"] +[workspace.lints] +rust.missing_debug_implementations = "warn" +rust.missing_docs = "warn" +rust.unreachable_pub = "warn" +rustdoc.all = "warn" +rust.unused_must_use = "deny" +rust.rust_2018_idioms = "deny" + +[workspace.lints.clippy] +# These are some of clippy's nursery (i.e., experimental) lints that we like. +# By default, nursery lints are allowed. Some of the lints below have made good +# suggestions which we fixed. The others didn't have any findings, so we can +# assume they don't have that many false positives. Let's enable them to +# prevent future problems. +branches_sharing_code = "warn" +clear_with_drain = "warn" +derive_partial_eq_without_eq = "warn" +empty_line_after_outer_attr = "warn" +equatable_if_let = "warn" +imprecise_flops = "warn" +iter_on_empty_collections = "warn" +iter_with_drain = "warn" +large_stack_frames = "warn" +manual_clamp = "warn" +mutex_integer = "warn" +needless_pass_by_ref_mut = "warn" +nonstandard_macro_braces = "warn" +or_fun_call = "warn" +path_buf_push_overwrite = "warn" +read_zero_byte_vec = "warn" +redundant_clone = "warn" +suboptimal_flops = "warn" +suspicious_operation_groupings = "warn" +trailing_empty_array = "warn" +trait_duplication_in_bounds = "warn" +transmute_undefined_repr = "warn" +trivial_regex = "warn" +tuple_array_conversions = "warn" +uninhabited_references = "warn" +unused_peekable = "warn" +unused_rounding = "warn" +useless_let_if_seq = "warn" +uninlined_format_args = "warn" + [workspace.dependencies] alloy = { git = "https://github.com/alloy-rs/alloy", rev = "f7333c4", features = [ # "dyn-abi", diff --git a/README.md b/README.md index 14f94db3..302d8d99 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ Example code using [alloy](https://github.com/alloy-rs/alloy) and [alloy-core](https://github.com/alloy-rs/core). These examples demonstrate the main features of [Alloy](https://github.com/alloy-rs/alloy) and how to use them. -To run an example, use the command `cargo run --example `. + +To run an example, use the command `cargo run --example `: ```sh cargo run --example mnemonic_signer diff --git a/examples/anvil/Cargo.toml b/examples/anvil/Cargo.toml index 7d05a6e4..89ebcca5 100644 --- a/examples/anvil/Cargo.toml +++ b/examples/anvil/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-anvil" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/anvil/examples/deploy_contract_anvil.rs b/examples/anvil/examples/deploy_contract_anvil.rs index a1c55994..152665d9 100644 --- a/examples/anvil/examples/deploy_contract_anvil.rs +++ b/examples/anvil/examples/deploy_contract_anvil.rs @@ -13,6 +13,7 @@ use eyre::Result; // Codegen from embedded Solidity code and precompiled bytecode. sol! { + #[allow(missing_docs)] // solc v0.8.24; solc a.sol --via-ir --optimize --bin #[sol(rpc, bytecode="608080604052346100155760d2908161001a8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c9081633fb5c1cb1460865781638381f58a14606f575063d09de08a146039575f80fd5b34606b575f366003190112606b575f545f1981146057576001015f55005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b34606b575f366003190112606b576020905f548152f35b34606b576020366003190112606b576004355f5500fea2646970667358221220bdecd3c1dd631eb40587cafcd6e8297479db76db6a328e18ad1ea5b340852e3864736f6c63430008180033")] contract Counter { @@ -31,17 +32,17 @@ sol! { #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().try_spawn()?; - // Set up wallet - let wallet: LocalWallet = anvil.keys()[0].clone().into(); + // Set up signer from the first default Anvil account (Alice). + let signer: LocalWallet = anvil.keys()[0].clone().into(); // Create a provider with a signer and the network. - let http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); println!("Anvil running at `{}`", anvil.endpoint()); @@ -54,7 +55,7 @@ async fn main() -> Result<()> { let contract_address = contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; - println!("Deployed contract at address: {:?}", contract_address); + println!("Deployed contract at address: {contract_address:?}"); let contract = Counter::new(contract_address, &provider); diff --git a/examples/anvil/examples/fork_anvil.rs b/examples/anvil/examples/fork_anvil.rs index 345a8ead..03ff1ca5 100644 --- a/examples/anvil/examples/fork_anvil.rs +++ b/examples/anvil/examples/fork_anvil.rs @@ -6,7 +6,7 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/anvil/examples/local_anvil.rs b/examples/anvil/examples/local_anvil.rs index c7a1a9ef..c69d7ab1 100644 --- a/examples/anvil/examples/local_anvil.rs +++ b/examples/anvil/examples/local_anvil.rs @@ -6,7 +6,7 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().block_time(1).chain_id(1337).try_spawn()?; println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/big-numbers/Cargo.toml b/examples/big-numbers/Cargo.toml index a8972527..17a46eef 100644 --- a/examples/big-numbers/Cargo.toml +++ b/examples/big-numbers/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-big-numbers" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml index e634e711..d02f79ea 100644 --- a/examples/contracts/Cargo.toml +++ b/examples/contracts/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-contracts" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index 8bf1ad80..26970c26 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -13,6 +13,7 @@ use eyre::Result; // Codegen from artifact. sol!( + #[allow(missing_docs)] #[sol(rpc)] Counter, "examples/artifacts/Counter.json" @@ -21,17 +22,17 @@ sol!( #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().try_spawn()?; - // Set up wallet - let wallet: LocalWallet = anvil.keys()[0].clone().into(); + // Set up signer from the first default Anvil account (Alice). + let signer: LocalWallet = anvil.keys()[0].clone().into(); // Create a provider with a signer. - let http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); println!("Anvil running at `{}`", anvil.endpoint()); @@ -44,7 +45,7 @@ async fn main() -> Result<()> { let contract_address = contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; - println!("Deployed contract at address: {:?}", contract_address); + println!("Deployed contract at address: {contract_address:?}"); let contract = Counter::new(contract_address, &provider); diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 6853aded..9ac06ba4 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -13,6 +13,7 @@ use eyre::Result; // Codegen from embedded Solidity code and precompiled bytecode. sol! { + #[allow(missing_docs)] // solc v0.8.24; solc a.sol --via-ir --optimize --bin #[sol(rpc, bytecode="608080604052346100155760d2908161001a8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c9081633fb5c1cb1460865781638381f58a14606f575063d09de08a146039575f80fd5b34606b575f366003190112606b575f545f1981146057576001015f55005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b34606b575f366003190112606b576020905f548152f35b34606b576020366003190112606b576004355f5500fea2646970667358221220bdecd3c1dd631eb40587cafcd6e8297479db76db6a328e18ad1ea5b340852e3864736f6c63430008180033")] contract Counter { @@ -31,17 +32,17 @@ sol! { #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().try_spawn()?; - // Set up wallet - let wallet: LocalWallet = anvil.keys()[0].clone().into(); + // Set up signer from the first default Anvil account (Alice). + let signer: LocalWallet = anvil.keys()[0].clone().into(); // Create a provider with a signer. - let http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); println!("Anvil running at `{}`", anvil.endpoint()); @@ -54,7 +55,7 @@ async fn main() -> Result<()> { let contract_address = contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; - println!("Deployed contract at address: {:?}", contract_address); + println!("Deployed contract at address: {contract_address:?}"); let contract = Counter::new(contract_address, &provider); diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index 4c7500a5..4055e3ee 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -5,6 +5,7 @@ use eyre::Result; // Codegen from ABI file to interact with the contract. sol!( + #[allow(missing_docs)] #[sol(rpc)] IERC20, "examples/abi/IERC20.json" @@ -13,7 +14,7 @@ sol!( #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; // Create a provider. diff --git a/examples/layers/Cargo.toml b/examples/layers/Cargo.toml index 2f182349..bbd8ee43 100644 --- a/examples/layers/Cargo.toml +++ b/examples/layers/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-layers" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/layers/examples/nonce_layer.rs b/examples/layers/examples/nonce_layer.rs index 0e6b1864..f7d8a237 100644 --- a/examples/layers/examples/nonce_layer.rs +++ b/examples/layers/examples/nonce_layer.rs @@ -22,27 +22,30 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // 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(); + // 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 http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() // 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)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); // Create an EIP-1559 type transaction. let tx = TransactionRequest::default() - .with_from(from) - .with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) + .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)) @@ -54,18 +57,18 @@ async fn main() -> Result<()> { // 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); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 0); - println!("Transaction sent with nonce: {}", pending_transaction.nonce); + 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_transaction = provider.get_transaction_by_hash(node_hash).await?; - assert_eq!(pending_transaction.nonce, 1); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 1); - println!("Transaction sent with nonce: {}", pending_transaction.nonce); + println!("Transaction sent with nonce: {}", pending_tx.nonce); Ok(()) } diff --git a/examples/layers/examples/recommended_layers.rs b/examples/layers/examples/recommended_layers.rs index 1efb549c..7d274c87 100644 --- a/examples/layers/examples/recommended_layers.rs +++ b/examples/layers/examples/recommended_layers.rs @@ -13,48 +13,51 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // 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(); + // 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 http = anvil.endpoint().parse()?; + let rpc_url = 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)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); // 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_from(alice) + .with_to(vitalik.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); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 0); - println!("Transaction sent with nonce: {}", pending_transaction.nonce); + 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_transaction = provider.get_transaction_by_hash(node_hash).await?; - assert_eq!(pending_transaction.nonce, 1); + let pending_tx = provider.get_transaction_by_hash(node_hash).await?; + assert_eq!(pending_tx.nonce, 1); - println!("Transaction sent with nonce: {}", pending_transaction.nonce); + println!("Transaction sent with nonce: {}", pending_tx.nonce); Ok(()) } diff --git a/examples/layers/examples/signer_layer.rs b/examples/layers/examples/signer_layer.rs index 82fb4fa8..d204a4e9 100644 --- a/examples/layers/examples/signer_layer.rs +++ b/examples/layers/examples/signer_layer.rs @@ -13,26 +13,29 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // 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(); + // 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 http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() // Add the `SignerLayer` to the provider - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); // Create a legacy type transaction. let tx = TransactionRequest::default() + .with_from(alice) // 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_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)) @@ -46,21 +49,17 @@ async fn main() -> Result<()> { node_hash == b256!("eb56033eab0279c6e9b685a5ec55ea0ff8d06056b62b7f36974898d4fbb57e64") ); - let pending = builder.register().await?; - let pending_transaction_hash = *pending.tx_hash(); + let pending_tx = builder.register().await?; + let pending_tx_hash = *pending_tx.tx_hash(); - println!( - "Pending transaction hash matches node hash: {}", - pending_transaction_hash == node_hash - ); + println!("Pending transaction hash matches node hash: {}", pending_tx_hash == node_hash); - let transaction_hash = pending.await?; - assert_eq!(transaction_hash, node_hash); + let tx_hash = pending_tx.await?; + assert_eq!(tx_hash, node_hash); - println!("Transaction hash matches node hash: {}", transaction_hash == node_hash); + println!("Transaction hash matches node hash: {}", tx_hash == node_hash); - let receipt = - provider.get_transaction_receipt(transaction_hash).await.unwrap().expect("no receipt"); + let receipt = provider.get_transaction_receipt(tx_hash).await?.expect("Receipt not found"); let receipt_hash = receipt.transaction_hash; assert_eq!(receipt_hash, node_hash); diff --git a/examples/providers/Cargo.toml b/examples/providers/Cargo.toml index 6e2768c3..f48fae12 100644 --- a/examples/providers/Cargo.toml +++ b/examples/providers/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-providers" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +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 diff --git a/examples/providers/examples/builder.rs b/examples/providers/examples/builder.rs index e9e0d566..bf626acd 100644 --- a/examples/providers/examples/builder.rs +++ b/examples/providers/examples/builder.rs @@ -6,43 +6,53 @@ use alloy::{ primitives::U256, providers::{Provider, ProviderBuilder, RootProvider}, rpc::{client::RpcClient, types::eth::TransactionRequest}, - signers::wallet::Wallet, + signers::wallet::LocalWallet, }; use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().block_time(1).try_spawn()?; - let pk = &anvil.keys()[0]; - let from = anvil.addresses()[0]; - let signer = Wallet::from(pk.to_owned()); + // Set up signer from the first default Anvil account (Alice). + let wallet: LocalWallet = anvil.keys()[0].clone().into(); - // Setup the HTTP transport which is consumed by the RPC client - let rpc_client = RpcClient::new_http(anvil.endpoint().parse().unwrap()); + // Create two users, Alice and Bob. + let alice = wallet.address(); + let bob = anvil.addresses()[1]; + + // Set up the HTTP transport which is consumed by the RPC client. + let rpc_client = RpcClient::new_http(anvil.endpoint().parse()?); let provider_with_signer = ProviderBuilder::new() - .signer(EthereumSigner::from(signer)) + .signer(EthereumSigner::from(wallet)) .provider(RootProvider::new(rpc_client)); - let to = anvil.addresses()[1]; - - let mut tx_req = TransactionRequest::default() - .to(Some(to)) + // Create a transaction. + let mut tx = TransactionRequest::default() + .to(Some(bob)) .value(U256::from(100)) .nonce(0) .gas_limit(U256::from(21000)); - tx_req.set_gas_price(U256::from(20e9)); + tx.set_gas_price(U256::from(20e9)); - let pending_tx = provider_with_signer.send_transaction(tx_req).await?; + // Send the transaction and wait for the receipt. + let pending_tx = provider_with_signer.send_transaction(tx).await?; println!("Pending transaction...{:?}", pending_tx.tx_hash()); + // Wait for the transaction to be included. let receipt = pending_tx.get_receipt().await?; - assert_eq!(receipt.from, from); + println!( + "Transaction included in block: {:?}", + receipt.block_number.expect("Failed to get block number").to_string() + ); + + assert_eq!(receipt.from, alice); + assert_eq!(receipt.to, Some(bob)); Ok(()) } diff --git a/examples/providers/examples/http.rs b/examples/providers/examples/http.rs index 2d94ed57..39d6425f 100644 --- a/examples/providers/examples/http.rs +++ b/examples/providers/examples/http.rs @@ -9,20 +9,20 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - // Setup the HTTP transport which is consumed by the RPC client + // Set up the HTTP transport which is consumed by the RPC client. let rpc_url = "https://eth.merkle.io".parse()?; - // Create the RPC client + // Create the RPC client. let rpc_client = RpcClient::new_http(rpc_url); // Provider can then be instantiated using the RPC client, HttpProvider is an alias // RootProvider. RootProvider requires two generics N: Network and T: Transport let provider = HttpProvider::::new(rpc_client); - // Get latest block number + // Get latest block number. let latest_block = provider.get_block_number().await?; - println!("Latest block number: {}", latest_block); + println!("Latest block number: {latest_block}"); Ok(()) } diff --git a/examples/providers/examples/ipc.rs b/examples/providers/examples/ipc.rs index 078a6b86..6e7d9125 100644 --- a/examples/providers/examples/ipc.rs +++ b/examples/providers/examples/ipc.rs @@ -10,20 +10,21 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - // Setup the IPC transport which is consumed by the RPC client + // Set up the IPC transport which is consumed by the RPC client. let ipc_path = "/tmp/reth.ipc"; - // IPC transport + // Create the IPC connection object. let ipc = IpcConnect::new(ipc_path.to_string()); - // RPC client using IPC transport + // Connect to the IPC client. let ipc_client = RpcClient::connect_pubsub(ipc).await?; + // Create the provider. let provider = RootProvider::::new(ipc_client); let latest_block = provider.get_block_number().await?; - println!("Latest block: {}", latest_block); + println!("Latest block: {latest_block}"); Ok(()) } diff --git a/examples/providers/examples/ws.rs b/examples/providers/examples/ws.rs index 65991af3..60c5a07e 100644 --- a/examples/providers/examples/ws.rs +++ b/examples/providers/examples/ws.rs @@ -10,17 +10,24 @@ use futures_util::StreamExt; #[tokio::main] async fn main() -> Result<()> { + // Set up the WS transport which is consumed by the RPC client. let rpc_url = "wss://eth-mainnet.g.alchemy.com/v2/your-api-key"; + // Create the WS connection object. let ws_transport = WsConnect::new(rpc_url); + // Connect to the WS client. let rpc_client = RpcClient::connect_pubsub(ws_transport).await?; + // Create the provider. let provider = RootProvider::::new(rpc_client); + // Subscribe to new blocks. let sub = provider.subscribe_blocks().await?; + // Wait and take the next 4 blocks. let mut stream = sub.into_stream().take(4); + println!("Awaiting blocks..."); while let Some(block) = stream.next().await { diff --git a/examples/providers/examples/ws_with_auth.rs b/examples/providers/examples/ws_with_auth.rs index b9456cfa..116f45e2 100644 --- a/examples/providers/examples/ws_with_auth.rs +++ b/examples/providers/examples/ws_with_auth.rs @@ -10,46 +10,50 @@ use futures_util::StreamExt; #[tokio::main] async fn main() -> Result<()> { + // Set up the WS transport which is consumed by the RPC client. let rpc_url = "wss://your-ws-endpoint.com/"; + // Create authorization methods. let auth = Authorization::basic("username", "password"); let auth_bearer = Authorization::bearer("bearer-token"); + // Create the WS connection object with authentication. let ws_transport_basic = WsConnect::with_auth(rpc_url, Some(auth)); - let ws_transport_bearer = WsConnect::with_auth(rpc_url, Some(auth_bearer)); + // Connect to the WS client. let rpc_client_basic = RpcClient::connect_pubsub(ws_transport_basic).await?; - let rpc_client_bearer = RpcClient::connect_pubsub(ws_transport_bearer).await?; + // Create the provider. let provider_basic = RootProvider::::new(rpc_client_basic); - let provider_bearer = RootProvider::::new(rpc_client_bearer); + // Subscribe to new blocks. let sub_basic = provider_basic.subscribe_blocks(); let sub_bearer = provider_bearer.subscribe_blocks(); + // Wait and take the next 4 blocks. let mut stream_basic = sub_basic.await?.into_stream().take(4); let mut stream_bearer = sub_bearer.await?.into_stream().take(4); println!("Awaiting blocks..."); - // Spawning the block processing for basic auth as a new task + // Spawning the block processing for basic auth as a new task. let basic_handle = tokio::spawn(async move { while let Some(block) = stream_basic.next().await { println!("From basic {:?}", block.header.number); } }); - // Similarly for bearer auth + // Similarly for bearer auth. let bearer_handle = tokio::spawn(async move { while let Some(block) = stream_bearer.next().await { println!("From bearer {:?}", block.header.number); } }); - // Wait for both tasks to complete + // Wait for both tasks to complete. let _ = tokio::try_join!(basic_handle, bearer_handle)?; Ok(()) diff --git a/examples/queries/Cargo.toml b/examples/queries/Cargo.toml index edac004c..b279e731 100644 --- a/examples/queries/Cargo.toml +++ b/examples/queries/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-queries" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/queries/examples/query_contract_storage.rs b/examples/queries/examples/query_contract_storage.rs index e583a187..f4a3769a 100644 --- a/examples/queries/examples/query_contract_storage.rs +++ b/examples/queries/examples/query_contract_storage.rs @@ -9,17 +9,16 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - let url = "https://eth.merkle.io".parse().unwrap(); - let provider = RootProvider::::new_http(url); + // Create a provider. + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = RootProvider::::new_http(rpc_url); - // Get slot0 from USDC-ETH Uniswap V3 pool + // 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?; - println!("Slot 0: {:?}", storage); + println!("Slot 0: {storage:?}"); Ok(()) } diff --git a/examples/queries/examples/query_deployed_bytecode.rs b/examples/queries/examples/query_deployed_bytecode.rs index 990308f6..22061089 100644 --- a/examples/queries/examples/query_deployed_bytecode.rs +++ b/examples/queries/examples/query_deployed_bytecode.rs @@ -1,4 +1,4 @@ -//! Example of querying deployed bytecode of a contract on Ethereum network. +//! Example of querying deployed bytecode of a contract on the Ethereum network. use alloy::{ network::Ethereum, @@ -10,16 +10,16 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - let url = "https://eth.merkle.io".parse().unwrap(); - let provider = RootProvider::::new_http(url); + // Create a provider. + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = RootProvider::::new_http(rpc_url); - // Get bytecode of USDC-ETH Uniswap V3 pool + // Get the bytecode of the Uniswap V3 USDC-ETH pool on Ethereum mainnet. let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"); - let bytecode = provider.get_code_at(pool_address, BlockId::Number(BlockNumberOrTag::Latest)).await?; - println!("Bytecode: {:?}", bytecode); + println!("Bytecode: {bytecode:?}"); Ok(()) } diff --git a/examples/queries/examples/query_logs.rs b/examples/queries/examples/query_logs.rs index 004418e5..a79644f0 100644 --- a/examples/queries/examples/query_logs.rs +++ b/examples/queries/examples/query_logs.rs @@ -1,50 +1,55 @@ +//! Example of querying logs from the Ethereum network. + use alloy::{ network::Ethereum, - primitives::{address, fixed_bytes}, + primitives::{address, b256}, providers::{Provider, RootProvider}, rpc::types::eth::Filter, }; use eyre::Result; + #[tokio::main] async fn main() -> Result<()> { - let url = "https://eth.merkle.io".parse().unwrap(); - let provider = RootProvider::::new_http(url); + // Create a provider. + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = RootProvider::::new_http(rpc_url); // Get logs from the latest block let latest_block = provider.get_block_number().await?; - // Get all logs from the latest block + // Create a filter to get all logs from the latest block. let filter = Filter::new().from_block(latest_block); + // Get all logs from the latest block that match the filter. let logs = provider.get_logs(&filter).await?; for log in logs { - println!("{:?}", log); + println!("{log:?}"); } + // Get all logs from the latest block that match the transfer event signature/topic. let tranfer_event_signature = - fixed_bytes!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"); - - // Get all logs from the latest block that match the transfer event signature/topic + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"); let filter = Filter::new().event_signature(tranfer_event_signature).from_block(latest_block); // You could also use the event name instead of the event signature like so: // .event("Transfer(address,address,uint256)") + // Get all logs from the latest block that match the filter. let logs = provider.get_logs(&filter).await?; for log in logs { - println!("Transfer event: {:?}", log); + println!("Transfer event: {log:?}"); } - let uni_address = address!("1f9840a85d5aF5bf1D1762F925BDADdC4201F984"); - - // Get all from the latest block emitted by the UNI token address - let filter = Filter::new().address(uni_address).from_block(latest_block); + // Get all from the latest block emitted by the UNI token address. + let uniswap_token_address = address!("1f9840a85d5aF5bf1D1762F925BDADdC4201F984"); + let filter = Filter::new().address(uniswap_token_address).from_block(latest_block); + // Get all logs from the latest block that match the filter. let logs = provider.get_logs(&filter).await?; for log in logs { - println!("UNI token logs: {:?}", log); + println!("Uniswap token logs: {log:?}"); } Ok(()) diff --git a/examples/subscriptions/Cargo.toml b/examples/subscriptions/Cargo.toml index 2a939ab6..d44e0a47 100644 --- a/examples/subscriptions/Cargo.toml +++ b/examples/subscriptions/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-subscriptions" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true # Temp fix for enabling features. Ref: https://github.com/alloy-rs/examples/pull/3/#discussion_r1537842062 diff --git a/examples/subscriptions/examples/event_multiplexer.rs b/examples/subscriptions/examples/event_multiplexer.rs index 8b8ef71b..6b1b79cd 100644 --- a/examples/subscriptions/examples/event_multiplexer.rs +++ b/examples/subscriptions/examples/event_multiplexer.rs @@ -1,15 +1,17 @@ -//! Example of multiplexing watching event logs. +//! Example of multiplexing the watching of event logs. use alloy::{network::Ethereum, node_bindings::Anvil, primitives::I256, sol, sol_types::SolEvent}; use alloy_provider::RootProvider; -use alloy_rpc_client::RpcClient; +use alloy_rpc_client::{RpcClient, WsConnect}; use eyre::Result; use futures_util::StreamExt; use std::str::FromStr; +// Codegen from embedded Solidity code and precompiled bytecode. +// solc v0.8.24; solc a.sol --via-ir --optimize --bin sol!( - #[derive(Debug)] - #[sol(rpc, bytecode = "0x608060405234801561001057600080fd5b50610485806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634350913814610051578063a5f3c23b1461006d578063adefc37b14610089578063bbe93d91146100a5575b600080fd5b61006b60048036038101906100669190610248565b6100c1565b005b61008760048036038101906100829190610248565b610114565b005b6100a3600480360381019061009e9190610248565b610167565b005b6100bf60048036038101906100ba9190610248565b6101ba565b005b80826100cd91906102e6565b3373ffffffffffffffffffffffffffffffffffffffff167f1c1e8bbe327890ea8d3f5b22370a56c3fcef7ff82f306161f64647fe5d28588160405160405180910390a35050565b80826101209190610350565b3373ffffffffffffffffffffffffffffffffffffffff167f6da406ea462447ed7804b4a4dc69c67b53d3d45a50381ae3e9cf878c9d7c23df60405160405180910390a35050565b80826101739190610394565b3373ffffffffffffffffffffffffffffffffffffffff167f32e913bf2ad35da1e845597618bb9f3f80642a68dd39f30a093a7838aa61fb2760405160405180910390a35050565b80826101c691906103d7565b3373ffffffffffffffffffffffffffffffffffffffff167fd7a123d4c8e44db3186e04b9c96c102287276929c930f2e8abcaa555ef5dcacc60405160405180910390a35050565b600080fd5b6000819050919050565b61022581610212565b811461023057600080fd5b50565b6000813590506102428161021c565b92915050565b6000806040838503121561025f5761025e61020d565b5b600061026d85828601610233565b925050602061027e85828601610233565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006102f182610212565b91506102fc83610212565b92508261030c5761030b610288565b5b600160000383147f800000000000000000000000000000000000000000000000000000000000000083141615610345576103446102b7565b5b828205905092915050565b600061035b82610212565b915061036683610212565b92508282019050828112156000831216838212600084121516171561038e5761038d6102b7565b5b92915050565b600061039f82610212565b91506103aa83610212565b92508282039050818112600084121682821360008512151617156103d1576103d06102b7565b5b92915050565b60006103e282610212565b91506103ed83610212565b92508282026103fb81610212565b91507f80000000000000000000000000000000000000000000000000000000000000008414600084121615610433576104326102b7565b5b8282058414831517610448576104476102b7565b5b509291505056fea2646970667358221220386c6c77ebc5f1bae50f37d123c5a510f2f678b30900c2d5ebf09f68c9353f4b64736f6c63430008180033")] + #[allow(missing_docs)] + #[sol(rpc, bytecode = "0x6080806040523461001657610213908161001b8239f35b5f80fdfe6080604052600480361015610012575f80fd5b5f3560e01c80634350913814610165578063a5f3c23b14610116578063adefc37b146100c75763bbe93d9114610046575f80fd5b346100c357610054366101c7565b8181029291905f8212600160ff1b8214166100b057818405149015171561009d5750337fd7a123d4c8e44db3186e04b9c96c102287276929c930f2e8abcaa555ef5dcacc5f80a3005b601190634e487b7160e01b5f525260245ffd5b601183634e487b7160e01b5f525260245ffd5b5f80fd5b50346100c3576100d6366101c7565b91905f838203931281841281169184139015161761009d5750337f32e913bf2ad35da1e845597618bb9f3f80642a68dd39f30a093a7838aa61fb275f80a3005b50346100c357610125366101c7565b91905f838201938412911290801582169115161761009d5750337f6da406ea462447ed7804b4a4dc69c67b53d3d45a50381ae3e9cf878c9d7c23df5f80a3005b50346100c357610174366101c7565b9182156101b457600160ff1b82145f1984141661009d575005337f1c1e8bbe327890ea8d3f5b22370a56c3fcef7ff82f306161f64647fe5d2858815f80a3005b601290634e487b7160e01b5f525260245ffd5b60409060031901126100c357600435906024359056fea26469706673582212208fc27b878cb877b8c4e5dee739e0a35a64f82759549ed8f6d4ddab5ded9717bb64736f6c63430008180033")] contract EventMultiplexer { event Add(address indexed sender, int256 indexed value); event Sub(address indexed sender, int256 indexed value); @@ -37,35 +39,40 @@ sol!( #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().block_time(1).try_spawn()?; - let ws = alloy_rpc_client::WsConnect::new(anvil.ws_endpoint()); + // Create a provider. + let ws = WsConnect::new(anvil.ws_endpoint()); let provider = RootProvider::::new(RpcClient::connect_pubsub(ws).await?); - let deployed_contract = EventMultiplexer::deploy(provider.clone()).await?; + // Deploy the `EventExample` contract. + let contract = EventMultiplexer::deploy(provider).await?; - println!("Deployed contract at: {:?}", deployed_contract.address()); + println!("Deployed contract at: {:?}", contract.address()); - let add_filter = deployed_contract.Add_filter().watch().await?; - let sub_filter = deployed_contract.Sub_filter().watch().await?; - let mul_filter = deployed_contract.Mul_filter().watch().await?; - let div_filter = deployed_contract.Div_filter().watch().await?; + // Create filters for each event. + let add_filter = contract.Add_filter().watch().await?; + let sub_filter = contract.Sub_filter().watch().await?; + let mul_filter = contract.Mul_filter().watch().await?; + let div_filter = contract.Div_filter().watch().await?; let a = I256::from_str("1").unwrap(); let b = I256::from_str("1").unwrap(); - // Build calls - let add_call = deployed_contract.add(a, b); - let sub_call = deployed_contract.sub(a, b); - let mul_call = deployed_contract.mul(a, b); - let div_call = deployed_contract.div(a, b); - // Send calls + // Build the transaction calls. + let add_call = contract.add(a, b); + let sub_call = contract.sub(a, b); + let mul_call = contract.mul(a, b); + let div_call = contract.div(a, b); + + // Send the transaction calls. let _ = add_call.send().await?; let _ = sub_call.send().await?; let _ = mul_call.send().await?; let _ = div_call.send().await?; + // Convert the filters into streams. let mut add_stream = add_filter.into_stream(); let mut sub_stream = sub_filter.into_stream(); let mut mul_stream = mul_filter.into_stream(); @@ -78,7 +85,7 @@ async fn main() -> Result<()> { // Use tokio::select! to multiplex the streams and capture the log // tokio::select! will return the first event that arrives from any of the streams - // The for loop helps capture all the logs + // The for loop helps capture all the logs. for _ in 0..4 { let log = tokio::select! { Some(log) = add_stream.next() => { @@ -98,13 +105,13 @@ async fn main() -> Result<()> { let topic = &log.topics[0]; if topic == add_log { - println!("Received Add: {:?}", log); + println!("Received Add: {log:?}"); } else if topic == sub_log { - println!("Received Sub: {:?}", log); + println!("Received Sub: {log:?}"); } else if topic == mul_log { - println!("Received Mul: {:?}", log); + println!("Received Mul: {log:?}"); } else if topic == div_log { - println!("Received Div: {:?}", log); + println!("Received Div: {log:?}"); } } diff --git a/examples/subscriptions/examples/subscribe_blocks.rs b/examples/subscriptions/examples/subscribe_blocks.rs index bcbb3617..613df443 100644 --- a/examples/subscriptions/examples/subscribe_blocks.rs +++ b/examples/subscriptions/examples/subscribe_blocks.rs @@ -1,4 +1,4 @@ -//! Example of subscribing to blocks and watching blocks. +//! Example of subscribing to blocks and watching block headers by polling. use alloy::{network::Ethereum, node_bindings::Anvil}; use alloy_provider::{Provider, RootProvider}; @@ -9,24 +9,27 @@ use futures_util::{stream, StreamExt}; #[tokio::main] async fn main() -> Result<()> { // Spin up a local Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().block_time(1).try_spawn()?; + // Create a provider. let ws = alloy_rpc_client::WsConnect::new(anvil.ws_endpoint()); let provider = RootProvider::::new(RpcClient::connect_pubsub(ws).await?); - let sub = provider.subscribe_blocks().await?; - let mut stream = sub.into_stream().take(2); + // Subscribe to blocks. + let subscription = provider.subscribe_blocks().await?; + let mut stream = subscription.into_stream().take(2); while let Some(block) = stream.next().await { - println!("Subscribed Block: {:?}", block.header.number); + println!("Received block number: {:?}", block.header.number.unwrap().to_string()); } + // Poll for block headers. let poller = provider.watch_blocks().await?; let mut stream = poller.into_stream().flat_map(stream::iter).take(2); while let Some(block_hash) = stream.next().await { - println!("Watched Block: {:?}", block_hash); + println!("Polled for block header: {block_hash:?}"); } Ok(()) diff --git a/examples/subscriptions/examples/watch_contract_event.rs b/examples/subscriptions/examples/watch_contract_event.rs index 91d2ee65..49e93863 100644 --- a/examples/subscriptions/examples/watch_contract_event.rs +++ b/examples/subscriptions/examples/watch_contract_event.rs @@ -6,9 +6,12 @@ use alloy_rpc_client::RpcClient; use eyre::Result; use futures_util::StreamExt; +// Codegen from embedded Solidity code and precompiled bytecode. +// solc v0.8.24; solc a.sol --via-ir --optimize --bin sol!( - #[sol(rpc, bytecode = "0x60806040526000805534801561001457600080fd5b50610260806100246000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632baeceb71461004657806361bc221a14610050578063d09de08a1461006e575b600080fd5b61004e610078565b005b6100586100d9565b6040516100659190610159565b60405180910390f35b6100766100df565b005b600160008082825461008a91906101a3565b925050819055506000543373ffffffffffffffffffffffffffffffffffffffff167fdc69c403b972fc566a14058b3b18e1513da476de6ac475716e489fae0cbe4a2660405160405180910390a3565b60005481565b60016000808282546100f191906101e6565b925050819055506000543373ffffffffffffffffffffffffffffffffffffffff167ff6d1d8d205b41f9fb9549900a8dba5d669d68117a3a2b88c1ebc61163e8117ba60405160405180910390a3565b6000819050919050565b61015381610140565b82525050565b600060208201905061016e600083018461014a565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101ae82610140565b91506101b983610140565b92508282039050818112600084121682821360008512151617156101e0576101df610174565b5b92915050565b60006101f182610140565b91506101fc83610140565b92508282019050828112156000831216838212600084121516171561022457610223610174565b5b9291505056fea26469706673582212208d0d34c26bfd2938ff07dd54c3fcc2bc4509e4ae654edff58101e5e7ab8cf18164736f6c63430008180033")] - contract EventExample { + #[allow(missing_docs)] + #[sol(rpc, bytecode = "0x60808060405234610019575f8055610143908161001e8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c80632baeceb7146100c357806361bc221a146100a75763d09de08a1461003a575f80fd5b346100a3575f3660031901126100a3575f5460018101905f60018312911290801582169115161761008f57805f55337ff6d1d8d205b41f9fb9549900a8dba5d669d68117a3a2b88c1ebc61163e8117ba5f80a3005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b346100a3575f3660031901126100a35760205f54604051908152f35b346100a3575f3660031901126100a3575f545f19810190811360011661008f57805f55337fdc69c403b972fc566a14058b3b18e1513da476de6ac475716e489fae0cbe4a265f80a300fea2646970667358221220c045c027059726f9175a4abd427eb3f7a3fe8e27108bc19e4ae46055e7c1842c64736f6c63430008180033")] + contract Counter { int256 public counter = 0; event Increment(address indexed by, int256 indexed value); @@ -28,38 +31,47 @@ sol!( #[tokio::main] async fn main() -> Result<()> { + // Spin up a local Anvil node. + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().block_time(1).try_spawn()?; - let ws = alloy_rpc_client::WsConnect::new(anvil.ws_endpoint()); + // Create a WebSocket provider. + let ws_rpc_url = anvil.ws_endpoint(); + let ws = alloy_rpc_client::WsConnect::new(ws_rpc_url); let provider = RootProvider::::new(RpcClient::connect_pubsub(ws).await?); - let deployed_contract = EventExample::deploy(provider.clone()).await?; + // Deploy the `Counter` contract. + let contract = Counter::deploy(provider.clone()).await?; - println!("Deployed contract at: {:?}", deployed_contract.address()); + println!("Deployed contract at: {:?}", contract.address()); - let increment_filter = deployed_contract.Increment_filter().watch().await?; - let decrement_filter = deployed_contract.Decrement_filter().watch().await?; + // Create filters for each event. + let increment_filter = contract.Increment_filter().watch().await?; + let decrement_filter = contract.Decrement_filter().watch().await?; - // Build a call to increment the counter - let increment_call = deployed_contract.increment(); - // Build a call to decrement the counter - let decrement_call = deployed_contract.decrement(); - // Send the call 2 times + // Build a call to increment the counter. + let increment_call = contract.increment(); + + // Build a call to decrement the counter. + let decrement_call = contract.decrement(); + + // Send the transaction call twice for each event. for _ in 0..2 { let _ = increment_call.send().await?; let _ = decrement_call.send().await?; } + // Listen for the events. increment_filter .into_stream() .take(2) .for_each(|log| async { match log { Ok((_event, log)) => { - println!("Received Increment: {:?}", log); + println!("Received Increment: {log:?}"); } Err(e) => { - println!("Error: {:?}", e); + println!("Error: {e:?}"); } } }) @@ -71,10 +83,10 @@ async fn main() -> Result<()> { .for_each(|log| async { match log { Ok((_event, log)) => { - println!("Received Decrement: {:?}", log); + println!("Received Decrement: {log:?}"); } Err(e) => { - println!("Error: {:?}", e); + println!("Error: {e:?}"); } } }) diff --git a/examples/transactions/Cargo.toml b/examples/transactions/Cargo.toml index f887fe70..b2d4f770 100644 --- a/examples/transactions/Cargo.toml +++ b/examples/transactions/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-transactions" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/transactions/examples/decode_input.rs b/examples/transactions/examples/decode_input.rs index 334ee5ff..6031d0a5 100644 --- a/examples/transactions/examples/decode_input.rs +++ b/examples/transactions/examples/decode_input.rs @@ -3,16 +3,17 @@ use alloy::{primitives::hex, sol, sol_types::SolCall}; use eyre::Result; -// Use the sol! macro to generate bindings for the swapExactTokensForTokens function +// Codegen from excerpt of Uniswap V2 Router interface. +// See: https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02 sol!( - #[derive(Debug)] + #[allow(missing_docs)] function swapExactTokensForTokens( - uint amountIn, - uint amountOutMin, + uint256 amountIn, + uint256 amountOutMin, address[] calldata path, address to, - uint deadline - ) external returns (uint[] memory amounts); + uint256 deadline + ) external returns (uint256[] memory amounts); ); #[tokio::main] @@ -20,25 +21,25 @@ async fn main() -> Result<()> { println!("Decoding https://etherscan.io/tx/0xd1b449d8b1552156957309bffb988924569de34fbf21b51e7af31070cc80fe9a"); let input = "0x38ed173900000000000000000000000000000000000000000001a717cc0a3e4f84c00000000000000000000000000000000000000000000000000000000000000283568400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000201f129111c60401630932d9f9811bd5b5fff34e000000000000000000000000000000000000000000000000000000006227723d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000095ad61b0a150d79219dcf64e1e6cc01f0b64c4ce000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7"; - let input = hex::decode(input)?; - // swapExactTokensForTokensCall generated by the sol! macro above + // Decode the input using the generated `swapExactTokensForTokens` bindings. let decoded = swapExactTokensForTokensCall::abi_decode(&input, false); match decoded { Ok(decoded) => { let path = decoded.path; + println!( "Swap {} of token {} to {} of token {}", decoded.amountIn, - path.first().unwrap(), + path.first().expect("Path is empty"), decoded.amountOutMin, - path.last().unwrap() + path.last().expect("Path is empty") ); } Err(e) => { - println!("Error decoding input: {:?}", e); + println!("Error decoding input: {e:?}"); } } diff --git a/examples/transactions/examples/gas_price_usd.rs b/examples/transactions/examples/gas_price_usd.rs index 6b880750..8b4cf7e7 100644 --- a/examples/transactions/examples/gas_price_usd.rs +++ b/examples/transactions/examples/gas_price_usd.rs @@ -13,47 +13,52 @@ use eyre::Result; use std::str::FromStr; const ETH_USD_FEED: Address = address!("5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"); +const ETH_USD_FEED_DECIMALS: u8 = 8; const ETH_DECIMALS: u32 = 18; +// Codegen from excerpt of Chainlink Aggregator interface. +// See: https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code sol!( - #[derive(Debug)] + #[allow(missing_docs)] function latestAnswer() external view returns (int256); ); #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; - let url = anvil.endpoint().parse().unwrap(); - let provider = HttpProvider::::new_http(url); + // Create a provider. + let rpc_url = anvil.endpoint().parse()?; + let provider = HttpProvider::::new_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 result = U256::from_str(&response.to_string())?; - let res = provider.call(&tx, None).await?; - - let u = U256::from_str(res.to_string().as_str()); - + // Get the gas price of the network. let wei_per_gas = provider.get_gas_price().await?; + // Convert the gas price to Gwei and USD. let gwei = format_units(wei_per_gas, "gwei")?.parse::()?; + let usd = get_usd_value(wei_per_gas, result)?; - let usd = usd_value(wei_per_gas, u.unwrap())?; - - println!("Gas price in Gwei: {}", gwei); - println!("Gas price in USD: {}", usd); + println!("Gas price in Gwei: {gwei}"); + println!("Gas price in USD: {usd}"); Ok(()) } -fn usd_value(amount: U256, price_usd: U256) -> Result { - let base: U256 = U256::from(10).pow(U256::from(ETH_DECIMALS)); - let value: U256 = amount * price_usd / base; - let usd_price_decimals: u8 = 8; - let f: String = format_units(value, usd_price_decimals)?; - Ok(f.parse::()?) +fn get_usd_value(amount: U256, price_usd: U256) -> Result { + let base = U256::from(10).pow(U256::from(ETH_DECIMALS)); + let value = 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 e257e3c7..6e416a58 100644 --- a/examples/transactions/examples/trace_call.rs +++ b/examples/transactions/examples/trace_call.rs @@ -2,8 +2,7 @@ use alloy::{ network::Ethereum, - node_bindings::Anvil, - primitives::U256, + primitives::{address, U256}, providers::{HttpProvider, Provider}, rpc::types::{ eth::{BlockId, BlockNumberOrTag, TransactionRequest}, @@ -14,27 +13,29 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH - let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; + // Create a provider. + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = HttpProvider::::new_http(rpc_url); - let provider = HttpProvider::::new_http("https://eth.merkle.io".parse()?); + // Create two users, Alice and Bob. + let alice = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let bob = address!("70997970C51812dc3A010C7d01b50e0d17dc79C8"); - let from = anvil.addresses()[0]; - let to = anvil.addresses()[1]; - - let tx_req = TransactionRequest { - from: Some(from), - to: Some(to), + // 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() }; + + // Trace the transaction on top of the latest block. let trace_type = [TraceType::Trace]; - let res = provider - .trace_call(&tx_req, &trace_type, Some(BlockId::Number(BlockNumberOrTag::Latest))) + let result = provider + .trace_call(&tx, &trace_type, Some(BlockId::Number(BlockNumberOrTag::Latest))) .await?; - println!("{:?}", res.trace); + println!("{:?}", result.trace); Ok(()) } diff --git a/examples/transactions/examples/trace_transaction.rs b/examples/transactions/examples/trace_transaction.rs index e2ee45c5..04a232de 100644 --- a/examples/transactions/examples/trace_transaction.rs +++ b/examples/transactions/examples/trace_transaction.rs @@ -3,7 +3,7 @@ use alloy::{ network::Ethereum, node_bindings::Anvil, - primitives::fixed_bytes, + primitives::b256, providers::{HttpProvider, Provider}, rpc::types::trace::geth::{ GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingOptions, @@ -15,20 +15,23 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; - let url = anvil.endpoint().parse().unwrap(); - let provider = HttpProvider::::new_http(url); - let hash = fixed_bytes!("97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7"); // Hash of the tx we want to trace + // Create a provider. + let rpc_url = anvil.endpoint().parse()?; + let provider = HttpProvider::::new_http(rpc_url); + + // Hash of the tx we want to trace + let hash = b256!("97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7"); // Default tracing let default_options = GethDebugTracingOptions::default(); - let res = provider.debug_trace_transaction(hash, default_options).await?; + let result = provider.debug_trace_transaction(hash, default_options).await?; - println!("DEFAULT_TRACE: {:?}", res); + println!("DEFAULT_TRACE: {result:?}"); - // Call tracing + // Trace with built-in call tracer. let call_options = GethDebugTracingOptions { config: GethDefaultTracingOptions { disable_storage: Some(true), @@ -38,19 +41,19 @@ async fn main() -> Result<()> { tracer: Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::CallTracer)), ..Default::default() }; - let res = provider.debug_trace_transaction(hash, call_options).await?; + let result = provider.debug_trace_transaction(hash, call_options).await?; - println!("CALL_TRACE: {:?}", res); + println!("CALL_TRACE: {result:?}"); - // JS tracer + // Trace using a custom JavaScript tracer. let js_options = GethDebugTracingOptions { tracer: Some(GethDebugTracerType::JsTracer("{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"DELEGATECALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}".into())), ..Default::default() }; - let res = provider.debug_trace_transaction(hash, js_options).await?; + let result = provider.debug_trace_transaction(hash, js_options).await?; - println!("JS_TRACER: {:?}", res); + println!("JS_TRACER: {result:?}"); Ok(()) } diff --git a/examples/transactions/examples/transfer_erc20.rs b/examples/transactions/examples/transfer_erc20.rs index d28fbbcc..9b028202 100644 --- a/examples/transactions/examples/transfer_erc20.rs +++ b/examples/transactions/examples/transfer_erc20.rs @@ -11,48 +11,53 @@ use alloy::{ }; use eyre::Result; -sol!(ERC20Example, "examples/contracts/ERC20Example.json"); +// Codegen from artifact. +sol!( + #[allow(missing_docs)] + ERC20Example, + "examples/contracts/ERC20Example.json" +); #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; - let url = anvil.endpoint().parse().unwrap(); - let provider = HttpProvider::::new_http(url); + // Create a provider. + let rpc_url = anvil.endpoint().parse()?; + let provider = HttpProvider::::new_http(rpc_url); - let from = anvil.addresses()[0]; + // Create two users, Alice and Bob. + let alice = anvil.addresses()[0]; + let bob = anvil.addresses()[1]; - let contract_address = deploy_token_contract(&provider, from).await?; + // Deploy the `ERC20Example` contract. + let contract_address = deploy_token_contract(&provider, alice).await?; - println!("Deployed contract at: {}", contract_address); - - let to = anvil.addresses()[1]; - - let input = ERC20Example::transferCall { to, amount: U256::from(100) }.abi_encode(); - // Convert to Bytes + // Create the transaction input to transfer 100 tokens from Alice to Bob. + let input = ERC20Example::transferCall { to: bob, amount: U256::from(100) }.abi_encode(); let input = Bytes::from(input); - let transfer_tx = TransactionRequest { - from: Some(from), + // Create a transaction with the input. + let tx = TransactionRequest { + from: Some(alice), to: Some(contract_address), input: Some(input).into(), ..Default::default() }; - let pending_tx = provider.send_transaction(transfer_tx).await?; + // Send the transaction and wait for the receipt. + let receipt = provider.send_transaction(tx).await?.get_receipt().await?; - println!("Transfer tx: {:?}", pending_tx.tx_hash()); + println!("Send transaction: {:?}", receipt.transaction_hash); - // Wait for confirmation - let _ = pending_tx.with_required_confirmations(1); + // Check the balances of Alice and Bob after the transfer. + let alice_balance = balance_of(&provider, alice, contract_address).await?; + let bob_balance = balance_of(&provider, bob, contract_address).await?; - let to_bal = balance_of(&provider, to, contract_address).await?; - let from_bal = balance_of(&provider, from, contract_address).await?; - - assert_eq!(to_bal, U256::from(100)); - assert_eq!(from_bal, U256::from(999999999999999999900_i128)); + assert_eq!(alice_balance, U256::from(999999999999999999900_i128)); + assert_eq!(bob_balance, U256::from(100)); Ok(()) } @@ -61,26 +66,25 @@ async fn deploy_token_contract( provider: &HttpProvider, from: Address, ) -> Result
{ - // Compile the contract + // Compile the contract. let bytecode = ERC20Example::BYTECODE.to_owned(); - let tx_req = TransactionRequest { + // Create a transaction. + let tx = TransactionRequest { from: Some(from), input: Some(bytecode).into(), to: None, ..Default::default() }; - // Deploy the contract - let pending_tx = provider.send_transaction(tx_req).await?; + // Send the transaction and wait for the receipt. + let receipt = provider.send_transaction(tx).await?.get_receipt().await?; - // Wait for the transaction to be mined - let _tx = provider.get_transaction_by_hash(pending_tx.tx_hash().to_owned()).await?; + // Get the contract address. + let contract_address = receipt.contract_address.expect("Contract address not found"); - // Get receipt - let receipt = provider.get_transaction_receipt(pending_tx.tx_hash().to_owned()).await?; + println!("Deployed contract at: {contract_address}"); - let contract_address = receipt.unwrap().contract_address.unwrap(); Ok(contract_address) } @@ -89,16 +93,22 @@ async fn balance_of( account: Address, contract_address: Address, ) -> Result { + // Encode the call. let call = ERC20Example::balanceOfCall { account }.abi_encode(); let input = Bytes::from(call); - let tx_req = TransactionRequest { + // Create a transaction. + let tx = TransactionRequest { to: Some(contract_address), input: Some(input).into(), ..Default::default() }; - let result = provider.call(&tx_req, None).await?; - let result = ERC20Example::balanceOfCall::abi_decode_returns(&result, true)?; - Ok(result._0) + // Call the contract. + let result = provider.call(&tx, None).await?; + + // Decode the result. + let result = ERC20Example::balanceOfCall::abi_decode_returns(&result, true)?._0; + + Ok(result) } diff --git a/examples/transactions/examples/transfer_eth.rs b/examples/transactions/examples/transfer_eth.rs index f0b02b32..4db7f451 100644 --- a/examples/transactions/examples/transfer_eth.rs +++ b/examples/transactions/examples/transfer_eth.rs @@ -3,7 +3,7 @@ use alloy::{ network::Ethereum, node_bindings::Anvil, - primitives::{address, Address, U256}, + primitives::U256, providers::{HttpProvider, Provider}, rpc::types::eth::TransactionRequest, }; @@ -12,25 +12,35 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { // Spin up a forked Anvil node. - // Ensure `anvil` is available in $PATH + // Ensure `anvil` is available in $PATH. let anvil = Anvil::new().fork("https://eth.merkle.io").try_spawn()?; - let url = anvil.endpoint().parse().unwrap(); - let provider = HttpProvider::::new_http(url); + // Create a provider. + let rpc_url = anvil.endpoint().parse()?; + let provider = HttpProvider::::new_http(rpc_url); - let from = anvil.addresses()[0]; - // Transfer 1ETH from 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 to Address::ZERO - let tx = TransactionRequest::default().from(from).value(U256::from(1)).to(Some(Address::ZERO)); + // Create two users, Alice and Bob. + let alice = anvil.addresses()[0]; + let bob = anvil.addresses()[1]; - let tx = provider.send_transaction(tx).await?; - let hash = tx.tx_hash(); - println!("Pending transaction hash: {}", hash); + // Create a transaction to transfer 1 wei from Alice to Bob. + let tx = TransactionRequest::default().from(alice).value(U256::from(1)).to(Some(bob)); - let transaction = provider.get_transaction_by_hash(hash.to_owned()).await?; + // Send the transaction and wait for the receipt. + let pending_tx = provider.send_transaction(tx).await?; - assert_eq!(transaction.from, address!("f39fd6e51aad88f6f4ce6ab8827279cfffb92266")); - assert_eq!(transaction.to, Some(Address::ZERO)); - assert_eq!(transaction.value, U256::from(1)); + println!("Pending transaction...{:?}", pending_tx.tx_hash()); + + // Wait for the transaction to be included. + let receipt = pending_tx.get_receipt().await?; + + println!( + "Transaction included in block: {:?}", + receipt.block_number.expect("Failed to get block number").to_string() + ); + + assert_eq!(receipt.from, alice); + assert_eq!(receipt.to, Some(bob)); Ok(()) } diff --git a/examples/wallets/Cargo.toml b/examples/wallets/Cargo.toml index eb186361..0d04582e 100644 --- a/examples/wallets/Cargo.toml +++ b/examples/wallets/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "examples-wallets" - publish.workspace = true version.workspace = true edition.workspace = true @@ -10,6 +9,9 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[lints] +workspace = true + [dev-dependencies] alloy.workspace = true diff --git a/examples/wallets/examples/create_keystore.rs b/examples/wallets/examples/create_keystore.rs index 2b2c1150..e65370ba 100644 --- a/examples/wallets/examples/create_keystore.rs +++ b/examples/wallets/examples/create_keystore.rs @@ -19,9 +19,9 @@ async fn main() -> Result<()> { // Create a keystore file from the private key of Alice, returning a [Wallet] instance. let (wallet, file_path) = - Wallet::encrypt_keystore(&dir, &mut rng, private_key, password, None).unwrap(); + Wallet::encrypt_keystore(&dir, &mut rng, private_key, password, None)?; - let keystore_file_path = dir.path().join(file_path.clone()); + let keystore_file_path = dir.path().join(file_path); println!("Wrote keystore for {:?} to {:?}", wallet.address(), keystore_file_path); @@ -40,7 +40,7 @@ async fn main() -> Result<()> { // Display the contents of the keystore file. let keystore_contents = read_to_string(keystore_file_path)?; - println!("Keystore file contents: {:?}", keystore_contents); + println!("Keystore file contents: {keystore_contents:?}"); Ok(()) } diff --git a/examples/wallets/examples/keystore_signer.rs b/examples/wallets/examples/keystore_signer.rs index 64a73ee5..6a5741e1 100644 --- a/examples/wallets/examples/keystore_signer.rs +++ b/examples/wallets/examples/keystore_signer.rs @@ -1,4 +1,4 @@ -//! Example of using a keystore wallet to sign and broadcast a transaction on a local Anvil node. +//! Example of using a keystore wallet to sign and send a transaction. use alloy::{ network::EthereumSigner, @@ -19,17 +19,17 @@ async fn main() -> Result<()> { // Password to decrypt the keystore file with. let password = "test"; - // Set up a wallet using Alice's keystore file. + // Set up signer using Alice's keystore file. // The private key belongs to Alice, the first default Anvil account. let keystore_file_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?).join("examples/keystore/alice.json"); - let wallet = Wallet::decrypt_keystore(keystore_file_path, password)?; + let signer = Wallet::decrypt_keystore(keystore_file_path, password)?; // Create a provider with the signer. - let http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); // Create a transaction. let tx = TransactionRequest { @@ -41,7 +41,7 @@ async fn main() -> Result<()> { ..Default::default() }; - // Broadcast the transaction and wait for the receipt. + // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.get_receipt().await?; println!("Send transaction: {:?}", receipt.transaction_hash); diff --git a/examples/wallets/examples/ledger_signer.rs b/examples/wallets/examples/ledger_signer.rs index 1b7a238b..1e40a95a 100644 --- a/examples/wallets/examples/ledger_signer.rs +++ b/examples/wallets/examples/ledger_signer.rs @@ -15,10 +15,10 @@ async fn main() -> Result<()> { let signer = LedgerSigner::new(HDPath::LedgerLive(0), Some(1)).await?; // Create a provider with the signer. - let http = "http://localhost:8545".parse()?; + let rpc_url = "http://localhost:8545".parse()?; let provider = ProviderBuilder::new() .signer(EthereumSigner::from(signer)) - .on_client(RpcClient::new_http(http)); + .on_client(RpcClient::new_http(rpc_url)); // Create a transaction. let tx = TransactionRequest { @@ -29,7 +29,7 @@ async fn main() -> Result<()> { ..Default::default() }; - // Broadcast the transaction and wait for the receipt. + // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?; diff --git a/examples/wallets/examples/private_key_signer.rs b/examples/wallets/examples/private_key_signer.rs index c55560ea..b3bd88aa 100644 --- a/examples/wallets/examples/private_key_signer.rs +++ b/examples/wallets/examples/private_key_signer.rs @@ -1,4 +1,4 @@ -//! Example of using a local wallet to sign and broadcast a transaction on a local Anvil node. +//! Example of using a local wallet to sign and send a transaction. use alloy::{ network::EthereumSigner, @@ -15,14 +15,14 @@ async fn main() -> Result<()> { // Spin up an Anvil node. let anvil = Anvil::new().block_time(1).try_spawn()?; - // Set up a local wallet from the first default Anvil account (Alice). - let wallet: LocalWallet = anvil.keys()[0].clone().into(); + // Set up signer from the first default Anvil account (Alice). + let signer: LocalWallet = anvil.keys()[0].clone().into(); // Create a provider with the signer. - let http = anvil.endpoint().parse()?; + let rpc_url = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() - .signer(EthereumSigner::from(wallet)) - .on_client(RpcClient::new_http(http)); + .signer(EthereumSigner::from(signer)) + .on_client(RpcClient::new_http(rpc_url)); // Create a transaction. let tx = TransactionRequest { @@ -34,7 +34,7 @@ async fn main() -> Result<()> { ..Default::default() }; - // Broadcast the transaction and wait for the receipt. + // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.get_receipt().await?; println!("Send transaction: {:?}", receipt.transaction_hash); diff --git a/examples/wallets/examples/sign_message.rs b/examples/wallets/examples/sign_message.rs index 81267249..8f830a69 100644 --- a/examples/wallets/examples/sign_message.rs +++ b/examples/wallets/examples/sign_message.rs @@ -5,23 +5,23 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - // Setup up wallet. - let wallet = LocalWallet::random(); + // Set up a random signer. + let signer = LocalWallet::random(); // Optionally, the wallet's chain id can be set, in order to use EIP-155 - // replay protection with different chains - let wallet = wallet.with_chain_id(Some(1337)); + // replay protection with different chains. + let signer = signer.with_chain_id(Some(1337)); // The message to sign. let message = b"hello"; - // Sign the message asynchronously with the wallet. - let signature = wallet.sign_message(message).await?; + // Sign the message asynchronously with the signer. + let signature = signer.sign_message(message).await?; - println!("Signature produced by {:?}: {:?}", wallet.address(), signature); + println!("Signature produced by {:?}: {:?}", signer.address(), signature); println!( "Signature recovered address: {:?}", - signature.recover_address_from_msg(&message[..]).unwrap() + signature.recover_address_from_msg(&message[..])? ); Ok(()) diff --git a/examples/wallets/examples/sign_permit_hash.rs b/examples/wallets/examples/sign_permit_hash.rs index 4c1045a0..e7448b3f 100644 --- a/examples/wallets/examples/sign_permit_hash.rs +++ b/examples/wallets/examples/sign_permit_hash.rs @@ -10,6 +10,7 @@ use eyre::Result; use serde::Serialize; sol! { + #[allow(missing_docs)] #[derive(Debug, Serialize)] struct Permit { address owner; @@ -22,8 +23,8 @@ sol! { #[tokio::main] async fn main() -> Result<()> { - // Setup up wallet. - let wallet = LocalWallet::random(); + // Set up a random signer. + let signer = LocalWallet::random(); let domain = eip712_domain! { name: "Uniswap V2", @@ -34,7 +35,7 @@ async fn main() -> Result<()> { }; let permit = Permit { - owner: wallet.address(), + owner: signer.address(), spender: address!("B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"), value: U256::from(100), nonce: U256::from(0), @@ -45,14 +46,14 @@ async fn main() -> Result<()> { let hash = permit.eip712_signing_hash(&domain); // Sign the hash asynchronously with the wallet. - let signature = wallet.sign_hash(&hash).await?; + let signature = signer.sign_hash(&hash).await?; println!( "Recovered address matches wallet address: {:?}", - signature.recover_address_from_prehash(&hash)? == wallet.address() + signature.recover_address_from_prehash(&hash)? == signer.address() ); - println!("Wallet signature matches: {:?}", wallet.sign_hash(&hash).await? == signature); + println!("Wallet signature matches: {:?}", signer.sign_hash(&hash).await? == signature); Ok(()) } diff --git a/examples/wallets/examples/trezor_signer.rs b/examples/wallets/examples/trezor_signer.rs index 4884e1b2..079b529c 100644 --- a/examples/wallets/examples/trezor_signer.rs +++ b/examples/wallets/examples/trezor_signer.rs @@ -15,10 +15,10 @@ async fn main() -> Result<()> { let signer = TrezorSigner::new(HDPath::TrezorLive(0), Some(1)).await?; // Create a provider with the signer. - let http = "http://localhost:8545".parse()?; + let rpc_url = "http://localhost:8545".parse()?; let provider = ProviderBuilder::new() .signer(EthereumSigner::from(signer)) - .on_client(RpcClient::new_http(http)); + .on_client(RpcClient::new_http(rpc_url)); // Create a transaction. let tx = TransactionRequest { @@ -29,7 +29,7 @@ async fn main() -> Result<()> { ..Default::default() }; - // Broadcast the transaction and wait for the receipt. + // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?; diff --git a/examples/wallets/examples/yubi_signer.rs b/examples/wallets/examples/yubi_signer.rs index d1ebb908..805ee7a8 100644 --- a/examples/wallets/examples/yubi_signer.rs +++ b/examples/wallets/examples/yubi_signer.rs @@ -24,10 +24,10 @@ async fn main() -> Result<()> { let signer = YubiWallet::connect(connector, Credentials::default(), 0); // Create a provider with the signer. - let http = "http://localhost:8545".parse()?; + let rpc_url = "http://localhost:8545".parse()?; let provider = ProviderBuilder::new() .signer(EthereumSigner::from(signer)) - .on_client(RpcClient::new_http(http)); + .on_client(RpcClient::new_http(rpc_url)); // Create a transaction. let tx = TransactionRequest { @@ -38,7 +38,7 @@ async fn main() -> Result<()> { ..Default::default() }; - // Broadcast the transaction and wait for the receipt. + // Send the transaction and wait for the receipt. let receipt = provider.send_transaction(tx).await?.with_required_confirmations(3).get_receipt().await?;