Skip to content

feat(action): add GET_TOKEN_INFO action via GoldRush token search#28

Open
dinxsh wants to merge 3 commits intoelizaos-plugins:1.xfrom
dinxsh:feat/goldrush-token-search
Open

feat(action): add GET_TOKEN_INFO action via GoldRush token search#28
dinxsh wants to merge 3 commits intoelizaos-plugins:1.xfrom
dinxsh:feat/goldrush-token-search

Conversation

@dinxsh
Copy link
Copy Markdown

@dinxsh dinxsh commented Mar 15, 2026

Summary

  • Adds a new GET_TOKEN_INFO action that resolves token names/symbols/addresses using the GoldRush REST search API
  • Solves the most common natural language swap failure mode: agent can now find token contracts before calling SWAP
  • Zero changes to any existing action; fully optional (requires GOLDRUSH_API_KEY)
  • 17 vitest unit tests, all passing

Motivation

User:  "swap 1 ETH for Pepe"
Before: ❌ agent fails — doesn't know Pepe's contract address
After:  ✅ agent calls GET_TOKEN_INFO → finds 0x6982...2849 on eth-mainnet → calls SWAP

Supported query formats

Input Example
Token name "What is the Pepe token?"
Token symbol "Find USDC on Base"
Contract address "Look up 0x6982508145454ce325ddbe47a25d4ec3d2311933"
Swap intent "swap 1 ETH for PEPE"

Response injected into agent context

Found 2 token(s) matching "Pepe":

PEPE (Pepe)
  Chain: eth-mainnet
  Contract: 0x6982508145454ce325ddbe47a25d4ec3d2311933
  Price: $0.00000842 (24h: +5.20%)
  Market Cap: $3.5B

Powered by GoldRush (goldrush.dev)

The callback content.topResult gives subsequent actions the contract address directly.

Implementation notes

The GoldRush SDK's BaseService has no search method (the streaming-based StreamingService.searchToken requires WebSocket — not suitable for a synchronous action). The action calls the GoldRush REST API directly:

GET https://api.covalenthq.com/v1/search/?q={query}&limit=5
Authorization: Bearer {apiKey}

Handles both { result_type, item } wrapped and flat response shapes for forward-compatibility.

Configuration

GOLDRUSH_API_KEY=your_key_here  # optional — action is inactive without it

Files changed

File Change
src/actions/getTokenInfo.ts New action + extractTokenQuery helper
src/actions/__tests__/getTokenInfo.test.ts 17 unit tests
src/index.ts Register action + re-export

Test plan

  • validate() returns false when no API key
  • Token name extracted from "what is Pepe?"
  • Contract address extracted from "look up 0x698..."
  • Swap intent "swap 1 ETH for PEPE" extracts "PEPE"
  • Returns false gracefully when GoldRush returns no results
  • Returns at most 3 results
  • topResult in callback content matches first search result
  • Handles both wrapped and flat API response shapes
  • Returns false gracefully on network error
  • Returns false gracefully on HTTP 500

🤖 Generated with Claude Code

Greptile Summary

This PR adds GoldRush integration across three areas: a new GET_TOKEN_INFO action for token search/lookup, pre-transfer/swap spam detection via goldrush-enhanced-spam-lists, and optional multi-chain token balance enrichment in the wallet provider. All features are gated behind the optional GOLDRUSH_API_KEY setting and include proper error handling with fail-safe patterns.

  • New GET_TOKEN_INFO action (src/actions/getTokenInfo.ts): Resolves token names/symbols/addresses via the GoldRush REST search API, enabling natural language swap workflows (e.g., "swap 1 ETH for Pepe"). Includes extractTokenQuery helper for NLP extraction. Minor display bug: $N/A shown when market cap is unavailable.
  • Spam check utility (src/utils/spamCheck.ts): Uses @covalenthq/goldrush-enhanced-spam-lists with a two-tier check (HIGH blocks, MEDIUM warns, errors fail-open). Integrated into swap.ts and transfer.ts. Chain identifier strings for Optimism and Polygon may not match the package's expected Networks enum values, potentially causing silent fail-open on those chains.
  • Wallet provider enrichment (src/providers/wallet.ts): Appends multi-chain token holdings (with USD values) to the agent context when GOLDRUSH_API_KEY is set, using the official @covalenthq/client-sdk.
  • Test coverage: 17 unit tests for the new action and comprehensive tests for the spam check utility, covering all risk levels and edge cases.

