feat: add chains list and chains gas commands#35
Conversation
Agents and automation tools need to discover available chains before using other commands. This adds `chains list` which enumerates all supported chains with names, slugs, CAIP-2 identifiers, namespaces, and accepted aliases. No API keys required; bypasses cache. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Agents planning execution need gas price context before deciding whether to proceed with swaps, bridges, or other on-chain operations. This adds `chains gas --chain <id>` which queries current base fee, priority fee, and legacy gas price via RPC with EIP-1559 detection. No API keys required, bypasses cache, supports --rpc-url override. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| BlockNumber int64 `json:"block_number"` | ||
| EIP1559 bool `json:"eip1559"` | ||
| BaseFeeGwei string `json:"base_fee_gwei"` | ||
| PriorityFeeGwei string `json:"priority_fee_gwei"` |
There was a problem hiding this comment.
Missing omitempty on EIP-1559-only JSON fields
Medium Severity
BaseFeeGwei and PriorityFeeGwei in GasPrice lack omitempty JSON tags. For non-EIP1559 (legacy) chains, these fields are never set by fetchGasPrice, so they serialize as "base_fee_gwei": "" and "priority_fee_gwei": "" — empty strings in a field that otherwise holds numeric gwei values. This is inconsistent with the SupportedChain struct in the same PR, which uses omitempty for its optional fields. For an automation-friendly CLI, empty strings in numeric-typed fields can break downstream parsers that use .get() with a "0" default, since float("") raises errors. Since this is a new API surface, fixing it later would be a breaking change.
Allow --chain to accept comma-separated chain identifiers (e.g. --chain 1,10,137,8453,42161) for parallel multi-chain gas price queries. Single-chain usage preserves the existing scalar response for backward compatibility. Multi-chain returns an array with partial-result support and warnings for failed chains. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New: Multi-chain batch gas queriesAdded support for comma-separated chains in # Before: one chain at a time
defi chains gas --chain 1 --results-only
defi chains gas --chain 10 --results-only
defi chains gas --chain 137 --results-only
# After: batch query with parallel RPC fetching
defi chains gas --chain 1,10,137,8453,42161 --results-onlyBehavior:
All existing tests pass + new tests for multi-chain, rpc-url rejection, non-EVM rejection in multi-chain, and scalar preservation. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| gwei := new(big.Float).SetInt(wei) | ||
| gwei.Quo(gwei, big.NewFloat(1e9)) | ||
| return gwei.Text('f', 6) | ||
| } |
There was a problem hiding this comment.
weiToGwei returns inconsistent format for nil versus zero
Low Severity
weiToGwei returns "0" (no decimal places) for a nil input but "0.000000" (six decimal places) for a zero *big.Int. This format inconsistency means two semantically equivalent zero values produce different string representations. While current callers never pass nil, the function's contract is inconsistent and could produce surprising output if future callers do.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 650fa54261
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| partial := len(warnings) > 0 | ||
| return s.emitSuccess(trimRootPath(cmd.CommandPath()), prices, warnings, cacheMetaBypass(), nil, partial) |
There was a problem hiding this comment.
Enforce strict mode before returning partial gas results
In the multi-chain chains gas path, partial failures are converted into warnings and then returned via emitSuccess, but this bypasses the strict-mode guard used by runCachedCommand to raise CodePartialStrict on partial data. As a result, defi chains gas --strict --chain ... can still exit successfully when one or more RPC calls fail, which is especially risky with --results-only because warnings are not emitted there and automation can treat incomplete results as complete.
Useful? React with 👍 / 👎.
| result, err := fetchGasPrice(ctx, entries[0].chain, entries[0].rpcURL, s.runner.now) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return s.emitSuccess(trimRootPath(cmd.CommandPath()), result, nil, cacheMetaBypass(), nil, false) |
There was a problem hiding this comment.
Keep chains gas response type consistent with schema metadata
This branch returns a scalar GasPrice object for a single chain, while the command metadata below declares the response as []model.GasPrice; schema-driven clients using schema chains gas will therefore expect an array and mis-handle the default single-chain response shape. The command should use one stable response type (or an explicit union schema) to avoid contract drift for automation.
Useful? React with 👍 / 👎.


Summary
chains listcommand to enumerate all supported chains with names, slugs, CAIP-2 identifiers, namespaces, and accepted aliaseschains gas --chain <id>command to query current EVM gas prices (base fee, priority fee, legacy gas price) via RPCchains list
Enables agents to programmatically discover valid
--chainvalues:chains gas
Gives agents gas price context before planning execution (swaps, bridges, lend operations):
defi chains gas --chain 1 --results-only # Returns: chain_id, chain_name, block_number, eip1559, base_fee_gwei, priority_fee_gwei, gas_price_gwei defi chains gas --chain base --rpc-url https://custom-rpc.example --results-onlyTest plan
ListChains(dedup, sort, aliases)weiToGweiconversionfetchGasPricewith mock JSON-RPC server (EIP-1559 and legacy modes)Runner.Runwith mock RPCgo test ./...passesgo vet ./...passes🤖 Generated with Claude Code
Note
Medium Risk
Introduces new CLI surfaces that open live RPC connections and add concurrent multi-chain fetching, which can affect reliability/latency and error handling, but changes are isolated to new commands and models.
Overview
Adds two new chain discovery utilities:
chains listto enumerate all supported chains (slug, CAIP-2, namespace, aliases), andchains gasto query live EVM gas pricing via JSON-RPC (EIP-1559 detection, block number, gwei values) with optional--rpc-urloverride.chains gassupports comma-separated multi-chain requests fetched in parallel with partial-result warnings, rejects non-EVM chains, and both new commands are treated as metadata by bypassing cache initialization. The PR also introduces new output models (SupportedChain,GasPrice), anid.ListChains()helper to dedupe/sort chains and surface aliases, plus comprehensive unit/E2E tests and docs/README/CHANGELOG updates for the new commands.Written by Cursor Bugbot for commit 650fa54. This will update automatically on new commits. Configure here.