Skip to content

feat(security): add GoldRush pre-transfer spam detection#27

Open
dinxsh wants to merge 2 commits intoelizaos-plugins:1.xfrom
dinxsh:feat/goldrush-spam-detection
Open

feat(security): add GoldRush pre-transfer spam detection#27
dinxsh wants to merge 2 commits intoelizaos-plugins:1.xfrom
dinxsh:feat/goldrush-spam-detection

Conversation

@dinxsh
Copy link
Copy Markdown

@dinxsh dinxsh commented Mar 15, 2026

Closes #15

Summary

  • Adds src/utils/spamCheck.ts — a reusable checkTokenSpam() utility backed by @covalenthq/goldrush-enhanced-spam-lists
  • Hooks into TransferAction.transfer() to block/warn on spam ERC20 tokens
  • Hooks into SwapAction.swap() to block/warn on spam destination tokens
  • Adds 13 vitest unit tests covering all behavior rules

Behavior

Spam confidence Action
Confidence.YES (HIGH) Throws — transaction blocked with descriptive error
Confidence.MAYBE (MEDIUM) elizaLogger.warn — transaction proceeds
No API key / unsupported chain / check failed Passes through — fail open
Native token (zero address / "native") Skipped entirely

Configuration

GOLDRUSH_API_KEY=your_key_here  # optional — feature is inactive without it

Supported chains for spam detection

eth-mainnet, base-mainnet, op-mainnet, pol-mainnet, bsc-mainnet, gnosis-mainnet

Tokens on other chains pass through unchanged.

Files changed

File Change
src/utils/spamCheck.ts New — checkTokenSpam() utility
src/tests/spamCheck.test.ts New — 13 unit tests
src/actions/transfer.ts Hook spam check on params.token
src/actions/swap.ts Hook spam check on resolved toToken
package.json / bun.lock Add @covalenthq/goldrush-enhanced-spam-lists

Test plan

  • HIGH confidence spam blocks transfer (test: "blocks transfer when token is HIGH confidence spam")
  • MEDIUM confidence spam logs warning but doesn't block (test: "warns but does not block when token is MAYBE spam")
  • Missing API key allows transfer through (test: "returns UNKNOWN when API key is missing")
  • Native token skips spam check (test: "returns UNKNOWN for native token zero address")
  • Failed spam check API allows transfer through (test: "returns UNKNOWN and does not block when the spam list API throws")
  • Unsupported chain allows transfer through (test: "returns UNKNOWN for unsupported chain without calling spam list")

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added optional token spam detection for swaps and transfers—blocking high-risk tokens and warning on medium-risk ones
    • Added multi-chain balance retrieval and wallet enrichment capability
  • Documentation

    • Added configuration guidance for enabling enhanced token security features via an optional API key
  • Tests

    • Added comprehensive test suite for spam detection functionality

Greptile Summary

This PR adds two GoldRush-powered features to the EVM plugin: (1) a pre-transfer/pre-swap spam detection gate using @covalenthq/goldrush-enhanced-spam-lists that blocks HIGH-confidence spam tokens and warns on MEDIUM, and (2) multi-chain token balance enrichment in the wallet provider using @covalenthq/client-sdk. Both features are opt-in via the GOLDRUSH_API_KEY env var and fail open gracefully.

  • Spam detection (spamCheck.ts): Clean utility with well-defined risk levels (HIGH blocks, MEDIUM warns, UNKNOWN passes through). Integrated into both TransferAction.transfer() and SwapAction.swap(). Covers 6 chains.
  • Balance enrichment (wallet.ts): Adds GoldRushClient usage to append token holdings with USD values to the wallet provider output. However, a new GoldRushClient is instantiated on every provider call — should be cached.
  • Missing agentConfig entry: GOLDRUSH_API_KEY is not listed in package.json's agentConfig.pluginParameters, inconsistent with all other env vars in this plugin.
  • Tests: 13 vitest unit tests cover all spam check behavior rules comprehensively.

