A lightweight Rust backend service that indexes Soroban smart contract events on the Stellar network and exposes them via a REST API.
- Rust + Axum (web framework)
- Tokio (async runtime)
- PostgreSQL + SQLx (database + migrations)
- Stellar Soroban RPC (event source)
src/
├── main.rs # Entry point, wires everything together
├── config.rs # Environment config
├── db.rs # DB pool + migrations
├── models.rs # Data types (Event, RPC response shapes)
├── indexer.rs # Background event polling worker
├── routes.rs # Axum router
├── handlers.rs # Request handlers
└── error.rs # Unified error type
migrations/
└── 20260314000000_create_events.sql
- Rust (stable)
- PostgreSQL 14+
sqlx-cli(optional, for manual migrations)
cp .env.example .env
# Edit .env with your values| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | required |
STELLAR_RPC_URL |
Soroban RPC endpoint | https://soroban-testnet.stellar.org |
START_LEDGER |
Ledger to start indexing from (0 = latest) | 0 |
PORT |
HTTP server port | 3000 |
docker-compose up --build# Start PostgreSQL, then:
cargo runMigrations run automatically on startup.
{ "status": "ok" }Returns paginated events across all contracts.
{
"data": [
{
"id": "uuid",
"contract_id": "CABC...",
"event_type": "contract",
"tx_hash": "abc123...",
"ledger": 1234567,
"timestamp": "2026-03-14T00:00:00Z",
"event_data": { "value": {}, "topic": [] },
"created_at": "2026-03-14T00:00:01Z"
}
],
"total": 100,
"page": 1,
"limit": 20
}Returns all events for a specific contract.
Returns all events from a specific transaction.
- On startup, the app connects to PostgreSQL and runs migrations.
- A background Tokio task (
indexer.rs) polls the Soroban RPCgetEventsmethod in a loop. - New events are inserted with
ON CONFLICT DO NOTHINGto avoid duplicates. - The Axum HTTP server runs concurrently, serving queries against the indexed data.
- The indexer polls every 5 seconds when no new ledgers are available, and 10 seconds on error.
START_LEDGER=0automatically starts from the latest ledger at boot time.- All endpoints return JSON. Errors include an
"error"field with a description.