diff --git a/crates/cli/src/utils/mod.rs b/crates/cli/src/utils/mod.rs index f833924f57fe..9f8475f63dab 100644 --- a/crates/cli/src/utils/mod.rs +++ b/crates/cli/src/utils/mod.rs @@ -39,8 +39,6 @@ pub const STATIC_FUZZ_SEED: [u8; 32] = [ 0x5d, 0x64, 0x0b, 0x19, 0xad, 0xf0, 0xe3, 0x57, 0xb8, 0xd4, 0xbe, 0x7d, 0x49, 0xee, 0x70, 0xe6, ]; -const DEFAULT_USER_AGENT: &str = concat!("foundry/", env!("CARGO_PKG_VERSION")); - /// Useful extensions to [`std::path::Path`]. pub trait FoundryPathExt { /// Returns true if the [`Path`] ends with `.t.sol` @@ -112,11 +110,7 @@ pub fn get_provider_builder(config: &Config) -> Result { builder = builder.timeout(Duration::from_secs(rpc_timeout)); } - if let Some(mut rpc_headers) = config.eth_rpc_headers.clone() { - if !rpc_headers.iter().any(|h| h.starts_with("User-Agent:")) { - rpc_headers.push(format!("User-Agent:{DEFAULT_USER_AGENT}")); - } - + if let Some(rpc_headers) = config.eth_rpc_headers.clone() { builder = builder.headers(rpc_headers); } diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs index 0ba0514c2b87..4ff3eb8d70fb 100644 --- a/crates/common/src/constants.rs +++ b/crates/common/src/constants.rs @@ -40,6 +40,9 @@ pub const OPTIMISM_SYSTEM_ADDRESS: Address = address!("deaddeaddeaddeaddeaddeadd /// Transaction identifier of System transaction types pub const SYSTEM_TRANSACTION_TYPE: u8 = 126; +/// Default user agent set as the header for requests that don't specify one. +pub const DEFAULT_USER_AGENT: &str = concat!("foundry/", env!("CARGO_PKG_VERSION")); + /// Returns whether the sender is a known L2 system sender that is the first tx in every block. /// /// Transactions from these senders usually don't have a any fee information. diff --git a/crates/common/src/provider/runtime_transport.rs b/crates/common/src/provider/runtime_transport.rs index a95969be5a40..563cec313850 100644 --- a/crates/common/src/provider/runtime_transport.rs +++ b/crates/common/src/provider/runtime_transport.rs @@ -1,7 +1,7 @@ //! Runtime transport that connects on first request, which can take either of an HTTP, //! WebSocket, or IPC transport and supports retries based on CUPS logic. -use crate::REQUEST_TIMEOUT; +use crate::{DEFAULT_USER_AGENT, REQUEST_TIMEOUT}; use alloy_json_rpc::{RequestPacket, ResponsePacket}; use alloy_pubsub::{PubSubConnect, PubSubFrontend}; use alloy_rpc_types::engine::{Claims, JwtSecret}; @@ -176,6 +176,14 @@ impl RuntimeTransport { ); } + if !headers.iter().any(|(k, _v)| k.as_str().starts_with("User-Agent:")) { + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_str(DEFAULT_USER_AGENT) + .expect("User-Agent should be valid string"), + ); + } + client_builder = client_builder.default_headers(headers); let client =