Skip to content

Commit

Permalink
feat(contracts): update to cb95183 and add `with_recommended_filler…
Browse files Browse the repository at this point in the history
…s()` to examples where appropriate (#50)

* upgrade to cd5a2c7

* start updating examples

* fix examples

* fix clippy and ordering

* requires signer and from, not sure why it is not inheriting from the provider

* upgrade to cb95183

* fix broken examples

* update layer -> singer, add gas_signer and improve documentation
  • Loading branch information
zerosnacks authored Apr 17, 2024
1 parent b7649b5 commit 4d111af
Show file tree
Hide file tree
Showing 26 changed files with 226 additions and 169 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ unnecessary_struct_initialization = "allow"
use_self = "allow"

[workspace.dependencies]
alloy = { git = "https://github.com/alloy-rs/alloy", rev = "bfd0fda", features = [
alloy = { git = "https://github.com/alloy-rs/alloy", rev = "cb95183", features = [
"contract",
"network",
"node-bindings",
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ This repository contains the following examples:
- [x] [Deploy from artifact](./examples/contracts/examples/deploy_from_artifact.rs)
- [x] [Deploy from contract](./examples/contracts/examples/deploy_from_contract.rs)
- [x] [Interact with ABI](./examples/contracts/examples/interact_with_abi.rs)
- [x] Layers (Middleware)
- [x] [Recommended layers](./examples/layers/examples/recommended_layers.rs)
- [x] [Nonce manager](./examples/layers/examples/nonce_layer.rs)
- [x] [Signature manager](./examples/layers/examples/signer_layer.rs)
- [x] Fillers (Middleware)
- [x] [Gas filler](./examples/fillers/examples/gas_filler.rs)
- [x] [Nonce management filler](./examples/fillers/examples/nonce_filler.rs)
- [x] [Recommended fillers](./examples/fillers/examples/recommended_fillers.rs)
- [x] [Signer management filler](./examples/fillers/examples/signer_filler.rs)
- [x] Subscriptions
- [x] [Subscribe and watch blocks](./examples/subscriptions/examples/subscribe_blocks.rs)
- [x] [Subscribe to contract events and watch logs](./examples/subscriptions/examples/watch_contract_event.rs)
Expand Down
36 changes: 14 additions & 22 deletions examples/anvil/examples/deploy_contract_anvil.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
//! Example of deploying a contract to Anvil and interacting with it.
use alloy::{
network::EthereumSigner,
node_bindings::Anvil,
primitives::U256,
providers::{Provider, ProviderBuilder},
signers::wallet::LocalWallet,
sol,
network::EthereumSigner, node_bindings::Anvil, primitives::U256, providers::ProviderBuilder,
signers::wallet::LocalWallet, sol,
};
use eyre::Result;

Expand Down Expand Up @@ -36,36 +32,32 @@ async fn main() -> Result<()> {

// Set up signer from the first default Anvil account (Alice).
let signer: LocalWallet = anvil.keys()[0].clone().into();
let from = signer.address();

// Create a provider with a signer and the network.
let rpc_url = anvil.endpoint().parse()?;
let provider =
ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new()
.with_recommended_fillers()
.signer(EthereumSigner::from(signer))
.on_http(rpc_url)?;

println!("Anvil running at `{}`", anvil.endpoint());

// Get the base fee for the block.
let base_fee = provider.get_gas_price().await?;

// Deploy the contract.
let contract_builder = Counter::deploy_builder(&provider);
let estimate = contract_builder.estimate_gas().await?;
let contract_address =
contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?;

println!("Deployed contract at address: {contract_address:?}");
let contract_builder = Counter::deploy_builder(&provider).from(from);
let contract_address = contract_builder.deploy().await?;
let contract = Counter::new(contract_address, provider);

let contract = Counter::new(contract_address, &provider);
println!("Deployed contract at address: {:?}", contract.address());

let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?;
let builder = contract.setNumber(U256::from(42)).nonce(1).gas(estimate).gas_price(base_fee);
// Set the number to 42.
let builder = contract.setNumber(U256::from(42)).from(from);
let receipt = builder.send().await?.get_receipt().await?;

println!("Set number to 42: {:?}", receipt.transaction_hash);

// Increment the number to 43.
let estimate = contract.increment().estimate_gas().await?;
let builder = contract.increment().nonce(2).gas(estimate).gas_price(base_fee);
let builder = contract.increment().from(from);
let receipt = builder.send().await?.get_receipt().await?;

println!("Incremented number: {:?}", receipt.transaction_hash);
Expand Down
3 changes: 1 addition & 2 deletions examples/contracts/examples/deploy_from_artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ async fn main() -> Result<()> {

// Create a provider with a signer.
let rpc_url = anvil.endpoint().parse()?;
let provider =
ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_http(rpc_url)?;

println!("Anvil running at `{}`", anvil.endpoint());

Expand Down
3 changes: 1 addition & 2 deletions examples/contracts/examples/deploy_from_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ async fn main() -> Result<()> {

// Create a provider with a signer.
let rpc_url = anvil.endpoint().parse()?;
let provider =
ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().signer(EthereumSigner::from(signer)).on_http(rpc_url)?;

println!("Anvil running at `{}`", anvil.endpoint());

Expand Down
2 changes: 1 addition & 1 deletion examples/contracts/examples/interact_with_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async fn main() -> Result<()> {

// Create a provider.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().on_http(rpc_url)?;

// Create a contract instance.
let contract = IERC20::new("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?, provider);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Example of using the `.with_recommended_layers()` method in the provider.
//! Example of using the `GasFiller` in the provider.
use alloy::{
network::{EthereumSigner, TransactionBuilder},
Expand Down Expand Up @@ -26,21 +26,21 @@ async fn main() -> Result<()> {
// Create a provider with the signer.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new()
// Adds the `GasEstimatorLayer` and the `NonceManagerLayer` layers.
.with_recommended_layers()
// Alternatively, you can add the layers individually:
// .with_gas_estimation()
// .with_nonce_management()
// Add the `GasFiller` to the provider.
// It is generally recommended to use the `.with_recommended_fillers()` method, which
// includes the `GasFiller`.
.with_gas_estimation()
.signer(EthereumSigner::from(signer))
.on_reqwest_http(rpc_url)?;
.on_http(rpc_url)?;

// Create an EIP-1559 type transaction.
// Notice that the `nonce` field is set by the `NonceManagerLayer`.
// Notice that without the `GasEstimatorLayer`, you need to set the gas related fields.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(vitalik.into())
.with_value(U256::from(100))
// Notice that without the `NonceFiller`, you need to set `nonce` field.
.with_nonce(0)
// Notice that without the `ChainIdFiller`, you need to set the `chain_id` field.
.with_chain_id(anvil.chain_id());

// Send the transaction, the nonce (0) is automatically managed by the provider.
Expand All @@ -51,6 +51,9 @@ async fn main() -> Result<()> {

println!("Transaction sent with nonce: {}", pending_tx.nonce);

// Update the nonce and send the transaction again.
let tx = tx.with_nonce(1);

// Send the transaction, the nonce (1) is automatically managed by the provider.
let builder = provider.send_transaction(tx).await?;
let node_hash = *builder.tx_hash();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! Example of using the `NonceManagerLayer` in the provider.
//! Example of using the `NonceFiller` in the provider.
use alloy::{
network::{EthereumSigner, TransactionBuilder},
node_bindings::Anvil,
primitives::{address, U256},
providers::{layers::NonceManagerLayer, Provider, ProviderBuilder},
providers::{Provider, ProviderBuilder},
rpc::types::eth::request::TransactionRequest,
signers::wallet::LocalWallet,
};
Expand Down Expand Up @@ -35,23 +35,23 @@ async fn main() -> Result<()> {
// Create a provider with the signer.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new()
// Add the `NonceManagerLayer` to the provider.
// It is generally recommended to use the `.with_recommended_layers()` method, which
// includes the `NonceManagerLayer`.
.layer(NonceManagerLayer)
// Add the `NonceFiller` to the provider.
// It is generally recommended to use the `.with_recommended_fillers()` method, which
// includes the `NonceFiller`.
.with_nonce_management()
.signer(EthereumSigner::from(signer))
.on_reqwest_http(rpc_url)?;
.on_http(rpc_url)?;

// Create an EIP-1559 type transaction.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(vitalik.into())
.with_value(U256::from(100))
// Notice that without the `GasEstimatorLayer`, you need to set the gas related fields.
.with_gas_limit(U256::from(21000))
.with_max_fee_per_gas(U256::from(20e9))
.with_max_priority_fee_per_gas(U256::from(1e9))
// It is required to set the chain_id for EIP-1559 transactions.
// Notice that without the `GasFiller`, you need to set the gas related fields.
.with_gas_limit(21_000)
.with_max_fee_per_gas(20_000_000_000)
.with_max_priority_fee_per_gas(1_000_000_000)
// Notice that without the `ChainIdFiller`, you need to set the `chain_id` field.
.with_chain_id(anvil.chain_id());

// Send the transaction, the nonce (0) is automatically managed by the provider.
Expand Down
60 changes: 60 additions & 0 deletions examples/fillers/examples/recommended_fillers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//! Example of using the `.with_recommended_fillers()` method in the provider.
use alloy::{
network::{EthereumSigner, TransactionBuilder},
node_bindings::Anvil,
primitives::{address, U256},
providers::{Provider, ProviderBuilder},
rpc::types::eth::request::TransactionRequest,
signers::wallet::LocalWallet,
};
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
// Spin up a local Anvil node.
// Ensure `anvil` is available in $PATH.
let anvil = Anvil::new().try_spawn()?;

// Set up signer from the first default Anvil account (Alice).
let signer: LocalWallet = anvil.keys()[0].clone().into();

// Create two users, Alice and Vitalik.
let alice = signer.address();
let vitalik = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045");

// Create a provider with the signer.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new()
// Adds the `ChainIdFiller`, `GasFiller` and the `NonceFiller` layers.
.with_recommended_fillers()
.signer(EthereumSigner::from(signer))
.on_http(rpc_url)?;

// Build a EIP-1559 type transaction.
// Notice that the `nonce` field is set by the `NonceFiller`.
// Notice that the gas related fields are set by the `GasFiller`.
// Notice that the `chain_id` field is set by the `ChainIdFiller`.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(vitalik.into())
.with_value(U256::from(100));

// Send the transaction, the nonce (0) is automatically managed by the provider.
let builder = provider.send_transaction(tx.clone()).await?;
let node_hash = *builder.tx_hash();
let pending_tx = provider.get_transaction_by_hash(node_hash).await?;
assert_eq!(pending_tx.nonce, 0);

println!("Transaction sent with nonce: {}", pending_tx.nonce);

// Send the transaction, the nonce (1) is automatically managed by the provider.
let builder = provider.send_transaction(tx).await?;
let node_hash = *builder.tx_hash();
let pending_tx = provider.get_transaction_by_hash(node_hash).await?;
assert_eq!(pending_tx.nonce, 1);

println!("Transaction sent with nonce: {}", pending_tx.nonce);

Ok(())
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Example of using the `SignerLayer` in the provider.
//! Example of using the `SignerFiller` in the provider.
use alloy::{
network::{EthereumSigner, TransactionBuilder},
Expand Down Expand Up @@ -26,20 +26,20 @@ async fn main() -> Result<()> {
// Create a provider with the signer.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new()
// Add the `SignerLayer` to the provider
// Add the `SignerFiller` to the provider
.signer(EthereumSigner::from(signer))
.on_reqwest_http(rpc_url)?;
.on_http(rpc_url)?;

// Create a legacy type transaction.
// Build a legacy type transaction to send 100 wei to Vitalik.
let tx = TransactionRequest::default()
.with_from(alice)
// Notice that without the `NonceManagerLayer`, you need to manually set the nonce field.
// Notice that without the `NonceFiller`, you need to manually set the nonce field.
.with_nonce(0)
.with_to(vitalik.into())
.with_value(U256::from(100))
// Notice that without the `GasEstimatorLayer`, you need to set the gas related fields.
.with_gas_price(U256::from(20e9))
.with_gas_limit(U256::from(21000));
// Notice that without the `GasFiller`, you need to set the gas related fields.
.with_gas_price(20_000_000_000)
.with_gas_limit(21_000);

let builder = provider.send_transaction(tx).await?;
let node_hash = *builder.tx_hash();
Expand Down
17 changes: 8 additions & 9 deletions examples/providers/examples/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@ async fn main() -> Result<()> {

// Set up the HTTP provider with the `reqwest` crate.
let rpc_url = anvil.endpoint().parse()?;
let provider =
ProviderBuilder::new().signer(EthereumSigner::from(wallet)).on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new()
.with_recommended_fillers()
.signer(EthereumSigner::from(wallet))
.on_http(rpc_url)?;

// Create a transaction.
let mut tx = TransactionRequest::default()
.to(Some(bob))
.value(U256::from(100))
.nonce(0)
.gas_limit(U256::from(21000));

tx.set_gas_price(U256::from(20e9));
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(bob.into())
.with_value(U256::from(100));

// Send the transaction and wait for the receipt.
let pending_tx = provider.send_transaction(tx).await?;
Expand Down
2 changes: 1 addition & 1 deletion examples/providers/examples/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ async fn main() -> Result<()> {
let rpc_url = "https://eth.merkle.io".parse()?;

// Create a provider with the HTTP transport using the `reqwest` crate.
let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().on_http(rpc_url)?;

// Get latest block number.
let latest_block = provider.get_block_number().await?;
Expand Down
3 changes: 2 additions & 1 deletion examples/queries/examples/query_contract_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use alloy::{
primitives::{address, U256},
providers::{Provider, ProviderBuilder},
rpc::types::eth::BlockId,
};
use eyre::Result;

Expand All @@ -15,7 +16,7 @@ async fn main() -> Result<()> {
// Get storage slot 0 from the Uniswap V3 USDC-ETH pool on Ethereum mainnet.
let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640");
let storage_slot = U256::from(0);
let storage = provider.get_storage_at(pool_address, storage_slot, None).await?;
let storage = provider.get_storage_at(pool_address, storage_slot, BlockId::latest()).await?;

println!("Slot 0: {storage:?}");

Expand Down
2 changes: 1 addition & 1 deletion examples/queries/examples/query_deployed_bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use eyre::Result;
async fn main() -> Result<()> {
// Create a provider.
let rpc_url = "https://eth.merkle.io".parse()?;
let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().on_http(rpc_url)?;

// Get the bytecode of the Uniswap V3 USDC-ETH pool on Ethereum mainnet.
let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640");
Expand Down
2 changes: 1 addition & 1 deletion examples/queries/examples/query_logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use eyre::Result;
async fn main() -> Result<()> {
// Create a provider.
let rpc_url = "https://eth.merkle.io".parse()?;
let provider = ProviderBuilder::new().on_reqwest_http(rpc_url)?;
let provider = ProviderBuilder::new().on_http(rpc_url)?;

// Get logs from the latest block
let latest_block = provider.get_block_number().await?;
Expand Down
Loading

0 comments on commit 4d111af

Please sign in to comment.