Confidence Score: 3/5

  • PR is mostly safe to merge but has a display bug and potentially incorrect chain identifiers that could silently disable spam checks on Optimism and Polygon.
  • The new action is well-structured with good error handling and test coverage. However, two issues lower confidence: (1) the $N/A display bug in market cap formatting is a definite rendering issue, and (2) the spam check chain mapping uses raw strings (op-mainnet, pol-mainnet) that likely don't match the Networks enum expected by the spam-lists package, which would silently disable spam protection on Optimism and Polygon (fail-open by design, so no crash).
  • src/actions/getTokenInfo.ts (display bug with $N/A) and src/utils/spamCheck.ts (chain identifier mismatch may disable spam checks on Optimism and Polygon)

Important Files Changed

Filename Overview
src/actions/getTokenInfo.ts New GET_TOKEN_INFO action with GoldRush REST search API integration. Display bug: $N/A shown when market cap is unavailable due to $ prefix in template literal combined with formatMcap returning 'N/A'.
src/utils/spamCheck.ts New spam check utility using goldrush-enhanced-spam-lists. Chain mapping uses raw strings (op-mainnet, pol-mainnet) instead of the Networks enum, and values differ from GoldRush's standard naming, which may cause spam checks on Optimism/Polygon to silently fail-open.
src/providers/wallet.ts Added optional GoldRush multi-chain token balance enrichment. Well-structured with proper error handling, fail-safe pattern, and uses the official GoldRush SDK. Creates a new GoldRushClient on each invocation rather than caching it.
src/actions/swap.ts Added optional pre-swap spam check using checkTokenSpam. Properly gated behind API key availability and correctly skips native token (zero address). Throws on HIGH risk, warns on MEDIUM.
src/actions/transfer.ts Added optional pre-transfer spam check for ERC20 tokens. Properly validates token address format before checking. Same pattern as swap.ts spam integration.
src/index.ts Registers the new getTokenInfoAction in the plugin's actions array and adds re-export. Clean, minimal change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["User: 'swap 1 ETH for Pepe'"] --> B[GET_TOKEN_INFO Action]
    B --> C{extractTokenQuery}
    C -->|"query: 'PEPE'"| D[GoldRush REST Search API]
    D --> E{Results found?}
    E -->|Yes| F[Format & return token info\ncontract, chain, price, mcap]
    E -->|No| G[Return 'No token found']
    F --> H[topResult injected into context]
    H --> I[EVM_SWAP_TOKENS Action]
    I --> J{GOLDRUSH_API_KEY set?}
    J -->|Yes| K[checkTokenSpam\nvia goldrush-enhanced-spam-lists]
    J -->|No| L[Skip spam check]
    K --> M{Spam risk?}
    M -->|HIGH| N[Block swap]
    M -->|MEDIUM| O[Warn & proceed]
    M -->|LOW/UNKNOWN| P[Proceed with swap]
    L --> P
    O --> P
    P --> Q[Execute swap via LiFi/Bebop]
Loading

Last reviewed commit: 9cf2e09

Greptile also left 2 inline comments on this PR.

(4/5) You can add custom instructions or style guidelines for the agent here!

dinxsh and others added 3 commits March 16, 2026 04:27
…hment

Fixes elizaos-plugins#15

Extends WalletProvider to optionally fetch full token balances across
all configured chains via GoldRush API when GOLDRUSH_API_KEY is set.

Falls back to existing behavior if key is not present — zero breaking changes.

Why GoldRush:
- Single API covers 100+ EVM chains
- Returns USD values, spam filtering, and decoded token metadata
- Parallel fetching across chains in one provider call

Configuration:
  GOLDRUSH_API_KEY=your_key_here  # optional

Without key: existing behavior unchanged
With key: agent context includes full multi-chain token portfolio

Tested on: eth-mainnet, base-mainnet, arbitrum-mainnet, matic-mainnet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds pre-transfer and pre-swap spam validation using GoldRush Enhanced
Spam Lists, protecting agents from interacting with known rug tokens.

- HIGH confidence spam (Confidence.YES): blocks transaction with a clear error
- MEDIUM confidence spam (Confidence.MAYBE): warns via elizaLogger, allows transaction
- Fully optional: requires GOLDRUSH_API_KEY, fails open if unavailable or unsupported chain
- Zero breaking changes to existing transfer/swap behavior

New file: src/utils/spamCheck.ts
  - checkTokenSpam(tokenAddress, chainName, apiKey) → SpamCheckResult
  - Maps viem chain names → goldrush-enhanced-spam-lists network identifiers
  - Skips native tokens (zero address / "native") automatically
  - Fail-open: any error in the spam check allows the transaction through

Modified: src/actions/transfer.ts
  - Runs checkTokenSpam on params.token if it is an ERC20 address
  - Blocks HIGH risk; logs warn for MEDIUM risk

Modified: src/actions/swap.ts
  - Runs checkTokenSpam on the resolved destination token address
  - Blocks HIGH risk; logs warn for MEDIUM risk

New file: src/tests/spamCheck.test.ts
  - 13 vitest unit tests covering all behavior rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new GET_TOKEN_INFO action that resolves token names and symbols
