Skip to content

Add token service#5964

Open
peachbits wants to merge 8 commits intodevelopfrom
matthew/token-info
Open

Add token service#5964
peachbits wants to merge 8 commits intodevelopfrom
matthew/token-info

Conversation

@peachbits
Copy link
Contributor

@peachbits peachbits commented Feb 26, 2026

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Requirements

If you have made any visual changes to the GUI. Make sure you have:

  • Tested on iOS device
  • Tested on Android device
  • Tested on small-screen device (iPod Touch)
  • Tested on large-screen device (tablet)


Note

Medium Risk
Changes core token listing/enabling paths (wallet list, manage tokens, token editing, and post-login migration) to depend on rates-server data, which could impact token availability/performance if server responses or caching behave unexpectedly.

Overview
Adds a new tokenService (plus useServerTokens/useServerTokenSearch hooks) to list/search/fetch tokens from the rates server with caching, and exposes RATES_SERVERS for these calls.

Updates wallet token UX to incorporate server tokens with pagination/search: WalletList and ManageTokensScene now merge server results with existing customTokens, support infinite scroll loaders, and enabling tokens now routes through a new changeEnabledTokenIds helper that fetches unknown tokens and adds them as customTokens before enabling.

Introduces a background post-login migration (migrateEnabledTokensFromServer) to backfill enabled tokens into customTokens, updates custom-token affordances to rely on currencyInfo.customTokenTemplate (not builtinTokens), and revises EditTokenScene autocomplete/conflict checks to use server search + mark user-created tokens (isUserCreated). Misc cleanups include renaming enableTokens to enableTokensWithSpinner, switching getCreateWalletList/helpers from builtinTokens to customTokens, and updating tests/snapshots accordingly.

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

Copy link

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

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

"detect-bundler": "^1.1.0",
"disklet": "^0.5.2",
"edge-core-js": "^2.43.1",
"edge-core-js": "file:../edge-core-js",
Copy link

Choose a reason for hiding this comment

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

Local file path dependency accidentally committed

High Severity

The edge-core-js dependency was changed from a versioned npm package (^2.43.1) to a local file path (file:../edge-core-js). This breaks builds for anyone who doesn't have a sibling edge-core-js checkout and will fail in CI. The resolved version in yarn.lock also downgraded from 2.43.1 to 2.42.0.

Additional Locations (1)

Fix in Cursor Fix in Web


// Create a stable key for the query params to detect changes
const queryKey = React.useMemo(() => {
const pluginIdStr = pluginIds != null ? pluginIds.sort().join(',') : 'all'
Copy link

Choose a reason for hiding this comment

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

In-place sort() mutates caller's pluginIds array

Medium Severity

pluginIds.sort() mutates the input array in place. In useServerTokens, this mutates the caller's memoized array inside a useMemo. In makeListCacheKey and makeSearchCacheKey, it mutates the arrays passed through listTokens/searchTokens. Notably, useServerTokenSearch at line 186 correctly uses [...pluginIds].sort() to avoid this, showing the correct pattern was known.

Additional Locations (2)

Fix in Cursor Fix in Web

tokenId: serverToken.tokenId,
createWalletIds,
networkLocation: edgeToken.networkLocation
})
Copy link

Choose a reason for hiding this comment

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

Server tokens can't be enabled from WalletList modal

High Severity

serverTokenCreateItems are added to the wallet list create rows, but when a user taps one, WalletListCreateRow calls wallet.changeEnabledTokenIds directly. Since the token isn't yet in customTokens, the wallet won't recognize the tokenId. The new changeEnabledTokenIds wrapper in CurrencyWalletHelpers handles this by fetching and adding unknown tokens first, but it's not used here.

Fix in Cursor Fix in Web

toWallet.currencyConfig.builtinTokens[toTokenId] != null) &&
(fromTokenId == null ||
fromWallet.currencyConfig.builtinTokens[fromTokenId] != null),
isBuiltInAsset: false,
Copy link

Choose a reason for hiding this comment

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

Swap analytics isBuiltInAsset hardcoded to false

Medium Severity

isBuiltInAsset is hardcoded to false for all swap success tracking events, losing the ability to distinguish between built-in and custom asset swaps in analytics. Previously, this was computed dynamically based on builtinTokens. A server-based replacement or removing the field entirely would preserve data integrity.

Fix in Cursor Fix in Web

console.log(
`Token migration: Migrated ${pluginId}:${tokenId} (${edgeToken.currencyCode})`
)
}
Copy link

Choose a reason for hiding this comment

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

Unguarded console.log calls in production code

Low Severity

console.log calls at lines 80 and 92 are not guarded behind a debug flag. The guard-debug-logging rule requires no unguarded console.log in production code. These log statements will appear in production builds for every token migration.

Additional Locations (1)

Fix in Cursor Fix in Web

cache.tokens.delete(key)
}
}
}
Copy link

Choose a reason for hiding this comment

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

Exported pruneTokenCache function is never used

Low Severity

pruneTokenCache is exported but never imported or called anywhere in the codebase. Only clearTokenCache is used (called on logout). This is dead code that adds maintenance burden.

Fix in Cursor Fix in Web

sprintf(
lstrings.warning_token_exists_1s,
builtinTokens[matchingBuiltinTokenId].currencyCode
customTokens[matchingBuiltinTokenId].currencyCode
Copy link

Choose a reason for hiding this comment

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

Duplicate token check makes override path unreachable

Medium Severity

The first conflict check (line 187) now searches customTokens and blocks with a warning if the token exists. Previously it searched builtinTokens, and a separate second check (line 201) against customTokens allowed overriding existing custom tokens via changeCustomToken. Now both checks target the same customTokens object, so the first check always blocks before the second is reached. Users who enter a contract address matching a server-migrated token get an "already exists" warning with no way to proceed or override it.

Additional Locations (1)

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