Implement transaction submission idempotency strategy - #169
Merged
El-swaggerito merged 2 commits intoJul 21, 2026
Merged
Conversation
Contributor
|
This PR cannot be merged automatically because it has merge conflicts. Please update the branch with the latest base branch and resolve the conflicts. After the conflicts are resolved and checks pass, the automation can review it again. |
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.
Closes #153
Description
This PR designs and implements a robust transaction submission idempotency strategy for the Stellar PocketPay SDK. It resolves the risk of duplicate payments/submissions during network drops and transaction timeouts by introducing status polling, transaction hash tracking, timebounds enforcement, and classification of retryable vs. non-retryable errors.
Key Changes
PocketPayError: AddedtransactionHash?: stringandretryable?: booleanparameters to the SDK's core error class to expose relevant context to consumers during failures.src/errors/index.ts): Introduced a classification helper that categorizes errors based on Stellar transaction result codes, HTTP statuses, and network/socket timeouts.tx_bad_auth,tx_bad_seq,tx_insufficient_balance).src/network/idempotency.ts):submitTransactionIdempotently: Automatically handles timeout/unknown status outcomes by falling back to polling.pollTransactionStatus: Queries Horizon for the transaction by its hash. It references the transaction'smaxTimebounds and throws a cleanTX_EXPIRED(retryable) error if the transaction fails to make it to the ledger before it expires.sendXLMinsrc/payments/index.tsto submit payments idempotently.docs/idempotency.md): Created a detailed consumer integration guide explaining duplicate submission risks and showing how to use the automated and manual helpers.docs/error-handling.md): Documented the new error properties and status codes.Verification & Tests
Written a full suite of tests in
tests/idempotency.test.tscovering:TX_EXPIREDwhen transaction maxTime bounds are exceeded.Ran all test suites successfully:
$ npm test ✓ tests/config.test.ts (7 tests) ✓ tests/idempotency.test.ts (9 tests) ✓ tests/fund.test.ts (22 tests) ✓ tests/utils.test.ts (34 tests) ✓ tests/payments.test.ts (7 tests) ✓ tests/wallet.test.ts (8 tests) Test Files 6 passed (6) Tests 87 passed (87)