Skip to content

Add token info endpoints#114

Open
peachbits wants to merge 7 commits intomasterfrom
token-info
Open

Add token info endpoints#114
peachbits wants to merge 7 commits intomasterfrom
token-info

Conversation

@peachbits
Copy link
Copy Markdown
Collaborator

@peachbits peachbits commented Aug 26, 2025

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

#113

Description

none

Note

Medium Risk
Adds new public endpoints plus an hourly background job that writes a new CouchDB database and makes external RPC/HTTP calls (Coingecko + Solana), so failures or data shape changes could impact availability and token results.

Overview
Adds a new token metadata pipeline and public API: an hourly Coingecko engine now builds/updates rates_tokens docs (rank, symbol/name, decimals, contract address, and chain-specific networkLocation) and exposes them via new GET endpoints /_v1/getToken, /_v1/findTokens, and /_v1/listTokens (with optional pluginIds filtering and basic paging/validation).

This introduces a new CouchDB database rates_tokens with Mango indexes, new settings templates for networkLocationTypes and tokenOverrides, and Solana/Ripple-specific networkLocation parsing (including Solana RPC lookups via @solana/web3.js). Coinrank paging is also made dynamic (stop when the page is not full), and Coingecko market parsing now tolerates market_cap_rank: null.

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

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 3 potential issues.

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

Comment thread bin/testTokenEndpoints.ts
item.displayName === 'Tether' &&
item.multiplier === 6 &&
item.chainPluginId === 'ethereum' &&
item.tokenId === 'dac17f958d2ee523a2206206994597c13d831ec7'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Test checks nonexistent multiplier field instead of decimals

Medium Severity

The test casts the response item to a type with multiplier and checks item.multiplier === 6, but the EdgeTokenInfo type returned by the API has a field named decimals, not multiplier. Since multiplier doesn't exist on the response object, item.multiplier is always undefined, and undefined === 6 is always false, causing this test to always fail regardless of the actual API response.

Fix in Cursor Fix in Web

const crosschainDocument = await dbSettings.get('crosschain:automated')
const crosschain = asCrossChainDoc(crosschainDocument).doc

const coinranksStr = await getAsync(`${REDIS_COINRANK_KEY_PREFIX}_iso: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.

Hardcoded Redis key ignores configurable defaultFiatCode

Medium Severity

updateTokenInfos hardcodes _iso:USD in the Redis key, while coinrankEngine writes using _${defaultFiatCode} from config. The existing pattern in exchangeRateRouter.ts also reads via the config value. If defaultFiatCode is ever changed from its default iso:USD, this function would silently read from a nonexistent key and return early, causing token info updates to stop without any error.

Fix in Cursor Fix in Web

Comment thread src/v3/getTokenInfo.ts
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ error: 'Page size must be between 10 and 100' })
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NaN from parseInt bypasses all validation checks

Low Severity

parseInt(pageStr) and parseInt(pageSizeStr) return NaN for non-numeric input like "abc". All subsequent validation comparisons (NaN < 0, NaN > 100, NaN < 10) evaluate to false, so NaN passes through all guards and gets forwarded to CouchDB as skip and limit values, resulting in an unhelpful error message from the catch block.

Fix in Cursor Fix in Web

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