sui_indexer/apis/
extended_api.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{errors::IndexerError, indexer_reader::IndexerReader};
5use jsonrpsee::{RpcModule, core::RpcResult};
6use sui_json_rpc::SuiRpcModule;
7use sui_json_rpc_api::{ExtendedApiServer, QUERY_MAX_RESULT_LIMIT_CHECKPOINTS, validate_limit};
8use sui_json_rpc_types::{
9    CheckpointedObjectID, EpochInfo, EpochPage, Page, QueryObjectsPage, SuiObjectResponseQuery,
10};
11use sui_open_rpc::Module;
12use sui_types::sui_serde::BigInt;
13
14pub(crate) struct ExtendedApi {
15    inner: IndexerReader,
16}
17
18impl ExtendedApi {
19    pub fn new(inner: IndexerReader) -> Self {
20        Self { inner }
21    }
22}
23
24#[async_trait::async_trait]
25impl ExtendedApiServer for ExtendedApi {
26    async fn get_epochs(
27        &self,
28        cursor: Option<BigInt<u64>>,
29        limit: Option<usize>,
30        descending_order: Option<bool>,
31    ) -> RpcResult<EpochPage> {
32        let limit = validate_limit(limit, QUERY_MAX_RESULT_LIMIT_CHECKPOINTS)
33            .map_err(IndexerError::from)?;
34        let mut epochs = self
35            .inner
36            .get_epochs(
37                cursor.map(|x| *x),
38                limit + 1,
39                descending_order.unwrap_or(false),
40            )
41            .await?;
42
43        let has_next_page = epochs.len() > limit;
44        epochs.truncate(limit);
45        let next_cursor = epochs.last().map(|e| e.epoch);
46        Ok(Page {
47            data: epochs,
48            next_cursor: next_cursor.map(|id| id.into()),
49            has_next_page,
50        })
51    }
52
53    async fn get_current_epoch(&self) -> RpcResult<EpochInfo> {
54        let stored_epoch = self.inner.get_latest_epoch_info_from_db().await?;
55        EpochInfo::try_from(stored_epoch).map_err(Into::into)
56    }
57
58    async fn query_objects(
59        &self,
60        _query: SuiObjectResponseQuery,
61        _cursor: Option<CheckpointedObjectID>,
62        _limit: Option<usize>,
63    ) -> RpcResult<QueryObjectsPage> {
64        Err(jsonrpsee::types::error::ErrorCode::MethodNotFound.into())
65    }
66
67    async fn get_total_transactions(&self) -> RpcResult<BigInt<u64>> {
68        let latest_checkpoint = self.inner.get_latest_checkpoint().await?;
69        Ok(latest_checkpoint.network_total_transactions.into())
70    }
71}
72
73impl SuiRpcModule for ExtendedApi {
74    fn rpc(self) -> RpcModule<Self> {
75        self.into_rpc()
76    }
77
78    fn rpc_doc_module() -> Module {
79        sui_json_rpc_api::ExtendedApiOpenRpc::module_doc()
80    }
81}