Skip to content

fix: scope rail balance lookup + surface merchant error.code in CLI envelope#18

Merged
vvillait88 merged 2 commits intomainfrom
fix/select-rail-filter-and-merchant-error-surfacing
May 5, 2026
Merged

fix: scope rail balance lookup + surface merchant error.code in CLI envelope#18
vvillait88 merged 2 commits intomainfrom
fix/select-rail-filter-and-merchant-error-surfacing

Conversation

@vvillait88
Copy link
Copy Markdown
Contributor

Summary

Two findings from today's redemption-flow smoke against `agents.agentscore.sh`.

1. `selectRail` over-fetched balances

`listHeldCandidates` used to query every held chain via `Promise.all`, even when the user passed an explicit `--chain`. With the public Solana mainnet RPC's 40-req/10s cap, multiple settles in quick succession produced

`rpc_error: solana mainnet RPC call failed: HTTP error (429): Too Many Requests`

on legitimate tempo + base settles. Threaded `filterChain` through `listHeldCandidates` and `selectRail` forwards `chainOverride` so an explicit override now does exactly one balance query.

2. `merchant_error` swallowed `error.code`

The wrapper printed only "Merchant returned 400 Bad Request" and stuffed the body into `error.extra.body`. The structured `error.code` / `error.message` the merchant returns in its 4xx envelope was discarded from the human-readable message. An agent reading recovery hints had to re-curl to find out whether the failure was `codes_not_accepted` vs `product_not_found` vs `unsupported_jurisdiction`. Now lifts `error.code` and `error.message` (when JSON-envelope-shaped) into the CLI display string and into `error.extra` as `merchant_code` / `merchant_message`. Falls back gracefully when the body isn't envelope-shaped.

Test plan

  • `bun run lint` + `bun run typecheck` clean
  • `bun run test` 353/353 passing
  • New test in `selection.test.ts` asserts only the chosen chain's balance is fetched when `chainOverride` is set
  • Coverage above thresholds (92/84/95/93 vs 85/80/85/90)

🤖 Generated with Claude Code

vvillait88 and others added 2 commits May 5, 2026 05:44
…nvelope

Two findings from the agents.agentscore.sh redemption-flow smoke today.

1. selectRail used to call listHeldCandidates with no chain filter, so every
   `pay --chain X` ran a Promise.all over base + solana + tempo. With the
   public Solana mainnet RPC's 40-req/10s cap, legitimate tempo + base settles
   intermittently surfaced as
   `rpc_error: solana mainnet RPC call failed: HTTP error (429): Too Many Requests`.
   listHeldCandidates now takes an optional filterChain and selectRail forwards
   chainOverride through, so explicit overrides do exactly one balance query.

2. The merchant_error wrapper printed only "Merchant returned 400 Bad Request",
   discarding the structured `error.code` / `error.message` the merchant returns
   in its 4xx envelope. An agent following 4xx recovery instructions had to
   re-curl manually to learn whether the failure was, e.g., codes_not_accepted
   vs product_not_found vs unsupported_jurisdiction. The CLI message now lifts
   `error.code` and `error.message` (when present) into the display string and
   into the error.extra block; falls back to bare status text when the body
   isn't envelope-shaped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Carries the rail-balance scoping + merchant_error.code surfacing fixes from
this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vvillait88 vvillait88 merged commit 5fcfcf4 into main May 5, 2026
6 checks passed
@vvillait88 vvillait88 deleted the fix/select-rail-filter-and-merchant-error-surfacing branch May 5, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant