@uniswap/token-list-bridge-utils 2.7.0 → 2.8.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.
@@ -0,0 +1,123 @@
1
+ import { ArbitrumMappingProvider } from './ArbitrumMappingProvider'
2
+ import { getL2TokenAddressesFromL1 } from '../arbitrum/gateway'
3
+ import { getNetworkConfig } from '../arbitrum/instantiate_bridge'
4
+ import { TokenList } from '@uniswap/token-lists'
5
+
6
+ jest.mock('../arbitrum/gateway')
7
+ jest.mock('../arbitrum/instantiate_bridge')
8
+
9
+ describe('ArbitrumMappingProvider', () => {
10
+ const mockL1TokenList: TokenList = {
11
+ name: 'Test Token List',
12
+ timestamp: '2024-01-01T00:00:00.000Z',
13
+ version: { major: 1, minor: 0, patch: 0 },
14
+ tokens: [
15
+ {
16
+ address: '0x1234',
17
+ chainId: 1,
18
+ decimals: 18,
19
+ name: 'Token1',
20
+ symbol: 'TK1',
21
+ },
22
+ {
23
+ address: '0x5678',
24
+ chainId: 1,
25
+ decimals: 18,
26
+ name: 'Token2',
27
+ symbol: 'TK2',
28
+ },
29
+ {
30
+ address: '0x9abc',
31
+ chainId: 1,
32
+ decimals: 18,
33
+ name: 'Token3',
34
+ symbol: 'TK3',
35
+ },
36
+ ],
37
+ }
38
+
39
+ const mockNetworkConfig = {
40
+ l1: {
41
+ multiCaller: 'mockMultiCaller',
42
+ },
43
+ l2: {
44
+ network: {
45
+ tokenBridge: {
46
+ l1GatewayRouter: '0xgatewayAddress',
47
+ },
48
+ },
49
+ },
50
+ }
51
+
52
+ beforeEach(() => {
53
+ jest.clearAllMocks()
54
+ ;(getNetworkConfig as jest.Mock).mockResolvedValue(mockNetworkConfig)
55
+ })
56
+
57
+ it('should correctly map L1 tokens to L2 addresses in batches', async () => {
58
+ const mockL2Addresses = ['0x1234L2', '0x5678L2', '0x9abcL2']
59
+ ;(getL2TokenAddressesFromL1 as jest.Mock).mockResolvedValue(mockL2Addresses)
60
+
61
+ const provider = new ArbitrumMappingProvider(mockL1TokenList)
62
+ const result = await provider.provide()
63
+
64
+ expect(result).toEqual({
65
+ '0x1234': '0x1234L2',
66
+ '0x5678': '0x5678L2',
67
+ '0x9abc': '0x9abcL2',
68
+ })
69
+
70
+ expect(getL2TokenAddressesFromL1).toHaveBeenCalledWith(
71
+ ['0x1234', '0x5678', '0x9abc'].map((addr) => addr.toLowerCase()),
72
+ 'mockMultiCaller',
73
+ '0xgatewayAddress'
74
+ )
75
+ })
76
+
77
+ it('should handle undefined L2 addresses correctly', async () => {
78
+ const mockL2Addresses = ['0x1234L2', undefined, '0x9abcL2']
79
+ ;(getL2TokenAddressesFromL1 as jest.Mock).mockImplementation(
80
+ (addresses) => {
81
+ // Return only the defined addresses from our mock data
82
+ return mockL2Addresses.filter((addr) => addr !== undefined)
83
+ }
84
+ )
85
+
86
+ const provider = new ArbitrumMappingProvider(mockL1TokenList)
87
+ const result = await provider.provide()
88
+
89
+ // Our implementation filters out undefined values before adding to batches array,
90
+ // so the indexes will shift. The final mapping will have undefined for any
91
+ // addresses that don't have a corresponding L2 address in order
92
+ expect(result).toEqual({
93
+ '0x1234': '0x1234L2',
94
+ '0x5678': '0x9abcL2', // Gets the next available L2 address
95
+ '0x9abc': undefined, // No more L2 addresses available
96
+ })
97
+ })
98
+
99
+ it('should process tokens in batches of 100', async () => {
100
+ // Create a token list with 150 tokens
101
+ const largeTokenList: TokenList = {
102
+ ...mockL1TokenList,
103
+ tokens: Array.from({ length: 150 }, (_, i) => ({
104
+ address: `0x${i}`,
105
+ chainId: 1,
106
+ decimals: 18,
107
+ name: `Token${i}`,
108
+ symbol: `TK${i}`,
109
+ })),
110
+ }
111
+
112
+ const provider = new ArbitrumMappingProvider(largeTokenList)
113
+ await provider.provide()
114
+
115
+ // Verify that getL2TokenAddressesFromL1 was called twice
116
+ // Once with 100 tokens and once with 50 tokens
117
+ expect(getL2TokenAddressesFromL1).toHaveBeenCalledTimes(2)
118
+ const firstCall = (getL2TokenAddressesFromL1 as jest.Mock).mock.calls[0][0]
119
+ const secondCall = (getL2TokenAddressesFromL1 as jest.Mock).mock.calls[1][0]
120
+ expect(firstCall.length).toBe(100)
121
+ expect(secondCall.length).toBe(50)
122
+ })
123
+ })
@@ -23,14 +23,24 @@ export class ArbitrumMappingProvider implements MappingProvider {
23
23
  token.address.toLowerCase()
24
24
  )
25
25
 
26
- const l2AddressesFromL1 = await getL2TokenAddressesFromL1(
27
- tokenAddresses,
28
- l1.multiCaller,
29
- l2.network.tokenBridge.l1GatewayRouter
30
- )
26
+ // batching calls to avoid rpc response size limits
27
+ const batchSize = 100
28
+ const batches: string[] = []
29
+ for (let i = 0; i < tokenAddresses.length; i += batchSize) {
30
+ const batch = tokenAddresses.slice(i, i + batchSize)
31
+ const batchResults = await getL2TokenAddressesFromL1(
32
+ batch,
33
+ l1.multiCaller,
34
+ l2.network.tokenBridge.l1GatewayRouter
35
+ )
36
+ const filteredResults = batchResults.filter(
37
+ (addr): addr is string => addr !== undefined
38
+ )
39
+ batches.push(...filteredResults)
40
+ }
31
41
 
32
42
  tokens = tokenAddresses.reduce(
33
- (obj, key, index) => ({ ...obj, [key]: l2AddressesFromL1[index] }),
43
+ (obj, key, index) => ({ ...obj, [key]: batches[index] }),
34
44
  {}
35
45
  )
36
46