Skip to main content

anvil_polkadot/server/
mod.rs

1//! Contains the code to launch an Ethereum RPC server.
2
3use anvil_server::{ServerConfig, ipc::IpcEndpoint};
4use axum::Router;
5use futures::StreamExt;
6use handler::{HttpEthRpcHandler, PubSubEthRpcHandler};
7use polkadot_sdk::sc_service::SpawnTaskHandle;
8use std::{io, pin::pin};
9use tokio::net::TcpListener;
10
11use crate::api_server::ApiHandle;
12
13mod handler;
14
15/// Configures a server that handles JSON-RPC calls via HTTP and WS.
16pub async fn serve_on(
17    tcp_listener: TcpListener,
18    config: ServerConfig,
19    api_handle: ApiHandle,
20) -> io::Result<()> {
21    axum::serve(tcp_listener, router(api_handle, config).into_make_service()).await
22}
23
24/// Launches an ipc server at the given path in a new task.
25pub fn try_spawn_ipc(
26    spawn_handle: &SpawnTaskHandle,
27    path: String,
28    api_handle: ApiHandle,
29) -> io::Result<()> {
30    let handler = PubSubEthRpcHandler::new(api_handle);
31    let ipc = IpcEndpoint::new(handler, path);
32    let incoming = ipc.incoming()?;
33
34    let inner_spawn_handle = spawn_handle.clone();
35
36    spawn_handle.spawn("ipc", "anvil", async move {
37        let mut incoming = pin!(incoming);
38        while let Some(stream) = incoming.next().await {
39            trace!(target: "ipc", "new ipc connection");
40            inner_spawn_handle.spawn("ipc-connection", "anvil", stream);
41        }
42    });
43
44    Ok(())
45}
46
47/// Configures an [`axum::Router`] that handles JSON-RPC calls via HTTP and WS.
48fn router(api_handle: ApiHandle, config: ServerConfig) -> Router {
49    let http = HttpEthRpcHandler::new(api_handle.clone());
50    let ws = PubSubEthRpcHandler::new(api_handle);
51    anvil_server::http_ws_router(config, http, ws)
52}