Skip to content

feat(backend): add Soroban contract event indexer#173

Merged
Wilfred007 merged 2 commits intoGildado:mainfrom
CMI-James-OD:codex/issue-150-contract-event-indexer
Feb 26, 2026
Merged

feat(backend): add Soroban contract event indexer#173
Wilfred007 merged 2 commits intoGildado:mainfrom
CMI-James-OD:codex/issue-150-contract-event-indexer

Conversation

@CMI-James
Copy link
Contributor

Description

Implement backend Soroban contract event indexer worker with persistent ledger checkpointing and query API.

Closes #150

Changes proposed

What were you told to do?

I was tasked with implementing a backend event indexer that:

  • Polls/streams Soroban contract events for bulk_payment, vesting_escrow, and revenue_split
  • Persists events in PostgreSQL with contract/event metadata and ledger sequence
  • Exposes paginated GET /api/events/:contractId
  • Skips duplicates idempotently
  • Restarts from last indexed ledger sequence after crashes/restarts

What did I do?

Added event index database schema

Added migration backend/src/db/migrations/015_create_contract_events.sql with:

  • contract_events table (contract_id, event_type, payload, ledger_sequence, tx_hash, event_id)
  • Unique index for idempotency (event_id, contract_id)
  • Ledger query index for fast pagination
  • contract_event_index_state table for checkpointing last indexed ledger

Implemented background indexer worker

Created backend/src/services/contractEventIndexerService.ts with:

  • Startup initialization for schema/state bootstrap
  • Poll loop (getEvents RPC) against Soroban RPC
  • Contract filtering using env-backed contract IDs
  • Idempotent inserts (ON CONFLICT DO NOTHING)
  • Ledger checkpoint updates after successful indexing
  • In-memory lock to prevent overlapping poll runs

Added contract events REST endpoint

Created:

  • backend/src/controllers/contractEventsController.ts
  • backend/src/routes/contractEventRoutes.ts

Endpoint behavior:

  • GET /api/events/:contractId?page=1&limit=20&eventType=...
  • Returns paginated contract event list ordered by latest ledger sequence

Wired worker + route into backend startup

Updated backend/src/index.ts to:

  • Mount /api/events route
  • Start indexer automatically on boot (unless ENABLE_CONTRACT_EVENT_INDEXER=false)
  • Stop worker on process shutdown (SIGTERM, SIGINT)

Check List (Check all the applicable boxes)

  • My code follows the code style of this project.
  • This PR does not contain plagiarized content.
  • The title and description of the PR is clear and explains the approach.
  • My commit messages styles matches our requested structure.
  • My code additions will fail neither code linting checks nor unit test.
  • I am only making changes to files I was requested to.

Screenshots / Testing Evidence

  • Full backend test/lint execution was not run in this environment
  • Event indexing logic, idempotency path, and checkpoint resume behavior validated by static code inspection
  • API pagination/query logic validated against SQL statements and response structure in controller

@Wilfred007 Wilfred007 merged commit daa1c7f into Gildado:main Feb 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#077: Backend Contract Event Indexer

2 participants