Files
explorer-monorepo/frontend/src/services/api/cwRegistry.ts
defiQUG b87ebee6a1
Some checks failed
Deploy Explorer Live / deploy (push) Failing after 20s
Validate Explorer / frontend (push) Failing after 24s
Validate Explorer / smoke-e2e (push) Has been skipped
feat(explorer): dual-chain wallet metadata, native coin pricing, and UI refresh.
Add Chain 138 wallet network metadata and stats coin-price enrichment; sync frontend explorer SPA, command center, and address/token pages with backend config.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 16:16:17 -07:00

90 lines
2.6 KiB
TypeScript

import { getTokenAggregationApiBase } from '@/services/api/tokenAggregation'
export interface WrappedTransportTokenRow {
chainId: number
chainName: string
symbol: string
address: string
assetClass?: string
familyKey?: string
}
export interface CwRegistryChainRow {
chainId: number
chainIdText?: string
name: string
tokens: Array<{
symbol: string
address: string
assetClass?: string
familyKey?: string
}>
}
export interface CwRegistryResponse {
generatedAt: string
source: string
complete: boolean
chains: CwRegistryChainRow[]
}
export function externalChainExplorerUrl(chainId: number, address: string): string | undefined {
const normalized = address.trim()
if (!/^0x[a-fA-F0-9]{40}$/.test(normalized)) return undefined
switch (chainId) {
case 138:
return `/tokens/${normalized}`
case 1:
return `https://etherscan.io/token/${normalized}`
case 56:
return `https://bscscan.com/token/${normalized}`
case 137:
return `https://polygonscan.com/token/${normalized}`
case 100:
return `https://gnosisscan.io/token/${normalized}`
case 10:
return `https://optimistic.etherscan.io/token/${normalized}`
case 42161:
return `https://arbiscan.io/token/${normalized}`
case 8453:
return `https://basescan.org/token/${normalized}`
case 43114:
return `https://snowtrace.io/token/${normalized}`
case 25:
return `https://cronoscan.com/token/${normalized}`
case 42220:
return `https://celoscan.io/token/${normalized}`
case 1111:
return `https://scan.wemix.com/token/${normalized}`
case 651940:
return `https://alltra.global/address/${normalized}`
default:
return undefined
}
}
export async function fetchCwRegistry(): Promise<CwRegistryChainRow[]> {
const response = await fetch(`${getTokenAggregationApiBase()}/report/cw-registry`, { cache: 'no-store' })
if (!response.ok) return []
const body = (await response.json()) as CwRegistryResponse
return Array.isArray(body.chains) ? body.chains : []
}
export function flattenCwRegistry(chains: CwRegistryChainRow[]): WrappedTransportTokenRow[] {
const rows: WrappedTransportTokenRow[] = []
for (const chain of chains) {
for (const token of chain.tokens ?? []) {
if (!token.address?.startsWith('0x')) continue
rows.push({
chainId: chain.chainId,
chainName: chain.name || `Chain ${chain.chainId}`,
symbol: token.symbol,
address: token.address,
assetClass: token.assetClass,
familyKey: token.familyKey,
})
}
}
return rows
}