1#![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}