@rhinestone/shared-configs 2.20.1 → 2.21.1
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/configs/chain-indexer.json +82 -23
- package/dist/configs/chains.json +62 -0
- package/dist/configs/contracts.dev.json +4 -0
- package/dist/configs/contracts.json +4 -0
- package/dist/configs/mainnets.json +7 -0
- package/dist/configs/providers.json +9 -0
- package/dist/scripts/__tests__/validation.test.js +152 -2
- package/dist/scripts/generate.js +6 -0
- package/dist/scripts/validation.d.ts +13 -8
- package/dist/scripts/validation.js +174 -21
- package/dist/src/chains.d.ts +6 -0
- package/dist/src/chains.js +67 -0
- package/dist/src/generated/contracts.dev.js +4 -0
- package/dist/src/generated/contracts.js +4 -0
- package/dist/src/generated/networks.d.ts +110 -1
- package/dist/src/generated/networks.js +2 -1
- package/dist/src/generated/packageVersion.d.ts +1 -1
- package/dist/src/generated/packageVersion.js +1 -1
- package/dist/src/types.d.ts +21 -1
- package/package.json +1 -1
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"reorg_window_k": 32,
|
|
11
11
|
"reverify_delay_ms": 500,
|
|
12
12
|
"scan_batch_max_blocks": 200,
|
|
13
|
-
"streaming_poll_interval_ms": 36000
|
|
13
|
+
"streaming_poll_interval_ms": 36000,
|
|
14
|
+
"vm": "evm"
|
|
14
15
|
},
|
|
15
16
|
"10": {
|
|
16
17
|
"finality": "sequencer",
|
|
@@ -23,7 +24,8 @@
|
|
|
23
24
|
"reorg_window_k": 16,
|
|
24
25
|
"reverify_delay_ms": 500,
|
|
25
26
|
"scan_batch_max_blocks": 200,
|
|
26
|
-
"streaming_poll_interval_ms": 6000
|
|
27
|
+
"streaming_poll_interval_ms": 6000,
|
|
28
|
+
"vm": "evm"
|
|
27
29
|
},
|
|
28
30
|
"56": {
|
|
29
31
|
"finality": "probabilistic",
|
|
@@ -36,7 +38,8 @@
|
|
|
36
38
|
"reorg_window_k": 32,
|
|
37
39
|
"reverify_delay_ms": 500,
|
|
38
40
|
"scan_batch_max_blocks": 200,
|
|
39
|
-
"streaming_poll_interval_ms": 3000
|
|
41
|
+
"streaming_poll_interval_ms": 3000,
|
|
42
|
+
"vm": "evm"
|
|
40
43
|
},
|
|
41
44
|
"100": {
|
|
42
45
|
"finality": "probabilistic",
|
|
@@ -49,7 +52,8 @@
|
|
|
49
52
|
"reorg_window_k": 32,
|
|
50
53
|
"reverify_delay_ms": 500,
|
|
51
54
|
"scan_batch_max_blocks": 200,
|
|
52
|
-
"streaming_poll_interval_ms": 15000
|
|
55
|
+
"streaming_poll_interval_ms": 15000,
|
|
56
|
+
"vm": "evm"
|
|
53
57
|
},
|
|
54
58
|
"130": {
|
|
55
59
|
"finality": "sequencer",
|
|
@@ -62,7 +66,8 @@
|
|
|
62
66
|
"reorg_window_k": 16,
|
|
63
67
|
"reverify_delay_ms": 500,
|
|
64
68
|
"scan_batch_max_blocks": 200,
|
|
65
|
-
"streaming_poll_interval_ms": 3000
|
|
69
|
+
"streaming_poll_interval_ms": 3000,
|
|
70
|
+
"vm": "evm"
|
|
66
71
|
},
|
|
67
72
|
"137": {
|
|
68
73
|
"finality": "probabilistic",
|
|
@@ -75,7 +80,8 @@
|
|
|
75
80
|
"reorg_window_k": 64,
|
|
76
81
|
"reverify_delay_ms": 500,
|
|
77
82
|
"scan_batch_max_blocks": 200,
|
|
78
|
-
"streaming_poll_interval_ms": 4500
|
|
83
|
+
"streaming_poll_interval_ms": 4500,
|
|
84
|
+
"vm": "evm"
|
|
79
85
|
},
|
|
80
86
|
"143": {
|
|
81
87
|
"finality": "instant",
|
|
@@ -88,7 +94,8 @@
|
|
|
88
94
|
"reorg_window_k": 4,
|
|
89
95
|
"reverify_delay_ms": 0,
|
|
90
96
|
"scan_batch_max_blocks": 200,
|
|
91
|
-
"streaming_poll_interval_ms": 3000
|
|
97
|
+
"streaming_poll_interval_ms": 3000,
|
|
98
|
+
"vm": "evm"
|
|
92
99
|
},
|
|
93
100
|
"146": {
|
|
94
101
|
"finality": "instant",
|
|
@@ -101,7 +108,8 @@
|
|
|
101
108
|
"reorg_window_k": 4,
|
|
102
109
|
"reverify_delay_ms": 0,
|
|
103
110
|
"scan_batch_max_blocks": 200,
|
|
104
|
-
"streaming_poll_interval_ms": 4500
|
|
111
|
+
"streaming_poll_interval_ms": 4500,
|
|
112
|
+
"vm": "evm"
|
|
105
113
|
},
|
|
106
114
|
"196": {
|
|
107
115
|
"finality": "sequencer",
|
|
@@ -114,7 +122,8 @@
|
|
|
114
122
|
"reorg_window_k": 16,
|
|
115
123
|
"reverify_delay_ms": 500,
|
|
116
124
|
"scan_batch_max_blocks": 200,
|
|
117
|
-
"streaming_poll_interval_ms": 3000
|
|
125
|
+
"streaming_poll_interval_ms": 3000,
|
|
126
|
+
"vm": "evm"
|
|
118
127
|
},
|
|
119
128
|
"999": {
|
|
120
129
|
"finality": "instant",
|
|
@@ -127,7 +136,8 @@
|
|
|
127
136
|
"reorg_window_k": 4,
|
|
128
137
|
"reverify_delay_ms": 0,
|
|
129
138
|
"scan_batch_max_blocks": 200,
|
|
130
|
-
"streaming_poll_interval_ms": 3000
|
|
139
|
+
"streaming_poll_interval_ms": 3000,
|
|
140
|
+
"vm": "evm"
|
|
131
141
|
},
|
|
132
142
|
"1868": {
|
|
133
143
|
"finality": "sequencer",
|
|
@@ -140,7 +150,8 @@
|
|
|
140
150
|
"reorg_window_k": 16,
|
|
141
151
|
"reverify_delay_ms": 500,
|
|
142
152
|
"scan_batch_max_blocks": 200,
|
|
143
|
-
"streaming_poll_interval_ms": 6000
|
|
153
|
+
"streaming_poll_interval_ms": 6000,
|
|
154
|
+
"vm": "evm"
|
|
144
155
|
},
|
|
145
156
|
"4663": {
|
|
146
157
|
"finality": "sequencer",
|
|
@@ -153,7 +164,22 @@
|
|
|
153
164
|
"reorg_window_k": 16,
|
|
154
165
|
"reverify_delay_ms": 500,
|
|
155
166
|
"scan_batch_max_blocks": 200,
|
|
156
|
-
"streaming_poll_interval_ms": 3000
|
|
167
|
+
"streaming_poll_interval_ms": 3000,
|
|
168
|
+
"vm": "evm"
|
|
169
|
+
},
|
|
170
|
+
"5042": {
|
|
171
|
+
"finality": "instant",
|
|
172
|
+
"finality_poll_interval_ms": 0,
|
|
173
|
+
"finality_source": "instant",
|
|
174
|
+
"grace_ms": 0,
|
|
175
|
+
"max_catchup_blocks": 5000,
|
|
176
|
+
"parse_concurrency": 8,
|
|
177
|
+
"poll_interval_ms": 1000,
|
|
178
|
+
"reorg_window_k": 4,
|
|
179
|
+
"reverify_delay_ms": 0,
|
|
180
|
+
"scan_batch_max_blocks": 200,
|
|
181
|
+
"streaming_poll_interval_ms": 15000,
|
|
182
|
+
"vm": "evm"
|
|
157
183
|
},
|
|
158
184
|
"8453": {
|
|
159
185
|
"finality": "sequencer",
|
|
@@ -166,7 +192,8 @@
|
|
|
166
192
|
"reorg_window_k": 16,
|
|
167
193
|
"reverify_delay_ms": 500,
|
|
168
194
|
"scan_batch_max_blocks": 200,
|
|
169
|
-
"streaming_poll_interval_ms": 6000
|
|
195
|
+
"streaming_poll_interval_ms": 6000,
|
|
196
|
+
"vm": "evm"
|
|
170
197
|
},
|
|
171
198
|
"9745": {
|
|
172
199
|
"finality": "instant",
|
|
@@ -179,7 +206,8 @@
|
|
|
179
206
|
"reorg_window_k": 4,
|
|
180
207
|
"reverify_delay_ms": 0,
|
|
181
208
|
"scan_batch_max_blocks": 200,
|
|
182
|
-
"streaming_poll_interval_ms": 3000
|
|
209
|
+
"streaming_poll_interval_ms": 3000,
|
|
210
|
+
"vm": "evm"
|
|
183
211
|
},
|
|
184
212
|
"9746": {
|
|
185
213
|
"finality": "instant",
|
|
@@ -192,7 +220,8 @@
|
|
|
192
220
|
"reorg_window_k": 4,
|
|
193
221
|
"reverify_delay_ms": 0,
|
|
194
222
|
"scan_batch_max_blocks": 200,
|
|
195
|
-
"streaming_poll_interval_ms": 3000
|
|
223
|
+
"streaming_poll_interval_ms": 3000,
|
|
224
|
+
"vm": "evm"
|
|
196
225
|
},
|
|
197
226
|
"42161": {
|
|
198
227
|
"finality": "sequencer",
|
|
@@ -205,7 +234,8 @@
|
|
|
205
234
|
"reorg_window_k": 16,
|
|
206
235
|
"reverify_delay_ms": 500,
|
|
207
236
|
"scan_batch_max_blocks": 200,
|
|
208
|
-
"streaming_poll_interval_ms": 3000
|
|
237
|
+
"streaming_poll_interval_ms": 3000,
|
|
238
|
+
"vm": "evm"
|
|
209
239
|
},
|
|
210
240
|
"43114": {
|
|
211
241
|
"finality": "instant",
|
|
@@ -218,7 +248,8 @@
|
|
|
218
248
|
"reorg_window_k": 4,
|
|
219
249
|
"reverify_delay_ms": 0,
|
|
220
250
|
"scan_batch_max_blocks": 200,
|
|
221
|
-
"streaming_poll_interval_ms": 3000
|
|
251
|
+
"streaming_poll_interval_ms": 3000,
|
|
252
|
+
"vm": "evm"
|
|
222
253
|
},
|
|
223
254
|
"57073": {
|
|
224
255
|
"finality": "sequencer",
|
|
@@ -231,7 +262,8 @@
|
|
|
231
262
|
"reorg_window_k": 16,
|
|
232
263
|
"reverify_delay_ms": 500,
|
|
233
264
|
"scan_batch_max_blocks": 200,
|
|
234
|
-
"streaming_poll_interval_ms": 3000
|
|
265
|
+
"streaming_poll_interval_ms": 3000,
|
|
266
|
+
"vm": "evm"
|
|
235
267
|
},
|
|
236
268
|
"84532": {
|
|
237
269
|
"finality": "sequencer",
|
|
@@ -244,7 +276,8 @@
|
|
|
244
276
|
"reorg_window_k": 8,
|
|
245
277
|
"reverify_delay_ms": 500,
|
|
246
278
|
"scan_batch_max_blocks": 200,
|
|
247
|
-
"streaming_poll_interval_ms": 6000
|
|
279
|
+
"streaming_poll_interval_ms": 6000,
|
|
280
|
+
"vm": "evm"
|
|
248
281
|
},
|
|
249
282
|
"421614": {
|
|
250
283
|
"finality": "sequencer",
|
|
@@ -257,7 +290,8 @@
|
|
|
257
290
|
"reorg_window_k": 8,
|
|
258
291
|
"reverify_delay_ms": 500,
|
|
259
292
|
"scan_batch_max_blocks": 200,
|
|
260
|
-
"streaming_poll_interval_ms": 3000
|
|
293
|
+
"streaming_poll_interval_ms": 3000,
|
|
294
|
+
"vm": "evm"
|
|
261
295
|
},
|
|
262
296
|
"747474": {
|
|
263
297
|
"finality": "sequencer",
|
|
@@ -270,7 +304,8 @@
|
|
|
270
304
|
"reorg_window_k": 16,
|
|
271
305
|
"reverify_delay_ms": 500,
|
|
272
306
|
"scan_batch_max_blocks": 200,
|
|
273
|
-
"streaming_poll_interval_ms": 3000
|
|
307
|
+
"streaming_poll_interval_ms": 3000,
|
|
308
|
+
"vm": "evm"
|
|
274
309
|
},
|
|
275
310
|
"11155111": {
|
|
276
311
|
"finality": "probabilistic",
|
|
@@ -283,7 +318,8 @@
|
|
|
283
318
|
"reorg_window_k": 32,
|
|
284
319
|
"reverify_delay_ms": 500,
|
|
285
320
|
"scan_batch_max_blocks": 200,
|
|
286
|
-
"streaming_poll_interval_ms": 36000
|
|
321
|
+
"streaming_poll_interval_ms": 36000,
|
|
322
|
+
"vm": "evm"
|
|
287
323
|
},
|
|
288
324
|
"11155420": {
|
|
289
325
|
"finality": "sequencer",
|
|
@@ -296,6 +332,29 @@
|
|
|
296
332
|
"reorg_window_k": 8,
|
|
297
333
|
"reverify_delay_ms": 500,
|
|
298
334
|
"scan_batch_max_blocks": 200,
|
|
299
|
-
"streaming_poll_interval_ms": 6000
|
|
335
|
+
"streaming_poll_interval_ms": 6000,
|
|
336
|
+
"vm": "evm"
|
|
337
|
+
},
|
|
338
|
+
"792703809": {
|
|
339
|
+
"commitment": "finalized",
|
|
340
|
+
"max_catchup_signatures": 5000,
|
|
341
|
+
"overlap_slots": 300,
|
|
342
|
+
"page_limit": 1000,
|
|
343
|
+
"poll_interval_ms": 2000,
|
|
344
|
+
"topics": [
|
|
345
|
+
"5q44zFF8gziimbCipqNQ7GYed8pkTRDmUKFUFTwd4DjB"
|
|
346
|
+
],
|
|
347
|
+
"vm": "svm"
|
|
348
|
+
},
|
|
349
|
+
"792703810": {
|
|
350
|
+
"commitment": "finalized",
|
|
351
|
+
"max_catchup_signatures": 5000,
|
|
352
|
+
"overlap_slots": 300,
|
|
353
|
+
"page_limit": 1000,
|
|
354
|
+
"poll_interval_ms": 2000,
|
|
355
|
+
"topics": [
|
|
356
|
+
"5q44zFF8gziimbCipqNQ7GYed8pkTRDmUKFUFTwd4DjB"
|
|
357
|
+
],
|
|
358
|
+
"vm": "svm"
|
|
300
359
|
}
|
|
301
360
|
}
|
package/dist/configs/chains.json
CHANGED
|
@@ -1519,6 +1519,66 @@
|
|
|
1519
1519
|
"symbol": "WETH"
|
|
1520
1520
|
}
|
|
1521
1521
|
},
|
|
1522
|
+
"5042": {
|
|
1523
|
+
"caip2": "eip155:5042",
|
|
1524
|
+
"explorer": {
|
|
1525
|
+
"addressPath": "/address/",
|
|
1526
|
+
"txPath": "/tx/",
|
|
1527
|
+
"url": "https://explorer.arc.io"
|
|
1528
|
+
},
|
|
1529
|
+
"iconSlug": "arc",
|
|
1530
|
+
"name": "Arc",
|
|
1531
|
+
"nativeToken": {
|
|
1532
|
+
"address": "0x0000000000000000000000000000000000000000",
|
|
1533
|
+
"decimals": 18,
|
|
1534
|
+
"symbol": "USDC"
|
|
1535
|
+
},
|
|
1536
|
+
"network": "mainnet",
|
|
1537
|
+
"providerIds": {
|
|
1538
|
+
"alchemy": null,
|
|
1539
|
+
"zerion": null
|
|
1540
|
+
},
|
|
1541
|
+
"publicRpcUrl": "https://rpc.mainnet.arc.io",
|
|
1542
|
+
"sessionCapable": false,
|
|
1543
|
+
"settlementConfig": {
|
|
1544
|
+
"cctp": {
|
|
1545
|
+
"domain": 26
|
|
1546
|
+
},
|
|
1547
|
+
"rhino": {
|
|
1548
|
+
"bridgeContract": "0x5e023c31e1d3dcd08a1b3e8c96f6ef8aa8fcacd1",
|
|
1549
|
+
"chainName": "ARC"
|
|
1550
|
+
}
|
|
1551
|
+
},
|
|
1552
|
+
"settlementLayers": [
|
|
1553
|
+
"ACROSS",
|
|
1554
|
+
"RELAY",
|
|
1555
|
+
"RHINO",
|
|
1556
|
+
"CCTP"
|
|
1557
|
+
],
|
|
1558
|
+
"stack": "vanilla",
|
|
1559
|
+
"swapQuoters": [],
|
|
1560
|
+
"tokens": [
|
|
1561
|
+
{
|
|
1562
|
+
"address": "0x3600000000000000000000000000000000000000",
|
|
1563
|
+
"appFee": true,
|
|
1564
|
+
"approvalSlot": null,
|
|
1565
|
+
"balanceSlot": null,
|
|
1566
|
+
"decimals": 6,
|
|
1567
|
+
"gasRefund": true,
|
|
1568
|
+
"pegGroup": "USD",
|
|
1569
|
+
"settlementLayers": [
|
|
1570
|
+
"ACROSS"
|
|
1571
|
+
],
|
|
1572
|
+
"symbol": "USDC"
|
|
1573
|
+
}
|
|
1574
|
+
],
|
|
1575
|
+
"vmType": "evm",
|
|
1576
|
+
"wrappedNativeToken": {
|
|
1577
|
+
"address": "0x3600000000000000000000000000000000000000",
|
|
1578
|
+
"decimals": 6,
|
|
1579
|
+
"symbol": "USDC"
|
|
1580
|
+
}
|
|
1581
|
+
},
|
|
1522
1582
|
"8453": {
|
|
1523
1583
|
"caip2": "eip155:8453",
|
|
1524
1584
|
"explorer": {
|
|
@@ -3142,6 +3202,7 @@
|
|
|
3142
3202
|
"alchemy": null,
|
|
3143
3203
|
"zerion": null
|
|
3144
3204
|
},
|
|
3205
|
+
"rpcId": "mainnet-beta",
|
|
3145
3206
|
"sessionCapable": false,
|
|
3146
3207
|
"settlementConfig": {
|
|
3147
3208
|
"cctp": {
|
|
@@ -3246,6 +3307,7 @@
|
|
|
3246
3307
|
"alchemy": null,
|
|
3247
3308
|
"zerion": null
|
|
3248
3309
|
},
|
|
3310
|
+
"rpcId": "devnet",
|
|
3249
3311
|
"sessionCapable": false,
|
|
3250
3312
|
"settlementConfig": {
|
|
3251
3313
|
"cctp": {
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"swapAdapter": "0x58BC7d9279A38a1537c2f74426dBDbD804AD3A18",
|
|
97
97
|
"swapAdapterTokenSpender": "0xc5f6641b3ade357c5df77a1859d16528fe8b3e93"
|
|
98
98
|
},
|
|
99
|
+
"5042": {
|
|
100
|
+
"acrossBridge": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84",
|
|
101
|
+
"spokepool": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84"
|
|
102
|
+
},
|
|
99
103
|
"8453": {
|
|
100
104
|
"ecoArbiter": "0x1BeBAfb3D05d84A5Bfd94800c88d1342f755d8AB",
|
|
101
105
|
"acrossBridge": "0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64",
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"swapAdapter": "0xaE448E141F230AC3c6F6dA981C0882356c9B91a6",
|
|
97
97
|
"swapAdapterTokenSpender": "0x3115c923734471b9da1d5bfef161d9c9e9963859"
|
|
98
98
|
},
|
|
99
|
+
"5042": {
|
|
100
|
+
"acrossBridge": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84",
|
|
101
|
+
"spokepool": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84"
|
|
102
|
+
},
|
|
99
103
|
"8453": {
|
|
100
104
|
"ecoArbiter": "0x2e7627CCfAe4eDb336eEb5a70f08415B0F1a2b8C",
|
|
101
105
|
"acrossBridge": "0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"999": "hyperliquid-mainnet",
|
|
14
14
|
"1868": "soneium-mainnet",
|
|
15
15
|
"4663": "robinhood-mainnet",
|
|
16
|
+
"5042": "arc-mainnet",
|
|
16
17
|
"8453": "base-mainnet",
|
|
17
18
|
"9745": "plasma-mainnet",
|
|
18
19
|
"9746": "plasma-testnet",
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"999": "hyperliquid",
|
|
42
43
|
"1868": "soneium",
|
|
43
44
|
"4663": "robinhood",
|
|
45
|
+
"5042": "arc",
|
|
44
46
|
"8453": "base",
|
|
45
47
|
"9745": "plasma",
|
|
46
48
|
"9746": "plasma-testnet",
|
|
@@ -55,6 +57,12 @@
|
|
|
55
57
|
},
|
|
56
58
|
"url_template": "https://lb.drpc.org/ogrpc?network={{chain_param}}&dkey=${DRPC_API_KEY}"
|
|
57
59
|
},
|
|
60
|
+
"arc-public-rpc": {
|
|
61
|
+
"chain_mapping": {
|
|
62
|
+
"5042": "5042"
|
|
63
|
+
},
|
|
64
|
+
"url_template": "https://rpc.mainnet.arc.io"
|
|
65
|
+
},
|
|
58
66
|
"eRPC": {
|
|
59
67
|
"chain_mapping": {
|
|
60
68
|
"1": "1",
|
|
@@ -69,6 +77,7 @@
|
|
|
69
77
|
"999": "999",
|
|
70
78
|
"1868": "1868",
|
|
71
79
|
"4663": "4663",
|
|
80
|
+
"5042": "5042",
|
|
72
81
|
"8453": "8453",
|
|
73
82
|
"9745": "9745",
|
|
74
83
|
"9746": "9746",
|
|
@@ -327,6 +327,56 @@ function errorsFor(chain) {
|
|
|
327
327
|
(0, bun_test_1.expect)(error.message).toContain("TELEPORT");
|
|
328
328
|
(0, bun_test_1.expect)(error.message).toContain("src/types.ts");
|
|
329
329
|
});
|
|
330
|
+
// Absent is fine: chainRegistry() defaults it to the chain id, and a
|
|
331
|
+
// consumer reading a document written before the field existed does the
|
|
332
|
+
// same. Only the two ways AUTHORING can get it wrong are checked.
|
|
333
|
+
(0, bun_test_1.it)("accepts a chain with no rpcId", () => {
|
|
334
|
+
(0, bun_test_1.expect)(errorsFor(validChain())).toEqual([]);
|
|
335
|
+
});
|
|
336
|
+
(0, bun_test_1.it)("accepts an rpcId that matches the chain id", () => {
|
|
337
|
+
(0, bun_test_1.expect)(errorsFor(validChain({ rpcId: "1" }))).toEqual([]);
|
|
338
|
+
});
|
|
339
|
+
(0, bun_test_1.it)("rejects an rpcId override on an EVM chain", () => {
|
|
340
|
+
const [error] = errorsFor(validChain({ rpcId: "mainnet" }));
|
|
341
|
+
(0, bun_test_1.expect)(error.message).toContain("does not match the chain id");
|
|
342
|
+
});
|
|
343
|
+
// The failure this prevents is an empty feed, which reads exactly like a
|
|
344
|
+
// chain with no traffic — so it has to fail the build, not runtime.
|
|
345
|
+
(0, bun_test_1.it)("rejects a Solana chain whose rpcId is still the numeric default", () => {
|
|
346
|
+
const errors = (0, validation_1.validateChainConfig)({
|
|
347
|
+
"792703810": validChain({
|
|
348
|
+
name: "Solana Devnet",
|
|
349
|
+
vmType: "svm",
|
|
350
|
+
network: "testnet",
|
|
351
|
+
caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
352
|
+
rpcId: "792703810",
|
|
353
|
+
}),
|
|
354
|
+
}).issues.filter((i) => i.severity === "error");
|
|
355
|
+
(0, bun_test_1.expect)(errors.map((e) => e.message).join("\n")).toContain("addressed by its cluster name");
|
|
356
|
+
});
|
|
357
|
+
(0, bun_test_1.it)("rejects a Solana chain with no rpcId at all", () => {
|
|
358
|
+
const errors = (0, validation_1.validateChainConfig)({
|
|
359
|
+
"792703810": validChain({
|
|
360
|
+
name: "Solana Devnet",
|
|
361
|
+
vmType: "svm",
|
|
362
|
+
network: "testnet",
|
|
363
|
+
caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
364
|
+
}),
|
|
365
|
+
}).issues.filter((i) => i.severity === "error");
|
|
366
|
+
(0, bun_test_1.expect)(errors.map((e) => e.message).join("\n")).toContain("addressed by its cluster name");
|
|
367
|
+
});
|
|
368
|
+
(0, bun_test_1.it)("accepts a Solana chain addressed by its cluster", () => {
|
|
369
|
+
const errors = (0, validation_1.validateChainConfig)({
|
|
370
|
+
"792703810": validChain({
|
|
371
|
+
name: "Solana Devnet",
|
|
372
|
+
vmType: "svm",
|
|
373
|
+
network: "testnet",
|
|
374
|
+
caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
375
|
+
rpcId: "devnet",
|
|
376
|
+
}),
|
|
377
|
+
}).issues.filter((i) => i.severity === "error");
|
|
378
|
+
(0, bun_test_1.expect)(errors).toEqual([]);
|
|
379
|
+
});
|
|
330
380
|
});
|
|
331
381
|
(0, bun_test_1.describe)("validateChainConfig — reachability", () => {
|
|
332
382
|
(0, bun_test_1.it)("returns no issues for chains with multiple settlement layers", () => {
|
|
@@ -516,6 +566,7 @@ function errorsFor(chain) {
|
|
|
516
566
|
/** A complete class-B entry, so semantic tests don't trip the shape checks. */
|
|
517
567
|
function validIndexerEntry(overrides = {}) {
|
|
518
568
|
return {
|
|
569
|
+
vm: "evm",
|
|
519
570
|
poll_interval_ms: 1000,
|
|
520
571
|
streaming_poll_interval_ms: 15000,
|
|
521
572
|
reorg_window_k: 16,
|
|
@@ -541,12 +592,12 @@ function validIndexerEntry(overrides = {}) {
|
|
|
541
592
|
(0, bun_test_1.expect)(issues).toHaveLength(1);
|
|
542
593
|
(0, bun_test_1.expect)(issues[0].message).toContain("no chain-indexer entry");
|
|
543
594
|
});
|
|
544
|
-
(0, bun_test_1.it)("reports an entry addressing
|
|
595
|
+
(0, bun_test_1.it)("reports an entry addressing a chain the indexer does not dial", () => {
|
|
545
596
|
const issues = (0, validation_1.validateChainIndexerCoverage)({}, {
|
|
546
597
|
"1": validIndexerEntry(),
|
|
547
598
|
});
|
|
548
599
|
(0, bun_test_1.expect)(issues).toHaveLength(1);
|
|
549
|
-
(0, bun_test_1.expect)(issues[0].message).toContain("no
|
|
600
|
+
(0, bun_test_1.expect)(issues[0].message).toContain("no chain the indexer dials");
|
|
550
601
|
});
|
|
551
602
|
// HyperCore is vmType "evm" with a hypercore: caip2 — the eip155 namespace,
|
|
552
603
|
// not vmType, decides whether the indexer dials a chain.
|
|
@@ -627,6 +678,105 @@ function validIndexerEntry(overrides = {}) {
|
|
|
627
678
|
});
|
|
628
679
|
(0, bun_test_1.expect)(issues.map((i) => i.message).join("\n")).toContain("the only legal value is false");
|
|
629
680
|
});
|
|
681
|
+
/** The Solana entry as the artifact publishes it. */
|
|
682
|
+
function validSvmEntry(overrides = {}) {
|
|
683
|
+
return {
|
|
684
|
+
vm: "svm",
|
|
685
|
+
poll_interval_ms: 2000,
|
|
686
|
+
commitment: "finalized",
|
|
687
|
+
topics: ["5q44zFF8gziimbCipqNQ7GYed8pkTRDmUKFUFTwd4DjB"],
|
|
688
|
+
page_limit: 1000,
|
|
689
|
+
overlap_slots: 300,
|
|
690
|
+
max_catchup_signatures: 5000,
|
|
691
|
+
...overrides,
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function solanaChain(overrides = {}) {
|
|
695
|
+
return validChain({
|
|
696
|
+
name: "Solana Devnet",
|
|
697
|
+
vmType: "svm",
|
|
698
|
+
network: "testnet",
|
|
699
|
+
caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
700
|
+
rpcId: "devnet",
|
|
701
|
+
...overrides,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
(0, bun_test_1.it)("accepts a complete SVM entry", () => {
|
|
705
|
+
(0, bun_test_1.expect)((0, validation_1.validateChainIndexerCoverage)({ "792703810": solanaChain() }, {
|
|
706
|
+
"792703810": validSvmEntry(),
|
|
707
|
+
})).toEqual([]);
|
|
708
|
+
});
|
|
709
|
+
(0, bun_test_1.it)("requires an entry for a Solana chain, like any other dialable chain", () => {
|
|
710
|
+
const issues = (0, validation_1.validateChainIndexerCoverage)({ "792703810": solanaChain() }, {});
|
|
711
|
+
(0, bun_test_1.expect)(issues).toHaveLength(1);
|
|
712
|
+
(0, bun_test_1.expect)(issues[0].message).toContain("SVM chain has no chain-indexer entry");
|
|
713
|
+
});
|
|
714
|
+
// The knob sets are disjoint, so judging an entry against the wrong one
|
|
715
|
+
// reports every field of both as wrong — which is the point: an SVM entry is
|
|
716
|
+
// not an EVM entry missing eleven fields.
|
|
717
|
+
(0, bun_test_1.it)("rejects EVM knobs on a Solana chain", () => {
|
|
718
|
+
const issues = (0, validation_1.validateChainIndexerCoverage)({ "792703810": solanaChain() }, { "792703810": validIndexerEntry() });
|
|
719
|
+
(0, bun_test_1.expect)(issues.map((i) => i.message).join("\n")).toContain('`vm` = "evm" but solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 is a svm chain');
|
|
720
|
+
});
|
|
721
|
+
// The dangerous direction: the indexer reads `vm` first and passes over
|
|
722
|
+
// families it does not index, so an svm tag on an EVM chain would validate
|
|
723
|
+
// as a coherent SVM entry here and then leave that chain silently unscanned.
|
|
724
|
+
(0, bun_test_1.it)("rejects an svm tag on an EVM chain", () => {
|
|
725
|
+
const issues = (0, validation_1.validateChainIndexerCoverage)({ "1": validChain() }, {
|
|
726
|
+
"1": validSvmEntry(),
|
|
727
|
+
});
|
|
728
|
+
(0, bun_test_1.expect)(issues.map((i) => i.message).join("\n")).toContain("would never be scanned");
|
|
729
|
+
});
|
|
730
|
+
bun_test_1.it.each([
|
|
731
|
+
["a missing SVM field", { topics: undefined }, "missing `topics`"],
|
|
732
|
+
["an empty topic list", { topics: [] }, "`topics` = [] is not a legal value"],
|
|
733
|
+
[
|
|
734
|
+
"a malformed topic",
|
|
735
|
+
{ topics: ["not-base58-и"] },
|
|
736
|
+
"is not a legal value",
|
|
737
|
+
],
|
|
738
|
+
// A character-count regex accepts both of these — they are legal base58
|
|
739
|
+
// characters at a legal length — but neither decodes to a 32-byte account.
|
|
740
|
+
// A marker like this would pass the build and then name a feed no
|
|
741
|
+
// transaction can appear in, which reads as a chain with no traffic.
|
|
742
|
+
[
|
|
743
|
+
"a topic that decodes to 33 bytes",
|
|
744
|
+
{ topics: ["z".repeat(44)] },
|
|
745
|
+
"is not a legal value",
|
|
746
|
+
],
|
|
747
|
+
[
|
|
748
|
+
"a topic that decodes to 43 zero bytes",
|
|
749
|
+
{ topics: ["1".repeat(43)] },
|
|
750
|
+
"is not a legal value",
|
|
751
|
+
],
|
|
752
|
+
[
|
|
753
|
+
"a commitment nothing settles at",
|
|
754
|
+
{ commitment: "processed" },
|
|
755
|
+
'`commitment` = "processed" is not a legal value',
|
|
756
|
+
],
|
|
757
|
+
// Not a narrow allowlist: the SVM entry omits every reorg and retraction
|
|
758
|
+
// knob BECAUSE a finalized signature is settled. Reading at `confirmed`
|
|
759
|
+
// has to arrive with the retraction kind, not as a value a facts release
|
|
760
|
+
// can set on its own.
|
|
761
|
+
[
|
|
762
|
+
"a reversible commitment the schema cannot retract",
|
|
763
|
+
{ commitment: "confirmed" },
|
|
764
|
+
'`commitment` = "confirmed" is not a legal value',
|
|
765
|
+
],
|
|
766
|
+
[
|
|
767
|
+
"a page limit above the RPC ceiling",
|
|
768
|
+
{ page_limit: 1001 },
|
|
769
|
+
"`page_limit` = 1001 is not a legal value",
|
|
770
|
+
],
|
|
771
|
+
[
|
|
772
|
+
"an EVM knob smuggled in",
|
|
773
|
+
{ reorg_window_k: 16 },
|
|
774
|
+
"unrecognized field `reorg_window_k`",
|
|
775
|
+
],
|
|
776
|
+
])("rejects %s on an SVM entry", (_label, overrides, expected) => {
|
|
777
|
+
const issues = (0, validation_1.validateChainIndexerCoverage)({ "792703810": solanaChain() }, { "792703810": validSvmEntry(overrides) });
|
|
778
|
+
(0, bun_test_1.expect)(issues.map((i) => i.message).join("\n")).toContain(expected);
|
|
779
|
+
});
|
|
630
780
|
(0, bun_test_1.it)("accepts a coherent instant-class entry", () => {
|
|
631
781
|
const entry = validIndexerEntry({
|
|
632
782
|
finality: "instant",
|
package/dist/scripts/generate.js
CHANGED
|
@@ -162,6 +162,12 @@ function renderChains(chainRegistry, mainnets, testnets) {
|
|
|
162
162
|
" /** Public, unauthenticated https JSON-RPC endpoint — what a browser needs to",
|
|
163
163
|
" * build this chain with `defineChain`. Absent means display-only. */",
|
|
164
164
|
" publicRpcUrl?: string;",
|
|
165
|
+
" /** How this chain is addressed when dialling it, within its architecture:",
|
|
166
|
+
" * the last segment of `{proxy}/{architecture}/{rpcId}`. Present only where",
|
|
167
|
+
" * the chain id is NOT what you dial — the cluster name (`mainnet-beta`,",
|
|
168
|
+
" * `devnet`) on Solana. Absent means the chain id is the id, so read it as",
|
|
169
|
+
" * `chain.rpcId ?? String(chainId)` rather than branching on vmType. */",
|
|
170
|
+
" rpcId?: string;",
|
|
165
171
|
" /** True for virtual chains (e.g. HyperCore) that settle on another chain. */",
|
|
166
172
|
" virtual?: boolean;",
|
|
167
173
|
" /** Which directions of transfer the chain supports; absent means both.",
|
|
@@ -226,19 +226,24 @@ export declare function validateChainConfig(chains: ChainRegistry): ValidationRe
|
|
|
226
226
|
*/
|
|
227
227
|
export declare function validateOftCoverage(chains: ChainRegistry, oft: Record<string, unknown>): ValidationIssue[];
|
|
228
228
|
/**
|
|
229
|
-
* Insists that every
|
|
230
|
-
* entry, and that no entry addresses a chain that does not exist.
|
|
229
|
+
* Insists that every chain the indexer dials carries a complete, coherent
|
|
230
|
+
* chain-indexer entry, and that no entry addresses a chain that does not exist.
|
|
231
231
|
*
|
|
232
|
-
* The indexer scans every dialable
|
|
233
|
-
* unclassified chain is a hard failure — this check moves that
|
|
234
|
-
* the indexer's boot to this build, where the person adding the
|
|
235
|
-
* (RHI-6107). Selected by the
|
|
232
|
+
* The indexer scans every dialable chain it has a machine for, and its contract
|
|
233
|
+
* is that an unclassified chain is a hard failure — this check moves that
|
|
234
|
+
* failure from the indexer's boot to this build, where the person adding the
|
|
235
|
+
* chain sees it (RHI-6107). Selected by the caip2 NAMESPACE, NOT by vmType:
|
|
236
236
|
* HyperCore is vmType "evm" with a `hypercore:` caip2 and must not require an
|
|
237
237
|
* entry — the same discriminator the publish workflow's contracts guard uses,
|
|
238
238
|
* for the same reason. Runs after `classifyChainCaip2`, which stamps the field.
|
|
239
239
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
240
|
+
* Two families today (`eip155:` → evm, `solana:` → svm), with disjoint knob
|
|
241
|
+
* sets — an entry is judged against the one its chain implies, and its own `vm`
|
|
242
|
+
* is cross-checked against that rather than trusted (RHI-7338).
|
|
243
|
+
*
|
|
244
|
+
* The EVM cross-field rules mirror chain-indexer's
|
|
245
|
+
* `ChainScanSettings::validate`, so a value set this check accepts is one the
|
|
246
|
+
* indexer will accept.
|
|
242
247
|
*
|
|
243
248
|
* A chain deliberately not indexed carries `{ indexed: false }` as its whole
|
|
244
249
|
* entry — a decision the check accepts, unlike a missing entry.
|
|
@@ -104,6 +104,47 @@ const isObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v)
|
|
|
104
104
|
const isNonEmptyString = (v) => typeof v === 'string' && v.length > 0;
|
|
105
105
|
const isNonNegativeInt = (v) => typeof v === 'number' && Number.isInteger(v) && v >= 0;
|
|
106
106
|
const isAbsentOr = (v, check) => v === undefined || check(v);
|
|
107
|
+
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
108
|
+
/**
|
|
109
|
+
* Decode base58 (Bitcoin/Solana alphabet), or null if the string is not
|
|
110
|
+
* base58. Each leading `1` stands for one leading zero byte.
|
|
111
|
+
*
|
|
112
|
+
* Decoded rather than pattern-matched because the length is what actually
|
|
113
|
+
* matters and a character-count regex does not imply it: 44 `z`s are all legal
|
|
114
|
+
* base58 characters and decode to THIRTY-THREE bytes, while 43 `1`s decode to
|
|
115
|
+
* 43 zero bytes. Both would pass a `{43,44}` regex and neither is an account.
|
|
116
|
+
* The failure that buys is a marker that validates here and then names a feed
|
|
117
|
+
* no transaction can ever appear in — silence indistinguishable from a chain
|
|
118
|
+
* with no traffic.
|
|
119
|
+
*/
|
|
120
|
+
function decodeBase58(value) {
|
|
121
|
+
if (value.length === 0)
|
|
122
|
+
return null;
|
|
123
|
+
const bytes = [];
|
|
124
|
+
for (const char of value) {
|
|
125
|
+
let carry = BASE58_ALPHABET.indexOf(char);
|
|
126
|
+
if (carry < 0)
|
|
127
|
+
return null;
|
|
128
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
129
|
+
carry += bytes[i] * 58;
|
|
130
|
+
bytes[i] = carry & 0xff;
|
|
131
|
+
carry >>= 8;
|
|
132
|
+
}
|
|
133
|
+
while (carry > 0) {
|
|
134
|
+
bytes.push(carry & 0xff);
|
|
135
|
+
carry >>= 8;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let zeros = 0;
|
|
139
|
+
while (zeros < value.length && value[zeros] === '1')
|
|
140
|
+
zeros += 1;
|
|
141
|
+
return Uint8Array.from([
|
|
142
|
+
...new Array(zeros).fill(0),
|
|
143
|
+
...bytes.reverse(),
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
/** A base58 Solana account address: exactly 32 bytes once decoded. */
|
|
147
|
+
const isBase58Account = (v) => typeof v === 'string' && decodeBase58(v)?.length === 32;
|
|
107
148
|
// Every vendor layer's REQUIRED payload, keyed by the SettlementLayer value
|
|
108
149
|
// that switches it on. This is what replaces the chain-id allowlists the
|
|
109
150
|
// jsonnet used to carry with "must match <map> in the orchestrator" comments —
|
|
@@ -282,6 +323,30 @@ function structuralProblems(registryChainId, chain) {
|
|
|
282
323
|
if (!isAbsentOr(chain.publicRpcUrl, isPublicRpcUrl)) {
|
|
283
324
|
problems.push(`publicRpcUrl ${JSON.stringify(chain.publicRpcUrl)} is not an https:// URL`);
|
|
284
325
|
}
|
|
326
|
+
// `rpcId` is authored, and only where the chain id is not what you dial — so
|
|
327
|
+
// absence is the normal answer and carries meaning ("the chain id is the
|
|
328
|
+
// id"). There is deliberately no blanket presence check; what is checked is
|
|
329
|
+
// the two ways authoring it can go wrong.
|
|
330
|
+
//
|
|
331
|
+
// An `rpcId` on an EVM chain that is not its own id routes every call for
|
|
332
|
+
// that chain to the wrong network. A Solana chain with none leaves a consumer
|
|
333
|
+
// falling back to `{proxy}/svm/792703810`, which reaches nothing — and the
|
|
334
|
+
// symptom is an empty feed, indistinguishable from a chain with no traffic,
|
|
335
|
+
// which is why it has to fail here rather than at runtime.
|
|
336
|
+
if (!isAbsentOr(chain.rpcId, isNonEmptyString)) {
|
|
337
|
+
problems.push(`rpcId ${JSON.stringify(chain.rpcId)} is not a non-empty string`);
|
|
338
|
+
}
|
|
339
|
+
else if (typeof chain.caip2 === 'string' &&
|
|
340
|
+
chain.caip2.startsWith('eip155:') &&
|
|
341
|
+
chain.rpcId !== undefined &&
|
|
342
|
+
chain.rpcId !== registryChainId) {
|
|
343
|
+
problems.push(`rpcId ${JSON.stringify(chain.rpcId)} does not match the chain id for an eip155 chain — EVM chains are addressed by their id, so drop the override`);
|
|
344
|
+
}
|
|
345
|
+
else if (typeof chain.caip2 === 'string' &&
|
|
346
|
+
chain.caip2.startsWith('solana:') &&
|
|
347
|
+
(chain.rpcId === undefined || chain.rpcId === registryChainId)) {
|
|
348
|
+
problems.push('rpcId is missing or is the chain id, but a Solana chain is addressed by its cluster name (e.g. "devnet") — author it in config/non_evm_chains.jsonnet');
|
|
349
|
+
}
|
|
285
350
|
if (!isAbsentOr(chain.virtual, (v) => typeof v === 'boolean')) {
|
|
286
351
|
problems.push('virtual is not a boolean');
|
|
287
352
|
}
|
|
@@ -1236,12 +1301,15 @@ const CHAIN_INDEXER_FINALITY_SOURCE = new Set([
|
|
|
1236
1301
|
'safe',
|
|
1237
1302
|
'instant',
|
|
1238
1303
|
]);
|
|
1239
|
-
// Every field of one chain-indexer entry, all required. The wire is exact
|
|
1240
|
-
// purpose: the indexer's own contract is "every field mandatory — a knob
|
|
1241
|
-
// set is a decision nobody made", so a missing field here is the same
|
|
1242
|
-
// mistake as a missing entry, and an unrecognized field is a typo
|
|
1243
|
-
// otherwise ship silently.
|
|
1304
|
+
// Every field of one EVM chain-indexer entry, all required. The wire is exact
|
|
1305
|
+
// on purpose: the indexer's own contract is "every field mandatory — a knob
|
|
1306
|
+
// nobody set is a decision nobody made", so a missing field here is the same
|
|
1307
|
+
// authoring mistake as a missing entry, and an unrecognized field is a typo
|
|
1308
|
+
// that would otherwise ship silently.
|
|
1309
|
+
//
|
|
1310
|
+
// The SVM set below is disjoint from this one — see CHAIN_INDEXER_FIELDS_BY_VM.
|
|
1244
1311
|
const CHAIN_INDEXER_FIELDS = {
|
|
1312
|
+
vm: (v) => v === 'evm',
|
|
1245
1313
|
poll_interval_ms: isNonNegativeInt,
|
|
1246
1314
|
streaming_poll_interval_ms: isNonNegativeInt,
|
|
1247
1315
|
reorg_window_k: isNonNegativeInt,
|
|
@@ -1254,38 +1322,104 @@ const CHAIN_INDEXER_FIELDS = {
|
|
|
1254
1322
|
finality_poll_interval_ms: isNonNegativeInt,
|
|
1255
1323
|
grace_ms: isNonNegativeInt,
|
|
1256
1324
|
};
|
|
1325
|
+
// `finalized` is the ONLY legal commitment, and that is a coherence rule, not
|
|
1326
|
+
// a narrow allowlist waiting to be widened.
|
|
1327
|
+
//
|
|
1328
|
+
// The SVM entry carries no reorg window, no grace period and no retraction
|
|
1329
|
+
// vocabulary — the family has one message kind where EVM has four — and it can
|
|
1330
|
+
// omit all of that precisely BECAUSE a finalized signature is settled. Admit
|
|
1331
|
+
// `confirmed` here and that stops being true: the indexer would publish
|
|
1332
|
+
// reversible signatures as settled with nothing in the schema able to take
|
|
1333
|
+
// them back, and the build would pass.
|
|
1334
|
+
//
|
|
1335
|
+
// So the two travel together. Reading at `confirmed` is a real thing we may
|
|
1336
|
+
// want one day; it arrives with the retraction kind, as one change, not as a
|
|
1337
|
+
// value someone can set in a facts release. Same shape as the EVM rule that
|
|
1338
|
+
// `finality: instant` and `finality_source: instant` imply each other.
|
|
1339
|
+
//
|
|
1340
|
+
// `processed` is absent for a further reason: eRPC refuses it outright for
|
|
1341
|
+
// getSignaturesForAddress and getTransaction.
|
|
1342
|
+
const CHAIN_INDEXER_COMMITMENT = new Set(['finalized']);
|
|
1343
|
+
// The SVM knob set — a different machine, so none of the EVM fields above
|
|
1344
|
+
// apply. There is no block scan, no parent-hash chain and no log filter: the
|
|
1345
|
+
// unit is a transaction signature reached through the address → signature
|
|
1346
|
+
// index. And no reorg or finality knobs, because ingest is at `finalized`
|
|
1347
|
+
// commitment where a signature is settled (RHI-7338).
|
|
1348
|
+
//
|
|
1349
|
+
// `commitment` is its own field rather than an assumed constant because
|
|
1350
|
+
// omitting it on the wire silently yields eRPC's `confirmed` network default —
|
|
1351
|
+
// unrooted reads that look exactly like correct operation.
|
|
1352
|
+
const CHAIN_INDEXER_SVM_FIELDS = {
|
|
1353
|
+
vm: (v) => v === 'svm',
|
|
1354
|
+
poll_interval_ms: isNonNegativeInt,
|
|
1355
|
+
commitment: (v) => typeof v === 'string' && CHAIN_INDEXER_COMMITMENT.has(v),
|
|
1356
|
+
// A list, not a scalar: rotating the marker or adding our own no-op program
|
|
1357
|
+
// id as a second topic must be a facts release, not an indexer deploy. Each
|
|
1358
|
+
// entry is a base58 account address.
|
|
1359
|
+
topics: (v) => Array.isArray(v) && v.length > 0 && v.every((t) => isBase58Account(t)),
|
|
1360
|
+
page_limit: (v) => isNonNegativeInt(v) && v > 0 && v <= 1000,
|
|
1361
|
+
overlap_slots: isNonNegativeInt,
|
|
1362
|
+
max_catchup_signatures: isNonNegativeInt,
|
|
1363
|
+
};
|
|
1364
|
+
// Which machine an entry's knobs belong to. Mirrors the `vm` tag chain-indexer
|
|
1365
|
+
// reads before anything else in the entry: an unrecognised value there is
|
|
1366
|
+
// skipped rather than indexed, so a typo here would silently stop a chain
|
|
1367
|
+
// being scanned, which is why it fails the build instead.
|
|
1368
|
+
const CHAIN_INDEXER_FIELDS_BY_VM = {
|
|
1369
|
+
evm: CHAIN_INDEXER_FIELDS,
|
|
1370
|
+
svm: CHAIN_INDEXER_SVM_FIELDS,
|
|
1371
|
+
};
|
|
1372
|
+
// Which caip2 namespace implies which machine, for the cross-check that an
|
|
1373
|
+
// entry's `vm` matches the chain it addresses. Namespace rather than vmType,
|
|
1374
|
+
// for the same reason coverage is selected that way: HyperCore is vmType "evm"
|
|
1375
|
+
// under a `hypercore:` caip2 and is not a chain the indexer dials.
|
|
1376
|
+
const CHAIN_INDEXER_VM_BY_NAMESPACE = {
|
|
1377
|
+
eip155: 'evm',
|
|
1378
|
+
solana: 'svm',
|
|
1379
|
+
};
|
|
1257
1380
|
/**
|
|
1258
|
-
* Insists that every
|
|
1259
|
-
* entry, and that no entry addresses a chain that does not exist.
|
|
1381
|
+
* Insists that every chain the indexer dials carries a complete, coherent
|
|
1382
|
+
* chain-indexer entry, and that no entry addresses a chain that does not exist.
|
|
1260
1383
|
*
|
|
1261
|
-
* The indexer scans every dialable
|
|
1262
|
-
* unclassified chain is a hard failure — this check moves that
|
|
1263
|
-
* the indexer's boot to this build, where the person adding the
|
|
1264
|
-
* (RHI-6107). Selected by the
|
|
1384
|
+
* The indexer scans every dialable chain it has a machine for, and its contract
|
|
1385
|
+
* is that an unclassified chain is a hard failure — this check moves that
|
|
1386
|
+
* failure from the indexer's boot to this build, where the person adding the
|
|
1387
|
+
* chain sees it (RHI-6107). Selected by the caip2 NAMESPACE, NOT by vmType:
|
|
1265
1388
|
* HyperCore is vmType "evm" with a `hypercore:` caip2 and must not require an
|
|
1266
1389
|
* entry — the same discriminator the publish workflow's contracts guard uses,
|
|
1267
1390
|
* for the same reason. Runs after `classifyChainCaip2`, which stamps the field.
|
|
1268
1391
|
*
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1392
|
+
* Two families today (`eip155:` → evm, `solana:` → svm), with disjoint knob
|
|
1393
|
+
* sets — an entry is judged against the one its chain implies, and its own `vm`
|
|
1394
|
+
* is cross-checked against that rather than trusted (RHI-7338).
|
|
1395
|
+
*
|
|
1396
|
+
* The EVM cross-field rules mirror chain-indexer's
|
|
1397
|
+
* `ChainScanSettings::validate`, so a value set this check accepts is one the
|
|
1398
|
+
* indexer will accept.
|
|
1271
1399
|
*
|
|
1272
1400
|
* A chain deliberately not indexed carries `{ indexed: false }` as its whole
|
|
1273
1401
|
* entry — a decision the check accepts, unlike a missing entry.
|
|
1274
1402
|
*/
|
|
1275
1403
|
function validateChainIndexerCoverage(chains, chainIndexer) {
|
|
1276
1404
|
const issues = [];
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1405
|
+
// Which machine's knobs a chain takes, or undefined for one the indexer does
|
|
1406
|
+
// not dial at all. Keyed on the caip2 NAMESPACE for the reason in the doc
|
|
1407
|
+
// comment: HyperCore is vmType "evm" under `hypercore:` and must stay
|
|
1408
|
+
// exempt.
|
|
1409
|
+
const machineOf = (chain) => typeof chain.caip2 === 'string'
|
|
1410
|
+
? CHAIN_INDEXER_VM_BY_NAMESPACE[chain.caip2.split(':')[0]]
|
|
1411
|
+
: undefined;
|
|
1412
|
+
const requiresEntry = (chain) => machineOf(chain) !== undefined && chain.virtual !== true;
|
|
1280
1413
|
for (const [chainId, chain] of Object.entries(chains)) {
|
|
1281
|
-
|
|
1414
|
+
const machine = machineOf(chain);
|
|
1415
|
+
if (machine === undefined || chain.virtual === true)
|
|
1282
1416
|
continue;
|
|
1283
1417
|
if (chainIndexer[chainId] === undefined) {
|
|
1284
1418
|
issues.push({
|
|
1285
1419
|
severity: 'error',
|
|
1286
1420
|
chainId,
|
|
1287
1421
|
chainName: isNonEmptyString(chain.name) ? chain.name : '<unnamed>',
|
|
1288
|
-
message:
|
|
1422
|
+
message: `${machine.toUpperCase()} chain has no chain-indexer entry — classify it in config/chain-indexer.jsonnet (see docs/add-chain.md, "Classify the chain for the indexer")`,
|
|
1289
1423
|
});
|
|
1290
1424
|
}
|
|
1291
1425
|
}
|
|
@@ -1294,7 +1428,7 @@ function validateChainIndexerCoverage(chains, chainIndexer) {
|
|
|
1294
1428
|
const chainName = chain && isNonEmptyString(chain.name) ? chain.name : '<not in registry>';
|
|
1295
1429
|
const issue = (message) => issues.push({ severity: 'error', chainId, chainName, message });
|
|
1296
1430
|
if (!chain || !requiresEntry(chain)) {
|
|
1297
|
-
issue('chain-indexer entry addresses no
|
|
1431
|
+
issue('chain-indexer entry addresses no chain the indexer dials — remove it from config/chain-indexer.jsonnet, or add the chain first');
|
|
1298
1432
|
continue;
|
|
1299
1433
|
}
|
|
1300
1434
|
if (!isObject(entry)) {
|
|
@@ -1316,7 +1450,19 @@ function validateChainIndexerCoverage(chains, chainIndexer) {
|
|
|
1316
1450
|
}
|
|
1317
1451
|
continue;
|
|
1318
1452
|
}
|
|
1319
|
-
|
|
1453
|
+
// Which machine's knobs this entry is judged against. Cross-checked
|
|
1454
|
+
// against the chain rather than taken from the entry: an `svm` tag on an
|
|
1455
|
+
// eip155 chain would otherwise be validated as a coherent SVM entry and
|
|
1456
|
+
// then silently skipped by the indexer, which reads `vm` first and passes
|
|
1457
|
+
// over families it does not index — a chain that stops being scanned with
|
|
1458
|
+
// nothing failing anywhere (RHI-7338).
|
|
1459
|
+
const machine = machineOf(chain);
|
|
1460
|
+
if (entry.vm !== undefined && entry.vm !== machine) {
|
|
1461
|
+
issue(`chain-indexer \`vm\` = ${JSON.stringify(entry.vm)} but ${chain.caip2} is a ${machine} chain — the indexer skips entries for machines it does not index, so this one would never be scanned`);
|
|
1462
|
+
continue;
|
|
1463
|
+
}
|
|
1464
|
+
const fields = CHAIN_INDEXER_FIELDS_BY_VM[machine];
|
|
1465
|
+
for (const [field, check] of Object.entries(fields)) {
|
|
1320
1466
|
if (entry[field] === undefined) {
|
|
1321
1467
|
issue(`chain-indexer entry is missing \`${field}\` — every field is mandatory, a knob nobody set is a decision nobody made`);
|
|
1322
1468
|
}
|
|
@@ -1325,10 +1471,17 @@ function validateChainIndexerCoverage(chains, chainIndexer) {
|
|
|
1325
1471
|
}
|
|
1326
1472
|
}
|
|
1327
1473
|
for (const field of Object.keys(entry)) {
|
|
1328
|
-
if (!(field in
|
|
1474
|
+
if (!(field in fields)) {
|
|
1329
1475
|
issue(`chain-indexer entry carries unrecognized field \`${field}\` — the artifact's shape is exact, fix the name or drop it`);
|
|
1330
1476
|
}
|
|
1331
1477
|
}
|
|
1478
|
+
// The cross-field rules below are EVM classification coherence — reorg
|
|
1479
|
+
// window against finality source against watermark cadence. The SVM entry
|
|
1480
|
+
// has no reorg or finality knobs to be incoherent about: at `finalized`
|
|
1481
|
+
// commitment a signature is settled, so there is no second classification
|
|
1482
|
+
// to agree with.
|
|
1483
|
+
if (machine !== 'evm')
|
|
1484
|
+
continue;
|
|
1332
1485
|
const instantClass = entry.finality === 'instant';
|
|
1333
1486
|
const instantSource = entry.finality_source === 'instant';
|
|
1334
1487
|
if (instantClass !== instantSource) {
|
package/dist/src/chains.d.ts
CHANGED
|
@@ -66,6 +66,12 @@ interface Chain {
|
|
|
66
66
|
/** Public, unauthenticated https JSON-RPC endpoint — what a browser needs to
|
|
67
67
|
* build this chain with `defineChain`. Absent means display-only. */
|
|
68
68
|
publicRpcUrl?: string;
|
|
69
|
+
/** How this chain is addressed when dialling it, within its architecture:
|
|
70
|
+
* the last segment of `{proxy}/{architecture}/{rpcId}`. Present only where
|
|
71
|
+
* the chain id is NOT what you dial — the cluster name (`mainnet-beta`,
|
|
72
|
+
* `devnet`) on Solana. Absent means the chain id is the id, so read it as
|
|
73
|
+
* `chain.rpcId ?? String(chainId)` rather than branching on vmType. */
|
|
74
|
+
rpcId?: string;
|
|
69
75
|
/** True for virtual chains (e.g. HyperCore) that settle on another chain. */
|
|
70
76
|
virtual?: boolean;
|
|
71
77
|
/** Which directions of transfer the chain supports; absent means both.
|
package/dist/src/chains.js
CHANGED
|
@@ -1572,6 +1572,71 @@ const chains = {
|
|
|
1572
1572
|
"Alchemy"
|
|
1573
1573
|
]
|
|
1574
1574
|
},
|
|
1575
|
+
"5042": {
|
|
1576
|
+
"caip2": "eip155:5042",
|
|
1577
|
+
"explorer": {
|
|
1578
|
+
"addressPath": "/address/",
|
|
1579
|
+
"txPath": "/tx/",
|
|
1580
|
+
"url": "https://explorer.arc.io"
|
|
1581
|
+
},
|
|
1582
|
+
"iconSlug": "arc",
|
|
1583
|
+
"name": "Arc",
|
|
1584
|
+
"nativeToken": {
|
|
1585
|
+
"address": "0x0000000000000000000000000000000000000000",
|
|
1586
|
+
"decimals": 18,
|
|
1587
|
+
"symbol": "USDC"
|
|
1588
|
+
},
|
|
1589
|
+
"network": "mainnet",
|
|
1590
|
+
"providerIds": {
|
|
1591
|
+
"alchemy": null,
|
|
1592
|
+
"zerion": null
|
|
1593
|
+
},
|
|
1594
|
+
"publicRpcUrl": "https://rpc.mainnet.arc.io",
|
|
1595
|
+
"sessionCapable": false,
|
|
1596
|
+
"settlementConfig": {
|
|
1597
|
+
"cctp": {
|
|
1598
|
+
"domain": 26
|
|
1599
|
+
},
|
|
1600
|
+
"rhino": {
|
|
1601
|
+
"bridgeContract": "0x5e023c31e1d3dcd08a1b3e8c96f6ef8aa8fcacd1",
|
|
1602
|
+
"chainName": "ARC"
|
|
1603
|
+
}
|
|
1604
|
+
},
|
|
1605
|
+
"settlementLayers": [
|
|
1606
|
+
"ACROSS",
|
|
1607
|
+
"RELAY",
|
|
1608
|
+
"RHINO",
|
|
1609
|
+
"CCTP"
|
|
1610
|
+
],
|
|
1611
|
+
"stack": "vanilla",
|
|
1612
|
+
"swapQuoters": [],
|
|
1613
|
+
"tokens": [
|
|
1614
|
+
{
|
|
1615
|
+
"address": "0x3600000000000000000000000000000000000000",
|
|
1616
|
+
"appFee": true,
|
|
1617
|
+
"approvalSlot": null,
|
|
1618
|
+
"balanceSlot": null,
|
|
1619
|
+
"decimals": 6,
|
|
1620
|
+
"gasRefund": true,
|
|
1621
|
+
"pegGroup": "USD",
|
|
1622
|
+
"settlementLayers": [
|
|
1623
|
+
"ACROSS"
|
|
1624
|
+
],
|
|
1625
|
+
"symbol": "USDC"
|
|
1626
|
+
}
|
|
1627
|
+
],
|
|
1628
|
+
"vmType": "evm",
|
|
1629
|
+
"wrappedNativeToken": {
|
|
1630
|
+
"address": "0x3600000000000000000000000000000000000000",
|
|
1631
|
+
"decimals": 6,
|
|
1632
|
+
"symbol": "USDC"
|
|
1633
|
+
},
|
|
1634
|
+
"providers": [
|
|
1635
|
+
"Alchemy",
|
|
1636
|
+
"arc-public-rpc",
|
|
1637
|
+
"DRPC"
|
|
1638
|
+
]
|
|
1639
|
+
},
|
|
1575
1640
|
"8453": {
|
|
1576
1641
|
"caip2": "eip155:8453",
|
|
1577
1642
|
"explorer": {
|
|
@@ -3245,6 +3310,7 @@ const chains = {
|
|
|
3245
3310
|
"alchemy": null,
|
|
3246
3311
|
"zerion": null
|
|
3247
3312
|
},
|
|
3313
|
+
"rpcId": "mainnet-beta",
|
|
3248
3314
|
"sessionCapable": false,
|
|
3249
3315
|
"settlementConfig": {
|
|
3250
3316
|
"cctp": {
|
|
@@ -3350,6 +3416,7 @@ const chains = {
|
|
|
3350
3416
|
"alchemy": null,
|
|
3351
3417
|
"zerion": null
|
|
3352
3418
|
},
|
|
3419
|
+
"rpcId": "devnet",
|
|
3353
3420
|
"sessionCapable": false,
|
|
3354
3421
|
"settlementConfig": {
|
|
3355
3422
|
"cctp": {
|
|
@@ -99,6 +99,10 @@ const contractAddresses = {
|
|
|
99
99
|
"swapAdapter": "0x58BC7d9279A38a1537c2f74426dBDbD804AD3A18",
|
|
100
100
|
"swapAdapterTokenSpender": "0xc5f6641b3ade357c5df77a1859d16528fe8b3e93"
|
|
101
101
|
},
|
|
102
|
+
"5042": {
|
|
103
|
+
"acrossBridge": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84",
|
|
104
|
+
"spokepool": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84"
|
|
105
|
+
},
|
|
102
106
|
"8453": {
|
|
103
107
|
"ecoArbiter": "0x1BeBAfb3D05d84A5Bfd94800c88d1342f755d8AB",
|
|
104
108
|
"acrossBridge": "0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64",
|
|
@@ -99,6 +99,10 @@ const contractAddresses = {
|
|
|
99
99
|
"swapAdapter": "0xaE448E141F230AC3c6F6dA981C0882356c9B91a6",
|
|
100
100
|
"swapAdapterTokenSpender": "0x3115c923734471b9da1d5bfef161d9c9e9963859"
|
|
101
101
|
},
|
|
102
|
+
"5042": {
|
|
103
|
+
"acrossBridge": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84",
|
|
104
|
+
"spokepool": "0x9b4A302A548c7e313c2b74C461db7b84d3074A84"
|
|
105
|
+
},
|
|
102
106
|
"8453": {
|
|
103
107
|
"ecoArbiter": "0x2e7627CCfAe4eDb336eEb5a70f08415B0F1a2b8C",
|
|
104
108
|
"acrossBridge": "0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64",
|
|
@@ -2222,6 +2222,60 @@ declare const mainnetChains: ({
|
|
|
2222
2222
|
}] | undefined;
|
|
2223
2223
|
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
2224
2224
|
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
2225
|
+
} | {
|
|
2226
|
+
blockExplorers?: {
|
|
2227
|
+
[key: string]: {
|
|
2228
|
+
name: string;
|
|
2229
|
+
url: string;
|
|
2230
|
+
apiUrl?: string | undefined;
|
|
2231
|
+
};
|
|
2232
|
+
default: {
|
|
2233
|
+
name: string;
|
|
2234
|
+
url: string;
|
|
2235
|
+
apiUrl?: string | undefined;
|
|
2236
|
+
};
|
|
2237
|
+
} | undefined | undefined;
|
|
2238
|
+
blockTime?: number | undefined | undefined;
|
|
2239
|
+
contracts?: {
|
|
2240
|
+
[x: string]: import("viem").ChainContract | {
|
|
2241
|
+
[sourceId: number]: import("viem").ChainContract | undefined;
|
|
2242
|
+
} | undefined;
|
|
2243
|
+
ensRegistry?: import("viem").ChainContract | undefined;
|
|
2244
|
+
ensUniversalResolver?: import("viem").ChainContract | undefined;
|
|
2245
|
+
multicall3?: import("viem").ChainContract | undefined;
|
|
2246
|
+
erc6492Verifier?: import("viem").ChainContract | undefined;
|
|
2247
|
+
} | undefined;
|
|
2248
|
+
ensTlds?: readonly string[] | undefined;
|
|
2249
|
+
id: 5042;
|
|
2250
|
+
name: "Arc";
|
|
2251
|
+
nativeCurrency: {
|
|
2252
|
+
readonly name: "USDC";
|
|
2253
|
+
readonly symbol: "USDC";
|
|
2254
|
+
readonly decimals: 18;
|
|
2255
|
+
};
|
|
2256
|
+
experimental_preconfirmationTime?: number | undefined | undefined;
|
|
2257
|
+
rpcUrls: {
|
|
2258
|
+
readonly default: {
|
|
2259
|
+
readonly http: readonly [];
|
|
2260
|
+
};
|
|
2261
|
+
};
|
|
2262
|
+
sourceId?: number | undefined | undefined;
|
|
2263
|
+
testnet?: boolean | undefined | undefined;
|
|
2264
|
+
custom?: Record<string, unknown> | undefined;
|
|
2265
|
+
extendSchema?: Record<string, unknown> | undefined;
|
|
2266
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
2267
|
+
formatters?: undefined;
|
|
2268
|
+
prepareTransactionRequest?: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
2269
|
+
client: import("viem").Client;
|
|
2270
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
2271
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | [fn: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
2272
|
+
client: import("viem").Client;
|
|
2273
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
2274
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | undefined, options: {
|
|
2275
|
+
runAt: readonly ("beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters")[];
|
|
2276
|
+
}] | undefined;
|
|
2277
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
2278
|
+
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
2225
2279
|
})[];
|
|
2226
2280
|
declare const testnetChains: ({
|
|
2227
2281
|
blockExplorers: {
|
|
@@ -5242,6 +5296,60 @@ declare const chains: ({
|
|
|
5242
5296
|
}] | undefined;
|
|
5243
5297
|
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
5244
5298
|
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
5299
|
+
} | {
|
|
5300
|
+
blockExplorers?: {
|
|
5301
|
+
[key: string]: {
|
|
5302
|
+
name: string;
|
|
5303
|
+
url: string;
|
|
5304
|
+
apiUrl?: string | undefined;
|
|
5305
|
+
};
|
|
5306
|
+
default: {
|
|
5307
|
+
name: string;
|
|
5308
|
+
url: string;
|
|
5309
|
+
apiUrl?: string | undefined;
|
|
5310
|
+
};
|
|
5311
|
+
} | undefined | undefined;
|
|
5312
|
+
blockTime?: number | undefined | undefined;
|
|
5313
|
+
contracts?: {
|
|
5314
|
+
[x: string]: import("viem").ChainContract | {
|
|
5315
|
+
[sourceId: number]: import("viem").ChainContract | undefined;
|
|
5316
|
+
} | undefined;
|
|
5317
|
+
ensRegistry?: import("viem").ChainContract | undefined;
|
|
5318
|
+
ensUniversalResolver?: import("viem").ChainContract | undefined;
|
|
5319
|
+
multicall3?: import("viem").ChainContract | undefined;
|
|
5320
|
+
erc6492Verifier?: import("viem").ChainContract | undefined;
|
|
5321
|
+
} | undefined;
|
|
5322
|
+
ensTlds?: readonly string[] | undefined;
|
|
5323
|
+
id: 5042;
|
|
5324
|
+
name: "Arc";
|
|
5325
|
+
nativeCurrency: {
|
|
5326
|
+
readonly name: "USDC";
|
|
5327
|
+
readonly symbol: "USDC";
|
|
5328
|
+
readonly decimals: 18;
|
|
5329
|
+
};
|
|
5330
|
+
experimental_preconfirmationTime?: number | undefined | undefined;
|
|
5331
|
+
rpcUrls: {
|
|
5332
|
+
readonly default: {
|
|
5333
|
+
readonly http: readonly [];
|
|
5334
|
+
};
|
|
5335
|
+
};
|
|
5336
|
+
sourceId?: number | undefined | undefined;
|
|
5337
|
+
testnet?: boolean | undefined | undefined;
|
|
5338
|
+
custom?: Record<string, unknown> | undefined;
|
|
5339
|
+
extendSchema?: Record<string, unknown> | undefined;
|
|
5340
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
5341
|
+
formatters?: undefined;
|
|
5342
|
+
prepareTransactionRequest?: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
5343
|
+
client: import("viem").Client;
|
|
5344
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
5345
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | [fn: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
5346
|
+
client: import("viem").Client;
|
|
5347
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
5348
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | undefined, options: {
|
|
5349
|
+
runAt: readonly ("beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters")[];
|
|
5350
|
+
}] | undefined;
|
|
5351
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
5352
|
+
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
5245
5353
|
} | {
|
|
5246
5354
|
blockExplorers: {
|
|
5247
5355
|
readonly default: {
|
|
@@ -6060,7 +6168,8 @@ declare enum MainnetNetwork {
|
|
|
6060
6168
|
ROBINHOOD,
|
|
6061
6169
|
AVALANCHE,
|
|
6062
6170
|
INK,
|
|
6063
|
-
XLAYER
|
|
6171
|
+
XLAYER,
|
|
6172
|
+
ARC
|
|
6064
6173
|
}
|
|
6065
6174
|
declare enum TestnetNetwork {
|
|
6066
6175
|
ETHEREUM_SEPOLIA,
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OPStackChains = exports.TestnetNetwork = exports.MainnetNetwork = exports.chains = exports.testnetChains = exports.mainnetChains = void 0;
|
|
4
4
|
// Auto-generated by scripts/generate.ts. Do not edit manually.
|
|
5
5
|
const chains_1 = require("viem/chains");
|
|
6
|
-
const mainnetChains = [chains_1.mainnet, chains_1.optimism, chains_1.base, chains_1.arbitrum, chains_1.polygon, chains_1.soneium, chains_1.sonic, chains_1.plasma, chains_1.gnosis, chains_1.bsc, chains_1.hyperEvm, chains_1.monad, chains_1.unichain, chains_1.katana, chains_1.robinhood, chains_1.avalanche, chains_1.ink, chains_1.xLayer];
|
|
6
|
+
const mainnetChains = [chains_1.mainnet, chains_1.optimism, chains_1.base, chains_1.arbitrum, chains_1.polygon, chains_1.soneium, chains_1.sonic, chains_1.plasma, chains_1.gnosis, chains_1.bsc, chains_1.hyperEvm, chains_1.monad, chains_1.unichain, chains_1.katana, chains_1.robinhood, chains_1.avalanche, chains_1.ink, chains_1.xLayer, chains_1.arc];
|
|
7
7
|
exports.mainnetChains = mainnetChains;
|
|
8
8
|
const testnetChains = [chains_1.sepolia, chains_1.optimismSepolia, chains_1.baseSepolia, chains_1.arbitrumSepolia, chains_1.plasmaTestnet];
|
|
9
9
|
exports.testnetChains = testnetChains;
|
|
@@ -34,6 +34,7 @@ var MainnetNetwork;
|
|
|
34
34
|
MainnetNetwork[MainnetNetwork["AVALANCHE"] = chains_1.avalanche.id] = "AVALANCHE";
|
|
35
35
|
MainnetNetwork[MainnetNetwork["INK"] = chains_1.ink.id] = "INK";
|
|
36
36
|
MainnetNetwork[MainnetNetwork["XLAYER"] = chains_1.xLayer.id] = "XLAYER";
|
|
37
|
+
MainnetNetwork[MainnetNetwork["ARC"] = chains_1.arc.id] = "ARC";
|
|
37
38
|
})(MainnetNetwork || (exports.MainnetNetwork = MainnetNetwork = {}));
|
|
38
39
|
var TestnetNetwork;
|
|
39
40
|
(function (TestnetNetwork) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const PACKAGE_VERSION = "2.
|
|
1
|
+
declare const PACKAGE_VERSION = "2.21.1";
|
|
2
2
|
export { PACKAGE_VERSION };
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PACKAGE_VERSION = void 0;
|
|
4
4
|
// Auto-generated by scripts/generate.ts. Do not edit manually.
|
|
5
|
-
const PACKAGE_VERSION = "2.
|
|
5
|
+
const PACKAGE_VERSION = "2.21.1";
|
|
6
6
|
exports.PACKAGE_VERSION = PACKAGE_VERSION;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -349,6 +349,26 @@ interface ChainEntry {
|
|
|
349
349
|
* `validateChainIconSlugs`.
|
|
350
350
|
*/
|
|
351
351
|
iconSlug?: string;
|
|
352
|
+
/**
|
|
353
|
+
* The identifier this chain is addressed by when you dial it, within its
|
|
354
|
+
* architecture — the last path segment of `{proxy}/{architecture}/{rpcId}`.
|
|
355
|
+
*
|
|
356
|
+
* For an EVM chain it is the chain id as a string. For Solana it is the
|
|
357
|
+
* cluster name (`mainnet-beta`, `devnet`), which is what every Solana RPC
|
|
358
|
+
* endpoint and the CLI call it, and what eRPC keys its network by. Not a
|
|
359
|
+
* proxy-specific spelling: a vendor endpoint uses the same word.
|
|
360
|
+
*
|
|
361
|
+
* Read this instead of branching on `vmType` and rebuilding the segment per
|
|
362
|
+
* family: every consumer that reached Solana previously kept its own caip2 →
|
|
363
|
+
* cluster table, and those tables drifted from each other.
|
|
364
|
+
*
|
|
365
|
+
* Present only where the chain id is NOT what you dial — the two Solana
|
|
366
|
+
* entries today, and nowhere else. **Absent means the chain id is the id**,
|
|
367
|
+
* so a consumer reads `chain.rpcId ?? String(chainId)`. Storing the id again
|
|
368
|
+
* on every EVM entry would be a second copy of the key it sits under, which
|
|
369
|
+
* is the kind of copy that drifts.
|
|
370
|
+
*/
|
|
371
|
+
rpcId?: string;
|
|
352
372
|
/**
|
|
353
373
|
* A public, unauthenticated JSON-RPC endpoint over HTTPS, when one is known.
|
|
354
374
|
*
|
|
@@ -463,7 +483,7 @@ type ContractAddresses = Record<string, Record<string, Address>>;
|
|
|
463
483
|
interface ChainRegistry {
|
|
464
484
|
[chainId: string]: ChainEntry;
|
|
465
485
|
}
|
|
466
|
-
type ProviderName = 'DRPC' | 'Alchemy' | 'gnosis-tenderly' | 'plasma-tenderly' | 'local-rpc' | 'quicknode-hypervm' | 'soneium-public-rpc';
|
|
486
|
+
type ProviderName = 'DRPC' | 'Alchemy' | 'gnosis-tenderly' | 'plasma-tenderly' | 'local-rpc' | 'quicknode-hypervm' | 'soneium-public-rpc' | 'arc-public-rpc';
|
|
467
487
|
interface ChainItem {
|
|
468
488
|
providers: ProviderName[];
|
|
469
489
|
}
|