@uniswap/token-list-bridge-utils 2.6.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.
- package/dist/token-list-bridge-utils.cjs.development.js +30 -11
- package/dist/token-list-bridge-utils.cjs.development.js.map +1 -1
- package/dist/token-list-bridge-utils.cjs.production.min.js +1 -1
- package/dist/token-list-bridge-utils.cjs.production.min.js.map +1 -1
- package/dist/token-list-bridge-utils.esm.js +30 -11
- package/dist/token-list-bridge-utils.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/local_mappings/unichain.json +0 -4
- package/src/providers/ArbitrumMappingProvider.test.ts +123 -0
- package/src/providers/ArbitrumMappingProvider.ts +16 -6
|
@@ -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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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]:
|
|
43
|
+
(obj, key, index) => ({ ...obj, [key]: batches[index] }),
|
|
34
44
|
{}
|
|
35
45
|
)
|
|
36
46
|
|