mina_node_native/http_server/routes/
state.rs1use axum::{
11 extract::{Query, State},
12 Json,
13};
14use serde::Deserialize;
15use utoipa_axum::{router::OpenApiRouter, routes};
16
17use mina_node::rpc::{RpcMessageProgressResponse, RpcPeersGetResponse, RpcRequest};
18use mina_node_common::rpc::RpcStateGetResponse;
19
20use crate::http_server::{AppError, AppResult, AppState, JsonErrorResponse};
21
22pub fn routes() -> OpenApiRouter<AppState> {
24 OpenApiRouter::new()
25 .routes(routes!(state_get, state_post))
26 .routes(routes!(peers))
27 .routes(routes!(message_progress))
28}
29
30#[derive(Deserialize, Default)]
31struct StateQueryParams {
32 filter: Option<String>,
34}
35
36#[utoipa::path(
38 get,
39 path = "/state",
40 tag = "state",
41 params(
42 ("filter" = Option<String>, Query, description = "JSONPath filter expression")
43 ),
44 responses(
45 (status = 200, description = "Node state"),
46 (status = 400, description = "Invalid filter expression", body = JsonErrorResponse,
47 example = json!({"error": "failed to parse filter expression: unexpected token"}))
48 )
49)]
50async fn state_get(
51 State(state): State<AppState>,
52 Query(params): Query<StateQueryParams>,
53) -> AppResult<Json<serde_json::Value>> {
54 state_handler(state, params.filter).await
55}
56
57#[utoipa::path(
59 post,
60 path = "/state",
61 tag = "state",
62 responses(
63 (status = 200, description = "Node state"),
64 (status = 400, description = "Invalid filter expression", body = JsonErrorResponse,
65 example = json!({"error": "failed to parse filter expression: unexpected token"}))
66 )
67)]
68async fn state_post(
69 State(state): State<AppState>,
70 Json(params): Json<StateQueryParams>,
71) -> AppResult<Json<serde_json::Value>> {
72 state_handler(state, params.filter).await
73}
74
75async fn state_handler(
77 state: AppState,
78 filter: Option<String>,
79) -> AppResult<Json<serde_json::Value>> {
80 let result: Option<RpcStateGetResponse> = state
81 .rpc_sender()
82 .oneshot_request(RpcRequest::StateGet(filter))
83 .await;
84
85 match result {
86 None => Err(AppError::ChannelDropped),
87 Some(Ok(value)) => Ok(Json(value)),
88 Some(Err(err)) => Err(AppError::BadRequest(err.to_string())),
89 }
90}
91
92#[utoipa::path(
94 get,
95 path = "/state/peers",
96 tag = "state",
97 responses(
98 (status = 200, description = "Connected peers", body = inline(RpcPeersGetResponse))
100 )
101)]
102async fn peers(State(state): State<AppState>) -> AppResult<Json<RpcPeersGetResponse>> {
103 jsonify_rpc!(state, RpcRequest::PeersGet)
104}
105
106#[utoipa::path(
108 get,
109 path = "/state/message-progress",
110 tag = "state",
111 responses(
112 (status = 200, description = "Message progress information", body = RpcMessageProgressResponse)
113 )
114)]
115async fn message_progress(
116 State(state): State<AppState>,
117) -> AppResult<Json<RpcMessageProgressResponse>> {
118 jsonify_rpc!(state, RpcRequest::MessageProgressGet)
119}