Title: feat: Blockchain Event Indexer — Soroban-to-PostgreSQL Sync Service
Labels: backend, blockchain, core, priority-high
Description:
The backend and blockchain currently have no real-time sync. When
an invoice is registered or escrow funded on-chain, the PostgreSQL
database does not know. This issue implements an event indexer
that bridges the gap and keeps the DB in sync with chain state.
What Needs to Be Done:
- IndexerService:
- Streams Soroban contract events using Stellar SDK
- Filters events by contract address
- Processes: InvoiceRegistered, InvoiceStatusChanged,
EscrowFunded, EscrowReleased, EscrowReclaimed
- Updates corresponding DB records on each event
- Stores last processed ledger cursor in Redis
key: indexer:cursor:{contract_address}
- On restart, resumes from stored cursor
- Event handlers (one per event type):
handleInvoiceRegistered — sets tx_hash on invoice
handleInvoiceStatusChanged — updates invoice status
handleEscrowFunded — updates offer status to ACTIVE
handleEscrowReleased — updates invoice to PAID
handleEscrowReclaimed — updates invoice to DEFAULTED
- Idempotency:
Each event has a unique ID
Processed event IDs stored in Redis with 24h TTL
Duplicate events safely ignored
- IndexerHealthController:
GET /indexer/status — returns last processed ledger, lag, errors
Key Files:
- apps/backend/src/indexer/indexer.module.ts (new)
- apps/backend/src/indexer/indexer.service.ts (new)
- apps/backend/src/indexer/handlers/ (new directory)
- apps/backend/src/indexer/indexer.controller.ts (new)
Acceptance Criteria:
- Invoice DB status updates automatically when on-chain event received
- Indexer resumes from correct cursor after restart
- Duplicate events safely ignored
- GET /indexer/status shows current ledger and processing lag
- Redis cursor updated after every successful event batch
- Unit tests cover: each event handler, cursor persistence,
idempotency check, error recovery
Security Notes:
- DB updates only after on-chain event confirmed
- No optimistic updates
- Indexer runs as read-only observer — never signs transactions
Branch: feat/blockchain-event-indexer
Commit: feat(indexer): add Soroban event indexer with Redis cursor tracking and idempotent handling
Title: feat: Blockchain Event Indexer — Soroban-to-PostgreSQL Sync Service
Labels: backend, blockchain, core, priority-high
Description:
The backend and blockchain currently have no real-time sync. When
an invoice is registered or escrow funded on-chain, the PostgreSQL
database does not know. This issue implements an event indexer
that bridges the gap and keeps the DB in sync with chain state.
What Needs to Be Done:
EscrowFunded, EscrowReleased, EscrowReclaimed
key: indexer:cursor:{contract_address}
handleInvoiceRegistered — sets tx_hash on invoice
handleInvoiceStatusChanged — updates invoice status
handleEscrowFunded — updates offer status to ACTIVE
handleEscrowReleased — updates invoice to PAID
handleEscrowReclaimed — updates invoice to DEFAULTED
Each event has a unique ID
Processed event IDs stored in Redis with 24h TTL
Duplicate events safely ignored
GET /indexer/status — returns last processed ledger, lag, errors
Key Files:
Acceptance Criteria:
idempotency check, error recovery
Security Notes:
Branch: feat/blockchain-event-indexer
Commit: feat(indexer): add Soroban event indexer with Redis cursor tracking and idempotent handling