1use crate::{EthApi, IpcTask};
5use anvil_server::{ServerConfig, ipc::IpcEndpoint};
6use axum::Router;
7use futures::StreamExt;
8use rpc_handlers::{HttpEthRpcHandler, PubSubEthRpcHandler};
9use std::{io, net::SocketAddr, pin::pin};
10use tokio::net::TcpListener;
11
12mod beacon;
13mod rpc_handlers;
14
15pub async fn serve(
20 addr: SocketAddr,
21 api: EthApi,
22 config: ServerConfig,
23) -> io::Result<impl Future<Output = io::Result<()>>> {
24 let tcp_listener = TcpListener::bind(addr).await?;
25 Ok(serve_on(tcp_listener, api, config))
26}
27
28pub async fn serve_on(
30 tcp_listener: TcpListener,
31 api: EthApi,
32 config: ServerConfig,
33) -> io::Result<()> {
34 axum::serve(tcp_listener, router(api, config).into_make_service()).await
35}
36
37pub fn router(api: EthApi, config: ServerConfig) -> Router {
40 let http = HttpEthRpcHandler::new(api.clone());
41 let ws = PubSubEthRpcHandler::new(api.clone());
42
43 let rpc_router = anvil_server::http_ws_router(config, http, ws);
45
46 let beacon_router = beacon::router(api);
48
49 rpc_router.merge(beacon_router)
51}
52
53#[track_caller]
59pub fn spawn_ipc(api: EthApi, path: String) -> IpcTask {
60 try_spawn_ipc(api, path).expect("failed to establish ipc connection")
61}
62
63pub fn try_spawn_ipc(api: EthApi, path: String) -> io::Result<IpcTask> {
65 let handler = PubSubEthRpcHandler::new(api);
66 let ipc = IpcEndpoint::new(handler, path);
67 let incoming = ipc.incoming()?;
68
69 let task = tokio::task::spawn(async move {
70 let mut incoming = pin!(incoming);
71 while let Some(stream) = incoming.next().await {
72 trace!(target: "ipc", "new ipc connection");
73 tokio::task::spawn(stream);
74 }
75 });
76
77 Ok(task)
78}