sui_indexer/
lib.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3#![recursion_limit = "256"]
4
5use std::time::Duration;
6
7use anyhow::Result;
8use config::JsonRpcConfig;
9use jsonrpsee::http_client::{HeaderMap, HeaderValue, HttpClient, HttpClientBuilder};
10use metrics::IndexerMetrics;
11use mysten_metrics::spawn_monitored_task;
12use prometheus::Registry;
13use system_package_task::SystemPackageTask;
14use tokio_util::sync::CancellationToken;
15use tracing::warn;
16
17use sui_json_rpc::ServerType;
18use sui_json_rpc::{JsonRpcServerBuilder, ServerHandle};
19use sui_json_rpc_api::CLIENT_SDK_TYPE_HEADER;
20
21use crate::apis::{
22    CoinReadApi, ExtendedApi, GovernanceReadApi, IndexerApi, MoveUtilsApi, ReadApi,
23    TransactionBuilderApi, WriteApi,
24};
25use crate::indexer_reader::IndexerReader;
26use errors::IndexerError;
27
28pub mod apis;
29pub mod backfill;
30pub mod config;
31pub mod database;
32pub mod db;
33pub mod errors;
34pub mod handlers;
35pub mod indexer;
36pub mod indexer_reader;
37pub mod metrics;
38pub mod models;
39pub mod schema;
40pub mod store;
41pub mod system_package_task;
42pub mod test_utils;
43pub mod types;
44
45pub async fn build_json_rpc_server(
46    prometheus_registry: &Registry,
47    reader: IndexerReader,
48    config: &JsonRpcConfig,
49    cancel: CancellationToken,
50) -> Result<ServerHandle, IndexerError> {
51    let mut builder =
52        JsonRpcServerBuilder::new(env!("CARGO_PKG_VERSION"), prometheus_registry, None, None);
53    let http_client = crate::get_http_client(&config.rpc_client_url)?;
54
55    builder.register_module(WriteApi::new(http_client.clone()))?;
56    builder.register_module(IndexerApi::new(
57        reader.clone(),
58        config.name_service_options.to_config(),
59    ))?;
60    builder.register_module(TransactionBuilderApi::new(reader.clone()))?;
61    builder.register_module(MoveUtilsApi::new(reader.clone()))?;
62    builder.register_module(GovernanceReadApi::new(reader.clone()))?;
63    builder.register_module(ReadApi::new(reader.clone()))?;
64    builder.register_module(CoinReadApi::new(reader.clone()))?;
65    builder.register_module(ExtendedApi::new(reader.clone()))?;
66
67    let system_package_task =
68        SystemPackageTask::new(reader.clone(), cancel.clone(), Duration::from_secs(10));
69
70    tracing::info!("Starting system package task");
71    spawn_monitored_task!(async move { system_package_task.run().await });
72
73    Ok(builder
74        .start(config.rpc_address, None, ServerType::Http, Some(cancel))
75        .await?)
76}
77
78fn get_http_client(rpc_client_url: &str) -> Result<HttpClient, IndexerError> {
79    let mut headers = HeaderMap::new();
80    headers.insert(CLIENT_SDK_TYPE_HEADER, HeaderValue::from_static("indexer"));
81
82    HttpClientBuilder::default()
83        .max_request_size(2 << 30)
84        .set_headers(headers.clone())
85        .build(rpc_client_url)
86        .map_err(|e| {
87            warn!("Failed to get new Http client with error: {:?}", e);
88            IndexerError::HttpClientInitError(format!(
89                "Failed to initialize fullnode RPC client with error: {:?}",
90                e
91            ))
92        })
93}