99 UniversalAddress ,
1010} from '@wormhole-foundation/sdk' ;
1111import type { TokenIcon , TokenConfig , WrappedTokenAddresses } from './types' ;
12- import { getWormholeContextV2 } from './index' ;
12+ import config , { getWormholeContextV2 } from './index' ;
1313import { isValidSuiType } from '@wormhole-foundation/sdk-sui' ;
14-
1514import { fetchTokenMetadata } from 'utils/coingecko' ;
1615
1716const TOKEN_CACHE_VERSION = 1 ;
@@ -46,6 +45,16 @@ class TokenIdLazy<C extends Chain = Chain> implements TokenId<C> {
4645 return new TokenIdLazy ( tuple [ 0 ] , tuple [ 1 ] ) ;
4746 }
4847}
48+ type TokenConstructorProps = {
49+ chain : Chain ;
50+ address : string ;
51+ decimals : number ;
52+ symbol : string ;
53+ name ?: string ;
54+ icon ?: TokenIcon | string ;
55+ tokenBridgeOriginalTokenId ?: TokenId ;
56+ coingeckoId ?: string ;
57+ } ;
4958
5059export class Token extends TokenIdLazy {
5160 decimals : number ;
@@ -67,16 +76,16 @@ export class Token extends TokenIdLazy {
6776 // Used when filtering out unknown/unverified tokens
6877 isBuiltin ?: boolean ;
6978
70- constructor (
71- chain : Chain ,
72- address : string ,
73- decimals : number ,
74- symbol : string ,
75- name ?: string ,
76- icon ?: TokenIcon | string ,
77- tokenBridgeOriginalTokenId ?: TokenId ,
78- coingeckoId ?: string ,
79- ) {
79+ constructor ( {
80+ chain,
81+ address,
82+ decimals,
83+ symbol,
84+ name,
85+ icon,
86+ tokenBridgeOriginalTokenId,
87+ coingeckoId,
88+ } : TokenConstructorProps ) {
8089 super ( chain , address ) ;
8190 this . decimals = decimals ;
8291 this . symbol = symbol ;
@@ -158,18 +167,18 @@ export class Token extends TokenIdLazy {
158167 tokenBridgeOriginalTokenId,
159168 coingeckoWebId,
160169 } : TokenJson ) {
161- return new Token (
162- chain as Chain ,
170+ return new Token ( {
171+ chain : chain as Chain ,
163172 address,
164173 decimals,
165174 symbol,
166175 name,
167- icon === '' ? undefined : icon ,
168- tokenBridgeOriginalTokenId
176+ icon : icon === '' ? undefined : icon ,
177+ tokenBridgeOriginalTokenId : tokenBridgeOriginalTokenId
169178 ? tokenIdFromTuple ( tokenBridgeOriginalTokenId )
170179 : undefined ,
171- coingeckoWebId ,
172- ) ;
180+ coingeckoId : coingeckoWebId ,
181+ } ) ;
173182 }
174183}
175184
@@ -389,19 +398,33 @@ export class TokenCache extends TokenMapping<Token> {
389398 // This should be used sparingly/never... use addresses instead.
390399 // Excludes wrapped tokens
391400 findBySymbol ( chain : Chain , symbol : string ) : Token | undefined {
392- let matching = this . getAllForChain ( chain ) . filter (
393- ( t ) => t . symbol . toLowerCase ( ) === symbol . toLowerCase ( ) ,
394- ) ;
401+ const chainOverrides = config . ui ?. tokenNameOverrides ?. [ chain ] ;
402+ const lowerCaseSymbol = symbol . toLowerCase ( ) ;
403+
404+ let matching = this . getAllForChain ( chain ) . filter ( ( t ) => {
405+ const symbolMatch = lowerCaseSymbol === t . symbol . toLowerCase ( ) ;
406+ const overrideMatch =
407+ lowerCaseSymbol ===
408+ chainOverrides ?. [ t . address . toString ( ) ] ?. toLowerCase ( ) ;
409+
410+ return symbolMatch || overrideMatch ;
411+ } ) ;
395412
396413 if ( matching . length > 1 ) {
397414 // Exclude wrapped tokens if there's multiple matches
398- matching = matching . filter ( ( t ) => ! t . isTokenBridgeWrappedToken ) ;
415+ matching = matching . filter ( ( t ) => {
416+ return ! t . isTokenBridgeWrappedToken ;
417+ } ) ;
399418 }
400419
401420 if ( matching . length === 1 ) {
402421 return matching [ 0 ] ;
403422 } else if ( matching . length > 1 ) {
404- // This means there's more than one native token (not wrapped) with this symbol
423+ const gasToken = matching . find ( ( t ) => t . address === 'native' ) ;
424+ // This means there's more than one native token (not wrapped) with this symbol.
425+ // prefer the gas token if there are multiple tokens with the same symbol.
426+ if ( gasToken ) return gasToken ;
427+
405428 console . error ( `Ambiguous token symbol: ${ symbol } ` ) ;
406429 }
407430
@@ -471,16 +494,16 @@ export class TokenCache extends TokenMapping<Token> {
471494 }
472495 }
473496
474- const t = new Token (
475- tokenId . chain ,
476- canonicalAddress ( tokenId ) ,
497+ const t = new Token ( {
498+ chain : tokenId . chain ,
499+ address : canonicalAddress ( tokenId ) ,
477500 decimals,
478501 symbol,
479502 name,
480- image ,
503+ icon : image ,
481504 tokenBridgeOriginalTokenId,
482505 coingeckoId,
483- ) ;
506+ } ) ;
484507
485508 this . add ( t ) ;
486509
@@ -538,16 +561,15 @@ export function buildTokenCache(
538561 cacheKey : string ,
539562) : TokenCache {
540563 const cache = TokenCache . load ( cacheKey ) ;
541-
542564 for ( const { tokenId, symbol, name, icon, decimals } of tokens ) {
543- const token = new Token (
544- tokenId . chain ,
545- tokenId . address . toString ( ) ,
565+ const token = new Token ( {
566+ chain : tokenId . chain ,
567+ address : tokenId . address . toString ( ) ,
546568 decimals,
547569 symbol,
548570 name,
549571 icon,
550- ) ;
572+ } ) ;
551573 token . isBuiltin = true ;
552574 cache . add ( token ) ;
553575 }
@@ -567,16 +589,15 @@ export function buildTokenCache(
567589 chainToPlatform ( otherChain as Chain ) === 'Evm' ? 18 : 8 ;
568590
569591 decimals = Math . min ( decimals , originalToken . decimals ) ;
570-
571- const wrappedToken = new Token (
572- otherChain as Chain ,
573- wrappedAddr ,
592+ const wrappedToken = new Token ( {
593+ chain : otherChain as Chain ,
594+ address : wrappedAddr ,
574595 decimals,
575- originalToken . symbol ,
576- originalToken . name ,
577- originalToken . icon ,
578- originalToken ,
579- ) ;
596+ symbol : originalToken . symbol ,
597+ name : originalToken . name ,
598+ icon : originalToken . icon ,
599+ tokenBridgeOriginalTokenId : originalToken ,
600+ } ) ;
580601 wrappedToken . isBuiltin = true ;
581602
582603 cache . add ( wrappedToken ) ;
0 commit comments