feat: add --chain filter to protocols fees and revenue#43
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>
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>
Add `stablecoins top` command using DefiLlama's free stablecoins API to list stablecoins ranked by circulating market cap. Returns price, chain count, peg type/mechanism, and day/week/month supply change deltas. Supports `--peg-type` filter and `--limit`. No API key required. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cap ranking Surface stablecoin liquidity distribution across chains using DefiLlama's stablecoinchains API. Returns chains ranked by total stablecoin supply with CAIP-2 chain IDs and dominant peg type. No API key required. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `protocols fees` command that ranks protocols by 24h fee revenue using the DefiLlama fees API. Includes 7d/30d totals, percentage changes (1d/7d/1m), category filtering, and chain counts. No API key required. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `dexes volume` command to rank DEXes by 24h trading volume with 7d/30d totals and 1d/7d/1m percentage changes. Uses DefiLlama DEX volume API (no API key required). Supports `--chain` filter for chain presence and `--limit`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revenue (protocol-retained fees) is the most important fundamental metric for protocol valuation. This adds `protocols revenue` using DefiLlama's /overview/fees?dataType=dailyRevenue endpoint with the same --category filter and --limit flags as protocols fees. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds --chain flag to `protocols top` that filters protocols by chain presence and ranks by chain-specific TVL from DefiLlama's chainTvls data. Supports combined --category and --chain filtering. Output now includes chains count field. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Filter protocols fees and revenue rankings by chain presence, consistent with dexes volume --chain and protocols top --chain. Supports combined --category and --chain filtering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 481f8e0f10
ℹ️ 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".
| if normCategory != "" && strings.ToLower(p.Category) != normCategory { | ||
| continue | ||
| } | ||
| if normChain != "" && !containsChain(p.Chains, normChain) { |
There was a problem hiding this comment.
Normalize chain filter before matching protocol chains
This filter compares the raw --chain string directly against DefiLlama chain names, so inputs like 1, eip155:1, or aliases such as mainnet will not match entries like Ethereum and will silently return empty results. Because this code path is used by the new protocols fees/protocols revenue chain filters, chain-scoped queries can be incorrect unless users know to provide DefiLlama display names exactly.
Useful? React with 👍 / 👎.
| gasCmd.Flags().StringVar(&gasChainArg, "chain", "", "Chain id/name/CAIP-2 (comma-separated for multiple)") | ||
| gasCmd.Flags().StringVar(&gasRPCURL, "rpc-url", "", "RPC URL override (single chain only)") | ||
| _ = gasCmd.MarkFlagRequired("chain") | ||
| gasResponse := schema.SchemaFromType([]model.GasPrice{}) |
There was a problem hiding this comment.
Fix chains gas schema to match single-chain response shape
The command metadata declares chains gas response as an array, but the implementation returns a scalar GasPrice object when a single chain is requested. This makes defi schema advertise the wrong contract for the common single-chain case, which can break schema-driven parsers/validators even though the CLI output is otherwise valid.
Useful? React with 👍 / 👎.
Combines market data commands (chains list/gas, stablecoins, protocols fees/revenue, dexes volume) with Tempo chain support additions from main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…response types - Fix peggedAmount to use map[string]float64 instead of hardcoded peggedUSD field. DefiLlama uses peg-specific keys (peggedEUR, etc.), so non-USD stablecoins previously reported zero circulating amounts. - Remove duplicate dexProtocolResp; reuse feesProtocolResp for DEX volume since the response schema is a superset. - Extract filterFeesProtocols and capLimit helpers to reduce duplicated filter+sort+limit logic across ProtocolsFees, ProtocolsRevenue, and DexesVolume. - Add test for non-USD peg type circulating amounts. - Document missing commands in Mintlify docs: chains gas, protocols revenue, protocols fees --chain, protocols top --chain, stablecoins chains. - Update cache TTL table with new market data commands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f67794a52c
ℹ️ 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".
| ctx := cmd.Context() | ||
|
|
||
| // Single chain: preserve the original scalar response. | ||
| if len(entries) == 1 { | ||
| result, err := fetchGasPrice(ctx, entries[0].chain, entries[0].rpcURL, s.runner.now) |
There was a problem hiding this comment.
Enforce timeout for chains gas RPC calls
chains gas uses cmd.Context() directly and never wraps it with context.WithTimeout(..., s.settings.Timeout), unlike the cached market-data paths. If an RPC endpoint is slow or hangs, both single-chain and multi-chain gas lookups can block indefinitely and ignore the global --timeout setting, which can stall automation pipelines waiting for this command to return.
Useful? React with 👍 / 👎.
| partial := len(warnings) > 0 | ||
| return s.emitSuccess(trimRootPath(cmd.CommandPath()), prices, warnings, cacheMetaBypass(), nil, partial) |
There was a problem hiding this comment.
Honor strict mode before emitting partial gas results
The multi-chain chains gas path returns partial success whenever at least one chain succeeds, but it does not check s.settings.Strict before calling emitSuccess. This means --strict still exits 0 for partial gas data (e.g., one chain RPC fails, another succeeds), which violates the CLI’s strict-mode contract to fail on partial results.
Useful? React with 👍 / 👎.
…ct mode - Wrap RPC context with s.settings.Timeout to prevent indefinite hangs when an RPC endpoint is unresponsive (P1). - Always return []GasPrice array even for single-chain queries so the response shape matches the schema metadata declaration (P2). - Check s.settings.Strict before emitting partial multi-chain results; return CodePartialStrict error when any chain fails in strict mode (P2). - Clarify --chain flag help text on protocols/fees/revenue/dexes commands to indicate DefiLlama chain names are expected (not CAIP-2/numeric IDs). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
| 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.
GasPrice emits empty strings for legacy chain fields
Low Severity
The GasPrice struct's BaseFeeGwei and PriorityFeeGwei fields lack omitempty JSON tags. For non-EIP1559 (legacy) chains, fetchGasPrice only sets these fields inside the if eip1559 block, so they serialize as "base_fee_gwei": "" in JSON output. For a CLI "built for AI agents and scripts," an empty string in a field that otherwise holds numeric strings like "1.000000" is problematic — downstream consumers parsing these as numbers will fail. The SupportedChain struct in the same file already uses omitempty for optional fields like EVMChainID.
Additional Locations (1)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 04bb81a147
ℹ️ 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".
| priorityFee, err = client.SuggestGasTipCap(ctx) | ||
| if err != nil { | ||
| priorityFee = new(big.Int) | ||
| } |
There was a problem hiding this comment.
Fail chains gas when priority-fee RPC call fails
On EIP-1559 chains, a failure from SuggestGasTipCap is currently converted to 0 and the command still succeeds, so RPCs that do not expose eth_maxPriorityFeePerGas (or transiently fail it) will silently emit an incorrect priority_fee_gwei instead of surfacing an error/partial result. This produces materially wrong gas data for automation even though the command reports success.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61eff7977a
ℹ️ 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".
| tvl = chainTVL(p.ChainTvls, normChain) | ||
| if tvl <= 0 { | ||
| tvl = p.TVL |
There was a problem hiding this comment.
Preserve zero chain TVL in chain-filtered rankings
When --chain is used, this fallback treats an explicit chain TVL of 0 as missing data and replaces it with the protocol's global TVL. That produces incorrect protocols top --chain ... output and rank ordering for protocols that are present on a chain but currently have zero TVL there (they get inflated by total cross-chain TVL). Use a map lookup with an ok check so only truly missing keys fall back, while real zero values remain zero.
Useful? React with 👍 / 👎.


Summary
--chainflag toprotocols feesandprotocols revenuecommands to filter by chain presence (e.g.protocols fees --chain Ethereum)--categoryand--chainfiltering, consistent with existingdexes volume --chainandprotocols top --chainbehaviorTest plan
go test ./...passesgo test -race ./...passesgo vet ./...passes--chainflag for both commands🤖 Generated with Claude Code
Note
Medium Risk
Adds several new CLI commands and expands the
MarketDataProviderinterface and output schemas, plus introduces parallel RPC gas fetching; this could affect downstream consumers expecting older JSON shapes or provider mocks. Network/RPC error-handling and partial-results behavior is new surface area but is covered by extensive unit tests.Overview
Adds new market commands:
chains list(enumerate supported chains/aliases) andchains gas(live EVM gas pricing via RPC, with optional--rpc-url, multi-chain parallel queries, and partial-result handling; both bypass cache).Extends protocol/market rankings by adding
protocols feesandprotocols revenue(with--category,--chain,--limitfilters) and wiring new top-leveldexes volumeandstablecoins top|chainscommands to new DefiLlama client endpoints;protocols topnow accepts--chainand returns achainscount.Updates the DefiLlama provider capabilities,
MarketDataProviderinterface, andinternal/modeltypes to support the new outputs, and adds comprehensive test coverage plus docs/README/CHANGELOG updates for the new command surface and cache-bypass semantics.Written by Cursor Bugbot for commit 61eff79. This will update automatically on new commits. Configure here.