Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add rpc namespace #994

Merged
merged 3 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ alloy-rpc-types-eth.workspace = true
alloy-rpc-types-trace = { workspace = true, optional = true }
alloy-rpc-types-txpool = { workspace = true, optional = true }
alloy-rpc-types-engine = { workspace = true, optional = true }
alloy-rpc-types = { workspace = true, optional = true }
alloy-transport-http = { workspace = true, optional = true }
alloy-transport-ipc = { workspace = true, optional = true }
alloy-transport-ws = { workspace = true, optional = true }
Expand Down Expand Up @@ -98,4 +99,5 @@ debug-api = ["dep:alloy-rpc-types-trace"]
engine-api = ["dep:alloy-rpc-types-engine"]
net-api = []
trace-api = ["dep:alloy-rpc-types-trace"]
rpc-api = ["dep:alloy-rpc-types"]
txpool-api = ["dep:alloy-rpc-types-txpool"]
5 changes: 5 additions & 0 deletions crates/provider/src/ext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ mod trace;
#[cfg(feature = "trace-api")]
pub use trace::{TraceApi, TraceCallList};

#[cfg(feature = "rpc-api")]
mod rpc;
#[cfg(feature = "rpc-api")]
pub use rpc::RpcApi;

#[cfg(feature = "txpool-api")]
mod txpool;
#[cfg(feature = "txpool-api")]
Expand Down
27 changes: 27 additions & 0 deletions crates/provider/src/ext/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! This module extends the Ethereum JSON-RPC provider with the Rpc namespace's RPC methods.
use crate::Provider;
use alloy_network::Network;
use alloy_rpc_types::RpcModules;
use alloy_transport::{Transport, TransportResult};

/// The rpc API provides methods to get information about the RPC server itself, such as the enabled
/// namespaces.
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait RpcApi<N, T>: Send + Sync {
/// Lists the enabled RPC namespaces and the versions of each.
async fn rpc_modules(&self) -> TransportResult<RpcModules>;
}

#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl<N, T, P> RpcApi<N, T> for P
where
N: Network,
T: Transport + Clone,
P: Provider<T, N>,
{
async fn rpc_modules(&self) -> TransportResult<RpcModules> {
self.client().request("rpc_modules", ()).await
}
}
4 changes: 4 additions & 0 deletions crates/rpc-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ alloy-rpc-types-eth = { workspace = true, optional = true }
alloy-rpc-types-mev = { workspace = true, optional = true }
alloy-rpc-types-trace = { workspace = true, optional = true }
alloy-rpc-types-txpool = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive", "std"]}

[dev-dependencies]
serde_json.workspace = true

[features]
default = ["eth"]
Expand Down
3 changes: 3 additions & 0 deletions crates/rpc-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

pub use alloy_serde as serde_helpers;

mod rpc;
pub use rpc::*;

#[cfg(feature = "admin")]
pub use alloy_rpc_types_admin as admin;

Expand Down
42 changes: 42 additions & 0 deletions crates/rpc-types/src/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! Types for the `rpc` API.
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Represents the `rpc_modules` response, which returns the
/// list of all available modules on that transport and their version
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(transparent)]
pub struct RpcModules {
module_map: HashMap<String, String>,
}

impl RpcModules {
/// Create a new instance of `RPCModules`
pub const fn new(module_map: HashMap<String, String>) -> Self {
Self { module_map }
}

/// Consumes self and returns the inner hashmap mapping module names to their versions
pub fn into_modules(self) -> HashMap<String, String> {
self.module_map
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_module_versions_roundtrip() {
let s = r#"{"txpool":"1.0","trace":"1.0","eth":"1.0","web3":"1.0","net":"1.0"}"#;
let module_map = HashMap::from([
("txpool".to_owned(), "1.0".to_owned()),
("trace".to_owned(), "1.0".to_owned()),
("eth".to_owned(), "1.0".to_owned()),
("web3".to_owned(), "1.0".to_owned()),
("net".to_owned(), "1.0".to_owned()),
]);
let m = RpcModules::new(module_map);
let de_serialized: RpcModules = serde_json::from_str(s).unwrap();
assert_eq!(de_serialized, m);
}
}