Skip to main content

espresso_api/
lib.rs

1//! Espresso API server with both Axum (HTTP/JSON) and gRPC endpoints
2
3// Module declarations
4mod axum;
5pub mod error;
6pub mod handlers;
7mod tonic;
8pub mod v1;
9pub mod v2;
10
11// Generated gRPC service code - committed to git for visibility in code review
12pub mod proto {
13    include!("espresso.api.v2.rs");
14}
15
16// Re-exports
17pub use self::{
18    axum::{create_combined_router, create_router_v1, create_router_v2, routes},
19    tonic::create_reward_service,
20};
21
22/// Start Axum HTTP server with combined v1 and v2 APIs
23///
24/// This serves both APIs at /v1/* and /v2/* from a single state implementation.
25pub async fn serve_axum<S>(port: u16, state: S) -> anyhow::Result<()>
26where
27    S: v1::RewardApi
28        + v1::AvailabilityApi
29        + v1::HotShotAvailabilityApi
30        + v2::RewardApi
31        + v2::DataApi
32        + v2::ConsensusApi
33        + Clone
34        + Send
35        + Sync
36        + 'static,
37{
38    tracing::info!("Starting Axum server on port {} with v1 and v2 APIs", port);
39
40    let app = create_combined_router(state);
41    let addr = format!("0.0.0.0:{}", port);
42
43    tracing::info!("Binding to {}", addr);
44    let listener = tokio::net::TcpListener::bind(&addr).await?;
45
46    tracing::info!(
47        "Axum API server listening on {} (v1 and v2 routes available)",
48        addr
49    );
50    ::axum::serve(listener, app.into_make_service()).await?;
51
52    tracing::info!("Axum server stopped");
53    Ok(())
54}
55
56/// Start Tonic gRPC server
57pub async fn serve_tonic<S>(port: u16, state: S) -> anyhow::Result<()>
58where
59    S: v2::RewardApi + Clone + Send + Sync + 'static,
60{
61    use ::tonic::transport::Server;
62
63    let addr = std::net::SocketAddr::from(([0, 0, 0, 0], port));
64
65    let reward_service = create_reward_service(state);
66
67    // Enable gRPC reflection for tools like grpcurl
68    let reflection_service = tonic_reflection::server::Builder::configure()
69        .register_encoded_file_descriptor_set(include_bytes!(concat!(
70            env!("OUT_DIR"),
71            "/reflection_descriptor.bin"
72        )))
73        .build_v1()?;
74
75    tracing::info!("gRPC server listening on {}", addr);
76    Server::builder()
77        .add_service(reward_service)
78        .add_service(reflection_service)
79        .serve(addr)
80        .await?;
81
82    Ok(())
83}