feat(bridge): new token management#361
Open
chrstph-dvx wants to merge 1 commit into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
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'> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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)).
route.provider = 'cctp' | 'canonical' | 'lifi'. There's no guessing anymore (useIsCctpTransfer, useIsOftV2Transfer, useIsCanonicalTransfer, LiFi validation).Steps to test