Skip to content

Commit af0fee2

Browse files
authored
feat: rpc_headers in cast and config (#9429)
* feat: specify `rpc_headers` in cast and config * test
1 parent fbbcc8c commit af0fee2

File tree

8 files changed

+51
-5
lines changed

8 files changed

+51
-5
lines changed

Cargo.lock

Lines changed: 18 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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ alloy-transport = { version = "0.6.4", default-features = false }
205205
alloy-transport-http = { version = "0.6.4", default-features = false }
206206
alloy-transport-ipc = { version = "0.6.4", default-features = false }
207207
alloy-transport-ws = { version = "0.6.4", default-features = false }
208+
alloy-node-bindings = { version = "0.6.4", default-features = false }
208209

209210
## alloy-core
210211
alloy-dyn-abi = "0.8.11"

crates/cast/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ tikv-jemallocator = { workspace = true, optional = true }
9494
[dev-dependencies]
9595
anvil.workspace = true
9696
foundry-test-utils.workspace = true
97+
alloy-node-bindings.workspace = true
9798

9899
async-trait.workspace = true
99100
divan.workspace = true

crates/cast/bin/cmd/run.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,9 @@ impl RunArgs {
107107
let compute_units_per_second =
108108
if self.no_rate_limit { Some(u64::MAX) } else { self.compute_units_per_second };
109109

110-
let provider = foundry_common::provider::ProviderBuilder::new(
111-
&config.get_rpc_url_or_localhost_http()?,
112-
)
113-
.compute_units_per_second_opt(compute_units_per_second)
114-
.build()?;
110+
let provider = foundry_cli::utils::get_provider_builder(&config)?
111+
.compute_units_per_second_opt(compute_units_per_second)
112+
.build()?;
115113

116114
let tx_hash = self.tx_hash.parse().wrap_err("invalid tx hash")?;
117115
let tx = provider

crates/cli/src/opts/ethereum.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ pub struct RpcOpts {
4848
/// Default value: 45
4949
#[arg(long, env = "ETH_RPC_TIMEOUT")]
5050
pub rpc_timeout: Option<u64>,
51+
52+
/// Specify custom headers for RPC requests.
53+
#[arg(long, alias = "headers", env = "ETH_RPC_HEADERS", value_delimiter(','))]
54+
pub rpc_headers: Option<Vec<String>>,
5155
}
5256

5357
impl_figment_convert_cast!(RpcOpts);
@@ -95,6 +99,9 @@ impl RpcOpts {
9599
if let Some(rpc_timeout) = self.rpc_timeout {
96100
dict.insert("eth_rpc_timeout".into(), rpc_timeout.into());
97101
}
102+
if let Some(headers) = &self.rpc_headers {
103+
dict.insert("eth_rpc_headers".into(), headers.clone().into());
104+
}
98105
dict
99106
}
100107
}

crates/cli/src/utils/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ pub const STATIC_FUZZ_SEED: [u8; 32] = [
3939
0x5d, 0x64, 0x0b, 0x19, 0xad, 0xf0, 0xe3, 0x57, 0xb8, 0xd4, 0xbe, 0x7d, 0x49, 0xee, 0x70, 0xe6,
4040
];
4141

42+
const DEFAULT_USER_AGENT: &str = concat!("foundry/", env!("CARGO_PKG_VERSION"));
43+
4244
/// Useful extensions to [`std::path::Path`].
4345
pub trait FoundryPathExt {
4446
/// Returns true if the [`Path`] ends with `.t.sol`
@@ -110,6 +112,14 @@ pub fn get_provider_builder(config: &Config) -> Result<ProviderBuilder> {
110112
builder = builder.timeout(Duration::from_secs(rpc_timeout));
111113
}
112114

115+
if let Some(mut rpc_headers) = config.eth_rpc_headers.clone() {
116+
if !rpc_headers.iter().any(|h| h.starts_with("User-Agent:")) {
117+
rpc_headers.push(format!("User-Agent:{DEFAULT_USER_AGENT}"));
118+
}
119+
120+
builder = builder.headers(rpc_headers);
121+
}
122+
113123
Ok(builder)
114124
}
115125

crates/config/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ pub struct Config {
253253
pub eth_rpc_jwt: Option<String>,
254254
/// Timeout that should be used for any rpc calls
255255
pub eth_rpc_timeout: Option<u64>,
256+
/// Headers that should be used for any rpc calls
257+
///
258+
/// # Example
259+
///
260+
/// rpc_headers = ["x-custom-header:value", "x-another-header:another-value"]
261+
///
262+
/// You can also the ETH_RPC_HEADERS env variable like so:
263+
/// `ETH_RPC_HEADERS="x-custom-header:value x-another-header:another-value"`
264+
pub eth_rpc_headers: Option<Vec<String>>,
256265
/// etherscan API key, or alias for an `EtherscanConfig` in `etherscan` table
257266
pub etherscan_api_key: Option<String>,
258267
/// Multiple etherscan api configs and their aliases
@@ -2347,6 +2356,7 @@ impl Default for Config {
23472356
eth_rpc_url: None,
23482357
eth_rpc_jwt: None,
23492358
eth_rpc_timeout: None,
2359+
eth_rpc_headers: None,
23502360
etherscan_api_key: None,
23512361
verbosity: 0,
23522362
remappings: vec![],

crates/forge/tests/cli/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ forgetest!(can_extract_config_values, |prj, cmd| {
109109
eth_rpc_url: Some("localhost".to_string()),
110110
eth_rpc_jwt: None,
111111
eth_rpc_timeout: None,
112+
eth_rpc_headers: None,
112113
etherscan_api_key: None,
113114
etherscan: Default::default(),
114115
verbosity: 4,

0 commit comments

Comments
 (0)