Confidence Score: 3/5

  • Generally safe to merge — all new behavior is opt-in behind GOLDRUSH_API_KEY — but has a config gap and a performance concern worth addressing.
  • Score of 3 reflects: the core spam detection logic is sound with proper fail-open behavior and good test coverage, but the missing agentConfig entry means the feature may not be discoverable by users, and the GoldRushClient instantiation on every provider call is a performance concern for production use.
  • src/providers/wallet.ts (GoldRushClient instantiated per-call), package.json (missing agentConfig entry for GOLDRUSH_API_KEY)

Important Files Changed

Filename Overview
src/utils/spamCheck.ts New utility: well-structured spam check with proper fail-open behavior. Minor: apiKey param is unused by the actual spam list API.
src/actions/transfer.ts Adds pre-transfer spam check gate. Clean integration — blocks HIGH spam, warns on MEDIUM, fails open gracefully.
src/actions/swap.ts Adds pre-swap spam check on destination token. Correctly placed before slippage retry loop. Only checks toToken, not fromToken.
src/providers/wallet.ts Adds GoldRush balance enrichment provider. Creates new GoldRushClient on every provider call which is inefficient. Unconditional import adds bundle size.
src/tests/spamCheck.test.ts 13 well-structured unit tests covering all spam check behavior rules including skip conditions, HIGH/MEDIUM/LOW risk, and fail-open.
package.json Adds two new dependencies. Missing GOLDRUSH_API_KEY in agentConfig.pluginParameters — inconsistent with how all other env vars are documented.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Transfer/Swap Action called] --> B{GOLDRUSH_API_KEY set?}
    B -- No --> G[Proceed with transaction]
    B -- Yes --> C{Token is native/zero address?}
    C -- Yes --> G
    C -- No --> D[checkTokenSpam]
    D --> E{Spam confidence?}
    E -- HIGH --> F[Throw Error - Transaction Blocked]
    E -- MEDIUM --> H[elizaLogger.warn] --> G
    E -- LOW/UNKNOWN --> G
    E -- API Error --> G
    
    I[Wallet Provider get] --> J{GOLDRUSH_API_KEY set?}
    J -- No --> K[Return native balances only]
    J -- Yes --> L[GoldRushClient.BalanceService] --> M[Append token holdings to result]
    M --> K
Loading

Last reviewed commit: 19cbf70

Greptile also left 3 inline comments on this PR.

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

dinxsh and others added 2 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>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Walkthrough

This PR integrates GoldRush spam detection and multi-chain balance tracking into the EVM plugin. It adds optional token spam validation to swap and transfer actions, introduces multi-chain balance retrieval capabilities, and includes comprehensive test coverage for the new spam-checking utility.

Changes

Cohort / File(s) Summary
Documentation & Dependencies
README.md, package.json
Added GOLDRUSH_API_KEY environment variable documentation and integrated two GoldRush dependencies (@covalenthq/client-sdk and @covalenthq/goldrush-enhanced-spam-lists).
Spam Detection Infrastructure
src/utils/spamCheck.ts, src/tests/spamCheck.test.ts
Created checkTokenSpam utility with SpamRisk type and SpamCheckResult interface; supports HIGH/MEDIUM/LOW/UNKNOWN risk levels with fail-open error handling. Comprehensive test suite covers all risk paths, network mapping, and edge cases.
Action Enhancements
src/actions/swap.ts, src/actions/transfer.ts
Integrated optional pre-operation spam checks: blocks HIGH-risk tokens, logs warnings for MEDIUM-risk tokens, and gracefully skips checks when GOLDRUSH_API_KEY is unavailable.
Provider Enrichment
src/providers/wallet.ts
Added GoldRush multi-chain balance retrieval via CHAIN_MAP translation and getMultiChainBalances function; augments wallet data with per-chain holdings and total USD value when API key is configured.

Sequence Diagrams

