Skip to content

fix(x402): scope token-availability error to the requested chain#469

Merged
bussyjd merged 1 commit into
mainfrom
fix/x402-tokens-chain-scoped-error
May 12, 2026
Merged

fix(x402): scope token-availability error to the requested chain#469
bussyjd merged 1 commit into
mainfrom
fix/x402-tokens-chain-scoped-error

Conversation

@bussyjd
Copy link
Copy Markdown
Collaborator

@bussyjd bussyjd commented May 12, 2026

Summary

  • --token X is not available on chain Y (supported tokens: …) returned the global token list, not the chain-scoped one — so operators saw OBOL listed as "supported" while the lookup had just rejected OBOL on base-sepolia/base.
  • Add TokensOnChain(chain) and ChainsForToken(token) helpers in internal/x402/tokens.go.
  • Rewrite resolveAssetTermsFor's error message to use both — now it tells you what's actually on the requested chain and where the token you asked for is registered.

How this surfaced

While wiring obol sell inference … --token OBOL --chain base-sepolia on spark2 against the v0.9.0 binary:

$ obol sell inference aeon … --token OBOL --chain base-sepolia
✗ --token OBOL is not available on chain base-sepolia (supported tokens: OBOL, USDC)

The OBOL Base Sepolia registry entry only landed in #452 (post-v0.9.0). That's fine — but the error message confidently claimed OBOL was supported, sending the operator off-trail. (The PR doesn't backport the registry entry; it's already on main.)

Before / after

Before:

--token OBOL is not available on chain base (supported tokens: OBOL, USDC)

After:

--token OBOL is not available on chain base; tokens on base: USDC; OBOL is registered on: base-sepolia, ethereum

Other branches handle "no tokens on this chain at all" and "this token isn't anywhere" without losing the chain context.

Test plan

  • go test ./internal/x402 -count=1 — new TestTokensOnChain and TestChainsForToken plus existing token tests pass.
  • go build ./... clean.
  • Repro on spark2: obol sell inference … --token OBOL --chain base (mainnet, OBOL not registered there) now shows the chain-scoped hint.

🤖 Generated with Claude Code

`resolveAssetTermsFor` returned `--token X is not available on chain Y
(supported tokens: OBOL, USDC)` when a token wasn't registered for the
requested chain. The "supported tokens" list came from the global
registry (`SupportedTokens()`), not from the chain, so operators reading
the error saw OBOL listed as supported even though the lookup just
failed on `base-sepolia`/`base`/etc. This was actively misleading.

Surfaced today on spark2 while wiring `obol sell inference … --token
OBOL --chain base-sepolia` — the binary (v0.9.0) rejected OBOL on
base-sepolia (registry entry added in #452 after the release was cut),
but the message claimed OBOL was supported.

Changes:
- Add `TokensOnChain(chain)` and `ChainsForToken(token)` helpers in
  internal/x402/tokens.go so callers can ask the registry chain-scoped
  questions without iterating it themselves.
- Rewrite the error in `resolveAssetTermsFor` to use both:
    `--token OBOL is not available on chain base-sepolia; tokens on
     base-sepolia: OBOL, USDC; OBOL is registered on: base-sepolia,
     ethereum`
  with four branches covering the chain-empty, token-empty, both-empty,
  and normal cases.
- Add table-driven tests covering the helpers (chains/tokens lookups,
  aliases, unknown chain/token, case-insensitive token names).
@bussyjd bussyjd merged commit ff73a41 into main May 12, 2026
6 checks passed
@bussyjd bussyjd deleted the fix/x402-tokens-chain-scoped-error branch May 12, 2026 09:06
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