From 4c6c3c74e2313d55f754dceb42f32cfc98480096 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:51:10 +0530 Subject: [PATCH 1/4] feat: JSON-RPC batch request --- README.md | 1 + examples/providers/examples/batch_rpc.rs | 45 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 examples/providers/examples/batch_rpc.rs diff --git a/README.md b/README.md index 9151341..dc8bcd3 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ This repository contains the following examples: - [x] [Subscribe and listen to pending transactions in the public mempool](./examples/subscriptions/examples/subscribe_pending_transactions.rs) - [x] [Event multiplexer](./examples/subscriptions/examples/event_multiplexer.rs) - [x] Providers + - [x] [JSON-RPC Batch Request](./examples/providers/examples/batch_rpc.rs) - [x] [Builder](./examples/providers/examples/builder.rs) - [x] [Builtin](./examples/providers/examples/builtin.rs) - [x] [HTTP with authentication](./examples/providers/examples/http_with_auth.rs) diff --git a/examples/providers/examples/batch_rpc.rs b/examples/providers/examples/batch_rpc.rs new file mode 100644 index 0000000..041b418 --- /dev/null +++ b/examples/providers/examples/batch_rpc.rs @@ -0,0 +1,45 @@ +//! Example depicting how to make a Batch RPC request using the HTTP provider. + +use alloy::{ + primitives::{address, U128, U64}, + rpc::client::ClientBuilder, +}; +use eyre::Result; + +#[tokio::main] +async fn main() -> Result<()> { + let rpc_url = "https://eth.merkle.io".parse()?; + + // Create a HTTP transport. + let client = ClientBuilder::default().http(rpc_url); + + // Instantiate a batch. + let mut batch = client.new_batch(); + + // Add calls to the batch. + let blobk_number_fut = + batch.add_call("eth_blockNumber", &())?.map_resp(|resp: U64| resp.to::()); + + let gas_price_fut = + batch.add_call("eth_gasPrice", &())?.map_resp(|resp: U128| resp.to::()); + + let vitalik = address!("d8da6bf26964af9d7eed9e03e53415d37aa96045"); + + let vitalik_nonce_fut = batch + .add_call("eth_getTransactionCount", &(vitalik, "latest"))? // Vitalik's nonce at BlockId::Latest + .map_resp(|resp: U128| resp.to::()); + + // Send the batch request. + batch.send().await?; + + // Get the results. + let latest_block = blobk_number_fut.await?; + let gas_price = gas_price_fut.await?; + let vitalik_nonce = vitalik_nonce_fut.await?; + + println!("Latest block number: {latest_block}"); + println!("Gas price: {gas_price}"); + println!("Vitalik's nonce: {vitalik_nonce}"); + + Ok(()) +} From e819394faf77f14a76ef1d50c7a9b701afe188e5 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:55:14 +0530 Subject: [PATCH 2/4] use anvil --- examples/providers/examples/batch_rpc.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/providers/examples/batch_rpc.rs b/examples/providers/examples/batch_rpc.rs index 041b418..c1d944b 100644 --- a/examples/providers/examples/batch_rpc.rs +++ b/examples/providers/examples/batch_rpc.rs @@ -1,6 +1,7 @@ //! Example depicting how to make a Batch RPC request using the HTTP provider. use alloy::{ + node_bindings::Anvil, primitives::{address, U128, U64}, rpc::client::ClientBuilder, }; @@ -8,7 +9,10 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - let rpc_url = "https://eth.merkle.io".parse()?; + let anvil = Anvil::new().spawn(); + + // Swap this out with a RPC_URL provider that supports JSON-RPC batch requests. e.g. https://eth.merkle.io + let rpc_url = anvil.endpoint_url(); // Create a HTTP transport. let client = ClientBuilder::default().http(rpc_url); From 6576ba7784bad81ea586f7ef0d1c5596a274182e Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:59:12 +0530 Subject: [PATCH 3/4] try_join! --- examples/providers/examples/batch_rpc.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/providers/examples/batch_rpc.rs b/examples/providers/examples/batch_rpc.rs index c1d944b..703f42a 100644 --- a/examples/providers/examples/batch_rpc.rs +++ b/examples/providers/examples/batch_rpc.rs @@ -37,9 +37,8 @@ async fn main() -> Result<()> { batch.send().await?; // Get the results. - let latest_block = blobk_number_fut.await?; - let gas_price = gas_price_fut.await?; - let vitalik_nonce = vitalik_nonce_fut.await?; + let (latest_block, gas_price, vitalik_nonce) = + tokio::try_join!(blobk_number_fut, gas_price_fut, vitalik_nonce_fut)?; println!("Latest block number: {latest_block}"); println!("Gas price: {gas_price}"); From add9d4b1da20a307bb892b8034770d88020349c9 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:00:08 +0530 Subject: [PATCH 4/4] nit --- examples/providers/examples/batch_rpc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/providers/examples/batch_rpc.rs b/examples/providers/examples/batch_rpc.rs index 703f42a..260f2b3 100644 --- a/examples/providers/examples/batch_rpc.rs +++ b/examples/providers/examples/batch_rpc.rs @@ -21,7 +21,7 @@ async fn main() -> Result<()> { let mut batch = client.new_batch(); // Add calls to the batch. - let blobk_number_fut = + let block_number_fut = batch.add_call("eth_blockNumber", &())?.map_resp(|resp: U64| resp.to::()); let gas_price_fut = @@ -38,7 +38,7 @@ async fn main() -> Result<()> { // Get the results. let (latest_block, gas_price, vitalik_nonce) = - tokio::try_join!(blobk_number_fut, gas_price_fut, vitalik_nonce_fut)?; + tokio::try_join!(block_number_fut, gas_price_fut, vitalik_nonce_fut)?; println!("Latest block number: {latest_block}"); println!("Gas price: {gas_price}");