1use std::{net::SocketAddr, sync::Arc};
6
7use axum::{Extension, Router, routing::post};
8use iota_sdk::IotaClient;
9use once_cell::sync::Lazy;
10use tracing::info;
11
12use crate::{
13 errors::Error,
14 state::{CheckpointBlockProvider, OnlineServerContext},
15 types::{Currency, IotaEnv},
16};
17
18mod account;
20mod block;
21mod construction;
22mod errors;
23mod network;
24pub mod operations;
25mod state;
26pub mod types;
27
28pub static IOTA: Lazy<Currency> = Lazy::new(|| Currency {
29 symbol: "IOTA".to_string(),
30 decimals: 9,
31});
32
33pub struct RosettaOnlineServer {
34 env: IotaEnv,
35 context: OnlineServerContext,
36}
37
38impl RosettaOnlineServer {
39 pub fn new(env: IotaEnv, client: IotaClient) -> Self {
40 let blocks = Arc::new(CheckpointBlockProvider::new(client.clone()));
41 Self {
42 env,
43 context: OnlineServerContext::new(client, blocks),
44 }
45 }
46
47 pub async fn serve(self, addr: SocketAddr) {
48 let app = Router::new()
50 .route("/account/balance", post(account::balance))
51 .route("/account/coins", post(account::coins))
52 .route("/block", post(block::block))
53 .route("/block/transaction", post(block::transaction))
54 .route("/construction/submit", post(construction::submit))
55 .route("/construction/metadata", post(construction::metadata))
56 .route("/network/status", post(network::status))
57 .route("/network/list", post(network::list))
58 .route("/network/options", post(network::options))
59 .layer(Extension(self.env))
60 .with_state(self.context);
61
62 let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
63
64 info!(
65 "IOTA Rosetta online server listening on {}",
66 listener.local_addr().unwrap()
67 );
68 axum::serve(listener, app).await.unwrap();
69 }
70}
71
72pub struct RosettaOfflineServer {
73 env: IotaEnv,
74}
75
76impl RosettaOfflineServer {
77 pub fn new(env: IotaEnv) -> Self {
78 Self { env }
79 }
80
81 pub async fn serve(self, addr: SocketAddr) {
82 let app = Router::new()
84 .route("/construction/derive", post(construction::derive))
85 .route("/construction/payloads", post(construction::payloads))
86 .route("/construction/combine", post(construction::combine))
87 .route("/construction/preprocess", post(construction::preprocess))
88 .route("/construction/hash", post(construction::hash))
89 .route("/construction/parse", post(construction::parse))
90 .route("/network/list", post(network::list))
91 .route("/network/options", post(network::options))
92 .layer(Extension(self.env));
93 let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
94
95 info!(
96 "IOTA Rosetta offline server listening on {}",
97 listener.local_addr().unwrap()
98 );
99 axum::serve(listener, app).await.unwrap();
100 }
101}