Sitelet https://github.com/SharkHand3/examples/commit/611cab04d5f1c95a9ab5bbda8d4219203eeebef1
Skip to content

Commit 611cab0

Browse files
authored
fix(examples): require explicit RPC configuration (alloy-rs#250)
* fix(examples): require explicit RPC configuration * fix(examples): configure websocket and IPC transports
1 parent ffe38f4 commit 611cab0

50 files changed

Lines changed: 207 additions & 61 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Cargo.lock‎

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["helpers", "examples/*", "benches"]
2+
members = ["example-support", "helpers", "examples/*", "benches"]
33
resolver = "2"
44

55
[workspace.package]
@@ -151,4 +151,5 @@ rlp-derive = "0.2.0"
151151
alloy-rlp = "0.3.12"
152152

153153
# helpers
154+
example-support = { path = "example-support" }
154155
helpers = { path = "helpers" }

‎README.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ To run an example, use the command `cargo run --example <Example>`:
1616
cargo run --example mnemonic_signer
1717
```
1818

19+
Examples that query a live network or fork it with Anvil require you to supply an endpoint:
20+
21+
```sh
22+
RPC_URL=https://your-ethereum-endpoint cargo run --example http
23+
```
24+
25+
WebSocket and IPC examples use `WS_URL` and `IPC_PATH`, respectively. Examples with authentication
26+
also list their required credential variables in the error they return.
27+
28+
The fallback-layer example accepts a comma-separated list instead:
29+
30+
```sh
31+
RPC_URLS=https://first-endpoint,https://second-endpoint cargo run --example fallback_layer
32+
```
33+
34+
Use an endpoint for the network named by the example. For example, `any_network` expects an
35+
Arbitrum Sepolia endpoint, while mainnet contract and ENS examples expect Ethereum mainnet.
36+
Examples that fork a network also require [`anvil`](https://getfoundry.sh/anvil/overview/) in
37+
`PATH`. Hardware-wallet and cloud-signer examples require the device or credentials described in
38+
their source code.
39+
1940
## Overview
2041

2142
This repository contains the following examples:

‎example-support/Cargo.toml‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "example-support"
3+
publish.workspace = true
4+
version.workspace = true
5+
edition.workspace = true
6+
rust-version.workspace = true
7+
authors.workspace = true
8+
license.workspace = true
9+
homepage.workspace = true
10+
repository.workspace = true
11+
12+
[lints]
13+
workspace = true
14+
15+
[dependencies]
16+
eyre.workspace = true

‎example-support/src/lib.rs‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//! Shared configuration helpers for the examples workspace.
2+
3+
use eyre::{bail, Result, WrapErr};
4+
5+
/// Returns a non-empty environment variable or an actionable error.
6+
pub fn required_env(name: &str) -> Result<String> {
7+
let value =
8+
std::env::var(name).wrap_err_with(|| format!("{name} must be set for this example"))?;
9+
10+
if value.trim().is_empty() {
11+
bail!("{name} must not be empty");
12+
}
13+
14+
Ok(value)
15+
}
16+
17+
/// Returns the JSON-RPC endpoint configured through `RPC_URL`.
18+
pub fn rpc_url() -> Result<String> {
19+
required_env("RPC_URL").wrap_err("RPC_URL must contain a JSON-RPC endpoint")
20+
}
21+
22+
/// Returns the WebSocket endpoint configured through `WS_URL`.
23+
pub fn ws_url() -> Result<String> {
24+
required_env("WS_URL").wrap_err("WS_URL must contain a WebSocket JSON-RPC endpoint")
25+
}
26+
27+
/// Returns the IPC socket path configured through `IPC_PATH`.
28+
pub fn ipc_path() -> Result<String> {
29+
required_env("IPC_PATH").wrap_err("IPC_PATH must contain a JSON-RPC IPC socket path")
30+
}
31+
32+
/// Returns the comma-separated JSON-RPC endpoints configured through `RPC_URLS`.
33+
pub fn rpc_urls() -> Result<Vec<String>> {
34+
let value = std::env::var("RPC_URLS")
35+
.wrap_err("RPC_URLS must be set to comma-separated JSON-RPC endpoints for this example")?;
36+
let urls: Vec<_> = value
37+
.split(',')
38+
.map(str::trim)
39+
.filter(|url| !url.is_empty())
40+
.map(ToOwned::to_owned)
41+
.collect();
42+
43+
if urls.len() < 2 {
44+
bail!("RPC_URLS must contain at least two JSON-RPC endpoints");
45+
}
46+
47+
Ok(urls)
48+
}

‎examples/advanced/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ workspace = true
1616
foundry-fork-db.workspace = true
1717
alloy.workspace = true
1818
alloy-evm.workspace = true
19+
example-support.workspace = true
1920
helpers.workspace = true
2021

2122
# reth

‎examples/advanced/examples/any_network.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use alloy::{
1111
signers::local::PrivateKeySigner,
1212
sol,
1313
};
14+
use example_support::{required_env, rpc_url};
1415
use eyre::Result;
1516

1617
// The address of the contract below deployed to Arbitrum Sepolia.
@@ -44,10 +45,10 @@ struct ArbOtherFields {
4445
async fn main() -> Result<()> {
4546
// [RISK WARNING! Writing a private key in the code file is insecure behavior.]
4647
// The following code is for testing only. Set up signer from private key, be aware of danger.
47-
let signer: PrivateKeySigner = "<PRIVATE_KEY>".parse().expect("should parse private key");
48+
let signer: PrivateKeySigner = required_env("PRIVATE_KEY")?.parse()?;
4849

4950
// Create a provider with the Arbitrum Sepolia network and the wallet.
50-
let rpc_url = "https://sepolia-rollup.arbitrum.io/rpc".parse()?;
51+
let rpc_url = rpc_url()?.parse()?;
5152
let provider =
5253
ProviderBuilder::new().network::<AnyNetwork>().wallet(signer).connect_http(rpc_url);
5354

‎examples/advanced/examples/uniswap_u256_alloy_simulation.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use alloy::{
99
sol,
1010
sol_types::SolCall,
1111
};
12+
use example_support::rpc_url;
1213
use eyre::Result;
1314
use helpers::alloy::{
1415
get_amount_in, get_amount_out, get_sushi_pair, get_uniswap_pair, set_hash_storage_slot,
@@ -38,8 +39,9 @@ async fn main() -> Result<()> {
3839
let sushi_pair = get_sushi_pair();
3940

4041
let wallet_address = address!("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
41-
let provider = ProviderBuilder::new()
42-
.connect_anvil_with_wallet_and_config(|a| a.fork("https://reth-ethereum.ithaca.xyz/rpc"))?;
42+
let rpc_url = rpc_url()?;
43+
let provider =
44+
ProviderBuilder::new().connect_anvil_with_wallet_and_config(|anvil| anvil.fork(rpc_url))?;
4345

4446
let executor = FlashBotsMultiCall::deploy(provider.clone(), wallet_address).await?;
4547
let iweth = IERC20::new(WETH_ADDR, provider.clone());

‎examples/contracts/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ workspace = true
1414

1515
[dev-dependencies]
1616
alloy.workspace = true
17+
example-support.workspace = true
1718

1819
eyre.workspace = true
1920
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

‎examples/contracts/examples/interact_with_abi.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Example of generating code from ABI file using the `sol!` macro to interact with the contract.
22
33
use alloy::{primitives::address, providers::ProviderBuilder, sol};
4+
use example_support::rpc_url;
45
use eyre::Result;
56

67
// Codegen from ABI file to interact with the contract.
@@ -15,7 +16,7 @@ sol!(
1516
async fn main() -> Result<()> {
1617
// Spin up a forked Anvil node.
1718
// Ensure `anvil` is available in $PATH.
18-
let rpc_url = "https://reth-ethereum.ithaca.xyz/rpc";
19+
let rpc_url = rpc_url()?;
1920
let provider =
2021
ProviderBuilder::new().connect_anvil_with_wallet_and_config(|anvil| anvil.fork(rpc_url))?;
2122

0 commit comments

Comments
 (0)