Solana Program Indexer with REST API & Docker Compose

GitHub: carsonpine/bubblegum README: read here Twitter thread: he


What it does

Bubblegum is a production-grade Solana program indexer written in Rust. You point it at any Anchor program, it fetches transactions via Helius RPC, decodes every instruction using the program’s IDL, and stores the results in a dual-database setup: PostgreSQL for recent data and fast lookups, ClickHouse for historical data and analytics. There’s a REST API and a live dashboard UI on top.

It supports both IDL sources the bounty asked for: you can either pass a local JSON file via IDL_PATH, or leave it unset and it’ll fetch the IDL directly from the on-chain account (derives the PDA, pulls the account, decompresses the zlib-encoded JSON).


Architecture

graph TD
    subgraph BUBBLEGUM [BUBBLEGUM System]
        Helius[Helius RPC]
        Indexer[Rust Indexer / Tokio]
        PostgreSQL[(PostgreSQL / Hot Data)]
        Decoder[Anchor IDL Decoder]
        ClickHouse[(ClickHouse / History)]
        Axum[Axum REST API + Dashboard]

        Helius --> Indexer
        Indexer --> PostgreSQL
        Indexer --> Decoder
        Decoder --> ClickHouse
        Helius --> ClickHouse
        PostgreSQL --- Axum
        Axum --> ClickHouse
    end
Component Technology Role
Indexer Rust / Tokio Core loop, decoding, storage
RPC Helius enhanced Solana RPC Transaction & slot fetching
IDL Decoder Borsh + Anchor discriminators Instruction argument decoding
Hot DB PostgreSQL 16 Recent txs, fast lookups
Cold DB ClickHouse 23 Historical data, analytics
API Axum 0.7 REST endpoints + static files
Dashboard Vanilla HTML/CSS/JS UI + SQL query tool

Launch instructions

Prerequisites: Docker + Docker Compose v2, a Helius API key, a Solana program ID(in the screenshots below, we utilized Meteora DLMM Program ID for the demo).

git clone <https://github.com/carsonpine/bubblegum>
cd bubblegum
cp .env.example .env
# Edit .env , set HELIUS_RPC_URL and PROGRAM_ID at minimum
docker compose up

Dashboard at http://localhost:3000. That’s it, health checks ensure the indexer waits for both databases before it starts.

Screenshot 2026-03-28 at 16-02-43 Bubblegum — Solana Indexer.png

Screenshot 2026-03-28 at 16-03-37 Bubblegum — Solana Indexer.png

Screenshot 2026-03-28 at 16-04-18 Bubblegum — Solana Indexer.png

To backfill historical data, add a start slot to .env:

START_SLOT=407900000