diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8d8f99f..b9727501 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,7 @@ jobs: cache-on-failure: true - name: cargo hack run: | - cargo hack build --workspace --target wasm32-unknown-unknown --exclude op-alloy-network --exclude op-alloy-rpc-types + cargo hack build --workspace --target wasm32-unknown-unknown --exclude op-alloy-network --exclude op-alloy-rpc-types --exclude op-alloy-rpc-jsonrpsee wasm-wasi: runs-on: ubuntu-latest @@ -94,7 +94,7 @@ jobs: cache-on-failure: true - name: cargo hack run: | - cargo hack build --workspace --target wasm32-wasi --exclude op-alloy-network --exclude op-alloy-rpc-types + cargo hack build --workspace --target wasm32-wasi --exclude op-alloy-network --exclude op-alloy-rpc-types --exclude op-alloy-rpc-jsonrpsee no-std: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index f083f0e2..d810a361 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ rustdoc-args = ["--cfg", "docsrs"] [workspace.dependencies] # Alloy +op-alloy-rpc-jsonrpsee = { version = "0.1.5", path = "crates/rpc-jsonrpsee" } op-alloy-rpc-types = { version = "0.1.5", path = "crates/rpc-types" } op-alloy-consensus = { version = "0.1.5", path = "crates/consensus" } @@ -48,6 +49,11 @@ alloy-signer = { version = "0.2", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +# rpc +jsonrpsee = { version = "0.24", features = ["jsonrpsee-core", "client-core", "server-core", "macros"] } +jsonrpsee-core = "0.24" +jsonrpsee-types = "0.24" + # misc derive_more = { version = "0.99", default-features = false } diff --git a/crates/rpc-jsonrpsee/Cargo.toml b/crates/rpc-jsonrpsee/Cargo.toml new file mode 100644 index 00000000..082091d3 --- /dev/null +++ b/crates/rpc-jsonrpsee/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "op-alloy-rpc-jsonrpsee" +description = "Optimism RPC Client" + +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +authors.workspace = true +repository.workspace = true +exclude.workspace = true + +[dependencies] +# Alloy +op-alloy-rpc-types.workspace = true +alloy-eips.workspace = true + +# rpc +jsonrpsee.workspace = true + +[features] +client = [ + "jsonrpsee/client", + "jsonrpsee/async-client", +] diff --git a/crates/rpc-jsonrpsee/README.md b/crates/rpc-jsonrpsee/README.md new file mode 100644 index 00000000..b20e1afd --- /dev/null +++ b/crates/rpc-jsonrpsee/README.md @@ -0,0 +1,3 @@ +# op-alloy-rpc-jsonrpsee + +Low-level Optimism JSON-RPC server and client implementations. diff --git a/crates/rpc-jsonrpsee/src/lib.rs b/crates/rpc-jsonrpsee/src/lib.rs new file mode 100644 index 00000000..166342f9 --- /dev/null +++ b/crates/rpc-jsonrpsee/src/lib.rs @@ -0,0 +1,18 @@ +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg", + html_favicon_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/favicon.ico" +)] +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +pub mod traits; diff --git a/crates/rpc-jsonrpsee/src/traits.rs b/crates/rpc-jsonrpsee/src/traits.rs new file mode 100644 index 00000000..885eec09 --- /dev/null +++ b/crates/rpc-jsonrpsee/src/traits.rs @@ -0,0 +1,30 @@ +//! Rollup Node + +use alloy_eips::BlockNumberOrTag; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use op_alloy_rpc_types::{config::RollupConfig, output::OutputResponse, sync::SyncStatus}; + +/// Optimism specified rpc interface. +/// +/// https://docs.optimism.io/builders/node-operators/json-rpc +/// https://github.com/ethereum-optimism/optimism/blob/8dd17a7b114a7c25505cd2e15ce4e3d0f7e3f7c1/op-node/node/api.go#L114 +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "optimism"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "optimism"))] +pub trait RollupNode { + /// Get the output root at a specific block. + #[method(name = "outputAtBlock")] + async fn op_output_at_block(&self, block_number: BlockNumberOrTag) + -> RpcResult; + + /// Get the synchronization status. + #[method(name = "syncStatus")] + async fn op_sync_status(&self) -> RpcResult; + + /// Get the rollup configuration parameters. + #[method(name = "rollupConfig")] + async fn op_rollup_config(&self) -> RpcResult; + + /// Get the software version. + #[method(name = "version")] + async fn op_version(&self) -> RpcResult; +} diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index 2a6bbaf9..7ab33e8d 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -18,6 +18,7 @@ pub mod config; pub mod genesis; pub mod net; +pub mod output; pub mod receipt; pub mod sync; pub mod transaction; diff --git a/crates/rpc-types/src/output.rs b/crates/rpc-types/src/output.rs new file mode 100644 index 00000000..d4f8cebe --- /dev/null +++ b/crates/rpc-types/src/output.rs @@ -0,0 +1,25 @@ +//! Output Types + +use crate::sync::{L2BlockRef, SyncStatus}; +use alloy_primitives::B256; +use serde::{Deserialize, Serialize}; + +/// An [output response][or] for Optimism Rollup. +/// +/// [or]: https://github.com/ethereum-optimism/optimism/blob/f20b92d3eb379355c876502c4f28e72a91ab902f/op-service/eth/output.go#L10-L17 +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct OutputResponse { + /// The output version. + pub version: B256, + /// The output root hash. + pub output_root: B256, + /// A reference to the L2 block. + pub block_ref: L2BlockRef, + /// The withdrawal storage root. + pub withdrawal_storage_root: B256, + /// The state root. + pub state_root: B256, + /// The status of the node sync. + pub sync_status: SyncStatus, +}