Skip to content

feat: add --chain filter to protocols fees and revenue#43

Merged
ggonzalez94 merged 14 commits into
mainfrom
feat/protocols-fees-revenue-chain-filter
Mar 20, 2026
Merged

feat: add --chain filter to protocols fees and revenue#43
ggonzalez94 merged 14 commits into
mainfrom
feat/protocols-fees-revenue-chain-filter

Conversation

@ggonzalez94
Copy link
Copy Markdown
Owner

@ggonzalez94 ggonzalez94 commented Mar 18, 2026

Summary

  • Adds --chain flag to protocols fees and protocols revenue commands to filter by chain presence (e.g. protocols fees --chain Ethereum)
  • Supports combined --category and --chain filtering, consistent with existing dexes volume --chain and protocols top --chain behavior
  • No API key required — uses the same DefiLlama fees API with client-side chain filtering

Test plan

  • go test ./... passes
  • go test -race ./... passes
  • go vet ./... passes
  • New unit tests for chain filter on both fees and revenue (4 new tests)
  • Combined category+chain filter tests for both commands
  • Help output shows --chain flag for both commands
  • CHANGELOG updated

🤖 Generated with Claude Code


Note

Medium Risk
Adds several new CLI commands and expands the MarketDataProvider interface 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) and chains 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 fees and protocols revenue (with --category, --chain, --limit filters) and wiring new top-level dexes volume and stablecoins top|chains commands to new DefiLlama client endpoints; protocols top now accepts --chain and returns a chains count.

Updates the DefiLlama provider capabilities, MarketDataProvider interface, and internal/model types 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.

ggonzalez94 and others added 10 commits March 8, 2026 15:28
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>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread internal/providers/defillama/client.go Outdated
if normCategory != "" && strings.ToLower(p.Category) != normCategory {
continue
}
if normChain != "" && !containsChain(p.Chains, normChain) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread internal/app/runner.go
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{})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread internal/providers/defillama/client.go
ggonzalez94 and others added 2 commits March 20, 2026 12:56
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>
Comment thread internal/app/runner.go
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread internal/app/runner.go Outdated
Comment on lines +454 to +458
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)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment thread internal/app/runner.go
Comment on lines +497 to +498
partial := len(warnings) > 0
return s.emitSuccess(trimRootPath(cmd.CommandPath()), prices, warnings, cacheMetaBypass(), nil, partial)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread internal/model/types.go
BlockNumber int64 `json:"block_number"`
EIP1559 bool `json:"eip1559"`
BaseFeeGwei string `json:"base_fee_gwei"`
PriorityFeeGwei string `json:"priority_fee_gwei"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread internal/app/runner.go
Comment on lines +2573 to +2576
priorityFee, err = client.SuggestGasTipCap(ctx)
if err != nil {
priorityFee = new(big.Int)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@ggonzalez94 ggonzalez94 merged commit cf2c298 into main Mar 20, 2026
16 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +223 to +225
tvl = chainTVL(p.ChainTvls, normChain)
if tvl <= 0 {
tvl = p.TVL
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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