sequenceDiagram
    participant User
    participant Action as Swap/Transfer Action
    participant SpamUtil as checkTokenSpam Utility
    participant GoldRush as GoldRush API
    participant Chain as Blockchain

    User->>Action: Initiate swap/transfer
    Action->>SpamUtil: checkTokenSpam(token, chain, apiKey)
    
    alt API Key Missing or Native Token
        SpamUtil-->>Action: UNKNOWN risk, no block
    else Valid ERC20 Token
        SpamUtil->>GoldRush: isERC20Spam(Confidence.YES)
        GoldRush-->>SpamUtil: true
        SpamUtil-->>Action: HIGH risk, shouldBlock=true
        Action-->>User: ❌ Blocked - HIGH spam risk
    else Not HIGH Risk
        SpamUtil->>GoldRush: isERC20Spam(Confidence.MAYBE)
        GoldRush-->>SpamUtil: true
        SpamUtil-->>Action: MEDIUM risk, shouldBlock=false
        Action->>Action: ⚠️ Log warning
        Action->>Chain: Proceed with operation
        Chain-->>User: ✓ Completed
    else Clean Token
        SpamUtil->>GoldRush: Confidence checks return false
        SpamUtil-->>Action: LOW risk, proceed
        Action->>Chain: Execute operation
        Chain-->>User: ✓ Completed
    end
Loading
sequenceDiagram
    participant Client
    participant WalletProvider as evmWalletProvider
    participant EVM as EVM Service
    participant GoldRush as GoldRush Client
    
    Client->>WalletProvider: get(walletAddress)
    
    alt Cached Data Exists
        WalletProvider->>WalletProvider: Build initial balance text
        
        alt API Key Configured
            WalletProvider->>GoldRush: getMultiChainBalances(address, key)
            GoldRush-->>WalletProvider: { chains: {balances, USD value} }
            WalletProvider->>WalletProvider: buildGoldRushText(results)
            WalletProvider->>WalletProvider: Augment text with multi-chain data
        else No API Key
            WalletProvider->>WalletProvider: Use base balance text
        end
        
        WalletProvider-->>Client: ProviderResult(text, data, values)
    else No Cached Data
        WalletProvider->>EVM: Direct balance fetch
        EVM-->>WalletProvider: Balance data
        WalletProvider-->>Client: ProviderResult
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With whiskers twitching, I hop through the chain,
GoldRush spam checks now filter the rain,
Multi-chain balances bloom, crystal and bright,
Each token assessed from LOW to HIGH might,
A safer path forward, no scams in our sight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds GoldRush spam detection and wallet enrichment features, but linked issue #15 requests basic plugin-evm awareness in Eliza agents, which is unrelated to spam detection. Verify the PR is addressing the correct issue. If spam detection is intentional, link it to appropriate security-related issues or create new issues tracking these features separately.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive The PR includes spam detection integration in swap.ts and transfer.ts, plus multi-chain wallet enrichment in wallet.ts. While spam detection aligns with security objectives, the wallet enrichment appears to extend beyond pre-transfer spam checks. Clarify whether multi-chain balance enrichment in wallet provider is in scope for this PR or should be separated into a distinct feature branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(security): add GoldRush pre-transfer spam detection' accurately summarizes the main security feature added: spam detection for transfers using GoldRush.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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.

