@uniswap/token-list-bridge-utils 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,14 @@ import { providers } from 'ethers'
3
3
 
4
4
  const networkID = 42161
5
5
 
6
+ const l2Rpc = (chainId: number) => {
7
+ if (chainId === 42161) return 'https://arb1.arbitrum.io/rpc'
8
+ else if (chainId === 421611) return 'https://rinkeby.arbitrum.io/rpc'
9
+ else if (chainId === 42170) return 'https://nova.arbitrum.io/rpc'
10
+ else if (chainId === 421613) return 'https://goerli-rollup.arbitrum.io/rpc'
11
+ throw new Error('No L2 RPC detected')
12
+ }
13
+
6
14
  // ref: https://github.com/OffchainLabs/arb-token-lists/blob/master/src/lib/instantiate_bridge.ts
7
15
  export const getNetworkConfig = async () => {
8
16
  const { getL1Network, getL2Network, MultiCaller } = await import(
@@ -11,8 +19,8 @@ export const getNetworkConfig = async () => {
11
19
  const l2Network = await getL2Network(networkID)
12
20
  const l1Network = await getL1Network(l2Network.partnerChainID)
13
21
 
14
- const arbProvider = new providers.JsonRpcProvider(l2Network.rpcURL)
15
- const ethProvider = new providers.JsonRpcProvider(l1Network.rpcURL)
22
+ const arbProvider = new providers.JsonRpcProvider(l2Rpc(l2Network.chainID))
23
+ const ethProvider = new providers.JsonRpcProvider(process.env.MAINNET_RPC)
16
24
 
17
25
  const l1MultiCaller = await MultiCaller.fromProvider(ethProvider)
18
26
  const l2MultiCaller = await MultiCaller.fromProvider(arbProvider)
@@ -12,9 +12,12 @@ export enum ChainId {
12
12
  POLYGON_MUMBAI = 80001,
13
13
 
14
14
  CELO = 42220,
15
+ CELO_ALFAJORES = 44787,
16
+
15
17
  BNB = 56,
16
18
 
17
19
  AVALANCHE = 43114,
18
20
 
21
+ BASE = 8453,
19
22
  BASE_GOERLI = 84531,
20
23
  }
@@ -11,7 +11,15 @@ export const COINBASE_WRAPPED_STAKED_ETH = new Token(
11
11
 
12
12
  export const COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI = new Token(
13
13
  ChainId.BASE_GOERLI,
14
- '0x7c6b91D9Be155A6Db01f749217d76fF02A7227F2',
14
+ '0x4fC531f8Ae7A7808E0dccCA08F1e3c7694582950',
15
+ 18,
16
+ 'cbETH',
17
+ 'Coinbase Wrapped Staked ETH'
18
+ )
19
+
20
+ export const COINBASE_WRAPPED_STAKED_ETH_BASE = new Token(
21
+ ChainId.BASE,
22
+ '0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22',
15
23
  18,
16
24
  'cbETH',
17
25
  'Coinbase Wrapped Staked ETH'
@@ -25,6 +33,14 @@ export const COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE = new Token(
25
33
  'Coinbase Wrapped Staked ETH'
26
34
  )
27
35
 
36
+ export const COINBASE_WRAPPED_STAKED_ETH_OPTIMISM = new Token(
37
+ ChainId.OPTIMISM,
38
+ '0xadDb6A0412DE1BA0F936DCaeb8Aaa24578dcF3B2',
39
+ 18,
40
+ 'cbETH',
41
+ 'Coinbase Wrapped Staked ETH'
42
+ )
43
+
28
44
  export const DAI = new Token(
29
45
  ChainId.MAINNET,
30
46
  '0x6B175474E89094C44Da98b954EedeAC495271d0F',
@@ -70,6 +86,22 @@ export const DAI_AVALANCHE = new Token(
70
86
  'DAI.e'
71
87
  )
72
88
 
89
+ export const DAI_BASE = new Token(
90
+ ChainId.BASE,
91
+ '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
92
+ 18,
93
+ 'DAI',
94
+ 'Dai Stablecoin'
95
+ )
96
+
97
+ export const DAI_BASE_GOERLI = new Token(
98
+ ChainId.BASE_GOERLI,
99
+ '0x174956bDfbCEb6e53089297cce4fE2825E58d92C',
100
+ 18,
101
+ 'DAI',
102
+ 'Dai Stablecoin'
103
+ )
104
+
73
105
  export const USDT = new Token(
74
106
  ChainId.MAINNET,
75
107
  '0xdAC17F958D2ee523a2206206994597C13D831ec7',
@@ -85,3 +117,11 @@ export const USDT_BNB = new Token(
85
117
  'USDT',
86
118
  'Tether USD'
87
119
  )
120
+
121
+ export const USDT_CELO = new Token(
122
+ ChainId.CELO,
123
+ '0x617f3112bf5397D0467D315cC709EF968D9ba546',
124
+ 6,
125
+ 'USDT',
126
+ 'Tether USD'
127
+ )
@@ -13,6 +13,11 @@ import {
13
13
  COINBASE_WRAPPED_STAKED_ETH,
14
14
  COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI,
15
15
  COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE,
16
+ COINBASE_WRAPPED_STAKED_ETH_BASE,
17
+ DAI_BASE_GOERLI,
18
+ COINBASE_WRAPPED_STAKED_ETH_OPTIMISM,
19
+ DAI_BASE,
20
+ USDT_CELO,
16
21
  } from '../constants/tokens'
17
22
  import { compareTokenInfos } from '../utils'
18
23
 
@@ -33,6 +38,9 @@ export const Tokens: Partial<Record<ChainId, Record<string, TokenInfo>>> = {
33
38
  },
34
39
  [ChainId.OPTIMISM]: {
35
40
  DAI: tokenToTokenInfo(DAI_OPTIMISM),
41
+ COINBASE_WRAPPED_STAKED_ETH: tokenToTokenInfo(
42
+ COINBASE_WRAPPED_STAKED_ETH_OPTIMISM
43
+ ),
36
44
  },
37
45
  [ChainId.BNB]: {
38
46
  DAI: tokenToTokenInfo(DAI_BNB),
@@ -41,11 +49,21 @@ export const Tokens: Partial<Record<ChainId, Record<string, TokenInfo>>> = {
41
49
  [ChainId.AVALANCHE]: {
42
50
  DAI: tokenToTokenInfo(DAI_AVALANCHE),
43
51
  },
52
+ [ChainId.BASE]: {
53
+ DAI: tokenToTokenInfo(DAI_BASE),
54
+ COINBASE_WRAPPED_STAKED_ETH: tokenToTokenInfo(
55
+ COINBASE_WRAPPED_STAKED_ETH_BASE
56
+ ),
57
+ },
44
58
  [ChainId.BASE_GOERLI]: {
59
+ DAI: tokenToTokenInfo(DAI_BASE_GOERLI),
45
60
  COINBASE_WRAPPED_STAKED_ETH: tokenToTokenInfo(
46
61
  COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI
47
62
  ),
48
63
  },
64
+ [ChainId.CELO]: {
65
+ USDT: tokenToTokenInfo(USDT_CELO),
66
+ },
49
67
  }
50
68
 
51
69
  export const sampleL1TokenList: TokenList = {
@@ -222,6 +240,33 @@ export const bnbedSampleTokenList_2 = {
222
240
  ].sort(compareTokenInfos),
223
241
  }
224
242
 
243
+ export const celoedSampleTokenList = {
244
+ ...sampleL1TokenList_2,
245
+ name: 'Celo Sample',
246
+ tokens: [
247
+ {
248
+ ...Tokens[ChainId.CELO]!.USDT,
249
+ extensions: {
250
+ bridgeInfo: {
251
+ [ChainId.MAINNET]: {
252
+ tokenAddress: USDT.address,
253
+ },
254
+ },
255
+ },
256
+ } as unknown as TokenInfo,
257
+ {
258
+ ...(Tokens[ChainId.MAINNET]!.USDT as unknown as TokenInfo),
259
+ extensions: {
260
+ bridgeInfo: {
261
+ [ChainId.CELO]: {
262
+ tokenAddress: USDT_CELO.address,
263
+ },
264
+ },
265
+ },
266
+ } as unknown as TokenInfo,
267
+ ].sort(compareTokenInfos),
268
+ }
269
+
225
270
  export const baseGoerliSampleTokenList_3 = {
226
271
  ...sampleL1TokenList_3,
227
272
  name: 'Base Goerli Sample_3',
@@ -250,6 +295,34 @@ export const baseGoerliSampleTokenList_3 = {
250
295
  ].sort(compareTokenInfos),
251
296
  }
252
297
 
298
+ export const baseSampleTokenList_3 = {
299
+ ...sampleL1TokenList_3,
300
+ name: 'Base Sample_3',
301
+ tokens: [
302
+ {
303
+ ...Tokens[ChainId.BASE]!.COINBASE_WRAPPED_STAKED_ETH,
304
+ extensions: {
305
+ bridgeInfo: {
306
+ [ChainId.MAINNET]: {
307
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH.address,
308
+ },
309
+ },
310
+ },
311
+ } as unknown as TokenInfo,
312
+ {
313
+ ...(Tokens[ChainId.MAINNET]!
314
+ .COINBASE_WRAPPED_STAKED_ETH as unknown as TokenInfo),
315
+ extensions: {
316
+ bridgeInfo: {
317
+ [ChainId.BASE]: {
318
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH_BASE.address,
319
+ },
320
+ },
321
+ },
322
+ } as unknown as TokenInfo,
323
+ ].sort(compareTokenInfos),
324
+ }
325
+
253
326
  export const optimizedSampleTokenList = {
254
327
  ...sampleL1TokenList,
255
328
  name: 'Optimized Sample',
package/src/index.test.ts CHANGED
@@ -4,10 +4,14 @@ import { ChainId } from './constants/chainId'
4
4
  import {
5
5
  COINBASE_WRAPPED_STAKED_ETH,
6
6
  COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE,
7
+ COINBASE_WRAPPED_STAKED_ETH_BASE,
7
8
  COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI,
9
+ COINBASE_WRAPPED_STAKED_ETH_OPTIMISM,
8
10
  DAI,
9
11
  DAI_ARBITRUM_ONE,
10
12
  DAI_AVALANCHE,
13
+ DAI_BASE,
14
+ DAI_BASE_GOERLI,
11
15
  DAI_BNB,
12
16
  DAI_OPTIMISM,
13
17
  DAI_POLYGON,
@@ -24,6 +28,8 @@ import {
24
28
  avalanchedSampleTokenList,
25
29
  sampleL1TokenList_3,
26
30
  baseGoerliSampleTokenList_3,
31
+ baseSampleTokenList_3,
32
+ celoedSampleTokenList,
27
33
  } from './fixtures'
28
34
 
29
35
  jest.setTimeout(15000)
@@ -125,6 +131,22 @@ it('outputs bnb list correctly', async () => {
125
131
  )
126
132
  })
127
133
 
134
+ it('outputs celo list correctly', async () => {
135
+ const tokenList = await chainifyTokenList([ChainId.CELO], sampleL1TokenList_2)
136
+ expect(tokenList).toBeDefined()
137
+ expect(tokenList?.version).toEqual(celoedSampleTokenList.version)
138
+ expect(
139
+ tokenList?.tokens.map((t) => [t.address, t.chainId, t.extensions])
140
+ ).toEqual(
141
+ // ignores other metadata
142
+ celoedSampleTokenList.tokens.map((t) => [
143
+ t.address,
144
+ t.chainId,
145
+ t.extensions,
146
+ ])
147
+ )
148
+ })
149
+
128
150
  it('outputs bnb list correctly with different decimals', async () => {
129
151
  const tokenList = await chainifyTokenList([ChainId.BNB], sampleL1TokenList_2)
130
152
  expect(tokenList).toBeDefined()
@@ -160,6 +182,22 @@ it('outputs base goerli list correctly', async () => {
160
182
  )
161
183
  })
162
184
 
185
+ it('outputs base list correctly', async () => {
186
+ const tokenList = await chainifyTokenList([ChainId.BASE], sampleL1TokenList_3)
187
+ expect(tokenList).toBeDefined()
188
+ expect(tokenList?.version).toEqual(baseSampleTokenList_3.version)
189
+ expect(
190
+ tokenList?.tokens.map((t) => [t.address, t.chainId, t.extensions])
191
+ ).toEqual(
192
+ // ignores other metadata
193
+ baseSampleTokenList_3.tokens.map((t) => [
194
+ t.address,
195
+ t.chainId,
196
+ t.extensions,
197
+ ])
198
+ )
199
+ })
200
+
163
201
  describe(mergeTokenLists, () => {
164
202
  it('correctly deduplicates', () => {
165
203
  const merged = mergeTokenLists(sampleL1TokenList, sampleL1TokenList)
@@ -255,32 +293,11 @@ describe(mergeTokenLists, () => {
255
293
  })
256
294
  })
257
295
  describe(chainify, () => {
258
- it('creates tokenMap correctly in chainify', async () => {
296
+ it('provides bridge extensions', async () => {
259
297
  const chainified = await chainify(sampleL1TokenList)
260
298
 
261
- expect(chainified.tokenMap).toEqual({
262
- '10_0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1': {
263
- ...Tokens[ChainId.OPTIMISM]!.DAI,
264
- name: 'Dai Stablecoin',
265
- extensions: {
266
- bridgeInfo: {
267
- [ChainId.MAINNET]: {
268
- tokenAddress: DAI.address,
269
- },
270
- },
271
- },
272
- },
273
- '137_0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063': {
274
- ...Tokens[ChainId.POLYGON]!.DAI,
275
- extensions: {
276
- bridgeInfo: {
277
- [ChainId.MAINNET]: {
278
- tokenAddress: DAI.address,
279
- },
280
- },
281
- },
282
- },
283
- '1_0x6B175474E89094C44Da98b954EedeAC495271d0F': {
299
+ expect(chainified.tokens).toEqual([
300
+ {
284
301
  ...Tokens[ChainId.MAINNET]!.DAI,
285
302
  extensions: {
286
303
  bridgeInfo: {
@@ -301,26 +318,18 @@ describe(chainify, () => {
301
318
  // destBridgeAddress: arbBridgeL2Address,
302
319
  // originBridgeAddress: arbBridgeL1Address,
303
320
  },
304
- },
305
- },
306
- },
307
- '42161_0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1': {
308
- ...Tokens[ChainId.ARBITRUM_ONE]!.DAI,
309
- extensions: {
310
- bridgeInfo: {
311
- [ChainId.MAINNET]: {
312
- tokenAddress: DAI.address,
313
- // originBridgeAddress: arbBridgeL2Address,
314
- // destBridgeAddress: arbBridgeL1Address,
321
+ [ChainId.BASE]: {
322
+ tokenAddress: DAI_BASE.address,
323
+ },
324
+ [ChainId.BASE_GOERLI]: {
325
+ tokenAddress: DAI_BASE_GOERLI.address,
315
326
  },
316
327
  },
317
328
  },
318
- name: 'Dai Stablecoin',
319
329
  },
320
- '43114_0xd586E7F844cEa2F87f50152665BCbc2C279D8d70': {
321
- ...Tokens[ChainId.AVALANCHE]!.DAI,
330
+ {
331
+ ...Tokens[ChainId.OPTIMISM]!.DAI,
322
332
  name: 'Dai Stablecoin',
323
- symbol: 'DAI',
324
333
  extensions: {
325
334
  bridgeInfo: {
326
335
  [ChainId.MAINNET]: {
@@ -329,7 +338,7 @@ describe(chainify, () => {
329
338
  },
330
339
  },
331
340
  },
332
- '56_0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3': {
341
+ {
333
342
  ...Tokens[ChainId.BNB]!.DAI,
334
343
  extensions: {
335
344
  bridgeInfo: {
@@ -339,40 +348,8 @@ describe(chainify, () => {
339
348
  },
340
349
  },
341
350
  },
342
- })
343
- })
344
-
345
- it('provides bridge extensions', async () => {
346
- const chainified = await chainify(sampleL1TokenList)
347
-
348
- expect(chainified.tokens).toEqual([
349
- {
350
- ...Tokens[ChainId.MAINNET]!.DAI,
351
- extensions: {
352
- bridgeInfo: {
353
- [ChainId.BNB]: {
354
- tokenAddress: DAI_BNB.address,
355
- },
356
- [ChainId.AVALANCHE]: {
357
- tokenAddress: DAI_AVALANCHE.address,
358
- },
359
- [ChainId.OPTIMISM]: {
360
- tokenAddress: DAI_OPTIMISM.address,
361
- },
362
- [ChainId.POLYGON]: {
363
- tokenAddress: DAI_POLYGON.address,
364
- },
365
- [ChainId.ARBITRUM_ONE]: {
366
- tokenAddress: DAI_ARBITRUM_ONE.address,
367
- // destBridgeAddress: arbBridgeL2Address,
368
- // originBridgeAddress: arbBridgeL1Address,
369
- },
370
- },
371
- },
372
- },
373
351
  {
374
- ...Tokens[ChainId.OPTIMISM]!.DAI,
375
- name: 'Dai Stablecoin',
352
+ ...Tokens[ChainId.POLYGON]!.DAI,
376
353
  extensions: {
377
354
  bridgeInfo: {
378
355
  [ChainId.MAINNET]: {
@@ -382,7 +359,7 @@ describe(chainify, () => {
382
359
  },
383
360
  },
384
361
  {
385
- ...Tokens[ChainId.BNB]!.DAI,
362
+ ...Tokens[ChainId.BASE]!.DAI,
386
363
  extensions: {
387
364
  bridgeInfo: {
388
365
  [ChainId.MAINNET]: {
@@ -392,32 +369,32 @@ describe(chainify, () => {
392
369
  },
393
370
  },
394
371
  {
395
- ...Tokens[ChainId.POLYGON]!.DAI,
372
+ ...Tokens[ChainId.ARBITRUM_ONE]!.DAI,
396
373
  extensions: {
397
374
  bridgeInfo: {
398
375
  [ChainId.MAINNET]: {
399
376
  tokenAddress: DAI.address,
377
+ // originBridgeAddress: arbBridgeL2Address,
378
+ // destBridgeAddress: arbBridgeL1Address,
400
379
  },
401
380
  },
402
381
  },
382
+ name: 'Dai Stablecoin',
403
383
  },
404
384
  {
405
- ...Tokens[ChainId.ARBITRUM_ONE]!.DAI,
385
+ ...Tokens[ChainId.AVALANCHE]!.DAI,
386
+ name: 'Dai Stablecoin',
387
+ symbol: 'DAI',
406
388
  extensions: {
407
389
  bridgeInfo: {
408
390
  [ChainId.MAINNET]: {
409
391
  tokenAddress: DAI.address,
410
- // originBridgeAddress: arbBridgeL2Address,
411
- // destBridgeAddress: arbBridgeL1Address,
412
392
  },
413
393
  },
414
394
  },
415
- name: 'Dai Stablecoin',
416
395
  },
417
396
  {
418
- ...Tokens[ChainId.AVALANCHE]!.DAI,
419
- name: 'Dai Stablecoin',
420
- symbol: 'DAI',
397
+ ...Tokens[ChainId.BASE_GOERLI]!.DAI,
421
398
  extensions: {
422
399
  bridgeInfo: {
423
400
  [ChainId.MAINNET]: {
@@ -429,7 +406,7 @@ describe(chainify, () => {
429
406
  ])
430
407
  })
431
408
 
432
- it('provides bridge extensions for base goerli list', async () => {
409
+ it('provides bridge extensions for base list', async () => {
433
410
  const chainified = await chainify(sampleL1TokenList_3)
434
411
 
435
412
  expect(chainified.tokens).toEqual([
@@ -437,12 +414,40 @@ describe(chainify, () => {
437
414
  ...Tokens[ChainId.MAINNET]!.COINBASE_WRAPPED_STAKED_ETH,
438
415
  extensions: {
439
416
  bridgeInfo: {
440
- [ChainId.ARBITRUM_ONE]: {
441
- tokenAddress: COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE.address,
417
+ [ChainId.OPTIMISM]: {
418
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH_OPTIMISM.address,
419
+ },
420
+ [ChainId.BASE]: {
421
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH_BASE.address,
442
422
  },
443
423
  [ChainId.BASE_GOERLI]: {
444
424
  tokenAddress: COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI.address,
445
425
  },
426
+ [ChainId.ARBITRUM_ONE]: {
427
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE.address,
428
+ },
429
+ },
430
+ },
431
+ },
432
+ {
433
+ ...Tokens[ChainId.OPTIMISM]!.COINBASE_WRAPPED_STAKED_ETH,
434
+ name: 'Coinbase Wrapped Staked ETH',
435
+ extensions: {
436
+ bridgeInfo: {
437
+ [ChainId.MAINNET]: {
438
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH.address,
439
+ },
440
+ },
441
+ },
442
+ },
443
+ {
444
+ ...Tokens[ChainId.BASE]!.COINBASE_WRAPPED_STAKED_ETH,
445
+ name: 'Coinbase Wrapped Staked ETH',
446
+ extensions: {
447
+ bridgeInfo: {
448
+ [ChainId.MAINNET]: {
449
+ tokenAddress: COINBASE_WRAPPED_STAKED_ETH.address,
450
+ },
446
451
  },
447
452
  },
448
453
  },
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ export async function chainify(
25
25
  ChainId.CELO,
26
26
  ChainId.BNB,
27
27
  ChainId.AVALANCHE,
28
+ ChainId.BASE,
28
29
  ChainId.BASE_GOERLI,
29
30
  ]
30
31
 
@@ -34,13 +35,7 @@ export async function chainify(
34
35
  chainified
35
36
  )
36
37
 
37
- const tokenMap = {}
38
- if (merged.tokens && merged.tokens.length > 0) {
39
- merged.tokens.forEach((token) => {
40
- tokenMap[`${token.chainId}_${token.address}`] = token
41
- })
42
- }
43
- return { ...merged, tokenMap }
38
+ return merged
44
39
  }
45
40
 
46
41
  /**
@@ -81,7 +76,10 @@ export function mergeTokenLists(
81
76
  }
82
77
 
83
78
  const merged = merge(group[0], group[1])
84
- if (merged.extensions?.bridgeInfo) {
79
+ if (
80
+ merged.extensions?.bridgeInfo &&
81
+ typeof merged.extensions.bridgeInfo === 'object'
82
+ ) {
85
83
  // remove reference to self-chain from merge
86
84
  delete merged.extensions.bridgeInfo[merged.chainId]
87
85
  }
@@ -0,0 +1,19 @@
1
+ {
2
+ "0xdac17f958d2ee523a2206206994597c13d831ec7": {
3
+ "childToken": "0x617f3112bf5397D0467D315cC709EF968D9ba546",
4
+ "decimals": 18
5
+ },
6
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": {
7
+ "childToken": "0xd71Ffd0940c920786eC4DbB5A12306669b5b81EF",
8
+ "decimals": 18
9
+ },
10
+ "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
11
+ "childToken": "0xb829b68f57CC546dA7E5806A929e53bE32a4625D",
12
+ "decimals": 18
13
+ },
14
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": {
15
+ "childToken": "0x37f750B7cC259A2f741AF45294f6a16572CF5cAd",
16
+ "decimals": 6
17
+ }
18
+ }
19
+
@@ -17,7 +17,7 @@ export class BaseGoerliMappingProvider implements MappingProvider {
17
17
 
18
18
  let allTokens = await getTokenList(baseGoerliTokenListURL)
19
19
 
20
- let opTokenId_baseGoerliAddressMap = {}
20
+ let opTokenId_baseGoerliAddressMap: Record<string, string> = {}
21
21
  allTokens.tokens.forEach((token) => {
22
22
  if (token.chainId === ChainId.BASE_GOERLI) {
23
23
  if (typeof token.extensions?.opTokenId === 'string') {
@@ -0,0 +1,42 @@
1
+ import { MappingProvider } from './MappingProvider'
2
+ import { ChainId } from '../constants/chainId'
3
+ import { getTokenList } from '../utils'
4
+ import { GenericMappedTokenData } from '../constants/types'
5
+
6
+ const baseGoerliTokenListURL =
7
+ 'https://raw.githubusercontent.com/' +
8
+ 'ethereum-optimism/ethereum-optimism.github.io/master/optimism.tokenlist.json'
9
+
10
+ /**
11
+ * The Base mapping (linked above) is manually maintained by the Coinbase team
12
+ * in this repository: https://github.com/ethereum-optimism/ethereum-optimism.github.io.
13
+ */
14
+ export class BaseMappingProvider implements MappingProvider {
15
+ async provide(): Promise<GenericMappedTokenData> {
16
+ const tokens: { [key: string]: string | undefined } = {}
17
+
18
+ let allTokens = await getTokenList(baseGoerliTokenListURL)
19
+
20
+ let opTokenId_baseAddressMap: Record<string, string> = {}
21
+ allTokens.tokens.forEach((token) => {
22
+ if (token.chainId === ChainId.BASE) {
23
+ if (typeof token.extensions?.opTokenId === 'string') {
24
+ opTokenId_baseAddressMap[token.extensions.opTokenId] = token.address
25
+ }
26
+ }
27
+ })
28
+
29
+ allTokens.tokens.forEach((token) => {
30
+ if (
31
+ token.chainId === ChainId.MAINNET &&
32
+ typeof token.extensions?.opTokenId === 'string' &&
33
+ token.extensions!.opTokenId in opTokenId_baseAddressMap
34
+ ) {
35
+ tokens[token.address.toLowerCase()] =
36
+ opTokenId_baseAddressMap[token.extensions!.opTokenId]
37
+ }
38
+ })
39
+
40
+ return tokens
41
+ }
42
+ }
@@ -0,0 +1,10 @@
1
+ import { MappingProvider } from './MappingProvider'
2
+ import { MappedTokenData } from '../constants/types'
3
+ import celoMappings from '../local_mappings/celo.json'
4
+
5
+ // barring a better external source, we use a local source of mappings for celo
6
+ export class CeloMappingProvider implements MappingProvider {
7
+ async provide(): Promise<MappedTokenData> {
8
+ return celoMappings as MappedTokenData
9
+ }
10
+ }
@@ -5,7 +5,7 @@ import { GenericMappedTokenData } from '../constants/types'
5
5
 
6
6
  const optimismTokenListURL =
7
7
  'https://raw.githubusercontent.com/' +
8
- 'ethereum-optimism/ethereum-optimism.github.io/2138386277e4156d159615d1840882cecc398437/optimism.tokenlist.json'
8
+ 'ethereum-optimism/ethereum-optimism.github.io/master/optimism.tokenlist.json'
9
9
 
10
10
  /**
11
11
  * The Optimism L2 mapping (linked above) is manually maintained by the Optimism team.
@@ -16,14 +16,27 @@ export class OptimismMappingProvider implements MappingProvider {
16
16
  async provide(): Promise<GenericMappedTokenData> {
17
17
  const tokens: { [key: string]: string | undefined } = {}
18
18
 
19
- let optimismTokens = await getTokenList(optimismTokenListURL)
19
+ let allTokens = await getTokenList(optimismTokenListURL)
20
20
 
21
- for (const token of optimismTokens.tokens) {
22
- if (token.chainId === ChainId.MAINNET) {
21
+ let opTokenId_baseAddressMap: Record<string, string> = {}
22
+ allTokens.tokens.forEach((token) => {
23
+ if (token.chainId === ChainId.OPTIMISM) {
24
+ if (typeof token.extensions?.opTokenId === 'string') {
25
+ opTokenId_baseAddressMap[token.extensions.opTokenId] = token.address
26
+ }
27
+ }
28
+ })
29
+
30
+ allTokens.tokens.forEach((token) => {
31
+ if (
32
+ token.chainId === ChainId.MAINNET &&
33
+ typeof token.extensions?.opTokenId === 'string' &&
34
+ token.extensions!.opTokenId in opTokenId_baseAddressMap
35
+ ) {
23
36
  tokens[token.address.toLowerCase()] =
24
- token?.extensions?.bridgeInfo![ChainId.OPTIMISM].tokenAddress
37
+ opTokenId_baseAddressMap[token.extensions!.opTokenId]
25
38
  }
26
- }
39
+ })
27
40
 
28
41
  return tokens
29
42
  }
@@ -3,7 +3,8 @@ import { MappingProvider } from './MappingProvider'
3
3
  import { PolygonMappedTokenData } from '../constants/types'
4
4
 
5
5
  // called from https://mapper.polygon.technology
6
- const url = 'https://open-api.polygon.technology/api/v1/info/all-mappings'
6
+ const url =
7
+ 'https://api-polygon-tokens.polygon.technology/api/v1/info/all-mappings'
7
8
  const access_token = '504afd90-3228-4df9-9d88-9b4d70646101'
8
9
 
9
10
  /**