Summary
When a client retries a buy or sell request due to a network timeout, the server may process the same transaction twice — charging the buyer or crediting the seller multiple times. A distributed idempotency layer backed by Redis should detect duplicate requests within a configurable window and return the original response without re-executing the transaction.
Scope
- Accept an
Idempotency-Key header on POST /buy and POST /sell endpoints
- On first request: execute the transaction, store
{ statusCode, body, resolvedAt } in Redis under the key with a 24-hour TTL, then return the response
- On duplicate request (same key within TTL): return the stored response immediately without touching the database or Soroban
- If the first request is still in-flight when a duplicate arrives, block the duplicate for up to 5 seconds then either return the in-progress result or a 409
request_in_progress
- Reject requests missing the
Idempotency-Key header with 400 missing_idempotency_key
- Namespace keys by wallet address to prevent cross-wallet collisions:
idempotency:{walletAddress}:{key}
- Add integration tests covering: first execution stores result, duplicate returns stored result, in-flight duplicate returns 409, missing header returns 400, expired key allows re-execution
Acceptance Criteria
ETA: 24 hours
Coordinate on Telegram
Summary
When a client retries a buy or sell request due to a network timeout, the server may process the same transaction twice — charging the buyer or crediting the seller multiple times. A distributed idempotency layer backed by Redis should detect duplicate requests within a configurable window and return the original response without re-executing the transaction.
Scope
Idempotency-Keyheader on POST /buy and POST /sell endpoints{ statusCode, body, resolvedAt }in Redis under the key with a 24-hour TTL, then return the responserequest_in_progressIdempotency-Keyheader with 400missing_idempotency_keyidempotency:{walletAddress}:{key}Acceptance Criteria
missing_idempotency_keyETA: 24 hours
Coordinate on Telegram