Comment on lines +63 to +64
const getMultiChainBalances = async (address: string, chains: string[], apiKey: string) => {
const client = new GoldRushClient(apiKey);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New GoldRushClient created on every call

getMultiChainBalances is called from buildGoldRushText, which runs inside evmWalletProvider.get() — a provider that executes on every agent message cycle. Each invocation constructs a new GoldRushClient(apiKey), which likely sets up internal HTTP connection state. Consider hoisting the client into a module-level singleton (or a lazy-initialized cache keyed by apiKey) to avoid repeated instantiation on every provider call.

Suggested change
const getMultiChainBalances = async (address: string, chains: string[], apiKey: string) => {
const client = new GoldRushClient(apiKey);
const getMultiChainBalances = async (address: string, chains: string[], client: GoldRushClient) => {

Comment on lines 24 to +25
"dependencies": {
"@covalenthq/client-sdk": "^3.0.5",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing GOLDRUSH_API_KEY in agentConfig

The agentConfig.pluginParameters section documents every other environment variable, but GOLDRUSH_API_KEY is absent. This means ElizaOS agent auto-configuration won't surface this optional setting to users. Add an entry like:

"GOLDRUSH_API_KEY": {
  "type": "string",
  "description": "Optional GoldRush API key to enable multi-chain token balance enrichment and pre-transfer spam detection.",
  "required": false,
  "sensitive": true
}

Comment on lines +34 to +38
export async function checkTokenSpam(
tokenAddress: string,
chainName: string,
apiKey: string
): Promise<SpamCheckResult> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

apiKey accepted but never passed to isERC20Spam

The apiKey parameter is used only as a feature gate (line 40), but is never forwarded to isERC20Spam. The @covalenthq/goldrush-enhanced-spam-lists package is a free public good that doesn't require authentication — so this works. However, gating the spam check on GOLDRUSH_API_KEY means spam detection is silently disabled when users only want balance enrichment disabled but might still benefit from free spam protection. Consider either:

  1. Documenting that the spam check is free and doesn't need the key, or
  2. Using a separate feature flag (e.g., EVM_SPAM_CHECK_ENABLED) so spam protection can work independently of the paid GoldRush balance API.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/providers/wallet.ts (1)

63-91: Consider adding type safety for GoldRush response items.

The item: any type in the reduce callback (line 81) loses type safety. If the GoldRush SDK provides types for balance items, consider using them to catch potential issues at compile time.

♻️ Suggested improvement
-        totalUSD: (resp.data?.items ?? []).reduce(
-          (sum: number, item: any) => sum + (item.quote ?? 0),
-          0
-        ),
+        totalUSD: (resp.data?.items ?? []).reduce(
+          (sum, item) => sum + (item.quote ?? 0),
+          0
+        ),

If the SDK exports types like BalanceItem, use those for the response data.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/providers/wallet.ts` around lines 63 - 91, The reduce callback in
getMultiChainBalances uses item: any which loses type safety; import and use the
SDK's BalanceItem (or equivalent) type for the response and annotate the
response and intermediate values (e.g., the return shape of
BalanceService.getTokenBalancesForWalletAddress, resp.data.items, and the
Promise result) so the reducer becomes (item: BalanceItem) and TypeScript can
check item.quote, item.symbol, etc.; update types on the mapped return object
(chain, items, totalUSD) and any Promise generics to propagate the correct types
through getMultiChainBalances, CHAIN_MAP usage, and the Promise.allSettled
mapping.
src/utils/spamCheck.ts (1)

60-81: Two sequential API calls for non-HIGH-risk tokens.

The current implementation makes two separate isERC20Spam calls for tokens that aren't HIGH risk. Consider whether the library offers a way to get the confidence level in a single call, or document that this is intentional for accuracy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/spamCheck.ts` around lines 60 - 81, The code currently calls
isERC20Spam twice (once with Confidence.YES and once with Confidence.MAYBE);
replace this with a single call that returns the confidence level (or use the
library's method that returns a Confidence enum/value) and switch on that result
to return the appropriate object, referencing isERC20Spam (or the library method
that provides confidence) and the Confidence enum, tokenAddress and spamNetwork;
if the library doesn't provide a single-call confidence result, add a comment
documenting why two calls are required and why we chose accuracy over an extra
API hit.
package.json (1)

25-26: Consider pinning @covalenthq/goldrush-enhanced-spam-lists to an exact version.

The @covalenthq/goldrush-enhanced-spam-lists package is at version 0.0.1 and is the only version released. While using ^0.0.1 allows patch updates under semver, pinning to exactly 0.0.1 is a best practice for pre-1.0 packages to avoid unexpected breakages if future minor versions are released with breaking changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 25 - 26, The package entry for
"@covalenthq/goldrush-enhanced-spam-lists" uses a caret range ("^0.0.1"); change
it to an exact pinned version ("0.0.1") in package.json to avoid automatic
updates for this pre-1.0 package—update the dependency value for
"@covalenthq/goldrush-enhanced-spam-lists" from "^0.0.1" to "0.0.1" and run your
package manager to lock the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/providers/wallet.ts`:
- Around line 106-120: The loop over chainResults may call BigInt(item.balance)
with malformed values; update the inner loop (referencing chainResults,
item.balance, formatUnits, lines, totalPortfolioUSD) to defensively validate
that item.balance is a valid integer string before converting: skip or coerce
non-string/null/undefined values and guard against invalid formats (e.g., use a
regex like /^[+-]?\d+$/ or attempt parsing inside a try/catch), only call BigInt
and formatUnits when validation succeeds, and otherwise continue the loop
(optionally log or treat quote as zero) so no runtime exception is thrown.
- Around line 38-61: Update the incorrect GoldRush chain identifiers in the
SPAM_CHAIN_MAP constant in spamCheck.ts so they match the canonical values used
in wallet.ts (replace 'op-mainnet' with 'optimism-mainnet' and 'pol-mainnet'
with 'matic-mainnet'); then update the expectations in spamCheck.test.ts (the
assertions around lines validating SPAM_CHAIN_MAP) to expect 'optimism-mainnet'
and 'matic-mainnet' instead of the old values so the spam list checks and tests
align with GoldRush API identifiers.

---

Nitpick comments:
In `@package.json`:
- Around line 25-26: The package entry for
"@covalenthq/goldrush-enhanced-spam-lists" uses a caret range ("^0.0.1"); change
it to an exact pinned version ("0.0.1") in package.json to avoid automatic
updates for this pre-1.0 package—update the dependency value for
"@covalenthq/goldrush-enhanced-spam-lists" from "^0.0.1" to "0.0.1" and run your
package manager to lock the change.

In `@src/providers/wallet.ts`:
- Around line 63-91: The reduce callback in getMultiChainBalances uses item: any
which loses type safety; import and use the SDK's BalanceItem (or equivalent)
type for the response and annotate the response and intermediate values (e.g.,
the return shape of BalanceService.getTokenBalancesForWalletAddress,
resp.data.items, and the Promise result) so the reducer becomes (item:
BalanceItem) and TypeScript can check item.quote, item.symbol, etc.; update
types on the mapped return object (chain, items, totalUSD) and any Promise
generics to propagate the correct types through getMultiChainBalances, CHAIN_MAP
usage, and the Promise.allSettled mapping.

In `@src/utils/spamCheck.ts`:
- Around line 60-81: The code currently calls isERC20Spam twice (once with
Confidence.YES and once with Confidence.MAYBE); replace this with a single call
that returns the confidence level (or use the library's method that returns a
Confidence enum/value) and switch on that result to return the appropriate
object, referencing isERC20Spam (or the library method that provides confidence)
and the Confidence enum, tokenAddress and spamNetwork; if the library doesn't
provide a single-call confidence result, add a comment documenting why two calls
are required and why we chose accuracy over an extra API hit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44586ca6-ca3d-4487-8d7b-e40f503502d2

📥 Commits

Reviewing files that changed from the base of the PR and between a423863 and 19cbf70.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • README.md
  • package.json
  • src/actions/swap.ts
  • src/actions/transfer.ts
  • src/providers/wallet.ts
  • src/tests/spamCheck.test.ts
  • src/utils/spamCheck.ts

Comment on lines +38 to +61
// Mapping from viem chain names to GoldRush chain names
const CHAIN_MAP: Record<string, string> = {
mainnet: 'eth-mainnet',
base: 'base-mainnet',
arbitrum: 'arbitrum-mainnet',
optimism: 'optimism-mainnet',
polygon: 'matic-mainnet',
bsc: 'bsc-mainnet',
avalanche: 'avalanche-mainnet',
fantom: 'fantom-mainnet',
gnosis: 'gnosis-mainnet',
celo: 'celo-mainnet',
moonbeam: 'moonbeam-mainnet',
moonriver: 'moonriver-mainnet',
cronos: 'cronos-mainnet',
klaytn: 'klaytn-mainnet',
aurora: 'aurora-mainnet',
linea: 'linea-mainnet',
scroll: 'scroll-mainnet',
mantle: 'mantle-mainnet',
zksync: 'zksync-mainnet',
polygonZkEvm: 'polygon-zkevm-mainnet',
arbitrumNova: 'arbitrum-nova-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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

GoldRush API chain identifiers eth-mainnet op-mainnet optimism-mainnet

💡 Result:

GoldRush API chainName identifiers:

Network GoldRush chainName Numeric chain ID
Ethereum Mainnet eth-mainnet 1 [1]
OP Mainnet (Optimism) optimism-mainnet 10 [2]

op-mainnet is not listed as a GoldRush chainName; for OP Mainnet you should use optimism-mainnet. [3]

Sources: [1] [2] [3]


🏁 Script executed:

# Find and read the spamCheck.ts file
fd -t f "spamCheck" --exec cat -n {} \;

Repository: elizaos-plugins/plugin-evm

Length of output: 10654


🌐 Web query:

GoldRush API Polygon chain identifier matic-mainnet pol-mainnet

💡 Result:

In the GoldRush (Covalent) API, Polygon PoS mainnet’s chain identifier is matic-mainnet (chain ID 137). GoldRush lets you use either the chain name or the numeric chain ID in requests. pol-mainnet is not the Polygon chain name in GoldRush. [1][2]

Example (using chain name): .../v1/matic-mainnet/...
Example (using chain id): .../v1/137/... [1][2]

Sources: [1] [2]


Critical bug: SPAM_CHAIN_MAP in spamCheck.ts uses incorrect GoldRush chain identifiers.

The identifiers in SPAM_CHAIN_MAP (lines 17-18) are invalid for GoldRush API:

  • op-mainnet → should be optimism-mainnet
  • pol-mainnet → should be matic-mainnet

The correct identifiers match those in wallet.ts. This bug will cause spam list checks to fail silently. The tests (spamCheck.test.ts, lines 94-108) also validate these incorrect identifiers.

Update SPAM_CHAIN_MAP and corresponding test expectations to use optimism-mainnet and matic-mainnet.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/providers/wallet.ts` around lines 38 - 61, Update the incorrect GoldRush
chain identifiers in the SPAM_CHAIN_MAP constant in spamCheck.ts so they match
the canonical values used in wallet.ts (replace 'op-mainnet' with
'optimism-mainnet' and 'pol-mainnet' with 'matic-mainnet'); then update the
expectations in spamCheck.test.ts (the assertions around lines validating
SPAM_CHAIN_MAP) to expect 'optimism-mainnet' and 'matic-mainnet' instead of the
old values so the spam list checks and tests align with GoldRush API
identifiers.

Comment on lines +106 to +120
for (const result of chainResults) {
for (const item of result.items) {
if (!item.balance || item.balance === '0') continue;
const symbol = item.contract_ticker_symbol ?? '???';
const decimals = item.contract_decimals ?? 18;
const balance = formatUnits(BigInt(item.balance), decimals);
const formattedBalance = Number(balance).toLocaleString('en-US', {
maximumFractionDigits: 4,
});
const usdValue = item.quote ?? 0;
const formattedUSD = `$${usdValue.toLocaleString('en-US', { maximumFractionDigits: 0 })}`;
lines.push(`${symbol} (${result.chain}): ${formattedBalance} ${symbol} — ${formattedUSD}`);
totalPortfolioUSD += usdValue;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential runtime error if item.balance is not a valid BigInt string.

Line 111 calls BigInt(item.balance) which will throw if balance is not a valid numeric string (e.g., if it's null, undefined, or malformed). The check on line 108 guards against '0' and falsy values but doesn't validate the string format.

🛡️ Suggested defensive fix
       for (const item of result.items) {
         if (!item.balance || item.balance === '0') continue;
+        let balance: string;
+        try {
+          balance = formatUnits(BigInt(item.balance), decimals);
+        } catch {
+          continue; // Skip items with invalid balance format
+        }
         const symbol = item.contract_ticker_symbol ?? '???';
         const decimals = item.contract_decimals ?? 18;
-        const balance = formatUnits(BigInt(item.balance), decimals);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/providers/wallet.ts` around lines 106 - 120, The loop over chainResults
may call BigInt(item.balance) with malformed values; update the inner loop
(referencing chainResults, item.balance, formatUnits, lines, totalPortfolioUSD)
to defensively validate that item.balance is a valid integer string before
converting: skip or coerce non-string/null/undefined values and guard against
invalid formats (e.g., use a regex like /^[+-]?\d+$/ or attempt parsing inside a
try/catch), only call BigInt and formatUnits when validation succeeds, and
otherwise continue the loop (optionally log or treat quote as zero) so no
runtime exception is thrown.

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.

Eliza agent is not aware by plugin evm

1 participant