diff --git a/Cargo.lock b/Cargo.lock index c52e0c3e..0db1501f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1926,6 +1926,15 @@ dependencies = [ "tracing-subscriber 0.3.22", ] +[[package]] +name = "base-client-cli" +version = "0.2.1" +dependencies = [ + "alloy-rpc-types-engine", + "clap", + "url", +] + [[package]] name = "base-client-node" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index e727a771..e626e08b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ base-flashtypes = { path = "crates/shared/flashtypes" } base-primitives = { path = "crates/shared/primitives" } base-reth-rpc-types = { path = "crates/shared/reth-rpc-types" } # Client +base-client-cli = { path = "crates/client/cli" } base-client-node = { path = "crates/client/node" } base-metering = { path = "crates/client/metering" } base-txpool = { path = "crates/client/txpool" } diff --git a/crates/client/cli/Cargo.toml b/crates/client/cli/Cargo.toml new file mode 100644 index 00000000..463d0954 --- /dev/null +++ b/crates/client/cli/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "base-client-cli" +description = "CLI argument types for Base node consensus clients" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# General +url.workspace = true +clap.workspace = true +alloy-rpc-types-engine.workspace = true diff --git a/crates/client/cli/README.md b/crates/client/cli/README.md new file mode 100644 index 00000000..6c318034 --- /dev/null +++ b/crates/client/cli/README.md @@ -0,0 +1,34 @@ +# `base-client-cli` + +CLI argument types for Base node consensus clients. + +## Overview + +This crate provides reusable CLI argument types for configuring Base node consensus clients: + +- **`L1ClientArgs`**: L1 execution client RPC configuration +- **`L2ClientArgs`**: L2 engine API configuration with JWT handling + +## Usage + +```toml +[dependencies] +base-client-cli = { workspace = true } +``` + +```rust +use base_client_cli::{L1ClientArgs, L2ClientArgs}; +use clap::Parser; + +#[derive(Parser)] +struct Cli { + #[clap(flatten)] + l1_args: L1ClientArgs, + #[clap(flatten)] + l2_args: L2ClientArgs, +} +``` + +## License + +Licensed under the MIT License. diff --git a/crates/client/cli/src/l1.rs b/crates/client/cli/src/l1.rs new file mode 100644 index 00000000..b4a36d27 --- /dev/null +++ b/crates/client/cli/src/l1.rs @@ -0,0 +1,47 @@ +//! L1 Client CLI arguments. + +use url::Url; + +const DEFAULT_L1_TRUST_RPC: bool = true; + +/// L1 client arguments. +#[derive(Clone, Debug, clap::Args)] +pub struct L1ClientArgs { + /// URL of the L1 execution client RPC API. + #[arg(long, visible_alias = "l1", env = "KONA_NODE_L1_ETH_RPC")] + pub l1_eth_rpc: Url, + /// Whether to trust the L1 RPC. + /// If false, block hash verification is performed for all retrieved blocks. + #[arg( + long, + visible_alias = "l1.trust-rpc", + env = "KONA_NODE_L1_TRUST_RPC", + default_value_t = DEFAULT_L1_TRUST_RPC + )] + pub l1_trust_rpc: bool, + /// URL of the L1 beacon API. + #[arg(long, visible_alias = "l1.beacon", env = "KONA_NODE_L1_BEACON")] + pub l1_beacon: Url, + /// Duration in seconds of an L1 slot. + /// + /// This is an optional argument that can be used to use a fixed slot duration for l1 blocks + /// and bypass the initial beacon spec fetch. This is useful for testing purposes when the + /// l1-beacon spec endpoint is not available (with anvil for example). + #[arg( + long, + visible_alias = "l1.slot-duration-override", + env = "KONA_NODE_L1_SLOT_DURATION_OVERRIDE" + )] + pub l1_slot_duration_override: Option, +} + +impl Default for L1ClientArgs { + fn default() -> Self { + Self { + l1_eth_rpc: Url::parse("http://localhost:8545").unwrap(), + l1_trust_rpc: DEFAULT_L1_TRUST_RPC, + l1_beacon: Url::parse("http://localhost:5052").unwrap(), + l1_slot_duration_override: None, + } + } +} diff --git a/crates/client/cli/src/l2.rs b/crates/client/cli/src/l2.rs new file mode 100644 index 00000000..ed0198d8 --- /dev/null +++ b/crates/client/cli/src/l2.rs @@ -0,0 +1,53 @@ +//! L2 Client CLI arguments with JWT handling. + +use std::path::PathBuf; + +use alloy_rpc_types_engine::JwtSecret; +use url::Url; + +const DEFAULT_L2_ENGINE_TIMEOUT: u64 = 30_000; +const DEFAULT_L2_TRUST_RPC: bool = true; + +/// L2 client arguments. +#[derive(Clone, Debug, clap::Args)] +pub struct L2ClientArgs { + /// URI of the engine API endpoint of an L2 execution client. + #[arg(long, visible_alias = "l2", env = "KONA_NODE_L2_ENGINE_RPC")] + pub l2_engine_rpc: Url, + /// JWT secret for the auth-rpc endpoint of the execution client. + /// This MUST be a valid path to a file containing the hex-encoded JWT secret. + #[arg(long, visible_alias = "l2.jwt-secret", env = "KONA_NODE_L2_ENGINE_AUTH")] + pub l2_engine_jwt_secret: Option, + /// Hex encoded JWT secret to use for the authenticated engine-API RPC server. + /// This MUST be a valid hex-encoded JWT secret of 64 digits. + #[arg(long, visible_alias = "l2.jwt-secret-encoded", env = "KONA_NODE_L2_ENGINE_AUTH_ENCODED")] + pub l2_engine_jwt_encoded: Option, + /// Timeout for http calls in milliseconds. + #[arg( + long, + visible_alias = "l2.timeout", + env = "KONA_NODE_L2_ENGINE_TIMEOUT", + default_value_t = DEFAULT_L2_ENGINE_TIMEOUT + )] + pub l2_engine_timeout: u64, + /// If false, block hash verification is performed for all retrieved blocks. + #[arg( + long, + visible_alias = "l2.trust-rpc", + env = "KONA_NODE_L2_TRUST_RPC", + default_value_t = DEFAULT_L2_TRUST_RPC + )] + pub l2_trust_rpc: bool, +} + +impl Default for L2ClientArgs { + fn default() -> Self { + Self { + l2_engine_rpc: Url::parse("http://localhost:8551").unwrap(), + l2_engine_jwt_secret: None, + l2_engine_jwt_encoded: None, + l2_engine_timeout: DEFAULT_L2_ENGINE_TIMEOUT, + l2_trust_rpc: DEFAULT_L2_TRUST_RPC, + } + } +} diff --git a/crates/client/cli/src/lib.rs b/crates/client/cli/src/lib.rs new file mode 100644 index 00000000..ad91a070 --- /dev/null +++ b/crates/client/cli/src/lib.rs @@ -0,0 +1,10 @@ +#![doc = include_str!("../README.md")] +#![doc(issue_tracker_base_url = "https://github.com/base/node-reth/issues/")] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +mod l1; +pub use l1::L1ClientArgs; + +mod l2; +pub use l2::L2ClientArgs;