anvil/server/
mod.rs
1use crate::{EthApi, IpcTask};
4use anvil_server::{ipc::IpcEndpoint, ServerConfig};
5use axum::Router;
6use futures::StreamExt;
7use handler::{HttpEthRpcHandler, PubSubEthRpcHandler};
8use std::{future::Future, io, net::SocketAddr, pin::pin};
9use tokio::net::TcpListener;
10
11pub mod error;
12mod handler;
13
14pub async fn serve(
19 addr: SocketAddr,
20 api: EthApi,
21 config: ServerConfig,
22) -> io::Result<impl Future<Output = io::Result<()>>> {
23 let tcp_listener = TcpListener::bind(addr).await?;
24 Ok(serve_on(tcp_listener, api, config))
25}
26
27pub async fn serve_on(
29 tcp_listener: TcpListener,
30 api: EthApi,
31 config: ServerConfig,
32) -> io::Result<()> {
33 axum::serve(tcp_listener, router(api, config).into_make_service()).await
34}
35
36pub fn router(api: EthApi, config: ServerConfig) -> Router {
38 let http = HttpEthRpcHandler::new(api.clone());
39 let ws = PubSubEthRpcHandler::new(api);
40 anvil_server::http_ws_router(config, http, ws)
41}
42
43#[track_caller]
49pub fn spawn_ipc(api: EthApi, path: String) -> IpcTask {
50 try_spawn_ipc(api, path).expect("failed to establish ipc connection")
51}
52
53pub fn try_spawn_ipc(api: EthApi, path: String) -> io::Result<IpcTask> {
55 let handler = PubSubEthRpcHandler::new(api);
56 let ipc = IpcEndpoint::new(handler, path);
57 let incoming = ipc.incoming()?;
58
59 let task = tokio::task::spawn(async move {
60 let mut incoming = pin!(incoming);
61 while let Some(stream) = incoming.next().await {
62 trace!(target: "ipc", "new ipc connection");
63 tokio::task::spawn(stream);
64 }
65 });
66
67 Ok(task)
68}