Repository navigation
Refactor/api hardening and disputes - #784
Merged
levoski1 merged 5 commits intoSep 25, 2026
Merged
Conversation
Every error response now uses a single envelope:
{ error: { code, message, details, correlationId } }
- Add typed errors in lib/errors.ts (ValidationError, NotFoundError,
ConflictError, UnauthorizedError, ContractError, RateLimitError,
ServiceMisconfiguredError, ...) and an asyncHandler wrapper so rejected
promises reach Express's error pipeline.
- Add a central error handler plus catch-all 404 in app.ts. Legacy
status-tagged errors are mapped to a code by status, and Soroban
"Error(Contract, #N)" messages become CONTRACT_ERROR with
details.contractCode.
- Zod validation (middleware/validate.ts) and the rate limiter now emit
the envelope; field-level issues go in details, retryAfter in details.
- requireEnv throws ServiceMisconfiguredError instead of writing to res.
- Routes throw typed errors instead of building responses by hand.
- Mount correlationId middleware before express.json so body-parse
errors also carry a correlationId.
- Fix missing requireEnv import in compliance.ts and the malformed
requireEnv call in simulate-settlement (both previously hung with 503
tests timing out).
- Update tests, OpenAPI ErrorResponse schema, api-reference.md,
error-codes.md, rate-limits.md and frontend callers that read
body.error as a string.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add helmet for a baseline of security headers (HSTS, nosniff, Referrer-Policy, frame options, ...) and drop X-Powered-By. - Use a strict CSP (default-src 'none', frame-ancestors 'none') for the JSON API, with a narrowly relaxed policy under /api-docs so Swagger UI can still load its same-origin scripts, inline styles and data: images. - Cap express.json() at 100kb. Oversized bodies return 413 in the standard envelope (code PAYLOAD_TOO_LARGE, details.limitBytes) instead of Express's default HTML page. - Add tests for the 413 path, header presence, and Swagger UI assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add CORS_ORIGINS, a comma-separated allowlist of browser origins. parseCorsOrigins() in lib/env.ts validates it (bare http(s) origins only; no paths, trailing slash or wildcards), normalises case/default ports, and fails app startup listing every invalid entry. - Add middleware/cors.ts: allowlisted origins get Access-Control-* headers; unknown origins (including preflight) are rejected with 403 CORS_ORIGIN_NOT_ALLOWED in the standard error envelope. Requests with no Origin header are unaffected. - Preflight allows Content-Type, Authorization, Idempotency-Key, X-Request-Id and X-Admin-Key, and exposes X-Request-Id, Retry-After and X-RateLimit-* to the browser. - CORS runs before body parsing and rate limiting. - Document CORS_ORIGINS in .env.local/testnet/mainnet examples and docs/api-reference.md; add tests for allowed/blocked origins, preflight, and env parsing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add GET /disputes with status (Raised | Resolved) and settlement_id
filters, following the invoices pagination convention
({ data, total, page, limit, totalPages }); invalid query params get
the standard validation envelope.
- Add GET /disputes/:id returning full details plus tallies
(claimant/counterparty/resolution weight, threshold, vote_count,
outcome, resolved_at). Unknown ids return 404 NOT_FOUND.
- Back disputes with an in-memory store populated by POST /disputes
(replacing the vote-only map). Voting on an unknown dispute now
returns 404 instead of silently creating state.
- Voter visibility: tallies are public; individual votes (signer
identities) are returned only to admins with a valid x-admin-key.
Signers are treasury multi-sig keys, and a public per-signer voting
record makes it easy to single out and pressure individual signers,
while clients only need tallies. This is defence in depth, not
secrecy: votes remain public on-chain. An invalid admin key is a 401.
- Fix the vote enum's custom message (zod 4 uses `message`, not
`errorMap`).
- Document in OpenAPI (Dispute/DisputeVote schemas) and
docs/api-reference.md; add supertest coverage including 404s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Dev-makeem Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
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 #712
Closes #713
Closes #714
Closes #715
SUMMARY
of building responses themselves.
details.contractCode.