Skip to content

fix(indexer): parse and persist ContribReconciled event (#169) - #177

Open
trenysx wants to merge 1 commit into
Cylo-Traders:masterfrom
trenysx:fix/contrib-reconciled-indexer-169
Open

fix(indexer): parse and persist ContribReconciled event (#169)#177
trenysx wants to merge 1 commit into
Cylo-Traders:masterfrom
trenysx:fix/contrib-reconciled-indexer-169

Conversation

@trenysx

@trenysx trenysx commented Aug 18, 2026

Copy link
Copy Markdown

Summary

Closes #169

The escrow contract emits a distinct ContribReconciled event from the privileged
eceive_contribution admin path (see emit_reconciled_contribution in contracts/production_escrow/src/events.rs). This event is intentionally separate from ContribReceived so off-chain monitoring can flag admin reconciliations vs. genuine deposits.

The indexer's EventParserService.parseEvent had no case for ContribReconciled — it fell through to default: return null and was silently dropped with no audit row, no broadcast, and no log.

Changes

  1. server/src/indexer/types/soroban-events.types.ts: Added ContribReconciledData interface (mirrors CampaignInvestedData) and included it in ParsedEventData union.

  2. server/src/indexer/parsers/event-parser.service.ts:

    • Added 'ContribReconciled' case in parseEvent → parseContribReconciled (payload shape: (investor, timestamp, amount) matching the contract).
    • Parsed events are tagged 'campaign.contrib_reconciled' (distinct from 'campaign.invested').
    • Added handleContribReconciled persistence handler: audit-only — upserts the user for FK validity, logs the reconciliation, but does not increment Campaign.totalFunded (the authoritative funded amount stays driven by ContribReceived/CampaignFunded events; the reconciliation is a bookkeeping path without real token transfer, per the contract's design and the issue's suggestion to consider keeping it separate).
    • The generic Transaction audit row is created automatically by persistEvent once the event type is recognized.
  3. server/src/websocket/events.types.ts + client/src/lib/websocket/events.types.ts: Added 'campaign.contrib_reconciled' to CampaignEventType union so realtime broadcast carries the correct event type.

Tests

Added a ContribReconciled describe block to event-parser.service.spec.ts:

  1. Parses and persists a distinctly-tagged Transaction row ( ype: 'campaign.contrib_reconciled') without creating an Investment row or incrementing otalFunded.
  2. Broadcasts a campaign.contrib_reconciled realtime event distinguishable from campaign.invested.
  3. Logs and skips malformed payloads.

All 48 unit tests pass; sc --noEmit and eslint are clean for changed files.

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.

[Backend] ContribReconciled — the contract's specifically-hardened admin-reconciliation event — is silently dropped by the indexer

1 participant