1use std::sync::Arc;
9
10use axum::extract::{Json, Query, State};
11use axum::http::HeaderMap;
12use axum::Router;
13
14pub fn status_service_rest_router<S>(service: Arc<S>) -> Router
22where
23 S: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
24{
25 Router::new()
26 .route("/v2/status/block-height", axum::routing::get(rest_status_service_get_block_height::<S>))
27 .route("/v2/status/success-rate", axum::routing::get(rest_status_service_get_success_rate::<S>))
28 .route("/v2/status/time-since-last-decide", axum::routing::get(rest_status_service_get_time_since_last_decide::<S>))
29 .route("/v2/status/keys", axum::routing::get(rest_status_service_get_node_keys::<S>))
30 .with_state(service)
31}
32
33#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
34async fn rest_status_service_get_block_height<S>(
38 State(service): State<Arc<S>>,
39 headers: HeaderMap,
40 Query(body): Query<crate::proto::GetBlockHeightRequest>,
41) -> Result<Json<crate::proto::BlockHeightResponse>, tonic_rest::RestError>
42where
43 S: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
44{
45 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
46 let response = service.get_block_height(req).await.map_err(tonic_rest::RestError::from)?;
47 Ok(Json(response.into_inner()))
48}
49
50#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
51async fn rest_status_service_get_success_rate<S>(
55 State(service): State<Arc<S>>,
56 headers: HeaderMap,
57 Query(body): Query<crate::proto::GetSuccessRateRequest>,
58) -> Result<Json<crate::proto::SuccessRateResponse>, tonic_rest::RestError>
59where
60 S: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
61{
62 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
63 let response = service.get_success_rate(req).await.map_err(tonic_rest::RestError::from)?;
64 Ok(Json(response.into_inner()))
65}
66
67#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
68async fn rest_status_service_get_time_since_last_decide<S>(
72 State(service): State<Arc<S>>,
73 headers: HeaderMap,
74 Query(body): Query<crate::proto::GetTimeSinceLastDecideRequest>,
75) -> Result<Json<crate::proto::TimeSinceLastDecideResponse>, tonic_rest::RestError>
76where
77 S: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
78{
79 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
80 let response = service.get_time_since_last_decide(req).await.map_err(tonic_rest::RestError::from)?;
81 Ok(Json(response.into_inner()))
82}
83
84#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
85async fn rest_status_service_get_node_keys<S>(
89 State(service): State<Arc<S>>,
90 headers: HeaderMap,
91 Query(body): Query<crate::proto::GetNodeKeysRequest>,
92) -> Result<Json<crate::proto::NodeKeysResponse>, tonic_rest::RestError>
93where
94 S: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
95{
96 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
97 let response = service.get_node_keys(req).await.map_err(tonic_rest::RestError::from)?;
98 Ok(Json(response.into_inner()))
99}
100
101pub fn token_service_rest_router<S>(service: Arc<S>) -> Router
109where
110 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
111{
112 Router::new()
113 .route("/v2/token/total-minted-supply", axum::routing::get(rest_token_service_get_total_minted_supply::<S>))
114 .route("/v2/token/circulating-supply", axum::routing::get(rest_token_service_get_circulating_supply::<S>))
115 .route("/v2/token/circulating-supply-ethereum", axum::routing::get(rest_token_service_get_circulating_supply_ethereum::<S>))
116 .route("/v2/token/total-issued-supply", axum::routing::get(rest_token_service_get_total_issued_supply::<S>))
117 .route("/v2/token/total-reward-distributed", axum::routing::get(rest_token_service_get_total_reward_distributed::<S>))
118 .with_state(service)
119}
120
121#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
122async fn rest_token_service_get_total_minted_supply<S>(
126 State(service): State<Arc<S>>,
127 headers: HeaderMap,
128 Query(body): Query<crate::proto::GetTotalMintedSupplyRequest>,
129) -> Result<Json<crate::proto::TotalMintedSupplyResponse>, tonic_rest::RestError>
130where
131 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
132{
133 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
134 let response = service.get_total_minted_supply(req).await.map_err(tonic_rest::RestError::from)?;
135 Ok(Json(response.into_inner()))
136}
137
138#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
139async fn rest_token_service_get_circulating_supply<S>(
143 State(service): State<Arc<S>>,
144 headers: HeaderMap,
145 Query(body): Query<crate::proto::GetCirculatingSupplyRequest>,
146) -> Result<Json<crate::proto::CirculatingSupplyResponse>, tonic_rest::RestError>
147where
148 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
149{
150 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
151 let response = service.get_circulating_supply(req).await.map_err(tonic_rest::RestError::from)?;
152 Ok(Json(response.into_inner()))
153}
154
155#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
156async fn rest_token_service_get_circulating_supply_ethereum<S>(
160 State(service): State<Arc<S>>,
161 headers: HeaderMap,
162 Query(body): Query<crate::proto::GetCirculatingSupplyEthereumRequest>,
163) -> Result<Json<crate::proto::CirculatingSupplyEthereumResponse>, tonic_rest::RestError>
164where
165 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
166{
167 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
168 let response = service.get_circulating_supply_ethereum(req).await.map_err(tonic_rest::RestError::from)?;
169 Ok(Json(response.into_inner()))
170}
171
172#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
173async fn rest_token_service_get_total_issued_supply<S>(
177 State(service): State<Arc<S>>,
178 headers: HeaderMap,
179 Query(body): Query<crate::proto::GetTotalIssuedSupplyRequest>,
180) -> Result<Json<crate::proto::TotalIssuedSupplyResponse>, tonic_rest::RestError>
181where
182 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
183{
184 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
185 let response = service.get_total_issued_supply(req).await.map_err(tonic_rest::RestError::from)?;
186 Ok(Json(response.into_inner()))
187}
188
189#[expect(clippy::too_many_arguments, clippy::needless_pass_by_value)]
190async fn rest_token_service_get_total_reward_distributed<S>(
194 State(service): State<Arc<S>>,
195 headers: HeaderMap,
196 Query(body): Query<crate::proto::GetTotalRewardDistributedRequest>,
197) -> Result<Json<crate::proto::TotalRewardDistributedResponse>, tonic_rest::RestError>
198where
199 S: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
200{
201 let req = tonic_rest::build_tonic_request::<_, ()>(body, &headers, None);
202 let response = service.get_total_reward_distributed(req).await.map_err(tonic_rest::RestError::from)?;
203 Ok(Json(response.into_inner()))
204}
205
206
207pub const PUBLIC_REST_PATHS: &[&str] = &[
216];
217
218pub fn all_rest_routes<S0, S1>(
226 status_service: Arc<S0>,
227 token_service: Arc<S1>,
228) -> Router
229where
230 S0: crate::proto::status_service_server::StatusService + Send + Sync + 'static,
231 S1: crate::proto::token_service_server::TokenService + Send + Sync + 'static,
232{
233 Router::new()
234 .merge(status_service_rest_router(status_service))
235 .merge(token_service_rest_router(token_service))
236}