Skip to content

fix(indexer): disambiguate dual-shape parsing by arity and enum-tag heuristic (#170) - #179

Open
trenysx wants to merge 1 commit into
Cylo-Traders:masterfrom
trenysx:fix/dual-shape-parsing-170
Open

fix(indexer): disambiguate dual-shape parsing by arity and enum-tag heuristic (#170)#179
trenysx wants to merge 1 commit into
Cylo-Traders:masterfrom
trenysx:fix/dual-shape-parsing-170

Conversation

@trenysx

@trenysx trenysx commented Aug 18, 2026

Copy link
Copy Markdown

Summary

Closes #170

Problem: The parseCampaignRegistered and parseFarmerRegistered parsers used a fragile ypeof === 'string' check to distinguish between the direct-call payload (which includes a real title/name) and the activity-log mirror payload (which emits an ActivityAction enum tag in the same slot). The stellar-sdk can decode fieldless enums as a bare string, a single-element array (['Variant']), or a { tag: 'Variant' } object. A bare-string enum decode would pass the ypeof === 'string' check and corrupt the campaign title/farmer name with the enum variant name (e.g., "CampaignRegistered").

Solution: Disambiguate deterministically by payload structure:

  • FarmerRegistered: arity differs — direct call has 4 elements (farmer, name, timestamp, ledger_sequence), activity mirror has 3 (actor, timestamp, ledger_sequence). For 4-element payloads, additionally check if the second element is an enum tag (via isTagLike + PascalCase heuristic).
  • CampaignRegistered: both shapes have 4 elements. Use isTagLike for array/object enum shapes, and a PascalCase heuristic (/^[A-Z][a-zA-Z0-9]*$/) for bare strings — enum variants are PascalCase without spaces; user titles typically contain spaces/lowercase.

Added looksLikeEnumTag helper for bare-string enum detection.

Tests added (regression coverage for all three documented enum-decoding shapes):

  • FarmerRegistered: bare string, array, object enum tags → no name corruption
  • CampaignRegistered: bare string, array, object enum tags → no title corruption
  • All existing tests still pass (direct-call titles/names still work correctly)

All 51 unit tests pass; sc --noEmit and eslint clean.

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] CampaignRegistered/FarmerRegistered dual-shape parsing can misidentify an activity-log enum tag as the real campaign title

1 participant