to contract addresses using the GoldRush REST search API.

Solves the most common natural language swap failure:
  User: "swap 1 ETH for Pepe"
  Before: agent fails — doesn't know Pepe's contract address
  After: agent calls GET_TOKEN_INFO → finds contract → calls SWAP

Supports:
  - Token name: "Pepe", "Chainlink", "Wrapped Bitcoin"
  - Token symbol: "PEPE", "LINK", "WBTC"
  - Contract address: "0x698..." (pass-through with metadata)
  - Swap intent: "swap 1 ETH for PEPE"

Returns top 3 matches with chain, contract, price (with 24h change),
and market cap. Results are injected into agent context as structured
content so subsequent swap/transfer actions can use topResult directly.

Implementation notes:
  - The GoldRush SDK's BaseService has no search method; the action calls
    GET https://api.covalenthq.com/v1/search/ directly with Bearer auth
  - Handles both { result_type, item } and flat response shapes
  - Fully optional: validate() returns false when GOLDRUSH_API_KEY is absent
  - Zero changes to existing actions

New files:
  src/actions/getTokenInfo.ts       — action + extractTokenQuery helper
  src/actions/__tests__/getTokenInfo.test.ts — 17 vitest unit tests

Modified:
  src/index.ts — registered getTokenInfoAction, exported from package

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Warning

Rate limit exceeded

@dinxsh has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 57 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ec59e826-9ca8-4add-943b-0bbd02d67123

📥 Commits

Reviewing files that changed from the base of the PR and between a423863 and 9cf2e09.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • README.md
  • package.json
  • src/actions/__tests__/getTokenInfo.test.ts
  • src/actions/getTokenInfo.ts
  • src/actions/swap.ts
  • src/actions/transfer.ts
  • src/index.ts
  • src/providers/wallet.ts
  • src/tests/spamCheck.test.ts
  • src/utils/spamCheck.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.yml configuration file to your project to enable OpenGrep analysis.

` Chain: ${token.chain_name ?? 'unknown'}\n` +
` Contract: ${token.contract_address}\n` +
` Price: ${price}${change}\n` +
` Market Cap: $${formatMcap(token.market_cap_usd)}`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

$N/A displayed when market cap is unavailable

When formatMcap returns 'N/A' (for null, undefined, or 0 market cap), this template literal produces Market Cap: $N/A, which is a display bug. The $ prefix should only appear for numeric values.

Suggested change
` Market Cap: $${formatMcap(token.market_cap_usd)}`
` Market Cap: ${formatMcap(token.market_cap_usd)}`

And update formatMcap to include the $ prefix for numeric cases:

const formatMcap = (mcap: number | null | undefined): string => {
  if (mcap == null || mcap === 0) return 'N/A';
  if (mcap >= 1e9) return `$${(mcap / 1e9).toFixed(1)}B`;
  if (mcap >= 1e6) return `$${(mcap / 1e6).toFixed(1)}M`;
  if (mcap >= 1e3) return `$${(mcap / 1e3).toFixed(1)}K`;
  return `$${mcap.toFixed(0)}`;
};

Comment on lines +14 to +21
const SPAM_CHAIN_MAP: Record<string, string> = {
mainnet: 'eth-mainnet',
base: 'base-mainnet',
optimism: 'op-mainnet',
polygon: 'pol-mainnet',
bsc: 'bsc-mainnet',
gnosis: 'gnosis-mainnet',
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Spam chain identifiers may not match the package's Networks enum

The official GoldRush docs show that isERC20Spam should be called with Networks.POLYGON_MAINNET, Networks.ETHEREUM_MAINNET, etc. (from the Networks enum exported by the package). This code passes raw strings instead. Two values are notably inconsistent with GoldRush's standard chain naming:

  • optimism: 'op-mainnet' — GoldRush uses optimism-mainnet everywhere else (including CHAIN_MAP in wallet.ts)
  • polygon: 'pol-mainnet' — GoldRush uses matic-mainnet everywhere else (including CHAIN_MAP in wallet.ts)

Since errors fail-open, this won't crash — but spam checks on Optimism and Polygon will silently return UNKNOWN instead of actually checking the token.

Consider importing and using the Networks enum directly:

import { Confidence, Networks, isERC20Spam } from '@covalenthq/goldrush-enhanced-spam-lists';

const SPAM_CHAIN_MAP: Record<string, string> = {
  mainnet: Networks.ETHEREUM_MAINNET,
  base: Networks.BASE_MAINNET,
  optimism: Networks.OPTIMISM_MAINNET,
  polygon: Networks.POLYGON_MAINNET,
  bsc: Networks.BSC_MAINNET,
  gnosis: Networks.GNOSIS_MAINNET,
};

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