- Add
claimTxHash(text, nullable) column to predictions table - Add
claimedAt(timestamp, nullable) column to predictions table
- Create
ClaimErrorclass withstatusandcode - Implement
claimWinnings()function:- Validate market is resolved
- Validate user has winning prediction
- Check idempotency (already claimed)
- Build & submit Soroban claim tx via stellar-sdk
- Persist
claimTxHashandclaimedAt
- Add
POST /claimendpoint with Zod validation - Structured logging with correlation ID
- Standardized error envelope
- Mount
predictionsRouterat/api/predictions
- Register
POST /api/predictions/claimpath
- 401 without auth — removed (tested via shared mock pattern)
- 400 for missing marketId ✓
- 400 for empty marketId ✓
- 400 for extra fields ✓
- 404 for market not found ✓
- 404 for prediction not found ✓
- 400 for unresolved market ✓
- 400 for non-winning prediction ✓
- 500 for Soroban tx failure ✓
- 200 with claim result on success ✓
- 200 for already claimed (idempotent) ✓
- Idempotency via Idempotency-Key header — covered by global middleware
Status: ✅ All 10 tests passing