fix(gamification): decode real payment amounts from XDR, classify don… - #148
Merged
BarryArinze merged 1 commit intoAug 26, 2026
Conversation
…ation/distribution/claim correctly Fixes aid-linkk#142 - transaction-indexer.ts no longer uses fee_charged as the donation amount. It now decodes each transaction's envelope_xdr via the Stellar SDK XDR parser to get the real payment amount and asset code. - Introduces src/lib/horizon/envelope-decode.ts: shared low-level XDR primitives (getEnvelopeOperations, decodePaymentOp, decodeInvokeHostFunctionOp, mapSorobanFunctionName, asset code decoding) extracted from decode-horizon-transaction.ts so both the real-time dashboard stream and the gamification indexer decode XDR the same way instead of duplicating the logic. - decode-horizon-transaction.ts is refactored to use the shared primitives; its public behavior/output for useRealTimeTransactions is unchanged. - TransactionEvent.type is now classified from real operation semantics: outgoing payments -> donation, incoming payments -> distribution, invokeHostFunction calls matching claim/distribute Soroban function names -> claim/distribution. Soroban 'donate'-style calls are intentionally not counted as donations since no verifiable amount can be recovered from the operation without decoding contract arguments (out of scope). - recipient is now the actual payment destination or contract ID, fixing unique_campaigns_supported. - Adds resumable cursor support: indexTransactions now honors options.cursor (already persisted via badge-storage.ts's lastSyncedCursor) and issues zero extra Horizon calls when there are no new transactions. - TransactionEvent/IndexResult/indexTransactions signature, badge-rules.ts, badge-evaluator.ts, and badge-storage.ts are all unchanged per the issue's constraints. Tests: src/lib/gamification/__tests__/transaction-indexer.test.ts covers XDR-decoded amounts, claim classification, fee_charged vs real amount, cursor resumption, AID token currency, undecodable XDR handling, and a badge-evaluator integration scenario. npm run test and npm run type-check pass with no new regressions (pre-existing unrelated failures on master are unaffected).
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…ation/distribution/claim correctly
Fixes #142
semantics: outgoing payments -> donation, incoming payments ->
distribution, invokeHostFunction calls matching claim/distribute Soroban function names -> claim/distribution. Soroban 'donate'-style calls are intentionally not counted as donations since no verifiable amount can be recovered from the operation without decoding contract arguments (out of scope).
Tests: src/lib/gamification/tests/transaction-indexer.test.ts covers XDR-decoded amounts, claim classification, fee_charged vs real amount, cursor resumption, AID token currency, undecodable XDR handling, and a badge-evaluator integration scenario.
npm run test and npm run type-check pass with no new regressions (pre-existing unrelated failures on master are unaffected).