Telegram (ask questions / claim the issue here first): https://t.me/+DOylgFv1jyJlNzM0
Why this matters
index.ts:32 calls sorobanIndexerService.start() AND index.ts:33 startWorkers() starts SorobanEventWorker; both poll STREAM_CONTRACT_ID and write Stream/StreamEvent. Both WITHDRAWN handlers READ-then-ADD withdrawnAmount (soroban-indexer.service.ts:216 and soroban-event-worker.ts:631) in separate transactions, so when both fetch the same new event before either commits, the increment is applied twice -> inflated withdrawnAmount -> wrong claimable. The legacy service also keeps cursor in-memory and ignores IndexerState.
Acceptance criteria
Files to touch
backend/src/index.ts
backend/src/services/soroban-indexer.service.ts
backend/src/workers/soroban-event-worker.ts
Out of scope
- Contract-side changes
- Frontend indexer status UI
Why this matters
index.ts:32 calls sorobanIndexerService.start() AND index.ts:33 startWorkers() starts SorobanEventWorker; both poll STREAM_CONTRACT_ID and write Stream/StreamEvent. Both WITHDRAWN handlers READ-then-ADD withdrawnAmount (soroban-indexer.service.ts:216 and soroban-event-worker.ts:631) in separate transactions, so when both fetch the same new event before either commits, the increment is applied twice -> inflated withdrawnAmount -> wrong claimable. The legacy service also keeps cursor in-memory and ignores IndexerState.
Acceptance criteria
Files to touch
backend/src/index.tsbackend/src/services/soroban-indexer.service.tsbackend/src/workers/soroban-event-worker.tsOut of scope