Repository navigation
Conversation
…rgepay#810) Adds src/services/horizon-errors.ts to parse SDK/Horizon rejections (result_codes and result_xdr), reduce them to allow-listed tokens, and map common transaction and operation codes onto stable API codes, HTTP statuses, and actionable hints. toProviderError and submitToHorizon now route rejections through the mapping; unknown codes keep PROVIDER_REJECTED while carrying only validated tokens. Covered by tests/horizon-errors.test.ts (17 cases) and updated tests/provider-errors.test.ts.
…mergepay#813) Extends tests/integration/sep10-auth.test.ts with the rejection paths a wallet can actually hit: a correctly signed challenge bound to a different web auth domain, an unsigned challenge carrying only the server signature, a home_domain claim that does not match the request, and an unparseable envelope — each asserted to fail before the user store is touched, alongside the existing valid-signature-to-JWT, wrong-key, wrong-domain, expired-challenge, and single-use redemption cases.
…flows (mergepay#809) The durable audit rows for treasury multisig and group settlement actions were already asserted, but the operator-facing structured Pino lines (src/lib/audit-logger.ts) were only covered for group flows. tests/audit-treasury-settlement-events.test.ts now pins full context — actor, action, target, groupId, outcome, timestamp — on both the structured line and the durable row for multisig signature collection and submission failure and for settlement execution and envelope-validation failure, and proves private keys, signed XDRs, and tokens are redacted before reaching either sink.
The suite's explicit 2000ms budget is runner patience only — the assertions pin the server's 80ms behaviour — but under full-suite parallel load the wall clock stretches past it and the test flakes. Raised to 10s; the behaviour under test is still bounded by TIMEOUT_MS.
|
@adiainit 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 #809
Closes #810
Closes #813
Closes #812
Summary
This PR closes three issues with one shared theme — hardening the Stellar-facing
paths with structured errors, deeper authentication test coverage, and complete
audit-trail verification.
#810 — Stellar Horizon error mapping utility
src/services/horizon-errors.ts:mapHorizonError()parses Stellar SDK /Horizon rejection shapes (
response.data.extras.result_codesand base64result_xdr), reduces them to an allow-listed vocabulary of validatedresult-code tokens, and maps common transaction- and operation-level codes
(
tx_bad_seq,tx_insufficient_fee,op_underfunded,op_no_trust,op_low_reserve, …) onto stable API codes, appropriate HTTP statuses (409 /422 / 502), and actionable client hints. Unrecognized codes still answer
PROVIDER_REJECTED, but only the validated tokens survive — raw upstreampayloads, operation details, and SDK message text never reach the client.
src/services/timeout.ts—toProviderError()routes Horizon errors throughthe mapping so every rejection carries its code-specific status, code, and
details.
src/lib/provider-error.tsgains optionalstatus/errorCode/detailsparameters; rate-limit and transport behaviour is unchanged.src/services/stellar.ts—submitToHorizon()replaces the oldstring-interpolated upstream message with the shared mapping, keeping
submission failures categorized for
classifyJobFailure.tests/horizon-errors.test.ts(17 cases — result_xdr precedence,payload-leak rejection, de-duplication, TransportError unwrapping,
rate-limit preservation) and
tests/provider-errors.test.tsupdated to thenew mapped codes.
#813 — SEP-10 challenge and verification integration tests
tests/integration/sep10-auth.test.tsextended with the rejection paths awallet can actually hit, each asserted to fail before the user store is
touched:
web_auth_domain,home_domainrequest claim that does not match the request,challenge structure (domains, ops, nonce, time bounds, server signature),
valid signature → JWT + refresh token with claims verification, wrong-key /
wrong-domain / expired-challenge rejection (
CHALLENGE_EXPIRED), andsingle-use redemption (replay → 401).
npm run test:integrationagainst a real Postgres:14/14 files, 108 tests passed, including all 11 SEP-10 auth tests.
#809 — Audit logging for treasury multisig and group settlement
The helper (
src/lib/audit-logger.ts,src/services/audit.ts), the handlerintegration (treasury proposal create/sign/submit/fail; settlement
create/confirm/execute/retry/validation-failed), and secret redaction were
already in place; what was untested was the operator-facing structured Pino
event for those two domains — the lines log aggregators filter on.
tests/audit-treasury-settlement-events.test.tspins full context —actor, action, target, groupId, outcome, timestamp — on both the durable
audit row and the structured
event = "audit"line for:bearer tokens are replaced with
[REDACTED]before reaching either sink.Housekeeping
tests/request-timeout.test.ts: the explicit 2000 ms budget is runnerpatience only (the assertions pin the server's 80 ms behaviour), but it
flaked under full-suite parallel load; widened to 10 s.
Testing & validation
npm run build— passes (strict TypeScript).npm run lint— 0 errors (32 pre-existing warnings in untouched files).npm test— 4271+ / 4295 tests green; every file touched by this PR passes,and the handful of full-suite failures observed on a heavily loaded dev
machine are pre-existing 5 s wall-clock flakes that pass in isolation and
passed in the pre-change baseline.
npm run test:integration— 14/14 files, 108 tests green against a realPostgres.