fix(x402): scope token-availability error to the requested chain#469
Merged
Conversation
`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).
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.
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 rejectedOBOLonbase-sepolia/base.TokensOnChain(chain)andChainsForToken(token)helpers ininternal/x402/tokens.go.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-sepoliaon spark2 against the v0.9.0 binary: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:
After:
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— newTestTokensOnChainandTestChainsForTokenplus existing token tests pass.go build ./...clean.obol sell inference … --token OBOL --chain base(mainnet, OBOL not registered there) now shows the chain-scoped hint.🤖 Generated with Claude Code