Skip to content

feat(bridge): new token management#361

Open
chrstph-dvx wants to merge 1 commit into
masterfrom
token-management-poc
Open

feat(bridge): new token management#361
chrstph-dvx wants to merge 1 commit into
masterfrom
token-management-poc

Conversation

@chrstph-dvx

@chrstph-dvx chrstph-dvx commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

A new data model for token list management, replacing the parent-address-keyed bridgeTokens approach. Live demo: pnpm dev → /token-registry-poc (Ethereum ↔ Arbitrum One).

Core idea: two layers, strictly separated. Tokens one one hand (per-chain metadata, keyed by chainId:address, native = zero address). And routes on the other hand (one route per provider, per (sourceToken, destinationToken)).

  • One source token → multiple destination tokens. USDC on Ethereum simultaneously routes to USDC.e (canonical), native USDC (CCTP), and ~1.2k swap targets (LiFi). Multiple source token can also map to one destination token (USDC and USDC.e on ArbitrumOne to USDC on Ethereum).
  • Route are clearly defined from the backend as route.provider = 'cctp' | 'canonical' | 'lifi'. There's no guessing anymore (useIsCctpTransfer, useIsOftV2Transfer, useIsCanonicalTransfer, LiFi validation).
  • A token without a default token on the destination is still allowed, swap destinations are fetched on demand.

Steps to test

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
arbitrum-portal Ready Ready Preview Jun 18, 2026 9:57am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Introduces a new “token registry + routes” architecture (with caching and a PoC UI) to support normalized per-chain token metadata, compact per-pair route artifacts, LiFi swap destinations, and a session-only canonical import flow.

Changes:

  • Added token-registry core types, normalization, hydrated per-pair RegistryView, and selectors for source/destination token lists and route materialization.
  • Implemented server-side generation (canonical + CCTP + LayerZero + LiFi), caching via unstable_cache, and Next.js API routes for tokens/routes/swap-destinations/import.
  • Added a Token Registry PoC page plus a focused Vitest suite (selectors/view/normalize/generation/import + a network-gated measurement harness).

Reviewed changes

Copilot reviewed 23 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/arb-token-bridge-ui/docs/token-registry.md Design doc for token registry, routes, selectors, caching, and migration plan.
packages/app/src/token-registry/types.ts Core token/route/import types + helpers (toTokenId, isNativeToken, etc.).
packages/app/src/token-registry/constants.ts Supported pairs/chains, hardcoded routes/tokens, curated metadata and coinKeys, exclusions.
packages/app/src/token-registry/normalize.ts Token normalization (lowercasing + curated metadata applied at generation time).
packages/app/src/token-registry/view.ts Hydration + per-pair RegistryView assembly (token map, source list, search index, overlay routes).
packages/app/src/token-registry/selectors.ts Selectors for token filtering, route materialization, swap destinations, defaults, and per-destination routing.
packages/app/src/token-registry/server/generate.ts Canonical/LiFi generation logic + cached accessors for tokens/routes/swap destinations.
packages/app/src/token-registry/server/resolveImport.ts Canonical-only import resolver (deposit + withdrawal) using on-chain derivation + metadata reads.
packages/app/src/token-registry/tests/* Unit tests covering types, normalization, view assembly, selectors, generation behavior, import, and measurement harness.
packages/app/src/app/token-registry-poc/TokenRegistryPoc.tsx Client PoC UI (virtualized lists, SWR loading, lazy swap-destinations fetch, import demo).
packages/app/src/app/token-registry-poc/page.tsx PoC page entry (noindex).
packages/app/src/app/api/token-registry/**/route.ts API routes for token registry (tokens/routes/swap-destinations/import).
.claude/settings.local.json Adds a local tool configuration file (should likely not be committed).
.pnpm-store/v11/.pnpm-needs-build-marker Build artifact committed into the repo.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +176 to +179
const token = tokens.get(destinationTokenId);
if (!token) {
return <span className="text-sm text-white/60">→ {truncateAddress(destinationTokenId)}</span>;
}
Comment on lines +321 to +324
async function buildChainTokens(chainId: number): Promise<TokenPayload[]> {
const listTokens = await fetchArbedTokenLists();
const lifiResults = await Promise.all(supportedPairs.map((pair) => generateLifi(pair)));

Comment on lines +328 to +332
- handlers wrap their compute in `unstable_cache` with a tag
(`tokens-42161`, `routes-1-42161`) and a `revalidate` window — long for
token registries (~24h), shorter for LiFi-backed route artifacts (~1h)
- upstream fetches (token lists, LiFi connections API) use
`fetch` with `next: { revalidate }` and are cached independently
Comment on lines +1 to +5
{
"permissions": {
"allow": [
"Bash(rtk grep *)",
"Bash(rtk read *)",
Global registry, sharded per chain:

```
GET /api/tokens/[chainId] → TokenPayload[] // Omit<Token, 'id' | 'chainId'>
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.

2 participants