A modular, high-performance blockchain explorer backend stack designed for Tendermint / Cosmos SDK-based networks (specifically Airchains Junction).
This meta-repository unifies two core services managed as Git submodules:
indexer: A concurrent blockchain ingestion engine crawling blocks, transactions, validators, track stations, pods, and ZK proofs into multi-tiered storage.indexer-api: A high-throughput Gin-based RESTful API server serving real-time and historical blockchain data to explorer frontends.
flowchart TD
subgraph Blockchain Node
RPC[Tendermint RPC]
API[Cosmos / Junction REST API]
end
subgraph "indexer (Ingestion Engine)"
WorkerOld[Old Block Worker]
WorkerNew[New Block Streamer]
WorkerLimit[Limit Block Worker]
WorkerVal[Validator Worker]
WorkerStats[Statistics Worker]
end
subgraph Storage Layer
LDB[(LevelDB)]
SQL[(MySQL)]
MDB[(MongoDB)]
end
subgraph "indexer-api (REST Gateway)"
Gin[Gin HTTP Server]
Routers[Block / Txn / Station / Validator / Address APIs]
end
Client([Explorer Frontend / API Clients])
%% Data ingestion flow
RPC -->|Blocks & Txns| WorkerOld
RPC -->|Block Events| WorkerNew
API -->|Validators, State| WorkerVal
API -->|Track Station State| WorkerStats
%% Storage writes
WorkerOld -->|Checkpoints| LDB
WorkerNew -->|Checkpoints| LDB
WorkerVal -->|Validators & Delegators| SQL
WorkerStats -->|Accounts & Metrics| SQL
WorkerOld -->|Block & Txn Documents| MDB
WorkerNew -->|Live Blocks & Events| MDB
WorkerLimit -->|Capped Limit Feeds| MDB
%% Serving flow
SQL --> Routers
MDB --> Routers
RPC -.->|Live query fallback| Routers
API -.->|Live query fallback| Routers
Routers --> Gin
Gin --> Client
| Submodule | Repository | Description | Tech Stack |
|---|---|---|---|
indexer |
deadlium/go-lang-indexer |
Background daemon syncing past and live chain data, tracking block sync pointers, and indexing track stations / pods. | Go 1.22, Tendermint RPC, Bun ORM (MySQL), MongoDB Driver, LevelDB |
indexer-api |
deadlium/go-lang-indexer-api |
RESTful API server providing endpoints for explorer search, blocks, transactions, validators, governance, and Airchains track stations. | Go 1.22, Gin, CORS, pprof, MySQL, MongoDB |
- LevelDB: Used by the indexer as an atomic, embedded key-value checkpoint store (
LastProcessedBlockandLastLatestBlock) to ensure fault-tolerant resume without re-indexing or skipped blocks. - MySQL: Relational persistence managed via Bun ORM for relational entities requiring indexed lookups:
validators: Monikers, operator/consensus addresses, voting power, tokens, commission rates, and jailed statuses.delegators: Delegator distribution and shares per validator.accounts: Account addresses, public keys, balances, and sequence numbers.activity&station_row: Chain-wide aggregate counters and station records.
- MongoDB: Document store holding high-volume, dynamic payload data:
- Full block records (
blocks) & transaction events (transactions). - Airchains track station details (
station_details,station_init_details) and governancevotes. - Capped limit collections (
limit_blocks,limit_transactions,limit_station_details,limit_votes) optimized for fast pagination and live homepage feeds.
- Full block records (
- Go:
1.22or higher - MySQL:
5.7or8.0+ - MongoDB:
4.4or higher - Tendermint / Cosmos RPC & API: An accessible RPC node (
:26657) and LCD/API node (:1317) running Airchains Junction or compatible chain
If cloning for the first time:
git clone --recurse-submodules <REPO_URL> explorer
cd explorerIf the repository was already cloned without submodules:
git submodule update --init --recursiveNavigate to indexer/ and create .env:
cd indexer
cp .env.exmaple .envFill in the configuration:
LEVEL_DB_PATH="path/to/leveldb/data"
TENDERMINT_RPC_URL="http://127.0.0.1:26657"
TENDERMINT_API_URL="http://127.0.0.1:1317"
SQL_HOST="127.0.0.1"
SQL_PORT="3306"
SQL_USER="indexer_user"
SQL_PASSWORD="your_password"
SQL_DATABASE="indexer_db"
MONGO_URL="mongodb://127.0.0.1:27017/indexer_db"Navigate to indexer-api/ and create .env:
cd ../indexer-api
touch .envAdd the following configuration:
TENDERMINT_RPC_URL="http://127.0.0.1:26657"
TENDERMINT_API_URL="http://127.0.0.1:1317"
SERVER_PORT="8080"
SQL_HOST="127.0.0.1"
SQL_PORT="3306"
SQL_USER="indexer_user"
SQL_PASSWORD="your_password"
SQL_DATABASE="indexer_db"
MONGO_URL="mongodb://127.0.0.1:27017/indexer_db"cd indexer
go run cmd/main.goThe indexer will:
- Verify database connections (LevelDB, MySQL, MongoDB).
- Query the latest block height from the Tendermint RPC node.
- Spawn concurrent goroutines for historical block backfilling, live block streaming, validator tracking, and statistical aggregation.
cd indexer-api
go run cmd/main.goThe API server starts listening on the configured SERVER_PORT (e.g. http://0.0.0.0:8080).
The indexer-api service exposes endpoints categorized as follows:
| Method | Endpoint | Description |
|---|---|---|
GET |
/block-list |
Get paginated list of indexed blocks |
GET |
/block-detail/:blockNumber |
Get detailed block information by height |
GET |
/block-txn/:blockNumber |
Get transactions included in a specific block |
| Method | Endpoint | Description |
|---|---|---|
GET |
/txn-list |
Get paginated list of recent transactions |
GET |
/txn-detail/:txHash |
Get full transaction details and execution logs |
| Method | Endpoint | Description |
|---|---|---|
GET |
/station-list |
List registered track stations |
GET |
/station-list-new |
List newly registered track stations |
GET |
/station-detail/:stationID |
Get station metadata and verification parameters |
GET |
/station-pod-list/:stationID |
List submitted Pods for a station |
GET |
/ext-station-list |
List external track stations |
GET |
/ext-station-detail/:stationID |
Get details for an external track station |
GET |
/ext-station-engagements-list/:stationID |
List engagement metrics and interactions |
GET |
/ext-station-engagements-detail/:stationID/:podNumber |
Get pod-specific engagement details |
| Method | Endpoint | Description |
|---|---|---|
GET |
/validator-list |
List active and inactive validators with voting power |
GET |
/validator-detail/:validatorAddress |
Get validator profile, commission, and consensus info |
GET |
/validator-delegator-detail/:validatorAddress |
List delegators and delegation amounts |
GET |
/validator-block-list/:validatorAddress |
List blocks proposed by a validator |
| Method | Endpoint | Description |
|---|---|---|
GET |
/proposal-list |
List on-chain governance proposals |
GET |
/proposal-detail/:proposalID |
Get proposal details, status, and tally results |
GET |
/proposal-vote-list/:proposalID |
List cast votes for a proposal |
| Method | Endpoint | Description |
|---|---|---|
GET |
/address-list |
List indexed account addresses |
GET |
/address-detail/:address |
Get account balances, sequence, and account number |
GET |
/address-transaction-list/:address |
List transactions involving an address |
GET |
/address-transfer-list/:address |
List asset transfers for an address |
GET |
/address-delegation-list/:address |
List active staking delegations for an address |
GET |
/address-station-list/:address |
List track stations created or managed by an address |
GET |
/address-ext-station-list/:address |
List external track stations associated with an address |
| Method | Endpoint | Description |
|---|---|---|
GET |
/home-zkp-list |
List recent ZK proof submissions and verifications |
GET |
/home-static-data |
Retrieve chain-wide aggregate stats (TPS, block time, totals) |
GET |
/home/:search |
Global search across blocks, transactions, stations, and addresses |
To update all submodules to their latest remote commits:
git submodule update --remote --mergeTo make changes in a submodule:
- Navigate into the submodule directory (
cd indexerorcd indexer-api). - Create/checkout your working branch, make changes, and commit.
- Push changes to the submodule's remote repository.
- From the root
explorerdirectory, commit the updated submodule pointer:git add indexer indexer-api git commit -m "Update submodules"