Skip to content

feat: add protocols fees command#39

Closed
ggonzalez94 wants to merge 6 commits into
mainfrom
feat/protocols-fees
Closed

feat: add protocols fees command#39
ggonzalez94 wants to merge 6 commits into
mainfrom
feat/protocols-fees

Conversation

@ggonzalez94
Copy link
Copy Markdown
Owner

@ggonzalez94 ggonzalez94 commented Mar 13, 2026

Summary

  • Add protocols fees command to rank protocols by 24h fee revenue using DefiLlama's fees API
  • Includes 7d/30d fee totals, 1d/7d/1m percentage changes, category filter (--category), and chain counts
  • No API key required; follows existing protocols top/protocols categories patterns exactly

Details

Fee/revenue data is one of the most critical metrics for evaluating protocol sustainability. This command surfaces it through the same agent-friendly JSON envelope used by all other commands.

Output fields: rank, protocol, category, fees_24h_usd, fees_7d_usd, fees_30d_usd, change_1d_pct, change_7d_pct, change_1m_pct, chains

Example usage:

defi protocols fees --limit 5 --results-only
defi protocols fees --category Dexs --limit 10 --results-only --select rank,protocol,fees_24h_usd

Test plan

  • go test ./... passes
  • go test -race ./... passes
  • go vet ./... passes
  • httptest-based adapter tests (sort, limit, category filter, null/zero exclusion)
  • Runner-level integration test
  • Manual smoke test against live DefiLlama API
  • CHANGELOG, README, and provider capabilities updated

🤖 Generated with Claude Code


Note

Medium Risk
Adds new CLI commands backed by external DefiLlama endpoints and live RPC gas queries (including parallel RPC fetching), which could affect reliability and output contracts but doesn’t touch execution/auth flows.

Overview
Expands market-discovery command surface with new JSON outputs and docs updates.

Adds protocols fees (DefiLlama /overview/fees) plus a new stablecoins command group (top, chains) sourced from DefiLlama stablecoins APIs, including new output models and provider capabilities/interface methods.

Adds chains list (enumerate supported chains/aliases from the local registry) and chains gas (live EVM gas price via RPC with optional single-chain --rpc-url, multi-chain parallel fetching, partial-result warnings), and marks chains list/chains gas as cache-bypassing metadata commands with new unit/integration tests.

Written by Cursor Bugbot for commit 1600fed. This will update automatically on new commits. Configure here.

ggonzalez94 and others added 6 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>
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 2 potential issues.

Fix All in Cursor

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


type peggedAmount struct {
PeggedUSD float64 `json:"peggedUSD"`
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

peggedAmount struct only decodes peggedUSD key

High Severity

The peggedAmount struct only has a PeggedUSD field with JSON tag "peggedUSD". DefiLlama's stablecoins API uses the peg type as the key in the circulating object (e.g., {"peggedEUR": value} for EUR-pegged stablecoins). Non-USD pegged stablecoins will deserialize with PeggedUSD: 0, resulting in zero CirculatingUSD, zero change deltas, and incorrect sort ordering. The stablecoinChainResp in the same file correctly uses map[string]float64 for the analogous field, highlighting the inconsistency. The test data masks this by using "peggedUSD" as the key even for the EUR-pegged test stablecoin.

Additional Locations (1)
Fix in Cursor Fix in Web

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 fields missing omitempty for legacy chains

Medium Severity

BaseFeeGwei and PriorityFeeGwei in the GasPrice struct lack omitempty JSON tags. For non-EIP1559 (legacy) chains, these fields are never set by fetchGasPrice, so they serialize as empty strings ("base_fee_gwei":""). This is inconsistent — the fields represent numeric values and empty strings are ambiguous for agent consumers. The eip1559 boolean signals their irrelevance, but agents would still need to special-case empty strings vs actual gwei values.

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: 1600feddbc

ℹ️ 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
}

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.

P1 Badge Honor --strict for partial chains gas responses

In multi-chain mode this path calls emitSuccess directly when at least one chain succeeds, so --strict is never enforced even if other chains fail and partial=true. A run like chains gas --chain 1,10 --strict can exit 0 with warnings whenever one RPC is down, which breaks automation that relies on strict mode to fail on partial results (other commands route through runCachedCommand, which performs this check).

Useful? React with 👍 / 👎.

Comment thread internal/app/runner.go
Comment on lines +499 to +500
gasResponse := schema.SchemaFromType([]model.GasPrice{})
_ = schema.SetCommandMetadata(gasCmd, schema.CommandMetadata{Response: &gasResponse})
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 Align chains gas schema with single-chain output type

The command metadata advertises chains gas as returning an array ([]GasPrice), but the implementation returns a scalar object for a single --chain input. This makes the machine-readable schema inaccurate for the most common call pattern and can cause schema-driven clients to deserialize the response incorrectly.

Useful? React with 👍 / 👎.

@ggonzalez94
Copy link
Copy Markdown
Owner Author

Closing: superseded by #43 which contains all commits from this stacked branch chain (this PR's 6 commits are included in #43's 10).

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