1use axum::{Extension, Json, extract::State};
8use axum_extra::extract::WithRejection;
9use fastcrypto::encoding::Hex;
10use iota_types::base_types::ObjectID;
11use serde_json::json;
12use strum::IntoEnumIterator;
13
14use crate::{
15 IotaEnv, OnlineServerContext,
16 errors::{Error, ErrorType},
17 types::{
18 Allow, Case, NetworkIdentifier, NetworkListResponse, NetworkOptionsResponse,
19 NetworkRequest, NetworkStatusResponse, OperationStatus, OperationType, Peer, SyncStatus,
20 Version,
21 },
22};
23
24pub async fn list(Extension(env): Extension<IotaEnv>) -> Result<NetworkListResponse, Error> {
29 Ok(NetworkListResponse {
30 network_identifiers: vec![NetworkIdentifier {
31 blockchain: "iota".to_string(),
32 network: env,
33 }],
34 })
35}
36
37pub async fn status(
41 State(context): State<OnlineServerContext>,
42 Extension(env): Extension<IotaEnv>,
43 WithRejection(Json(request), _): WithRejection<Json<NetworkRequest>, Error>,
44) -> Result<NetworkStatusResponse, Error> {
45 env.check_network_identifier(&request.network_identifier)?;
46
47 let peers = context
49 .client
50 .governance_api()
51 .get_latest_iota_system_state()
52 .await?
53 .iter_committee_members()
54 .map(|committee_member| Peer {
55 peer_id: ObjectID::from(committee_member.iota_address).into(),
56 metadata: Some(json!({
57 "public_key": Hex::from_bytes(&committee_member.authority_pubkey_bytes),
58 "stake_amount": committee_member.staking_pool_iota_balance,
59 })),
60 })
61 .collect();
62 let blocks = context.blocks();
63 let current_block = blocks.current_block().await?;
64 let index = current_block.block.block_identifier.index;
65 let target = context
66 .client
67 .read_api()
68 .get_latest_checkpoint_sequence_number()
69 .await?;
70
71 Ok(NetworkStatusResponse {
72 current_block_identifier: current_block.block.block_identifier,
73 current_block_timestamp: current_block.block.timestamp,
74 genesis_block_identifier: blocks.genesis_block_identifier().await?,
75 oldest_block_identifier: Some(blocks.oldest_block_identifier().await?),
76 sync_status: Some(SyncStatus {
77 current_index: Some(index),
78 target_index: Some(target),
79 stage: None,
80 synced: Some(index == target),
81 }),
82 peers,
83 })
84}
85
86pub async fn options(
91 Extension(env): Extension<IotaEnv>,
92 WithRejection(Json(request), _): WithRejection<Json<NetworkRequest>, Error>,
93) -> Result<NetworkOptionsResponse, Error> {
94 env.check_network_identifier(&request.network_identifier)?;
95
96 let errors = ErrorType::iter().collect();
97 let operation_statuses = vec![
98 json!({"status": OperationStatus::Success, "successful" : true}),
99 json!({"status": OperationStatus::Failure, "successful" : false}),
100 ];
101
102 Ok(NetworkOptionsResponse {
103 version: Version {
104 rosetta_version: "1.4.14".to_string(),
105 node_version: env!("CARGO_PKG_VERSION").to_owned(),
106 middleware_version: None,
107 metadata: None,
108 },
109 allow: Allow {
110 operation_statuses,
111 operation_types: OperationType::iter().collect(),
112 errors,
113 historical_balance_lookup: true,
114 timestamp_start_index: None,
115 call_methods: vec![],
116 balance_exemptions: vec![],
117 mempool_coins: false,
118 block_hash_case: Some(Case::Null),
119 transaction_hash_case: Some(Case::Null),
120 },
121 })
122}