@snowbridge/registry 0.3.3 → 0.4.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/.turbo/turbo-build.log +1 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -2
- package/dist/paseo_sepolia_bridge_info.g.d.ts +330 -0
- package/dist/paseo_sepolia_bridge_info.g.d.ts.map +1 -0
- package/dist/paseo_sepolia_bridge_info.g.js +350 -0
- package/dist/polkadot_mainnet_bridge_info.g.d.ts +1983 -0
- package/dist/polkadot_mainnet_bridge_info.g.d.ts.map +1 -0
- package/dist/polkadot_mainnet_bridge_info.g.js +2264 -0
- package/dist/transfers.d.ts +3 -8
- package/dist/transfers.d.ts.map +1 -1
- package/dist/transfers.js +54 -215
- package/dist/westend_sepolia_bridge_info.g.d.ts +344 -0
- package/dist/westend_sepolia_bridge_info.g.d.ts.map +1 -0
- package/dist/westend_sepolia_bridge_info.g.js +376 -0
- package/package.json +5 -5
- package/scripts/buildRegistry.ts +466 -29
- package/src/index.ts +24 -2
- package/src/paseo_sepolia_bridge_info.g.ts +349 -0
- package/src/polkadot_mainnet_bridge_info.g.ts +2287 -0
- package/src/transfers.ts +58 -266
- package/src/westend_sepolia_bridge_info.g.ts +384 -0
- package/dist/environment.d.ts +0 -3
- package/dist/environment.d.ts.map +0 -1
- package/dist/environment.js +0 -181
- package/dist/local_e2e.registry.json +0 -391
- package/dist/paseo_sepolia.registry.json +0 -231
- package/dist/polkadot_mainnet.registry.json +0 -1805
- package/dist/registry.d.ts +0 -3
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -61
- package/dist/westend_sepolia.registry.json +0 -283
- package/src/environment.ts +0 -185
- package/src/local_e2e.registry.json +0 -391
- package/src/paseo_sepolia.registry.json +0 -231
- package/src/polkadot_mainnet.registry.json +0 -1805
- package/src/registry.ts +0 -63
- package/src/westend_sepolia.registry.json +0 -283
package/scripts/buildRegistry.ts
CHANGED
|
@@ -16,15 +16,399 @@ import {
|
|
|
16
16
|
PrecompileMap,
|
|
17
17
|
XC20TokenMap,
|
|
18
18
|
XcmVersion,
|
|
19
|
+
BridgeInfo,
|
|
20
|
+
TransferRoute,
|
|
21
|
+
ChainId,
|
|
22
|
+
ChainKey,
|
|
23
|
+
ParachainKind,
|
|
19
24
|
} from "@snowbridge/base-types"
|
|
20
25
|
import { ApiPromise, HttpProvider, WsProvider } from "@polkadot/api"
|
|
21
26
|
import { isFunction } from "@polkadot/util"
|
|
22
27
|
import { writeFile } from "fs/promises"
|
|
23
|
-
import { environmentFor } from "../src"
|
|
24
28
|
import { AbstractProvider, Contract, ethers } from "ethers"
|
|
25
29
|
import { IGatewayV1__factory as IGateway__factory } from "@snowbridge/contract-types"
|
|
26
30
|
import { parachains as ParaImpl, xcmBuilder, assetsV2 } from "@snowbridge/api"
|
|
27
31
|
|
|
32
|
+
export type Path = {
|
|
33
|
+
source: ChainId
|
|
34
|
+
destination: ChainId
|
|
35
|
+
asset: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const SNOWBRIDGE_ENV: { [env: string]: Environment } = {
|
|
39
|
+
local_e2e: {
|
|
40
|
+
name: "local_e2e",
|
|
41
|
+
ethChainId: 11155111,
|
|
42
|
+
beaconApiUrl: "http://127.0.0.1:9596",
|
|
43
|
+
ethereumChains: {
|
|
44
|
+
"11155111": "ws://127.0.0.1:8546",
|
|
45
|
+
},
|
|
46
|
+
relaychainUrl: "ws://127.0.0.1:9944",
|
|
47
|
+
parachains: {
|
|
48
|
+
"1000": "ws://127.0.0.1:12144",
|
|
49
|
+
"1002": "ws://127.0.0.1:11144",
|
|
50
|
+
"2000": "ws://127.0.0.1:13144",
|
|
51
|
+
},
|
|
52
|
+
gatewayContract: "0xb1185ede04202fe62d38f5db72f71e38ff3e8305",
|
|
53
|
+
beefyContract: "0x83428c7db9815f482a39a1715684dcf755021997",
|
|
54
|
+
assetHubParaId: 1000,
|
|
55
|
+
bridgeHubParaId: 1002,
|
|
56
|
+
v2_parachains: [1000],
|
|
57
|
+
indexerGraphQlUrl: "http://127.0.0.1/does/not/exist",
|
|
58
|
+
},
|
|
59
|
+
paseo_sepolia: {
|
|
60
|
+
name: "paseo_sepolia",
|
|
61
|
+
ethChainId: 11155111,
|
|
62
|
+
beaconApiUrl: "https://lodestar-sepolia.chainsafe.io",
|
|
63
|
+
ethereumChains: {
|
|
64
|
+
"11155111": "https://ethereum-sepolia-rpc.publicnode.com",
|
|
65
|
+
},
|
|
66
|
+
relaychainUrl: "wss://paseo-rpc.n.dwellir.com",
|
|
67
|
+
parachains: {
|
|
68
|
+
"1000": "wss://asset-hub-paseo-rpc.n.dwellir.com",
|
|
69
|
+
"1002": "wss://bridge-hub-paseo.dotters.network",
|
|
70
|
+
"3369": "wss://paseo-muse-rpc.polkadot.io",
|
|
71
|
+
"2043": `wss://parachain-testnet-rpc.origin-trail.network`,
|
|
72
|
+
},
|
|
73
|
+
gatewayContract: "0x1607C1368bc943130258318c91bBd8cFf3D063E6",
|
|
74
|
+
beefyContract: "0x2c780945beb1241fE9c645800110cb9C4bBbb639",
|
|
75
|
+
assetHubParaId: 1000,
|
|
76
|
+
bridgeHubParaId: 1002,
|
|
77
|
+
v2_parachains: [1000],
|
|
78
|
+
indexerGraphQlUrl:
|
|
79
|
+
"https://snowbridge.squids.live/snowbridge-subsquid-paseo@v1/api/graphql",
|
|
80
|
+
metadataOverrides: {
|
|
81
|
+
// Change the name of TRAC
|
|
82
|
+
"0xef32abea56beff54f61da319a7311098d6fbcea9": {
|
|
83
|
+
name: "OriginTrail TRAC",
|
|
84
|
+
symbol: "TRAC",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
polkadot_mainnet: {
|
|
89
|
+
name: "polkadot_mainnet",
|
|
90
|
+
ethChainId: 1,
|
|
91
|
+
beaconApiUrl: "https://lodestar-mainnet.chainsafe.io",
|
|
92
|
+
ethereumChains: {
|
|
93
|
+
"1": "https://ethereum-rpc.publicnode.com",
|
|
94
|
+
"1284": "https://rpc.api.moonbeam.network",
|
|
95
|
+
"8453": "https://base-rpc.publicnode.com",
|
|
96
|
+
},
|
|
97
|
+
relaychainUrl: "https://polkadot-rpc.n.dwellir.com",
|
|
98
|
+
parachains: {
|
|
99
|
+
"1000": "wss://asset-hub-polkadot-rpc.n.dwellir.com",
|
|
100
|
+
"1002": "https://bridge-hub-polkadot-rpc.n.dwellir.com",
|
|
101
|
+
"3369": "wss://polkadot-mythos-rpc.polkadot.io",
|
|
102
|
+
"2034": "wss://hydration-rpc.n.dwellir.com",
|
|
103
|
+
"2030": "wss://bifrost-polkadot.ibp.network",
|
|
104
|
+
"2004": "wss://moonbeam.ibp.network",
|
|
105
|
+
"2000": "wss://acala-rpc-0.aca-api.network",
|
|
106
|
+
"2043": "wss://parachain-rpc.origin-trail.network",
|
|
107
|
+
// TODO: Add back in jampton once we have an indexer in place.
|
|
108
|
+
//"3397": "wss://rpc.jamton.network",
|
|
109
|
+
},
|
|
110
|
+
gatewayContract: "0x27ca963c279c93801941e1eb8799c23f407d68e7",
|
|
111
|
+
beefyContract: "0x1817874feAb3ce053d0F40AbC23870DB35C2AFfc",
|
|
112
|
+
assetHubParaId: 1000,
|
|
113
|
+
bridgeHubParaId: 1002,
|
|
114
|
+
v2_parachains: [1000],
|
|
115
|
+
indexerGraphQlUrl:
|
|
116
|
+
"https://snowbridge.squids.live/snowbridge-subsquid-polkadot@v2/api/graphql",
|
|
117
|
+
kusama: {
|
|
118
|
+
assetHubParaId: 1000,
|
|
119
|
+
bridgeHubParaId: 1002,
|
|
120
|
+
parachains: {
|
|
121
|
+
"1000": "wss://asset-hub-kusama-rpc.n.dwellir.com",
|
|
122
|
+
"1002": "https://bridge-hub-kusama-rpc.n.dwellir.com",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
precompiles: {
|
|
126
|
+
// Add override for mythos token and add precompile for moonbeam
|
|
127
|
+
"2004": "0x000000000000000000000000000000000000081a",
|
|
128
|
+
},
|
|
129
|
+
metadataOverrides: {
|
|
130
|
+
// Change the name of TRAC
|
|
131
|
+
"0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f": {
|
|
132
|
+
name: "OriginTrail TRAC",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
l2Bridge: {
|
|
136
|
+
acrossAPIUrl: "https://app.across.to/api",
|
|
137
|
+
l1AdapterAddress: "0x313E8c9Fb47613f2B1A436bE978c2BB75727fcC5",
|
|
138
|
+
l1HandlerAddress: "0x924a9f036260DdD5808007E1AA95f08eD08aA569",
|
|
139
|
+
l1FeeTokenAddress: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
|
140
|
+
l1SwapQuoterAddress: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e",
|
|
141
|
+
l1SwapRouterAddress: "0xE592427A0AEce92De3Edee1F18E0157C05861564",
|
|
142
|
+
l2Chains: {
|
|
143
|
+
"8453": {
|
|
144
|
+
adapterAddress: "0xCd5d2c665E3AC84bF5c67FE7a0C48748dA40db2F",
|
|
145
|
+
feeTokenAddress: "0x4200000000000000000000000000000000000006",
|
|
146
|
+
swapRoutes: [
|
|
147
|
+
// WETH
|
|
148
|
+
{
|
|
149
|
+
inputToken: "0x4200000000000000000000000000000000000006",
|
|
150
|
+
outputToken: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
|
151
|
+
swapFee: 0,
|
|
152
|
+
},
|
|
153
|
+
// USDC
|
|
154
|
+
{
|
|
155
|
+
inputToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
156
|
+
outputToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
157
|
+
swapFee: 500,
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
westend_sepolia: {
|
|
165
|
+
name: "westend_sepolia",
|
|
166
|
+
ethChainId: 11155111,
|
|
167
|
+
beaconApiUrl: "https://lodestar-sepolia.chainsafe.io",
|
|
168
|
+
ethereumChains: {
|
|
169
|
+
"11155111": "https://ethereum-sepolia-rpc.publicnode.com",
|
|
170
|
+
"84532": "https://base-sepolia-rpc.publicnode.com",
|
|
171
|
+
},
|
|
172
|
+
relaychainUrl: "wss://westend-rpc.n.dwellir.com",
|
|
173
|
+
parachains: {
|
|
174
|
+
"1000": "wss://asset-hub-westend-rpc.n.dwellir.com",
|
|
175
|
+
"1002": "wss://bridge-hub-westend-rpc.n.dwellir.com",
|
|
176
|
+
},
|
|
177
|
+
gatewayContract: "0x9ed8b47bc3417e3bd0507adc06e56e2fa360a4e9",
|
|
178
|
+
beefyContract: "0xA04460B1D8bBef33F54edB2C3115e3E4D41237A6",
|
|
179
|
+
assetHubParaId: 1000,
|
|
180
|
+
bridgeHubParaId: 1002,
|
|
181
|
+
v2_parachains: [1000],
|
|
182
|
+
indexerGraphQlUrl:
|
|
183
|
+
"https://snowbridge.squids.live/snowbridge-subsquid-westend@v1/api/graphql",
|
|
184
|
+
l2Bridge: {
|
|
185
|
+
acrossAPIUrl: "https://testnet.across.to/api",
|
|
186
|
+
l1AdapterAddress: "0xA5B8589bD534701be49916c4d2e634aB1c765Cbf",
|
|
187
|
+
l1HandlerAddress: "0x924a9f036260DdD5808007E1AA95f08eD08aA569",
|
|
188
|
+
l1FeeTokenAddress: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14",
|
|
189
|
+
l1SwapRouterAddress: "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E",
|
|
190
|
+
l1SwapQuoterAddress: "0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3",
|
|
191
|
+
l2Chains: {
|
|
192
|
+
"84532": {
|
|
193
|
+
adapterAddress: "0xf06939613A3838Af11104c898758220dB9093679",
|
|
194
|
+
feeTokenAddress: "0x4200000000000000000000000000000000000006",
|
|
195
|
+
swapRoutes: [
|
|
196
|
+
// WETH
|
|
197
|
+
{
|
|
198
|
+
inputToken: "0x4200000000000000000000000000000000000006",
|
|
199
|
+
outputToken: "0xfff9976782d46cc05630d1f6ebab18b2324d6b14",
|
|
200
|
+
swapFee: 0,
|
|
201
|
+
},
|
|
202
|
+
// USDC
|
|
203
|
+
{
|
|
204
|
+
inputToken: "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
|
|
205
|
+
outputToken: "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
|
|
206
|
+
swapFee: 500,
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function defaultPathFilter(envName: string): (_: Path) => boolean {
|
|
216
|
+
switch (envName) {
|
|
217
|
+
case "westend_sepolia": {
|
|
218
|
+
return (path: Path) => {
|
|
219
|
+
// Frequency
|
|
220
|
+
if (path.asset === "0x72c610e05eaafcdf1fa7a2da15374ee90edb1620") {
|
|
221
|
+
return false
|
|
222
|
+
}
|
|
223
|
+
// Disable para to para transfers
|
|
224
|
+
if (path.source.kind === "polkadot" && path.destination.kind === "polkadot") {
|
|
225
|
+
return false
|
|
226
|
+
}
|
|
227
|
+
return true
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
case "paseo_sepolia":
|
|
231
|
+
return (path: Path) => {
|
|
232
|
+
// Disallow MUSE to any location but 3369
|
|
233
|
+
if (
|
|
234
|
+
path.asset === "0xb34a6924a02100ba6ef12af1c798285e8f7a16ee" &&
|
|
235
|
+
((path.destination.id !== 3369 && path.source.kind === "ethereum") ||
|
|
236
|
+
(path.source.id !== 3369 && path.source.kind === "polkadot"))
|
|
237
|
+
) {
|
|
238
|
+
return false
|
|
239
|
+
}
|
|
240
|
+
// Disable para to para transfers
|
|
241
|
+
if (path.source.kind === "polkadot" && path.destination.kind === "polkadot") {
|
|
242
|
+
return false
|
|
243
|
+
}
|
|
244
|
+
return true
|
|
245
|
+
}
|
|
246
|
+
case "polkadot_mainnet":
|
|
247
|
+
return (path: Path) => {
|
|
248
|
+
// Disallow MYTH to any location but 3369
|
|
249
|
+
if (
|
|
250
|
+
path.asset === "0xba41ddf06b7ffd89d1267b5a93bfef2424eb2003" &&
|
|
251
|
+
((path.destination.id !== 3369 && path.source.kind === "ethereum") ||
|
|
252
|
+
(path.source.id !== 3369 && path.source.kind === "polkadot"))
|
|
253
|
+
) {
|
|
254
|
+
return false
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Allow TRAC to go to Hydration (2034) and Neuroweb (2043) only
|
|
258
|
+
if (
|
|
259
|
+
path.asset === "0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f" &&
|
|
260
|
+
((path.destination.id !== 2034 &&
|
|
261
|
+
path.destination.id !== 2043 &&
|
|
262
|
+
path.source.kind === "ethereum") ||
|
|
263
|
+
(path.source.id !== 2034 &&
|
|
264
|
+
path.source.id !== 2043 &&
|
|
265
|
+
path.source.kind === "polkadot"))
|
|
266
|
+
) {
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Disable stable coins in the UI from Ethereum to Polkadot
|
|
271
|
+
if (
|
|
272
|
+
(path.asset === "0x9d39a5de30e57443bff2a8307a4256c8797a3497" || // Staked USDe
|
|
273
|
+
path.asset === "0xa3931d71877c0e7a3148cb7eb4463524fec27fbd" || // Savings USD
|
|
274
|
+
path.asset === "0x6b175474e89094c44da98b954eedeac495271d0f") && // DAI
|
|
275
|
+
path.destination.id === 2034 // Hydration
|
|
276
|
+
) {
|
|
277
|
+
return false
|
|
278
|
+
}
|
|
279
|
+
// Disable para to para transfers except for hydration
|
|
280
|
+
if (
|
|
281
|
+
path.source.kind === "polkadot" &&
|
|
282
|
+
path.destination.kind === "polkadot" &&
|
|
283
|
+
!(
|
|
284
|
+
(path.source.id === 2034 && path.destination.id == 1000) ||
|
|
285
|
+
(path.source.id === 1000 && path.destination.id === 2034)
|
|
286
|
+
)
|
|
287
|
+
) {
|
|
288
|
+
return false
|
|
289
|
+
}
|
|
290
|
+
return true
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
default:
|
|
294
|
+
return (_: Path) => true
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function buildTransferLocations(
|
|
299
|
+
registry: AssetRegistry,
|
|
300
|
+
filter?: (path: Path) => boolean,
|
|
301
|
+
): TransferRoute[] {
|
|
302
|
+
const ethChain = registry.ethereumChains[`ethereum_${registry.ethChainId}`]
|
|
303
|
+
const parachains = Object.values(registry.parachains).filter(
|
|
304
|
+
(p) => !(p.kind === "polkadot" && p.id === registry.bridgeHubParaId),
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
const pathFilter = filter ?? defaultPathFilter(registry.environment)
|
|
308
|
+
|
|
309
|
+
const locations: Path[] = []
|
|
310
|
+
|
|
311
|
+
const ethAssets = Object.keys(ethChain.assets)
|
|
312
|
+
// Bridged paths
|
|
313
|
+
for (const parachain of parachains) {
|
|
314
|
+
const destinationAssets = Object.keys(parachain.assets)
|
|
315
|
+
const commonAssets = new Set(
|
|
316
|
+
ethAssets.filter((sa) => destinationAssets.find((da) => da === sa)),
|
|
317
|
+
)
|
|
318
|
+
for (const asset of commonAssets) {
|
|
319
|
+
const p1: Path = {
|
|
320
|
+
source: { kind: ethChain.kind, id: ethChain.id },
|
|
321
|
+
destination: { kind: parachain.kind, id: parachain.id },
|
|
322
|
+
asset,
|
|
323
|
+
}
|
|
324
|
+
if (pathFilter(p1)) {
|
|
325
|
+
locations.push(p1)
|
|
326
|
+
}
|
|
327
|
+
const p2: Path = {
|
|
328
|
+
source: p1.destination,
|
|
329
|
+
destination: p1.source,
|
|
330
|
+
asset,
|
|
331
|
+
}
|
|
332
|
+
if (pathFilter(p2)) {
|
|
333
|
+
locations.push(p2)
|
|
334
|
+
}
|
|
335
|
+
if (
|
|
336
|
+
parachain.info.evmChainId &&
|
|
337
|
+
registry.ethereumChains[`ethereum_${parachain.info.evmChainId}`]
|
|
338
|
+
) {
|
|
339
|
+
const p3: Path = {
|
|
340
|
+
source: {
|
|
341
|
+
kind: "ethereum",
|
|
342
|
+
id: parachain.info.evmChainId,
|
|
343
|
+
},
|
|
344
|
+
destination: p1.source, // Ethereum
|
|
345
|
+
asset,
|
|
346
|
+
}
|
|
347
|
+
if (pathFilter(p3)) {
|
|
348
|
+
locations.push(p3)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Local paths
|
|
355
|
+
const assetHub = registry.parachains[`polkadot_${registry.assetHubParaId}`]
|
|
356
|
+
for (const parachain of parachains) {
|
|
357
|
+
if (parachain.kind === assetHub.kind && parachain.id === assetHub.id) continue
|
|
358
|
+
const assetHubAssets = Object.keys(assetHub.assets)
|
|
359
|
+
const destinationAssets = Object.keys(parachain.assets)
|
|
360
|
+
|
|
361
|
+
// The asset exists on ethereum, parachain and asset hub
|
|
362
|
+
const commonAssets = new Set(
|
|
363
|
+
ethAssets.filter(
|
|
364
|
+
(sa) =>
|
|
365
|
+
assetHubAssets.find((da) => da === sa) &&
|
|
366
|
+
destinationAssets.find((da) => da === sa),
|
|
367
|
+
),
|
|
368
|
+
)
|
|
369
|
+
for (const asset of commonAssets) {
|
|
370
|
+
const p1: Path = {
|
|
371
|
+
source: { kind: assetHub.kind, id: assetHub.id },
|
|
372
|
+
destination: { kind: parachain.kind, id: parachain.id },
|
|
373
|
+
asset,
|
|
374
|
+
}
|
|
375
|
+
if (pathFilter(p1)) {
|
|
376
|
+
locations.push(p1)
|
|
377
|
+
}
|
|
378
|
+
const p2: Path = {
|
|
379
|
+
source: p1.destination, // Parachain
|
|
380
|
+
destination: p1.source, // Asset Hub
|
|
381
|
+
asset,
|
|
382
|
+
}
|
|
383
|
+
if (pathFilter(p2)) {
|
|
384
|
+
locations.push(p2)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const results: TransferRoute[] = []
|
|
390
|
+
for (const location of locations) {
|
|
391
|
+
let source = results.find(
|
|
392
|
+
(s) =>
|
|
393
|
+
s.from.kind === location.source.kind &&
|
|
394
|
+
s.from.id === location.source.id &&
|
|
395
|
+
s.to.kind === location.destination.kind &&
|
|
396
|
+
s.to.id === location.destination.id,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
if (!source) {
|
|
400
|
+
source = {
|
|
401
|
+
from: location.source,
|
|
402
|
+
to: location.destination,
|
|
403
|
+
assets: [],
|
|
404
|
+
}
|
|
405
|
+
results.push(source)
|
|
406
|
+
}
|
|
407
|
+
source.assets = source.assets.concat(location.asset)
|
|
408
|
+
}
|
|
409
|
+
return results
|
|
410
|
+
}
|
|
411
|
+
|
|
28
412
|
async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
29
413
|
const {
|
|
30
414
|
relaychainUrl,
|
|
@@ -139,6 +523,7 @@ async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
|
139
523
|
const para = await indexParachain(
|
|
140
524
|
accessor,
|
|
141
525
|
providers[assetHubParaId.toString()].accessor,
|
|
526
|
+
"polkadot",
|
|
142
527
|
ethChainId,
|
|
143
528
|
parachainId,
|
|
144
529
|
assetHubParaId,
|
|
@@ -149,7 +534,7 @@ async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
|
149
534
|
return { parachainId, para }
|
|
150
535
|
}),
|
|
151
536
|
)) {
|
|
152
|
-
paras[parachainId
|
|
537
|
+
paras[`polkadot_${parachainId}`] = para
|
|
153
538
|
}
|
|
154
539
|
|
|
155
540
|
// Index Ethereum chain
|
|
@@ -170,7 +555,7 @@ async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
|
170
555
|
)
|
|
171
556
|
}),
|
|
172
557
|
)) {
|
|
173
|
-
ethChains[ethChainInfo.
|
|
558
|
+
ethChains[ethChainInfo.key] = ethChainInfo
|
|
174
559
|
}
|
|
175
560
|
|
|
176
561
|
let kusamaConfig: KusamaConfig | undefined
|
|
@@ -187,6 +572,7 @@ async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
|
187
572
|
const para = await indexParachain(
|
|
188
573
|
accessor,
|
|
189
574
|
providers[assetHubParaId].accessor,
|
|
575
|
+
"kusama",
|
|
190
576
|
ethChainId,
|
|
191
577
|
accessor.parachainId,
|
|
192
578
|
assetHubParaId,
|
|
@@ -195,7 +581,7 @@ async function buildRegistry(environment: Environment): Promise<AssetRegistry> {
|
|
|
195
581
|
)
|
|
196
582
|
|
|
197
583
|
const kusamaParas: ParachainMap = {}
|
|
198
|
-
kusamaParas[para.
|
|
584
|
+
kusamaParas[para.key] = para
|
|
199
585
|
|
|
200
586
|
kusamaConfig = {
|
|
201
587
|
parachains: kusamaParas,
|
|
@@ -304,12 +690,13 @@ async function checkSnowbridgeV2Support(
|
|
|
304
690
|
async function indexParachain(
|
|
305
691
|
parachain: ParaImpl.ParachainBase,
|
|
306
692
|
assetHub: ParaImpl.ParachainBase,
|
|
693
|
+
kind: ParachainKind,
|
|
307
694
|
ethChainId: number,
|
|
308
695
|
parachainId: number,
|
|
309
696
|
assetHubParaId: number,
|
|
310
697
|
pnaAssets: PNAMap,
|
|
311
698
|
assetOverrides: AssetOverrideMap,
|
|
312
|
-
v2_parachains?: number[],
|
|
699
|
+
v2_parachains?: readonly number[],
|
|
313
700
|
): Promise<Parachain> {
|
|
314
701
|
const info = await parachain.chainProperties()
|
|
315
702
|
|
|
@@ -386,7 +773,9 @@ async function indexParachain(
|
|
|
386
773
|
)
|
|
387
774
|
}
|
|
388
775
|
return {
|
|
389
|
-
parachainId,
|
|
776
|
+
id: parachainId,
|
|
777
|
+
kind,
|
|
778
|
+
key: `${kind}_${parachainId}`,
|
|
390
779
|
features: {
|
|
391
780
|
hasPalletXcm,
|
|
392
781
|
hasDryRunApi,
|
|
@@ -422,7 +811,7 @@ async function indexEthChain(
|
|
|
422
811
|
const id = networkName !== "unknown" ? networkName : undefined
|
|
423
812
|
if (networkChainId == ethChainId) {
|
|
424
813
|
// Asset Hub and get meta data
|
|
425
|
-
const assetHub = parachains[assetHubParaId
|
|
814
|
+
const assetHub = parachains[`polkadot_${assetHubParaId}`]
|
|
426
815
|
const gateway = IGateway__factory.connect(gatewayAddress, provider)
|
|
427
816
|
|
|
428
817
|
const assets: ERC20MetadataMap = {}
|
|
@@ -475,9 +864,10 @@ async function indexEthChain(
|
|
|
475
864
|
)
|
|
476
865
|
}
|
|
477
866
|
return {
|
|
478
|
-
|
|
867
|
+
kind: "ethereum",
|
|
868
|
+
id: networkChainId,
|
|
479
869
|
assets,
|
|
480
|
-
|
|
870
|
+
key: `ethereum_${networkChainId}`,
|
|
481
871
|
baseDeliveryGas: 120_000n,
|
|
482
872
|
}
|
|
483
873
|
} else if (networkChainId in l2Chains) {
|
|
@@ -499,14 +889,15 @@ async function indexEthChain(
|
|
|
499
889
|
swapFee: 0,
|
|
500
890
|
}
|
|
501
891
|
return {
|
|
502
|
-
|
|
892
|
+
kind: "ethereum_l2",
|
|
893
|
+
id: networkChainId,
|
|
503
894
|
assets,
|
|
504
|
-
|
|
895
|
+
key: `ethereum_l2_${networkChainId}`,
|
|
505
896
|
}
|
|
506
897
|
} else {
|
|
507
898
|
let evmParachainChain: Parachain | undefined
|
|
508
899
|
for (const paraId in parachains) {
|
|
509
|
-
const parachain = parachains[paraId]
|
|
900
|
+
const parachain = parachains[paraId as ChainKey<"polkadot">]
|
|
510
901
|
if (parachain.info.evmChainId === networkChainId) {
|
|
511
902
|
evmParachainChain = parachain
|
|
512
903
|
break
|
|
@@ -526,7 +917,7 @@ async function indexEthChain(
|
|
|
526
917
|
xcTokenMap[token] = xc20
|
|
527
918
|
assets[xc20] = asset
|
|
528
919
|
}
|
|
529
|
-
const paraId = evmParachainChain.
|
|
920
|
+
const paraId = evmParachainChain.id.toString()
|
|
530
921
|
if (!(paraId in precompiles)) {
|
|
531
922
|
throw Error(
|
|
532
923
|
`No precompile configured for parachain ${paraId} (ethereum chain ${networkChainId}).`,
|
|
@@ -548,13 +939,14 @@ async function indexEthChain(
|
|
|
548
939
|
assets[evmParachainChain.xcDOT] = xc20DOTAsset
|
|
549
940
|
|
|
550
941
|
return {
|
|
551
|
-
|
|
552
|
-
|
|
942
|
+
kind: "ethereum",
|
|
943
|
+
id: networkChainId,
|
|
944
|
+
key: `ethereum_${networkChainId}`,
|
|
945
|
+
evmParachainId: evmParachainChain.id,
|
|
553
946
|
assets,
|
|
554
947
|
precompile,
|
|
555
948
|
xcDOT: evmParachainChain.xcDOT,
|
|
556
949
|
xcTokenMap,
|
|
557
|
-
id: id ?? `evm_${evmParachainChain.info.specName}`,
|
|
558
950
|
}
|
|
559
951
|
}
|
|
560
952
|
}
|
|
@@ -652,18 +1044,63 @@ async function getRegisteredPnas(
|
|
|
652
1044
|
if (process.env.NODE_ENV !== undefined) {
|
|
653
1045
|
env = process.env.NODE_ENV
|
|
654
1046
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
1047
|
+
if (!(env in SNOWBRIDGE_ENV)) {
|
|
1048
|
+
throw Error(`Unknown environment ${env}.`)
|
|
1049
|
+
}
|
|
1050
|
+
const environment = SNOWBRIDGE_ENV[env]
|
|
1051
|
+
const registry = await buildRegistry(environment)
|
|
1052
|
+
const routes = buildTransferLocations(registry)
|
|
1053
|
+
const bridge: BridgeInfo = { environment, routes, registry }
|
|
1054
|
+
const json = generateTsObject(bridge, 4)
|
|
1055
|
+
const fileContents = `const registry = ${json} as const\nexport default registry\n`
|
|
1056
|
+
const filepath = `src/${env}_bridge_info.g.ts`
|
|
1057
|
+
await writeFile(filepath, fileContents)
|
|
1058
|
+
})()
|
|
1059
|
+
|
|
1060
|
+
function generateTsObject(value: unknown, indentSize = 4): string {
|
|
1061
|
+
const indentUnit = " ".repeat(indentSize)
|
|
1062
|
+
const serialize = (val: unknown, depth: number): string | undefined => {
|
|
1063
|
+
if (val === null) return "null"
|
|
1064
|
+
if (val === undefined) return undefined
|
|
1065
|
+
if (typeof val === "function" || typeof val === "symbol") return undefined
|
|
1066
|
+
if (typeof val === "bigint") return `${val}n`
|
|
1067
|
+
if (typeof val === "string") return JSON.stringify(val)
|
|
1068
|
+
if (typeof val === "number" || typeof val === "boolean") return String(val)
|
|
1069
|
+
if (Array.isArray(val)) {
|
|
1070
|
+
if (val.length === 0) return "[]"
|
|
1071
|
+
const indent = indentUnit.repeat(depth + 1)
|
|
1072
|
+
const closingIndent = indentUnit.repeat(depth)
|
|
1073
|
+
const items = val
|
|
1074
|
+
.map((item) => {
|
|
1075
|
+
const serialized = serialize(item, depth + 1)
|
|
1076
|
+
return `${indent}${serialized ?? "null"}`
|
|
1077
|
+
})
|
|
1078
|
+
.join(",\n")
|
|
1079
|
+
return `[\n${items}\n${closingIndent}]`
|
|
1080
|
+
}
|
|
1081
|
+
if (typeof val === "object") {
|
|
1082
|
+
const obj = val as Record<string, unknown>
|
|
1083
|
+
const keys = Object.keys(obj)
|
|
1084
|
+
const indent = indentUnit.repeat(depth + 1)
|
|
1085
|
+
const closingIndent = indentUnit.repeat(depth)
|
|
1086
|
+
const items: string[] = []
|
|
1087
|
+
for (const key of keys) {
|
|
1088
|
+
const serialized = serialize(obj[key], depth + 1)
|
|
1089
|
+
if (serialized === undefined) continue
|
|
1090
|
+
const keyLiteral = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)
|
|
1091
|
+
? key
|
|
1092
|
+
: JSON.stringify(key)
|
|
1093
|
+
items.push(`${indent}${keyLiteral}: ${serialized},`)
|
|
661
1094
|
}
|
|
662
|
-
return
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
1095
|
+
if (items.length === 0) return "{}"
|
|
1096
|
+
return `{\n${items.join("\n")}\n${closingIndent}}`
|
|
1097
|
+
}
|
|
1098
|
+
throw new Error(`Unsupported type in registry output: ${typeof val}`)
|
|
1099
|
+
}
|
|
666
1100
|
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
1101
|
+
const serialized = serialize(value, 0)
|
|
1102
|
+
if (serialized === undefined) {
|
|
1103
|
+
throw new Error("Registry output is not serializable")
|
|
1104
|
+
}
|
|
1105
|
+
return serialized
|
|
1106
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
-
export * from "./environment"
|
|
2
|
-
export * from "./registry"
|
|
3
1
|
export * from "./transfers"
|
|
2
|
+
|
|
3
|
+
import polkadot_mainnet from "./polkadot_mainnet_bridge_info.g"
|
|
4
|
+
import westend_sepolia from "./westend_sepolia_bridge_info.g"
|
|
5
|
+
import paseo_sepolia from "./paseo_sepolia_bridge_info.g"
|
|
6
|
+
|
|
7
|
+
export { paseo_sepolia, westend_sepolia, polkadot_mainnet }
|
|
8
|
+
|
|
9
|
+
import { BridgeInfo } from "@snowbridge/base-types"
|
|
10
|
+
|
|
11
|
+
export function bridgeInfoFor(
|
|
12
|
+
env: "polkadot_mainnet" | "westend_sepolia" | "paseo_sepolia" | (string & {}),
|
|
13
|
+
): Readonly<BridgeInfo> {
|
|
14
|
+
switch (env) {
|
|
15
|
+
case "polkadot_mainnet":
|
|
16
|
+
return polkadot_mainnet satisfies BridgeInfo
|
|
17
|
+
break
|
|
18
|
+
case "westend_sepolia":
|
|
19
|
+
return westend_sepolia satisfies BridgeInfo
|
|
20
|
+
case "paseo_sepolia":
|
|
21
|
+
return paseo_sepolia satisfies BridgeInfo
|
|
22
|
+
default:
|
|
23
|
+
throw Error(`Unknown env '${env}'`)
|
|
24
|
+
}
|
|
25
|
+
}
|