@hyperbridge/sdk 1.2.2 → 1.3.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/browser/index.d.ts +651 -28
- package/dist/browser/index.js +2341 -2186
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.d.ts +651 -28
- package/dist/node/index.js +2341 -2186
- package/dist/node/index.js.map +1 -1
- package/package.json +2 -2
package/dist/node/index.js
CHANGED
|
@@ -3,15 +3,15 @@ import { join } from 'path';
|
|
|
3
3
|
import { TextDecoder as TextDecoder$1, TextEncoder as TextEncoder$1 } from 'util';
|
|
4
4
|
import { createConsola, LogLevels } from 'consola';
|
|
5
5
|
import { flatten, zip, capitalize, maxBy, isNil } from 'lodash-es';
|
|
6
|
-
import {
|
|
6
|
+
import { hexToBytes, encodePacked, toHex, keccak256, encodeAbiParameters, bytesToHex, concatHex, createPublicClient, http, encodeFunctionData, erc20Abi, bytesToBigInt, pad, toBytes, maxUint256, parseUnits } from 'viem';
|
|
7
7
|
import mergeRace from '@async-generator/merge-race';
|
|
8
|
+
import { hasWindow, isNode, env } from 'std-env';
|
|
9
|
+
import { Vector, u8, Struct, Tuple, Enum, _void, u64, u32, Option, bool, u128 } from 'scale-ts';
|
|
8
10
|
import { gnosisChiado, gnosis, bscTestnet, bsc, soneium, baseSepolia, base, optimismSepolia, optimism, arbitrumSepolia, arbitrum, mainnet, sepolia } from 'viem/chains';
|
|
9
11
|
import { match } from 'ts-pattern';
|
|
10
12
|
import { WsProvider, ApiPromise } from '@polkadot/api';
|
|
11
13
|
import { RpcWebSocketClient } from 'rpc-websocket-client';
|
|
12
|
-
import { Vector, u8, Struct, Tuple, Enum, _void, u64, u32, Option, bool, u128 } from 'scale-ts';
|
|
13
14
|
import { keccakAsU8a, decodeAddress, xxhashAsU8a } from '@polkadot/util-crypto';
|
|
14
|
-
import { hasWindow, isNode, env } from 'std-env';
|
|
15
15
|
import { GraphQLClient } from 'graphql-request';
|
|
16
16
|
import { u8aToHex } from '@polkadot/util';
|
|
17
17
|
|
|
@@ -230,234 +230,6 @@ var init_node = __esm({
|
|
|
230
230
|
}
|
|
231
231
|
});
|
|
232
232
|
|
|
233
|
-
// src/queries.ts
|
|
234
|
-
var POST_REQUEST_STATUS = `
|
|
235
|
-
query RequestStatusM($hash: String!) {
|
|
236
|
-
requests(
|
|
237
|
-
filter: { commitment: { equalTo: $hash } }
|
|
238
|
-
) {
|
|
239
|
-
nodes {
|
|
240
|
-
commitment
|
|
241
|
-
timeoutTimestamp
|
|
242
|
-
source
|
|
243
|
-
dest
|
|
244
|
-
to
|
|
245
|
-
from
|
|
246
|
-
nonce
|
|
247
|
-
body
|
|
248
|
-
statusMetadata {
|
|
249
|
-
nodes {
|
|
250
|
-
blockHash
|
|
251
|
-
blockNumber
|
|
252
|
-
timestamp
|
|
253
|
-
chain
|
|
254
|
-
status
|
|
255
|
-
transactionHash
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
`;
|
|
262
|
-
var GET_REQUEST_STATUS = `
|
|
263
|
-
query GetRequestDetails($commitment: String!) {
|
|
264
|
-
getRequests(
|
|
265
|
-
filter: { commitment: { equalTo: $commitment } }
|
|
266
|
-
) {
|
|
267
|
-
nodes {
|
|
268
|
-
id
|
|
269
|
-
source
|
|
270
|
-
dest
|
|
271
|
-
from
|
|
272
|
-
keys
|
|
273
|
-
nonce
|
|
274
|
-
height
|
|
275
|
-
context
|
|
276
|
-
timeoutTimestamp
|
|
277
|
-
fee
|
|
278
|
-
blockNumber
|
|
279
|
-
blockHash
|
|
280
|
-
transactionHash
|
|
281
|
-
blockTimestamp
|
|
282
|
-
status
|
|
283
|
-
chain
|
|
284
|
-
commitment
|
|
285
|
-
statusMetadata {
|
|
286
|
-
nodes {
|
|
287
|
-
status
|
|
288
|
-
chain
|
|
289
|
-
timestamp
|
|
290
|
-
blockNumber
|
|
291
|
-
blockHash
|
|
292
|
-
transactionHash
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}`;
|
|
298
|
-
var STATE_MACHINE_UPDATES_BY_HEIGHT = `
|
|
299
|
-
query StateMachineUpdatesByHeight($statemachineId: String!, $height: Int!, $chain: String!) {
|
|
300
|
-
stateMachineUpdateEvents(
|
|
301
|
-
filter: {
|
|
302
|
-
and: [
|
|
303
|
-
{ stateMachineId: { equalTo: $statemachineId } }
|
|
304
|
-
{ height: { greaterThanOrEqualTo: $height } }
|
|
305
|
-
{ chain: { equalTo: $chain } }
|
|
306
|
-
]
|
|
307
|
-
}
|
|
308
|
-
orderBy: HEIGHT_ASC
|
|
309
|
-
first: 1
|
|
310
|
-
) {
|
|
311
|
-
nodes {
|
|
312
|
-
height
|
|
313
|
-
stateMachineId
|
|
314
|
-
chain
|
|
315
|
-
blockHash
|
|
316
|
-
blockNumber
|
|
317
|
-
transactionHash
|
|
318
|
-
createdAt
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
`;
|
|
323
|
-
var STATE_MACHINE_UPDATES_BY_TIMESTAMP = `
|
|
324
|
-
query StateMachineUpdatesByTimestamp($statemachineId: String!, $commitmentTimestamp: BigFloat!, $chain: String!) {
|
|
325
|
-
stateMachineUpdateEvents(
|
|
326
|
-
filter: {
|
|
327
|
-
and: [
|
|
328
|
-
{ stateMachineId: { equalTo: $statemachineId } }
|
|
329
|
-
{ commitmentTimestamp: { greaterThanOrEqualTo: $commitmentTimestamp } }
|
|
330
|
-
{ chain: { equalTo: $chain } }
|
|
331
|
-
]
|
|
332
|
-
}
|
|
333
|
-
orderBy: COMMITMENT_TIMESTAMP_DESC
|
|
334
|
-
first: 1
|
|
335
|
-
) {
|
|
336
|
-
nodes {
|
|
337
|
-
height
|
|
338
|
-
stateMachineId
|
|
339
|
-
chain
|
|
340
|
-
blockHash
|
|
341
|
-
blockNumber
|
|
342
|
-
transactionHash
|
|
343
|
-
commitmentTimestamp
|
|
344
|
-
createdAt
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
`;
|
|
349
|
-
var ASSET_TELEPORTED_BY_PARAMS = `
|
|
350
|
-
query AssetTeleportedByParams($from: String!, $to: String!, $dest: String!, $blockNumber: Int!) {
|
|
351
|
-
assetTeleporteds(
|
|
352
|
-
filter: {
|
|
353
|
-
and: [
|
|
354
|
-
{ from: { equalTo: $from } }
|
|
355
|
-
{ to: { equalTo: $to } }
|
|
356
|
-
{ dest: { includes: $dest } }
|
|
357
|
-
{ blockNumber: { greaterThanOrEqualTo: $blockNumber } }
|
|
358
|
-
]
|
|
359
|
-
}
|
|
360
|
-
orderBy: CREATED_AT_DESC
|
|
361
|
-
first: 1
|
|
362
|
-
) {
|
|
363
|
-
nodes {
|
|
364
|
-
id
|
|
365
|
-
from
|
|
366
|
-
to
|
|
367
|
-
amount
|
|
368
|
-
dest
|
|
369
|
-
commitment
|
|
370
|
-
createdAt
|
|
371
|
-
blockNumber
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
`;
|
|
376
|
-
var GET_RESPONSE_BY_REQUEST_ID = `
|
|
377
|
-
query GetResponseByRequestId($requestId: String!) {
|
|
378
|
-
getResponses(filter: {requestId: {equalTo: $requestId}}) {
|
|
379
|
-
nodes {
|
|
380
|
-
id
|
|
381
|
-
commitment
|
|
382
|
-
responseMessage
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
`;
|
|
387
|
-
var ORDER_STATUS = `
|
|
388
|
-
query OrderStatus($commitment: String!) {
|
|
389
|
-
orderPlaceds(
|
|
390
|
-
filter: { commitment: { equalTo: $commitment } }
|
|
391
|
-
) {
|
|
392
|
-
nodes {
|
|
393
|
-
id
|
|
394
|
-
user
|
|
395
|
-
sourceChain
|
|
396
|
-
destChain
|
|
397
|
-
commitment
|
|
398
|
-
deadline
|
|
399
|
-
nonce
|
|
400
|
-
fees
|
|
401
|
-
inputTokens
|
|
402
|
-
inputAmounts
|
|
403
|
-
inputValuesUSD
|
|
404
|
-
inputUSD
|
|
405
|
-
outputTokens
|
|
406
|
-
outputAmounts
|
|
407
|
-
outputBeneficiaries
|
|
408
|
-
calldata
|
|
409
|
-
status
|
|
410
|
-
createdAt
|
|
411
|
-
blockNumber
|
|
412
|
-
blockTimestamp
|
|
413
|
-
transactionHash
|
|
414
|
-
statusMetadata {
|
|
415
|
-
nodes {
|
|
416
|
-
status
|
|
417
|
-
chain
|
|
418
|
-
timestamp
|
|
419
|
-
blockNumber
|
|
420
|
-
transactionHash
|
|
421
|
-
filler
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}`;
|
|
427
|
-
var TOKEN_GATEWAY_ASSET_TELEPORTED_STATUS = `
|
|
428
|
-
query TokenGatewayAssetTeleportedStatus($commitment: String!) {
|
|
429
|
-
tokenGatewayAssetTeleporteds(
|
|
430
|
-
filter: { commitment: { equalTo: $commitment } }
|
|
431
|
-
) {
|
|
432
|
-
nodes {
|
|
433
|
-
id
|
|
434
|
-
from
|
|
435
|
-
to
|
|
436
|
-
sourceChain
|
|
437
|
-
destChain
|
|
438
|
-
commitment
|
|
439
|
-
amount
|
|
440
|
-
usdValue
|
|
441
|
-
assetId
|
|
442
|
-
redeem
|
|
443
|
-
status
|
|
444
|
-
createdAt
|
|
445
|
-
blockNumber
|
|
446
|
-
blockTimestamp
|
|
447
|
-
transactionHash
|
|
448
|
-
statusMetadata {
|
|
449
|
-
nodes {
|
|
450
|
-
status
|
|
451
|
-
chain
|
|
452
|
-
timestamp
|
|
453
|
-
blockNumber
|
|
454
|
-
transactionHash
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}`;
|
|
460
|
-
|
|
461
233
|
// src/types/index.ts
|
|
462
234
|
var RequestStatus = Object.freeze({
|
|
463
235
|
SOURCE: "SOURCE",
|
|
@@ -505,16 +277,6 @@ var RequestKind = /* @__PURE__ */ ((RequestKind2) => {
|
|
|
505
277
|
RequestKind2[RequestKind2["UpdateParams"] = 2] = "UpdateParams";
|
|
506
278
|
return RequestKind2;
|
|
507
279
|
})(RequestKind || {});
|
|
508
|
-
var AbortSignalInternal = class _AbortSignalInternal extends Error {
|
|
509
|
-
constructor(message) {
|
|
510
|
-
super();
|
|
511
|
-
this.name = "AbortSignalInternal";
|
|
512
|
-
this.message = message;
|
|
513
|
-
}
|
|
514
|
-
static isError(error) {
|
|
515
|
-
return error instanceof _AbortSignalInternal;
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
280
|
|
|
519
281
|
// src/abis/evmHost.ts
|
|
520
282
|
var ABI = [
|
|
@@ -3541,1985 +3303,2290 @@ var ABI2 = [
|
|
|
3541
3303
|
}
|
|
3542
3304
|
];
|
|
3543
3305
|
var handler_default = { ABI: ABI2 };
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: 10200,
|
|
3556
|
-
["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */]: 4009,
|
|
3557
|
-
["EVM-11155111" /* SEPOLIA */]: 11155111,
|
|
3558
|
-
["EVM-1" /* MAINNET */]: 1,
|
|
3559
|
-
["EVM-56" /* BSC_MAINNET */]: 56
|
|
3560
|
-
};
|
|
3561
|
-
var viemChains = {
|
|
3562
|
-
"97": bscTestnet,
|
|
3563
|
-
"10200": gnosisChiado,
|
|
3564
|
-
"11155111": sepolia,
|
|
3565
|
-
"1": mainnet,
|
|
3566
|
-
"56": bsc
|
|
3567
|
-
};
|
|
3568
|
-
var WrappedNativeDecimals = {
|
|
3569
|
-
["EVM-97" /* BSC_CHAPEL */]: 18,
|
|
3570
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: 18,
|
|
3571
|
-
["EVM-11155111" /* SEPOLIA */]: 18,
|
|
3572
|
-
["EVM-1" /* MAINNET */]: 18,
|
|
3573
|
-
["EVM-56" /* BSC_MAINNET */]: 18
|
|
3574
|
-
};
|
|
3575
|
-
var assets = {
|
|
3576
|
-
["EVM-97" /* BSC_CHAPEL */]: {
|
|
3577
|
-
WETH: "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase(),
|
|
3578
|
-
DAI: "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase(),
|
|
3579
|
-
USDC: "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase(),
|
|
3580
|
-
USDT: "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase()
|
|
3581
|
-
},
|
|
3582
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: {
|
|
3583
|
-
WETH: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
3584
|
-
DAI: "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase(),
|
|
3585
|
-
USDC: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
3586
|
-
USDT: "0x0000000000000000000000000000000000000000".toLowerCase()
|
|
3587
|
-
},
|
|
3588
|
-
["EVM-11155111" /* SEPOLIA */]: {
|
|
3589
|
-
WETH: "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9".toLowerCase(),
|
|
3590
|
-
USDC: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
3591
|
-
USDT: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
3592
|
-
DAI: "0x0000000000000000000000000000000000000000".toLowerCase()
|
|
3593
|
-
},
|
|
3594
|
-
["EVM-1" /* MAINNET */]: {
|
|
3595
|
-
WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".toLowerCase(),
|
|
3596
|
-
DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F".toLowerCase(),
|
|
3597
|
-
USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".toLowerCase(),
|
|
3598
|
-
USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7".toLowerCase()
|
|
3599
|
-
},
|
|
3600
|
-
["EVM-56" /* BSC_MAINNET */]: {
|
|
3601
|
-
WETH: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c".toLowerCase(),
|
|
3602
|
-
DAI: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3".toLowerCase(),
|
|
3603
|
-
USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d".toLowerCase(),
|
|
3604
|
-
USDT: "0x55d398326f99059fF775485246999027B3197955".toLowerCase()
|
|
3605
|
-
}
|
|
3606
|
-
};
|
|
3607
|
-
var addresses = {
|
|
3608
|
-
IntentGateway: {
|
|
3609
|
-
["EVM-97" /* BSC_CHAPEL */]: "0xb6C27F4beF379d0b5e2fe3Bb36c248D6B71f91A6",
|
|
3610
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: "0xb6C27F4beF379d0b5e2fe3Bb36c248D6B71f91A6",
|
|
3611
|
-
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
3612
|
-
["EVM-1" /* MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA",
|
|
3613
|
-
["EVM-56" /* BSC_MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA"
|
|
3614
|
-
},
|
|
3615
|
-
Host: {
|
|
3616
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7",
|
|
3617
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: "0x58a41b89f4871725e5d898d98ef4bf917601c5eb",
|
|
3618
|
-
["EVM-11155111" /* SEPOLIA */]: "0x2EdB74C269948b60ec1000040E104cef0eABaae8",
|
|
3619
|
-
["EVM-1" /* MAINNET */]: "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20",
|
|
3620
|
-
["EVM-56" /* BSC_MAINNET */]: "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7"
|
|
3621
|
-
},
|
|
3622
|
-
UniswapRouter02: {
|
|
3623
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
|
|
3624
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: "0x0000000000000000000000000000000000000000",
|
|
3625
|
-
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
3626
|
-
["EVM-1" /* MAINNET */]: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
|
|
3627
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3628
|
-
},
|
|
3629
|
-
UniswapV2Factory: {
|
|
3630
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x12e036669DA18F4A2777853d6e2136b32AceEC86",
|
|
3631
|
-
["EVM-10200" /* GNOSIS_CHIADO */]: "0x0000000000000000000000000000000000000000",
|
|
3632
|
-
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
3633
|
-
["EVM-1" /* MAINNET */]: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
|
|
3634
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3635
|
-
},
|
|
3636
|
-
BatchExecutor: {
|
|
3637
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x4CC58B5D8FBf838d062E4b21F75C327835B5F0ef",
|
|
3638
|
-
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
3639
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3640
|
-
},
|
|
3641
|
-
UniversalRouter: {
|
|
3642
|
-
["EVM-97" /* BSC_CHAPEL */]: "0xcc6d5ece3d4a57245bf5a2f64f3ed9179b81f714",
|
|
3643
|
-
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
3644
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3645
|
-
},
|
|
3646
|
-
UniswapV3Router: {
|
|
3647
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
3648
|
-
["EVM-1" /* MAINNET */]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
3649
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3650
|
-
},
|
|
3651
|
-
UniswapV3Factory: {
|
|
3652
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
3653
|
-
["EVM-1" /* MAINNET */]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
3654
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3655
|
-
},
|
|
3656
|
-
UniswapV3Quoter: {
|
|
3657
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
3658
|
-
["EVM-1" /* MAINNET */]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e",
|
|
3659
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3660
|
-
},
|
|
3661
|
-
UniswapV4PoolManager: {
|
|
3662
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
3663
|
-
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
3664
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3665
|
-
},
|
|
3666
|
-
UniswapV4Quoter: {
|
|
3667
|
-
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
3668
|
-
["EVM-1" /* MAINNET */]: "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",
|
|
3669
|
-
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
3670
|
-
},
|
|
3671
|
-
Calldispatcher: {
|
|
3672
|
-
["EVM-11155111" /* SEPOLIA */]: "0xC7f13b6D03A0A7F3239d38897503E90553ABe155"
|
|
3306
|
+
function getPeakPosByHeight(height) {
|
|
3307
|
+
return (1n << BigInt(height + 1)) - 2n;
|
|
3308
|
+
}
|
|
3309
|
+
function leftPeakHeightPos(mmrSize) {
|
|
3310
|
+
let height = 1;
|
|
3311
|
+
let prevPos = 0n;
|
|
3312
|
+
let pos = getPeakPosByHeight(height);
|
|
3313
|
+
while (pos < mmrSize) {
|
|
3314
|
+
height += 1;
|
|
3315
|
+
prevPos = pos;
|
|
3316
|
+
pos = getPeakPosByHeight(height);
|
|
3673
3317
|
}
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */]: "PAS0",
|
|
3687
|
-
["EVM-11155111" /* SEPOLIA */]: "ETH0",
|
|
3688
|
-
["EVM-1" /* MAINNET */]: "ETH0",
|
|
3689
|
-
["EVM-56" /* BSC_MAINNET */]: "BSC0"
|
|
3690
|
-
};
|
|
3691
|
-
|
|
3692
|
-
// src/configs/ChainConfigService.ts
|
|
3693
|
-
var ChainConfigService = class {
|
|
3694
|
-
rpcUrls;
|
|
3695
|
-
constructor(env2 = process.env) {
|
|
3696
|
-
this.rpcUrls = createRpcUrls(env2);
|
|
3318
|
+
return [height - 1, prevPos];
|
|
3319
|
+
}
|
|
3320
|
+
function getRightPeak(initialHeight, initialPos, mmrSize) {
|
|
3321
|
+
let height = initialHeight;
|
|
3322
|
+
let pos = initialPos;
|
|
3323
|
+
pos += siblingOffset(height);
|
|
3324
|
+
while (pos > mmrSize - 1n) {
|
|
3325
|
+
if (height === 0) {
|
|
3326
|
+
return null;
|
|
3327
|
+
}
|
|
3328
|
+
pos -= parentOffset(height - 1);
|
|
3329
|
+
height -= 1;
|
|
3697
3330
|
}
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3331
|
+
return [height, pos];
|
|
3332
|
+
}
|
|
3333
|
+
function getPeaks(mmrSize) {
|
|
3334
|
+
const positions = [];
|
|
3335
|
+
let [height, pos] = leftPeakHeightPos(mmrSize);
|
|
3336
|
+
positions.push(pos);
|
|
3337
|
+
while (height > 0) {
|
|
3338
|
+
const peak = getRightPeak(height, pos, mmrSize);
|
|
3339
|
+
if (!peak) break;
|
|
3340
|
+
[height, pos] = peak;
|
|
3341
|
+
positions.push(pos);
|
|
3704
3342
|
}
|
|
3705
|
-
|
|
3706
|
-
|
|
3343
|
+
return positions;
|
|
3344
|
+
}
|
|
3345
|
+
function allOnes(num) {
|
|
3346
|
+
if (num === 0n) return false;
|
|
3347
|
+
return num.toString(2).split("").every((bit) => bit === "1");
|
|
3348
|
+
}
|
|
3349
|
+
function jumpLeft(pos) {
|
|
3350
|
+
const bitLength = pos.toString(2).length;
|
|
3351
|
+
const mostSignificantBits = 1n << BigInt(bitLength - 1);
|
|
3352
|
+
return pos - (mostSignificantBits - 1n);
|
|
3353
|
+
}
|
|
3354
|
+
function posHeightInTree(initialPos) {
|
|
3355
|
+
let pos = initialPos + 1n;
|
|
3356
|
+
while (!allOnes(pos)) {
|
|
3357
|
+
pos = jumpLeft(pos);
|
|
3707
3358
|
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3359
|
+
return pos.toString(2).length - 1;
|
|
3360
|
+
}
|
|
3361
|
+
function parentOffset(height) {
|
|
3362
|
+
return 2n << BigInt(height);
|
|
3363
|
+
}
|
|
3364
|
+
function siblingOffset(height) {
|
|
3365
|
+
return (2n << BigInt(height)) - 1n;
|
|
3366
|
+
}
|
|
3367
|
+
function takeWhileVec(v, p) {
|
|
3368
|
+
const index = v.findIndex((item) => !p(item));
|
|
3369
|
+
if (index === -1) {
|
|
3370
|
+
const result = [...v];
|
|
3371
|
+
v.length = 0;
|
|
3372
|
+
return result;
|
|
3710
3373
|
}
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3374
|
+
return v.splice(0, index);
|
|
3375
|
+
}
|
|
3376
|
+
function mmrPositionToKIndex(initialLeaves, mmrSize) {
|
|
3377
|
+
const leaves = [...initialLeaves];
|
|
3378
|
+
const peaks = getPeaks(mmrSize);
|
|
3379
|
+
const leavesWithKIndices = [];
|
|
3380
|
+
for (const peak of peaks) {
|
|
3381
|
+
const peakLeaves = takeWhileVec(leaves, (pos) => pos <= peak);
|
|
3382
|
+
if (peakLeaves.length > 0) {
|
|
3383
|
+
for (const pos of peakLeaves) {
|
|
3384
|
+
const height = posHeightInTree(peak);
|
|
3385
|
+
let index = 0n;
|
|
3386
|
+
let parentPos = peak;
|
|
3387
|
+
for (let h = height; h >= 1; h--) {
|
|
3388
|
+
const leftChild = parentPos - parentOffset(h - 1);
|
|
3389
|
+
const rightChild = leftChild + siblingOffset(h - 1);
|
|
3390
|
+
index *= 2n;
|
|
3391
|
+
if (leftChild >= pos) {
|
|
3392
|
+
parentPos = leftChild;
|
|
3393
|
+
} else {
|
|
3394
|
+
parentPos = rightChild;
|
|
3395
|
+
index += 1n;
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
leavesWithKIndices.push([pos, index]);
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3716
3401
|
}
|
|
3717
|
-
|
|
3718
|
-
|
|
3402
|
+
return leavesWithKIndices;
|
|
3403
|
+
}
|
|
3404
|
+
function calculateMMRSize(numberOfLeaves) {
|
|
3405
|
+
const numberOfPeaks = numberOfLeaves.toString(2).split("1").length - 1;
|
|
3406
|
+
return 2n * numberOfLeaves - BigInt(numberOfPeaks);
|
|
3407
|
+
}
|
|
3408
|
+
async function generateRootWithProof(postRequest, treeSize) {
|
|
3409
|
+
const { generate_root_with_proof: generate_root_with_proof2 } = await load_ckb_mmr();
|
|
3410
|
+
const { commitment: hash, encodePacked: encodePacked2 } = postRequestCommitment(postRequest);
|
|
3411
|
+
const result = JSON.parse(generate_root_with_proof2(hexToBytes(encodePacked2), treeSize));
|
|
3412
|
+
const { root, proof, mmr_size, leaf_positions, keccak_hash_calldata } = result;
|
|
3413
|
+
if (keccak_hash_calldata !== hash) {
|
|
3414
|
+
console.log("keccak_hash", keccak_hash_calldata);
|
|
3415
|
+
console.log("hash", hash);
|
|
3416
|
+
throw new Error("Abi keccak hash mismatch");
|
|
3719
3417
|
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3418
|
+
const [[, kIndex]] = mmrPositionToKIndex(leaf_positions, BigInt(mmr_size));
|
|
3419
|
+
return {
|
|
3420
|
+
root,
|
|
3421
|
+
proof,
|
|
3422
|
+
index: treeSize - 1n,
|
|
3423
|
+
kIndex,
|
|
3424
|
+
treeSize,
|
|
3425
|
+
mmrSize: mmr_size
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
async function load_ckb_mmr() {
|
|
3429
|
+
if (hasWindow) {
|
|
3430
|
+
const wasm2 = await Promise.resolve().then(() => (init_node(), node_exports));
|
|
3431
|
+
await wasm2.default();
|
|
3432
|
+
return wasm2;
|
|
3722
3433
|
}
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
getChainId(chain) {
|
|
3727
|
-
return chainIds[chain];
|
|
3728
|
-
}
|
|
3729
|
-
getConsensusStateId(chain) {
|
|
3730
|
-
return toHex(consensusStateIds[chain]);
|
|
3731
|
-
}
|
|
3732
|
-
getHyperbridgeChainId() {
|
|
3733
|
-
return chainIds["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */];
|
|
3734
|
-
}
|
|
3735
|
-
getRpcUrl(chain) {
|
|
3736
|
-
return this.rpcUrls[chain];
|
|
3737
|
-
}
|
|
3738
|
-
getUniswapRouterV2Address(chain) {
|
|
3739
|
-
return addresses.UniswapRouter02[chain];
|
|
3740
|
-
}
|
|
3741
|
-
getUniswapV2FactoryAddress(chain) {
|
|
3742
|
-
return addresses.UniswapV2Factory[chain];
|
|
3743
|
-
}
|
|
3744
|
-
getBatchExecutorAddress(chain) {
|
|
3745
|
-
return addresses.BatchExecutor[chain];
|
|
3746
|
-
}
|
|
3747
|
-
getUniversalRouterAddress(chain) {
|
|
3748
|
-
return addresses.UniversalRouter[chain];
|
|
3749
|
-
}
|
|
3750
|
-
getUniswapV3RouterAddress(chain) {
|
|
3751
|
-
return addresses.UniswapV3Router[chain];
|
|
3752
|
-
}
|
|
3753
|
-
getUniswapV3FactoryAddress(chain) {
|
|
3754
|
-
return addresses.UniswapV3Factory[chain];
|
|
3755
|
-
}
|
|
3756
|
-
getUniswapV3QuoterAddress(chain) {
|
|
3757
|
-
return addresses.UniswapV3Quoter[chain];
|
|
3758
|
-
}
|
|
3759
|
-
getUniswapV4PoolManagerAddress(chain) {
|
|
3760
|
-
return addresses.UniswapV4PoolManager[chain];
|
|
3761
|
-
}
|
|
3762
|
-
getUniswapV4QuoterAddress(chain) {
|
|
3763
|
-
return addresses.UniswapV4Quoter[chain];
|
|
3764
|
-
}
|
|
3765
|
-
};
|
|
3766
|
-
|
|
3767
|
-
// src/chains/evm.ts
|
|
3768
|
-
var chains = {
|
|
3769
|
-
[mainnet.id]: mainnet,
|
|
3770
|
-
[arbitrum.id]: arbitrum,
|
|
3771
|
-
[arbitrumSepolia.id]: arbitrumSepolia,
|
|
3772
|
-
[optimism.id]: optimism,
|
|
3773
|
-
[optimismSepolia.id]: optimismSepolia,
|
|
3774
|
-
[base.id]: base,
|
|
3775
|
-
[baseSepolia.id]: baseSepolia,
|
|
3776
|
-
[soneium.id]: soneium,
|
|
3777
|
-
[bsc.id]: bsc,
|
|
3778
|
-
[bscTestnet.id]: bscTestnet,
|
|
3779
|
-
[gnosis.id]: gnosis,
|
|
3780
|
-
[gnosisChiado.id]: gnosisChiado
|
|
3781
|
-
};
|
|
3782
|
-
var DEFAULT_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
3783
|
-
var EvmChain = class {
|
|
3784
|
-
constructor(params) {
|
|
3785
|
-
this.params = params;
|
|
3786
|
-
this.publicClient = createPublicClient({
|
|
3787
|
-
// @ts-ignore
|
|
3788
|
-
chain: chains[params.chainId],
|
|
3789
|
-
transport: http(params.url)
|
|
3790
|
-
});
|
|
3791
|
-
this.chainConfigService = new ChainConfigService();
|
|
3792
|
-
}
|
|
3793
|
-
publicClient;
|
|
3794
|
-
chainConfigService;
|
|
3795
|
-
// Expose minimal getters for external helpers/classes
|
|
3796
|
-
get client() {
|
|
3797
|
-
return this.publicClient;
|
|
3798
|
-
}
|
|
3799
|
-
get host() {
|
|
3800
|
-
return this.params.host;
|
|
3801
|
-
}
|
|
3802
|
-
get config() {
|
|
3803
|
-
return this.chainConfigService;
|
|
3434
|
+
if (isNode) {
|
|
3435
|
+
const wasm2 = await Promise.resolve().then(() => (init_node(), node_exports));
|
|
3436
|
+
return wasm2;
|
|
3804
3437
|
}
|
|
3438
|
+
throw new Error(`SDK not setup for ${env}`);
|
|
3439
|
+
}
|
|
3440
|
+
async function __test() {
|
|
3441
|
+
const { generate_root_with_proof: generate_root_with_proof2 } = await load_ckb_mmr();
|
|
3442
|
+
return generate_root_with_proof2(new Uint8Array(), 120n);
|
|
3443
|
+
}
|
|
3444
|
+
var H256 = Vector(u8, 32);
|
|
3445
|
+
var EvmStateProof = Struct({
|
|
3805
3446
|
/**
|
|
3806
|
-
*
|
|
3807
|
-
* @param {HexString} commitment - The commitment to derive the key from.
|
|
3808
|
-
* @returns {HexString} The derived key.
|
|
3447
|
+
* Proof of the contract state.
|
|
3809
3448
|
*/
|
|
3810
|
-
|
|
3811
|
-
return deriveMapKey(hexToBytes(commitment), REQUEST_RECEIPTS_SLOT);
|
|
3812
|
-
}
|
|
3449
|
+
contractProof: Vector(Vector(u8)),
|
|
3813
3450
|
/**
|
|
3814
|
-
*
|
|
3815
|
-
* @param {HexString} commitment - The commitment to query.
|
|
3816
|
-
* @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
|
|
3451
|
+
* Proof of the storage state.
|
|
3817
3452
|
*/
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3453
|
+
storageProof: Vector(Tuple(Vector(u8), Vector(Vector(u8))))
|
|
3454
|
+
});
|
|
3455
|
+
var SubstrateHashing = Enum({
|
|
3456
|
+
/* For chains that use keccak as their hashing algo */
|
|
3457
|
+
Keccak: _void,
|
|
3458
|
+
/* For chains that use blake2b as their hashing algo */
|
|
3459
|
+
Blake2: _void
|
|
3460
|
+
});
|
|
3461
|
+
var SubstrateStateMachineProof = Struct({
|
|
3827
3462
|
/**
|
|
3828
|
-
*
|
|
3829
|
-
* @param {IMessage} message - The message to query.
|
|
3830
|
-
* @param {string} counterparty - The counterparty address.
|
|
3831
|
-
* @param {bigint} [at] - The block number to query at.
|
|
3832
|
-
* @returns {Promise<HexString>} The proof.
|
|
3463
|
+
* The hasher used to hash the state machine state.
|
|
3833
3464
|
*/
|
|
3834
|
-
|
|
3835
|
-
const commitmentKeys = "Requests" in message ? message.Requests.map((key) => requestCommitmentKey(key)) : message.Responses.map((key) => responseCommitmentKey(key));
|
|
3836
|
-
const config = {
|
|
3837
|
-
address: this.params.host,
|
|
3838
|
-
storageKeys: commitmentKeys
|
|
3839
|
-
};
|
|
3840
|
-
if (!at) {
|
|
3841
|
-
config.blockTag = "latest";
|
|
3842
|
-
} else {
|
|
3843
|
-
config.blockNumber = at;
|
|
3844
|
-
}
|
|
3845
|
-
const proof = await this.publicClient.getProof(config);
|
|
3846
|
-
const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
|
|
3847
|
-
const encoded = EvmStateProof.enc({
|
|
3848
|
-
contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
|
|
3849
|
-
storageProof: [
|
|
3850
|
-
[Array.from(hexToBytes(this.params.host)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
3851
|
-
]
|
|
3852
|
-
});
|
|
3853
|
-
return toHex(encoded);
|
|
3854
|
-
}
|
|
3465
|
+
hasher: SubstrateHashing,
|
|
3855
3466
|
/**
|
|
3856
|
-
*
|
|
3857
|
-
* @param {bigint} at - The block height at which to query the storage proof.
|
|
3858
|
-
* @param {HexString[]} keys - The keys for which to query the storage proof.
|
|
3859
|
-
* @returns {Promise<HexString>} The encoded storage proof.
|
|
3467
|
+
* Proof of the state machine state.
|
|
3860
3468
|
*/
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
if (!at) {
|
|
3867
|
-
config.blockTag = "latest";
|
|
3868
|
-
} else {
|
|
3869
|
-
config.blockNumber = at;
|
|
3870
|
-
}
|
|
3871
|
-
const proof = await this.publicClient.getProof(config);
|
|
3872
|
-
const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
|
|
3873
|
-
const encoded = EvmStateProof.enc({
|
|
3874
|
-
contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
|
|
3875
|
-
storageProof: [
|
|
3876
|
-
[Array.from(hexToBytes(this.params.host)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
3877
|
-
]
|
|
3878
|
-
});
|
|
3879
|
-
return toHex(encoded);
|
|
3880
|
-
}
|
|
3881
|
-
/**
|
|
3882
|
-
* Returns the current timestamp of the chain.
|
|
3883
|
-
* @returns {Promise<bigint>} The current timestamp.
|
|
3469
|
+
storageProof: Vector(Vector(u8))
|
|
3470
|
+
});
|
|
3471
|
+
var SubstrateStateProof = Enum({
|
|
3472
|
+
/*
|
|
3473
|
+
* Uses overlay root for verification
|
|
3884
3474
|
*/
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
abi: evmHost_default.ABI,
|
|
3889
|
-
functionName: "timestamp"
|
|
3890
|
-
});
|
|
3891
|
-
return BigInt(data);
|
|
3892
|
-
}
|
|
3893
|
-
/**
|
|
3894
|
-
* Get the latest state machine height for a given state machine ID.
|
|
3895
|
-
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
3896
|
-
* @returns {Promise<bigint>} The latest state machine height.
|
|
3475
|
+
OverlayProof: SubstrateStateMachineProof,
|
|
3476
|
+
/*
|
|
3477
|
+
* Uses state root for verification
|
|
3897
3478
|
*/
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
);
|
|
3905
|
-
const data = await this.publicClient.readContract({
|
|
3906
|
-
address: this.params.host,
|
|
3907
|
-
abi: evmHost_default.ABI,
|
|
3908
|
-
functionName: "latestStateMachineHeight",
|
|
3909
|
-
args: [BigInt(id)]
|
|
3910
|
-
});
|
|
3911
|
-
return data;
|
|
3912
|
-
}
|
|
3913
|
-
/**
|
|
3914
|
-
* Get the state machine update time for a given state machine height.
|
|
3915
|
-
* @param {StateMachineHeight} stateMachineHeight - The state machine height.
|
|
3916
|
-
* @returns {Promise<bigint>} The statemachine update time in seconds.
|
|
3479
|
+
StateProof: SubstrateStateMachineProof
|
|
3480
|
+
});
|
|
3481
|
+
var BasicProof = Vector(Vector(u8));
|
|
3482
|
+
var LeafIndexAndPos = Struct({
|
|
3483
|
+
/*
|
|
3484
|
+
* Leaf index
|
|
3917
3485
|
*/
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
if (!id) throw new Error("Expected Polkadot or Kusama State machine id when reading state machine update time");
|
|
3922
|
-
const data = await this.publicClient.readContract({
|
|
3923
|
-
address: this.params.host,
|
|
3924
|
-
abi: evmHost_default.ABI,
|
|
3925
|
-
functionName: "stateMachineCommitmentUpdateTime",
|
|
3926
|
-
args: [{ stateMachineId: BigInt(id), height: stateMachineHeight.height }]
|
|
3927
|
-
});
|
|
3928
|
-
return data;
|
|
3929
|
-
}
|
|
3930
|
-
/**
|
|
3931
|
-
* Get the challenge period for a given state machine id.
|
|
3932
|
-
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
3933
|
-
* @returns {Promise<bigint>} The challenge period in seconds.
|
|
3486
|
+
leafIndex: u64,
|
|
3487
|
+
/*
|
|
3488
|
+
* Leaf position in the MMR
|
|
3934
3489
|
*/
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
"Expected Polkadot or Kusama State machine id when reading latest state machine height on evm"
|
|
3941
|
-
);
|
|
3942
|
-
const data = await this.publicClient.readContract({
|
|
3943
|
-
address: this.params.host,
|
|
3944
|
-
abi: evmHost_default.ABI,
|
|
3945
|
-
functionName: "challengePeriod"
|
|
3946
|
-
});
|
|
3947
|
-
return data;
|
|
3948
|
-
}
|
|
3949
|
-
/**
|
|
3950
|
-
* Encodes an ISMP message for the EVM chain.
|
|
3951
|
-
* @param {IIsmpMessage} message The ISMP message to encode.
|
|
3952
|
-
* @returns {HexString} The encoded calldata.
|
|
3490
|
+
pos: u64
|
|
3491
|
+
});
|
|
3492
|
+
var MmrProof = Struct({
|
|
3493
|
+
/*
|
|
3494
|
+
* Proof of the leaf index and position.
|
|
3953
3495
|
*/
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
*
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
3496
|
+
leafIndexAndPos: Vector(LeafIndexAndPos),
|
|
3497
|
+
/*
|
|
3498
|
+
* Proof of the leaf data.
|
|
3499
|
+
*/
|
|
3500
|
+
leafCount: u64,
|
|
3501
|
+
/*
|
|
3502
|
+
* Proof elements (hashes of siblings of inner nodes on the path to the leaf).
|
|
3503
|
+
*/
|
|
3504
|
+
items: Vector(H256)
|
|
3505
|
+
});
|
|
3506
|
+
var ConsensusStateId = Vector(u8, 4);
|
|
3507
|
+
var ConsensusMessage = Struct({
|
|
3508
|
+
/*
|
|
3509
|
+
* Consensus message data.
|
|
3510
|
+
*/
|
|
3511
|
+
consensusProof: Vector(u8),
|
|
3512
|
+
/*
|
|
3513
|
+
* Consensus state Id
|
|
3514
|
+
*/
|
|
3515
|
+
consensusStateId: ConsensusStateId,
|
|
3516
|
+
/*
|
|
3517
|
+
* Public key of the sender
|
|
3518
|
+
*/
|
|
3519
|
+
signer: Vector(u8)
|
|
3520
|
+
});
|
|
3521
|
+
var FraudProofMessage = Struct({
|
|
3522
|
+
/*
|
|
3523
|
+
* The first valid consensus proof
|
|
3524
|
+
*/
|
|
3525
|
+
proof1: Vector(u8),
|
|
3526
|
+
/*
|
|
3527
|
+
* The second valid consensus proof
|
|
3528
|
+
*/
|
|
3529
|
+
proof2: Vector(u8),
|
|
3530
|
+
/*
|
|
3531
|
+
* Consensus state Id
|
|
3532
|
+
*/
|
|
3533
|
+
consensusStateId: ConsensusStateId
|
|
3534
|
+
});
|
|
3535
|
+
var StateMachine = Enum({
|
|
3536
|
+
/*
|
|
3537
|
+
* Evm state machines
|
|
3538
|
+
*/
|
|
3539
|
+
Evm: u32,
|
|
3540
|
+
/*
|
|
3541
|
+
* Polkadot parachains
|
|
3542
|
+
*/
|
|
3543
|
+
Polkadot: u32,
|
|
3544
|
+
/*
|
|
3545
|
+
* Kusama parachains
|
|
3546
|
+
*/
|
|
3547
|
+
Kusama: u32,
|
|
3548
|
+
/*
|
|
3549
|
+
* Substrate-based standalone chain
|
|
3550
|
+
*/
|
|
3551
|
+
Substrate: ConsensusStateId,
|
|
3552
|
+
/*
|
|
3553
|
+
* Tendermint chains
|
|
3554
|
+
*/
|
|
3555
|
+
Tendermint: ConsensusStateId
|
|
3556
|
+
});
|
|
3557
|
+
var StateMachineId = Struct({
|
|
3558
|
+
/*
|
|
3559
|
+
* The state machine id
|
|
3560
|
+
*/
|
|
3561
|
+
id: StateMachine,
|
|
3562
|
+
/*
|
|
3563
|
+
* The consensus state id
|
|
3564
|
+
*/
|
|
3565
|
+
consensusStateId: ConsensusStateId
|
|
3566
|
+
});
|
|
3567
|
+
var StateMachineHeight = Struct({
|
|
3568
|
+
/*
|
|
3569
|
+
* The state machine id
|
|
3570
|
+
*/
|
|
3571
|
+
id: StateMachineId,
|
|
3572
|
+
/*
|
|
3573
|
+
* The height of the state machine
|
|
3574
|
+
*/
|
|
3575
|
+
height: u64
|
|
3576
|
+
});
|
|
3577
|
+
var Proof = Struct({
|
|
3578
|
+
/*
|
|
3579
|
+
* The height of the state machine
|
|
3580
|
+
*/
|
|
3581
|
+
height: StateMachineHeight,
|
|
3582
|
+
/*
|
|
3583
|
+
* The proof
|
|
3584
|
+
*/
|
|
3585
|
+
proof: Vector(u8)
|
|
3586
|
+
});
|
|
3587
|
+
var PostRequest = Struct({
|
|
3588
|
+
/*
|
|
3589
|
+
* The source state machine of this request.
|
|
3590
|
+
*/
|
|
3591
|
+
source: StateMachine,
|
|
3592
|
+
/*
|
|
3593
|
+
* The destination state machine of this request.
|
|
3594
|
+
*/
|
|
3595
|
+
dest: StateMachine,
|
|
3596
|
+
/*
|
|
3597
|
+
* The nonce of this request on the source chain
|
|
3598
|
+
*/
|
|
3599
|
+
nonce: u64,
|
|
3600
|
+
/*
|
|
3601
|
+
* Module identifier of the sending module
|
|
3602
|
+
*/
|
|
3603
|
+
from: Vector(u8),
|
|
3604
|
+
/*
|
|
3605
|
+
* Module identifier of the receiving module
|
|
3606
|
+
*/
|
|
3607
|
+
to: Vector(u8),
|
|
3608
|
+
/*
|
|
3609
|
+
* Timestamp which this request expires in seconds.
|
|
3610
|
+
*/
|
|
3611
|
+
timeoutTimestamp: u64,
|
|
3612
|
+
/*
|
|
3613
|
+
* Encoded request body
|
|
3614
|
+
*/
|
|
3615
|
+
body: Vector(u8)
|
|
3616
|
+
});
|
|
3617
|
+
var PostResponse = Struct({
|
|
3618
|
+
/*
|
|
3619
|
+
* The request that triggered this response.
|
|
3620
|
+
*/
|
|
3621
|
+
post: PostRequest,
|
|
3622
|
+
/*
|
|
3623
|
+
* The response message.
|
|
3624
|
+
*/
|
|
3625
|
+
response: Vector(u8),
|
|
3626
|
+
/*
|
|
3627
|
+
* Timestamp at which this response expires in seconds.
|
|
3628
|
+
*/
|
|
3629
|
+
timeoutTimestamp: u64
|
|
3630
|
+
});
|
|
3631
|
+
var GetRequest = Struct({
|
|
3632
|
+
/*
|
|
3633
|
+
* The source state machine of this request.
|
|
3634
|
+
*/
|
|
3635
|
+
source: StateMachine,
|
|
3636
|
+
/*
|
|
3637
|
+
* The destination state machine of this request.
|
|
3638
|
+
*/
|
|
3639
|
+
dest: StateMachine,
|
|
3640
|
+
/*
|
|
3641
|
+
* The nonce of this request on the source chain
|
|
3642
|
+
*/
|
|
3643
|
+
nonce: u64,
|
|
3644
|
+
/*
|
|
3645
|
+
* Module identifier of the sending module
|
|
3646
|
+
*/
|
|
3647
|
+
from: Vector(u8),
|
|
3648
|
+
/*
|
|
3649
|
+
* Raw Storage keys that would be used to fetch the values from the counterparty
|
|
3650
|
+
* For deriving storage keys for ink contract fields follow the guide in the link below
|
|
3651
|
+
* `<https://use.ink/datastructures/storage-in-metadata#a-full-example>`
|
|
3652
|
+
* Substrate Keys
|
|
3653
|
+
*/
|
|
3654
|
+
keys: Vector(Vector(u8)),
|
|
3655
|
+
/*
|
|
3656
|
+
* Some application-specific metadata relating to this request
|
|
3657
|
+
*/
|
|
3658
|
+
context: Vector(u8),
|
|
3659
|
+
/*
|
|
3660
|
+
* Host timestamp at which this request expires in seconds
|
|
3661
|
+
*/
|
|
3662
|
+
timeoutTimestamp: u64
|
|
3663
|
+
});
|
|
3664
|
+
var StorageValue = Struct({
|
|
3665
|
+
/*
|
|
3666
|
+
* The request storage keys
|
|
3667
|
+
*/
|
|
3668
|
+
key: Vector(u8),
|
|
3669
|
+
/*
|
|
3670
|
+
* The verified value
|
|
3671
|
+
*/
|
|
3672
|
+
value: Option(Vector(u8))
|
|
3673
|
+
});
|
|
3674
|
+
var GetResponse = Struct({
|
|
3675
|
+
/*
|
|
3676
|
+
* The Get request that triggered this response.
|
|
3677
|
+
*/
|
|
3678
|
+
get: GetRequest,
|
|
3679
|
+
/*
|
|
3680
|
+
* Values derived from the state proof
|
|
3681
|
+
*/
|
|
3682
|
+
values: Vector(StorageValue)
|
|
3683
|
+
});
|
|
3684
|
+
var Request = Enum({
|
|
3685
|
+
/*
|
|
3686
|
+
* A post request allows a module on a state machine to send arbitrary bytes to another module
|
|
3687
|
+
* living in another state machine.
|
|
3688
|
+
*/
|
|
3689
|
+
Post: PostRequest,
|
|
3690
|
+
/*
|
|
3691
|
+
* A get request allows a module on a state machine to read the storage of another module
|
|
3692
|
+
* living in another state machine.
|
|
3693
|
+
*/
|
|
3694
|
+
Get: GetRequest
|
|
3695
|
+
});
|
|
3696
|
+
var Response = Enum({
|
|
3697
|
+
/*
|
|
3698
|
+
* The response to a POST request
|
|
3699
|
+
*/
|
|
3700
|
+
Post: PostResponse,
|
|
3701
|
+
/*
|
|
3702
|
+
* The response to a GET request
|
|
3703
|
+
*/
|
|
3704
|
+
Get: GetResponse
|
|
3705
|
+
});
|
|
3706
|
+
var RequestMessage = Struct({
|
|
3707
|
+
/*
|
|
3708
|
+
* Requests from source chain
|
|
4081
3709
|
*/
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
abi: evmHost_default.ABI,
|
|
4086
|
-
functionName: "perByteFee",
|
|
4087
|
-
args: [toHex(request.dest)]
|
|
4088
|
-
});
|
|
4089
|
-
const bodyByteLength = Math.floor((request.body.length - 2) / 2);
|
|
4090
|
-
const length = bodyByteLength < 32 ? 32 : bodyByteLength;
|
|
4091
|
-
return perByteFee * BigInt(length);
|
|
4092
|
-
}
|
|
4093
|
-
/**
|
|
4094
|
-
* Estimates the gas required for a post request execution on this chain.
|
|
4095
|
-
* This function generates mock proofs for the post request, creates a state override
|
|
4096
|
-
* with the necessary overlay root, and estimates the gas cost for executing the
|
|
4097
|
-
* handlePostRequests transaction on the handler contract.
|
|
4098
|
-
*
|
|
4099
|
-
* @param request - The post request to estimate gas for
|
|
4100
|
-
* @param paraId - The ID of the parachain (Hyperbridge) that will process the request
|
|
4101
|
-
* @returns The estimated gas amount in gas units
|
|
3710
|
+
requests: Vector(PostRequest),
|
|
3711
|
+
/*
|
|
3712
|
+
* Membership batch proof for these requests
|
|
4102
3713
|
*/
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
abi: evmHost_default.ABI,
|
|
4107
|
-
functionName: "hostParams"
|
|
4108
|
-
});
|
|
4109
|
-
const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(request, 2n ** 10n);
|
|
4110
|
-
const latestStateMachineHeight = 6291991n;
|
|
4111
|
-
const paraId = 4009n;
|
|
4112
|
-
const overlayRootSlot = getStateCommitmentFieldSlot(
|
|
4113
|
-
paraId,
|
|
4114
|
-
// Hyperbridge chain id
|
|
4115
|
-
latestStateMachineHeight,
|
|
4116
|
-
// Hyperbridge chain height
|
|
4117
|
-
1
|
|
4118
|
-
// For overlayRoot
|
|
4119
|
-
);
|
|
4120
|
-
const postParams = {
|
|
4121
|
-
height: {
|
|
4122
|
-
stateMachineId: BigInt(paraId),
|
|
4123
|
-
height: latestStateMachineHeight
|
|
4124
|
-
},
|
|
4125
|
-
multiproof: proof,
|
|
4126
|
-
leafCount: treeSize
|
|
4127
|
-
};
|
|
4128
|
-
const gas = await this.publicClient.estimateContractGas({
|
|
4129
|
-
address: hostParams.handler,
|
|
4130
|
-
abi: handler_default.ABI,
|
|
4131
|
-
functionName: "handlePostRequests",
|
|
4132
|
-
args: [
|
|
4133
|
-
this.params.host,
|
|
4134
|
-
{
|
|
4135
|
-
proof: postParams,
|
|
4136
|
-
requests: [
|
|
4137
|
-
{
|
|
4138
|
-
request: {
|
|
4139
|
-
...request,
|
|
4140
|
-
source: toHex(request.source),
|
|
4141
|
-
dest: toHex(request.dest)
|
|
4142
|
-
},
|
|
4143
|
-
index,
|
|
4144
|
-
kIndex
|
|
4145
|
-
}
|
|
4146
|
-
]
|
|
4147
|
-
}
|
|
4148
|
-
],
|
|
4149
|
-
stateOverride: [
|
|
4150
|
-
{
|
|
4151
|
-
address: this.params.host,
|
|
4152
|
-
stateDiff: [
|
|
4153
|
-
{
|
|
4154
|
-
slot: overlayRootSlot,
|
|
4155
|
-
value: root
|
|
4156
|
-
}
|
|
4157
|
-
]
|
|
4158
|
-
}
|
|
4159
|
-
]
|
|
4160
|
-
});
|
|
4161
|
-
return gas;
|
|
4162
|
-
}
|
|
4163
|
-
/**
|
|
4164
|
-
* Gets the fee token address and decimals for the chain.
|
|
4165
|
-
* This function gets the fee token address and decimals for the chain.
|
|
4166
|
-
*
|
|
4167
|
-
* @returns The fee token address and decimals
|
|
3714
|
+
proof: Proof,
|
|
3715
|
+
/*
|
|
3716
|
+
* Signer information. Ideally should be their account identifier
|
|
4168
3717
|
*/
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
});
|
|
4175
|
-
const feeTokenAddress = hostParams.feeToken;
|
|
4176
|
-
const feeTokenDecimals = await this.publicClient.readContract({
|
|
4177
|
-
address: feeTokenAddress,
|
|
4178
|
-
abi: erc20Abi,
|
|
4179
|
-
functionName: "decimals"
|
|
4180
|
-
});
|
|
4181
|
-
return { address: feeTokenAddress, decimals: feeTokenDecimals };
|
|
4182
|
-
}
|
|
4183
|
-
/**
|
|
4184
|
-
* Gets the nonce of the host.
|
|
4185
|
-
* This function gets the nonce of the host.
|
|
4186
|
-
*
|
|
4187
|
-
* @returns The nonce of the host
|
|
3718
|
+
signer: Vector(u8)
|
|
3719
|
+
});
|
|
3720
|
+
var RequestResponse = Enum({
|
|
3721
|
+
/*
|
|
3722
|
+
* A set of requests
|
|
4188
3723
|
*/
|
|
4189
|
-
|
|
4190
|
-
const nonce = await this.publicClient.readContract({
|
|
4191
|
-
abi: evmHost_default.ABI,
|
|
4192
|
-
address: this.params.host,
|
|
4193
|
-
functionName: "nonce"
|
|
4194
|
-
});
|
|
4195
|
-
return nonce;
|
|
4196
|
-
}
|
|
4197
|
-
};
|
|
4198
|
-
var REQUEST_COMMITMENTS_SLOT = 0n;
|
|
4199
|
-
var RESPONSE_COMMITMENTS_SLOT = 1n;
|
|
4200
|
-
var REQUEST_RECEIPTS_SLOT = 2n;
|
|
4201
|
-
var RESPONSE_RECEIPTS_SLOT = 3n;
|
|
4202
|
-
var STATE_COMMITMENTS_SLOT = 5n;
|
|
4203
|
-
function requestCommitmentKey(key) {
|
|
4204
|
-
const keyBytes = hexToBytes(key);
|
|
4205
|
-
const slot = REQUEST_COMMITMENTS_SLOT;
|
|
4206
|
-
const mappedKey = deriveMapKey(keyBytes, slot);
|
|
4207
|
-
const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n;
|
|
4208
|
-
return pad(`0x${number.toString(16)}`, { size: 32 });
|
|
4209
|
-
}
|
|
4210
|
-
function responseCommitmentKey(key) {
|
|
4211
|
-
const keyBytes = hexToBytes(key);
|
|
4212
|
-
const slot = RESPONSE_COMMITMENTS_SLOT;
|
|
4213
|
-
const mappedKey = deriveMapKey(keyBytes, slot);
|
|
4214
|
-
const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n;
|
|
4215
|
-
return pad(`0x${number.toString(16)}`, { size: 32 });
|
|
4216
|
-
}
|
|
4217
|
-
function deriveMapKey(key, slot) {
|
|
4218
|
-
const slotBytes = pad(`0x${slot.toString(16)}`, { size: 32 });
|
|
4219
|
-
const combined = new Uint8Array([...key, ...toBytes(slotBytes)]);
|
|
4220
|
-
return keccak256(combined);
|
|
4221
|
-
}
|
|
4222
|
-
function getStateCommitmentFieldSlot(stateMachineId, height, field) {
|
|
4223
|
-
const baseSlot = getStateCommitmentSlot(stateMachineId, height);
|
|
4224
|
-
const slotNumber = bytesToBigInt(toBytes(baseSlot)) + BigInt(field);
|
|
4225
|
-
return pad(`0x${slotNumber.toString(16)}`, { size: 32 });
|
|
4226
|
-
}
|
|
4227
|
-
function getStateCommitmentSlot(stateMachineId, height) {
|
|
4228
|
-
const firstLevelSlot = deriveFirstLevelSlot(stateMachineId, STATE_COMMITMENTS_SLOT);
|
|
4229
|
-
return deriveSecondLevelSlot(height, firstLevelSlot);
|
|
4230
|
-
}
|
|
4231
|
-
function deriveFirstLevelSlot(key, slot) {
|
|
4232
|
-
const keyHex = pad(`0x${key.toString(16)}`, { size: 32 });
|
|
4233
|
-
const keyBytes = toBytes(keyHex);
|
|
4234
|
-
const slotBytes = toBytes(pad(`0x${slot.toString(16)}`, { size: 32 }));
|
|
4235
|
-
const combined = new Uint8Array([...keyBytes, ...slotBytes]);
|
|
4236
|
-
return keccak256(combined);
|
|
4237
|
-
}
|
|
4238
|
-
function deriveSecondLevelSlot(key, firstLevelSlot) {
|
|
4239
|
-
const keyHex = pad(`0x${key.toString(16)}`, { size: 32 });
|
|
4240
|
-
const keyBytes = toBytes(keyHex);
|
|
4241
|
-
const slotBytes = toBytes(firstLevelSlot);
|
|
4242
|
-
const combined = new Uint8Array([...keyBytes, ...slotBytes]);
|
|
4243
|
-
return keccak256(combined);
|
|
4244
|
-
}
|
|
4245
|
-
var SubstrateChain = class {
|
|
4246
|
-
constructor(params) {
|
|
4247
|
-
this.params = params;
|
|
4248
|
-
}
|
|
3724
|
+
Request: Vector(Request),
|
|
4249
3725
|
/*
|
|
4250
|
-
*
|
|
3726
|
+
* A set of responses
|
|
4251
3727
|
*/
|
|
4252
|
-
|
|
3728
|
+
Response: Vector(Response)
|
|
3729
|
+
});
|
|
3730
|
+
var ResponseMessage = Struct({
|
|
4253
3731
|
/*
|
|
4254
|
-
*
|
|
3732
|
+
* A set of either POST requests or responses to be handled
|
|
4255
3733
|
*/
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
3734
|
+
datagram: Vector(RequestResponse),
|
|
3735
|
+
/*
|
|
3736
|
+
* Membership batch proof for these requests/responses
|
|
3737
|
+
*/
|
|
3738
|
+
proof: Proof,
|
|
3739
|
+
/*
|
|
3740
|
+
* Signer information. Ideally should be their account identifier
|
|
3741
|
+
*/
|
|
3742
|
+
signer: Vector(u8)
|
|
3743
|
+
});
|
|
3744
|
+
var TimeoutMessage = Enum({
|
|
3745
|
+
/*
|
|
3746
|
+
* A non memership proof for POST requests
|
|
3747
|
+
*/
|
|
3748
|
+
Post: Struct({
|
|
3749
|
+
/*
|
|
3750
|
+
* Timed out requests
|
|
3751
|
+
*/
|
|
3752
|
+
requests: Vector(Request),
|
|
3753
|
+
/*
|
|
3754
|
+
* Membership batch proof for these requests
|
|
3755
|
+
*/
|
|
3756
|
+
proof: Proof
|
|
3757
|
+
}),
|
|
3758
|
+
/*
|
|
3759
|
+
* A non memership proof for POST responses
|
|
3760
|
+
*/
|
|
3761
|
+
PostResponse: Struct({
|
|
3762
|
+
/*
|
|
3763
|
+
* Timed out responses
|
|
3764
|
+
*/
|
|
3765
|
+
responses: Vector(Response),
|
|
3766
|
+
/*
|
|
3767
|
+
* Membership batch proof for these responses
|
|
3768
|
+
*/
|
|
3769
|
+
proof: Proof
|
|
3770
|
+
}),
|
|
3771
|
+
/*
|
|
3772
|
+
* There are no proofs for Get timeouts
|
|
3773
|
+
*/
|
|
3774
|
+
Get: Struct({
|
|
3775
|
+
/*
|
|
3776
|
+
* Timed out requests
|
|
3777
|
+
*/
|
|
3778
|
+
requests: Vector(Request)
|
|
3779
|
+
})
|
|
3780
|
+
});
|
|
3781
|
+
var Message = Enum({
|
|
3782
|
+
/*
|
|
3783
|
+
* A consensus update message
|
|
3784
|
+
*/
|
|
3785
|
+
ConsensusMessage,
|
|
3786
|
+
/*
|
|
3787
|
+
* A fraud proof message
|
|
3788
|
+
*/
|
|
3789
|
+
FraudProofMessage,
|
|
3790
|
+
/*
|
|
3791
|
+
* A request message
|
|
3792
|
+
*/
|
|
3793
|
+
RequestMessage,
|
|
3794
|
+
/*
|
|
3795
|
+
* A response message
|
|
4275
3796
|
*/
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
this.api = void 0;
|
|
4280
|
-
}
|
|
4281
|
-
}
|
|
4282
|
-
/**
|
|
4283
|
-
* Returns the storage key for a request receipt in the child trie
|
|
4284
|
-
* The request commitment is the key
|
|
4285
|
-
* @param key - The H256 hash key (as a 0x-prefixed hex string)
|
|
4286
|
-
* @returns The storage key as a hex string
|
|
3797
|
+
ResponseMessage,
|
|
3798
|
+
/*
|
|
3799
|
+
* A request timeout message
|
|
4287
3800
|
*/
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
3801
|
+
TimeoutMessage
|
|
3802
|
+
});
|
|
3803
|
+
|
|
3804
|
+
// src/utils.ts
|
|
3805
|
+
var DEFAULT_POLL_INTERVAL = 5e3;
|
|
3806
|
+
var ADDRESS_ZERO = "0x0000000000000000000000000000000000000000";
|
|
3807
|
+
var MOCK_ADDRESS = "0x1234567890123456789012345678901234567890";
|
|
3808
|
+
var DUMMY_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
3809
|
+
var DEFAULT_GRAFFITI = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
3810
|
+
function sleep(ms) {
|
|
3811
|
+
return new Promise((resolve) => setTimeout(resolve, ms || DEFAULT_POLL_INTERVAL));
|
|
3812
|
+
}
|
|
3813
|
+
async function waitForChallengePeriod(chain, stateMachineHeight) {
|
|
3814
|
+
const challengePeriod = await chain.challengePeriod(stateMachineHeight.id);
|
|
3815
|
+
if (challengePeriod === BigInt(0)) return;
|
|
3816
|
+
const updateTime = await chain.stateMachineUpdateTime(stateMachineHeight);
|
|
3817
|
+
let currentTimestamp = await chain.timestamp();
|
|
3818
|
+
let timeElapsed = currentTimestamp - updateTime;
|
|
3819
|
+
if (timeElapsed > challengePeriod) return;
|
|
3820
|
+
await sleep(Number(challengePeriod) * 1e3);
|
|
3821
|
+
while (timeElapsed <= challengePeriod) {
|
|
3822
|
+
const remainingTime = challengePeriod - timeElapsed;
|
|
3823
|
+
await sleep(Number(remainingTime) * 1e3);
|
|
3824
|
+
currentTimestamp = await chain.timestamp();
|
|
3825
|
+
timeElapsed = currentTimestamp - updateTime;
|
|
4292
3826
|
}
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
3827
|
+
}
|
|
3828
|
+
function isEvmChain(stateMachineId) {
|
|
3829
|
+
return stateMachineId.startsWith("EVM");
|
|
3830
|
+
}
|
|
3831
|
+
function isSubstrateChain(stateMachineId) {
|
|
3832
|
+
return stateMachineId.startsWith("POLKADOT") || stateMachineId.startsWith("KUSAMA") || stateMachineId.startsWith("SUBSTRATE");
|
|
3833
|
+
}
|
|
3834
|
+
function parseStateMachineId(stateMachineId) {
|
|
3835
|
+
const [type, value] = stateMachineId.split("-");
|
|
3836
|
+
if (!type || !value) {
|
|
3837
|
+
throw new Error(
|
|
3838
|
+
`Invalid state machine ID format: ${stateMachineId}. Expected format like "EVM-97" or "SUBSTRATE-cere"`
|
|
3839
|
+
);
|
|
4303
3840
|
}
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
3841
|
+
const stateId = {};
|
|
3842
|
+
switch (type.toUpperCase()) {
|
|
3843
|
+
case "EVM": {
|
|
3844
|
+
const evmChainId = Number.parseInt(value, 10);
|
|
3845
|
+
if (Number.isNaN(evmChainId)) {
|
|
3846
|
+
throw new Error(`Invalid EVM chain ID: ${value}. Expected a number.`);
|
|
3847
|
+
}
|
|
3848
|
+
stateId.Evm = evmChainId;
|
|
3849
|
+
break;
|
|
3850
|
+
}
|
|
3851
|
+
case "SUBSTRATE": {
|
|
3852
|
+
const bytes = Buffer.from(value, "utf8");
|
|
3853
|
+
stateId.Substrate = `0x${bytes.toString("hex")}`;
|
|
3854
|
+
break;
|
|
3855
|
+
}
|
|
3856
|
+
case "POLKADOT": {
|
|
3857
|
+
const polkadotChainId = Number.parseInt(value, 10);
|
|
3858
|
+
if (Number.isNaN(polkadotChainId)) {
|
|
3859
|
+
throw new Error(`Invalid Polkadot chain ID: ${value}. Expected a number.`);
|
|
3860
|
+
}
|
|
3861
|
+
stateId.Polkadot = polkadotChainId;
|
|
3862
|
+
break;
|
|
3863
|
+
}
|
|
3864
|
+
case "KUSAMA": {
|
|
3865
|
+
const kusamaChainId = Number.parseInt(value, 10);
|
|
3866
|
+
if (Number.isNaN(kusamaChainId)) {
|
|
3867
|
+
throw new Error(`Invalid Kusama chain ID: ${value}. Expected a number.`);
|
|
3868
|
+
}
|
|
3869
|
+
stateId.Kusama = kusamaChainId;
|
|
3870
|
+
break;
|
|
3871
|
+
}
|
|
3872
|
+
default:
|
|
3873
|
+
throw new Error(`Unsupported chain type: ${type}. Expected one of: EVM, SUBSTRATE, POLKADOT, KUSAMA.`);
|
|
4316
3874
|
}
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
3875
|
+
return { stateId };
|
|
3876
|
+
}
|
|
3877
|
+
function postRequestCommitment(post) {
|
|
3878
|
+
const data = encodePacked(
|
|
3879
|
+
["bytes", "bytes", "uint64", "uint64", "bytes", "bytes", "bytes"],
|
|
3880
|
+
[toHex(post.source), toHex(post.dest), post.nonce, post.timeoutTimestamp, post.from, post.to, post.body]
|
|
3881
|
+
);
|
|
3882
|
+
return {
|
|
3883
|
+
commitment: keccak256(data),
|
|
3884
|
+
encodePacked: data
|
|
3885
|
+
};
|
|
3886
|
+
}
|
|
3887
|
+
function orderCommitment(order) {
|
|
3888
|
+
const encodedOrder = encodeAbiParameters(
|
|
3889
|
+
[
|
|
3890
|
+
{
|
|
3891
|
+
name: "order",
|
|
3892
|
+
type: "tuple",
|
|
3893
|
+
components: [
|
|
3894
|
+
{ name: "user", type: "bytes32" },
|
|
3895
|
+
{ name: "sourceChain", type: "bytes" },
|
|
3896
|
+
{ name: "destChain", type: "bytes" },
|
|
3897
|
+
{ name: "deadline", type: "uint256" },
|
|
3898
|
+
{ name: "nonce", type: "uint256" },
|
|
3899
|
+
{ name: "fees", type: "uint256" },
|
|
3900
|
+
{
|
|
3901
|
+
name: "outputs",
|
|
3902
|
+
type: "tuple[]",
|
|
3903
|
+
components: [
|
|
3904
|
+
{ name: "token", type: "bytes32" },
|
|
3905
|
+
{ name: "amount", type: "uint256" },
|
|
3906
|
+
{ name: "beneficiary", type: "bytes32" }
|
|
3907
|
+
]
|
|
3908
|
+
},
|
|
3909
|
+
{
|
|
3910
|
+
name: "inputs",
|
|
3911
|
+
type: "tuple[]",
|
|
3912
|
+
components: [
|
|
3913
|
+
{ name: "token", type: "bytes32" },
|
|
3914
|
+
{ name: "amount", type: "uint256" }
|
|
3915
|
+
]
|
|
3916
|
+
},
|
|
3917
|
+
{ name: "callData", type: "bytes" }
|
|
3918
|
+
]
|
|
3919
|
+
}
|
|
3920
|
+
],
|
|
3921
|
+
[
|
|
3922
|
+
{
|
|
3923
|
+
user: order.user,
|
|
3924
|
+
sourceChain: order.sourceChain.startsWith("0x") ? order.sourceChain : toHex(order.sourceChain),
|
|
3925
|
+
destChain: order.destChain.startsWith("0x") ? order.destChain : toHex(order.destChain),
|
|
3926
|
+
deadline: order.deadline,
|
|
3927
|
+
nonce: order.nonce,
|
|
3928
|
+
fees: order.fees,
|
|
3929
|
+
outputs: order.outputs,
|
|
3930
|
+
inputs: order.inputs,
|
|
3931
|
+
callData: order.callData
|
|
3932
|
+
}
|
|
3933
|
+
]
|
|
3934
|
+
);
|
|
3935
|
+
return keccak256(encodedOrder);
|
|
3936
|
+
}
|
|
3937
|
+
function bytes32ToBytes20(bytes32Address) {
|
|
3938
|
+
if (bytes32Address === ADDRESS_ZERO) {
|
|
3939
|
+
return ADDRESS_ZERO;
|
|
4329
3940
|
}
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
3941
|
+
const bytes = hexToBytes(bytes32Address);
|
|
3942
|
+
const addressBytes = bytes.slice(12);
|
|
3943
|
+
return bytesToHex(addressBytes);
|
|
3944
|
+
}
|
|
3945
|
+
function bytes20ToBytes32(bytes20Address) {
|
|
3946
|
+
return `0x${bytes20Address.slice(2).padStart(64, "0")}`;
|
|
3947
|
+
}
|
|
3948
|
+
function hexToString(hex) {
|
|
3949
|
+
const hexWithoutPrefix = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
3950
|
+
const bytes = new Uint8Array(hexWithoutPrefix.length / 2);
|
|
3951
|
+
for (let i = 0; i < hexWithoutPrefix.length; i += 2) {
|
|
3952
|
+
bytes[i / 2] = Number.parseInt(hexWithoutPrefix.slice(i, i + 2), 16);
|
|
4338
3953
|
}
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
3954
|
+
return new TextDecoder().decode(bytes);
|
|
3955
|
+
}
|
|
3956
|
+
var DEFAULT_LOGGER = createConsola({
|
|
3957
|
+
level: LogLevels.silent
|
|
3958
|
+
});
|
|
3959
|
+
async function retryPromise(operation, retryConfig) {
|
|
3960
|
+
const { logger = DEFAULT_LOGGER, logMessage = "Retry operation failed" } = retryConfig;
|
|
3961
|
+
let lastError;
|
|
3962
|
+
for (let i = 0; i < retryConfig.maxRetries; i++) {
|
|
3963
|
+
try {
|
|
3964
|
+
return await operation();
|
|
3965
|
+
} catch (error) {
|
|
3966
|
+
logger.trace(`Retrying(${i}) > ${logMessage}`);
|
|
3967
|
+
lastError = error;
|
|
3968
|
+
await new Promise((resolve) => setTimeout(resolve, retryConfig.backoffMs * 2 ** i));
|
|
4352
3969
|
}
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
3970
|
+
}
|
|
3971
|
+
throw lastError;
|
|
3972
|
+
}
|
|
3973
|
+
function getRequestCommitment(get) {
|
|
3974
|
+
const keysEncoding = "0x".concat(get.keys.map((key) => key.slice(2)).join(""));
|
|
3975
|
+
return keccak256(
|
|
3976
|
+
encodePacked(
|
|
3977
|
+
["bytes", "bytes", "uint64", "uint64", "uint64", "bytes", "bytes", "bytes"],
|
|
3978
|
+
[
|
|
3979
|
+
toHex(get.source),
|
|
3980
|
+
toHex(get.dest),
|
|
3981
|
+
get.nonce,
|
|
3982
|
+
get.height,
|
|
3983
|
+
get.timeoutTimestamp,
|
|
3984
|
+
get.from,
|
|
3985
|
+
keysEncoding,
|
|
3986
|
+
get.context
|
|
3987
|
+
]
|
|
3988
|
+
)
|
|
3989
|
+
);
|
|
3990
|
+
}
|
|
3991
|
+
var REQUEST_STATUS_WEIGHTS = {
|
|
3992
|
+
[RequestStatus.SOURCE]: 0,
|
|
3993
|
+
[RequestStatus.SOURCE_FINALIZED]: 1,
|
|
3994
|
+
[RequestStatus.HYPERBRIDGE_DELIVERED]: 2,
|
|
3995
|
+
[RequestStatus.HYPERBRIDGE_FINALIZED]: 3,
|
|
3996
|
+
[RequestStatus.DESTINATION]: 4,
|
|
3997
|
+
[RequestStatus.HYPERBRIDGE_TIMED_OUT]: 5,
|
|
3998
|
+
[RequestStatus.TIMED_OUT]: 6
|
|
3999
|
+
};
|
|
4000
|
+
var TIMEOUT_STATUS_WEIGHTS = {
|
|
4001
|
+
[TimeoutStatus.PENDING_TIMEOUT]: 1,
|
|
4002
|
+
[TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 2,
|
|
4003
|
+
[TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 3,
|
|
4004
|
+
[TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 4,
|
|
4005
|
+
[TimeoutStatus.TIMED_OUT]: 5
|
|
4006
|
+
};
|
|
4007
|
+
var COMBINED_STATUS_WEIGHTS = {
|
|
4008
|
+
[RequestStatus.SOURCE]: 0,
|
|
4009
|
+
[RequestStatus.SOURCE_FINALIZED]: 1,
|
|
4010
|
+
[RequestStatus.HYPERBRIDGE_DELIVERED]: 2,
|
|
4011
|
+
[RequestStatus.HYPERBRIDGE_FINALIZED]: 3,
|
|
4012
|
+
[RequestStatus.DESTINATION]: 4,
|
|
4013
|
+
[TimeoutStatus.PENDING_TIMEOUT]: 5,
|
|
4014
|
+
[TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 6,
|
|
4015
|
+
[TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 7,
|
|
4016
|
+
[TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 8,
|
|
4017
|
+
[TimeoutStatus.TIMED_OUT]: 9
|
|
4018
|
+
};
|
|
4019
|
+
async function estimateGasForPost(params) {
|
|
4020
|
+
const hostParams = await params.sourceClient.readContract({
|
|
4021
|
+
address: params.hostAddress,
|
|
4022
|
+
abi: evmHost_default.ABI,
|
|
4023
|
+
functionName: "hostParams"
|
|
4024
|
+
});
|
|
4025
|
+
const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(params.postRequest, 2n ** 10n);
|
|
4026
|
+
const latestStateMachineHeight = params.hostLatestStateMachineHeight;
|
|
4027
|
+
const overlayRootSlot = getStateCommitmentFieldSlot(
|
|
4028
|
+
BigInt(4009n),
|
|
4029
|
+
// Hyperbridge chain id
|
|
4030
|
+
latestStateMachineHeight,
|
|
4031
|
+
// Hyperbridge chain height
|
|
4032
|
+
1
|
|
4033
|
+
// For overlayRoot
|
|
4034
|
+
);
|
|
4035
|
+
const postParams = {
|
|
4036
|
+
height: {
|
|
4037
|
+
stateMachineId: BigInt(4009n),
|
|
4038
|
+
height: latestStateMachineHeight
|
|
4039
|
+
},
|
|
4040
|
+
multiproof: proof,
|
|
4041
|
+
leafCount: treeSize
|
|
4042
|
+
};
|
|
4043
|
+
const call_data = [
|
|
4044
|
+
params.hostAddress,
|
|
4045
|
+
{
|
|
4046
|
+
proof: postParams,
|
|
4047
|
+
requests: [
|
|
4048
|
+
{
|
|
4049
|
+
request: {
|
|
4050
|
+
...params.postRequest,
|
|
4051
|
+
source: toHex(params.postRequest.source),
|
|
4052
|
+
dest: toHex(params.postRequest.dest)
|
|
4363
4053
|
},
|
|
4364
|
-
|
|
4054
|
+
index,
|
|
4055
|
+
kIndex
|
|
4365
4056
|
}
|
|
4366
|
-
|
|
4367
|
-
return toHex(encoded);
|
|
4057
|
+
]
|
|
4368
4058
|
}
|
|
4369
|
-
|
|
4059
|
+
];
|
|
4060
|
+
const gas_fee = await params.sourceClient.estimateContractGas({
|
|
4061
|
+
address: hostParams.handler,
|
|
4062
|
+
abi: handler_default.ABI,
|
|
4063
|
+
functionName: "handlePostRequests",
|
|
4064
|
+
args: call_data,
|
|
4065
|
+
stateOverride: [
|
|
4066
|
+
{
|
|
4067
|
+
address: params.hostAddress,
|
|
4068
|
+
stateDiff: [
|
|
4069
|
+
{
|
|
4070
|
+
slot: overlayRootSlot,
|
|
4071
|
+
value: root
|
|
4072
|
+
}
|
|
4073
|
+
]
|
|
4074
|
+
}
|
|
4075
|
+
]
|
|
4076
|
+
});
|
|
4077
|
+
return { gas_fee, call_data };
|
|
4078
|
+
}
|
|
4079
|
+
function constructRedeemEscrowRequestBody(order, beneficiary) {
|
|
4080
|
+
const commitment = order.id;
|
|
4081
|
+
const inputs = order.inputs;
|
|
4082
|
+
const requestKind = encodePacked(["uint8"], [0 /* RedeemEscrow */]);
|
|
4083
|
+
const requestBody = {
|
|
4084
|
+
commitment,
|
|
4085
|
+
beneficiary: bytes20ToBytes32(beneficiary),
|
|
4086
|
+
tokens: inputs
|
|
4087
|
+
};
|
|
4088
|
+
const encodedRequestBody = encodeAbiParameters(
|
|
4089
|
+
[
|
|
4090
|
+
{
|
|
4091
|
+
name: "requestBody",
|
|
4092
|
+
type: "tuple",
|
|
4093
|
+
components: [
|
|
4094
|
+
{ name: "commitment", type: "bytes32" },
|
|
4095
|
+
{ name: "beneficiary", type: "bytes32" },
|
|
4096
|
+
{
|
|
4097
|
+
name: "tokens",
|
|
4098
|
+
type: "tuple[]",
|
|
4099
|
+
components: [
|
|
4100
|
+
{ name: "token", type: "bytes32" },
|
|
4101
|
+
{ name: "amount", type: "uint256" }
|
|
4102
|
+
]
|
|
4103
|
+
}
|
|
4104
|
+
]
|
|
4105
|
+
}
|
|
4106
|
+
],
|
|
4107
|
+
[requestBody]
|
|
4108
|
+
);
|
|
4109
|
+
return concatHex([requestKind, encodedRequestBody]);
|
|
4110
|
+
}
|
|
4111
|
+
var dateStringtoTimestamp = (date) => {
|
|
4112
|
+
if (!date.endsWith("Z")) {
|
|
4113
|
+
date = `${date}Z`;
|
|
4370
4114
|
}
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
});
|
|
4397
|
-
} else if (isError) {
|
|
4398
|
-
unsub();
|
|
4399
|
-
console.error("Unsigned transaction failed: ", dispatchError);
|
|
4400
|
-
reject(dispatchError);
|
|
4401
|
-
}
|
|
4402
|
-
}).then((unsubscribe) => {
|
|
4403
|
-
unsub = unsubscribe;
|
|
4404
|
-
}).catch(reject);
|
|
4405
|
-
});
|
|
4115
|
+
return new Date(date).getTime();
|
|
4116
|
+
};
|
|
4117
|
+
function mapTestnetToMainnet(identifier) {
|
|
4118
|
+
identifier = identifier.toLowerCase();
|
|
4119
|
+
switch (identifier) {
|
|
4120
|
+
case "bnb":
|
|
4121
|
+
return "wbnb";
|
|
4122
|
+
case "eth":
|
|
4123
|
+
return "weth";
|
|
4124
|
+
case "tbnb":
|
|
4125
|
+
return "wbnb";
|
|
4126
|
+
case "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase():
|
|
4127
|
+
return "dai";
|
|
4128
|
+
case "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase():
|
|
4129
|
+
return "wbnb";
|
|
4130
|
+
case "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase():
|
|
4131
|
+
return "dai";
|
|
4132
|
+
case "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase():
|
|
4133
|
+
return "dai";
|
|
4134
|
+
case "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase():
|
|
4135
|
+
return "dai";
|
|
4136
|
+
case "0xa801da100bf16d07f668f4a49e1f71fc54d05177".toLowerCase():
|
|
4137
|
+
return "dai";
|
|
4138
|
+
default:
|
|
4139
|
+
return identifier;
|
|
4406
4140
|
}
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
hasher: {
|
|
4423
|
-
tag: this.params.hasher,
|
|
4424
|
-
value: void 0
|
|
4425
|
-
},
|
|
4426
|
-
storageProof: basicProof
|
|
4427
|
-
}
|
|
4428
|
-
});
|
|
4429
|
-
return toHex(encoded);
|
|
4141
|
+
}
|
|
4142
|
+
async function fetchTokenUsdPrice(identifier) {
|
|
4143
|
+
try {
|
|
4144
|
+
const coinGeckoPrice = await fetchFromCoinGecko(identifier);
|
|
4145
|
+
return coinGeckoPrice;
|
|
4146
|
+
} catch (error) {
|
|
4147
|
+
try {
|
|
4148
|
+
const defillamaPrice = await fetchFromDefillama(identifier);
|
|
4149
|
+
return defillamaPrice;
|
|
4150
|
+
} catch (fallbackError) {
|
|
4151
|
+
console.log(
|
|
4152
|
+
`Both APIs failed for ${identifier}. CoinGecko: ${error}, Defillama: ${fallbackError}. Returning 1`
|
|
4153
|
+
);
|
|
4154
|
+
return 1;
|
|
4155
|
+
}
|
|
4430
4156
|
}
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
const latestHeight = await this.api.query.ismp.latestStateMachineHeight(stateMachineId);
|
|
4439
|
-
return BigInt(latestHeight.toString());
|
|
4157
|
+
}
|
|
4158
|
+
async function fetchFromCoinGecko(identifier) {
|
|
4159
|
+
const mappedIdentifier = mapTestnetToMainnet(identifier);
|
|
4160
|
+
const url = mappedIdentifier.startsWith("0x") ? `https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses=${mappedIdentifier}&vs_currencies=usd` : `https://api.coingecko.com/api/v3/simple/price?ids=${mappedIdentifier}&vs_currencies=usd`;
|
|
4161
|
+
const response = await fetch(url);
|
|
4162
|
+
if (!response.ok) {
|
|
4163
|
+
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
4440
4164
|
}
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
*/
|
|
4446
|
-
async stateMachineUpdateTime(stateMachineHeight) {
|
|
4447
|
-
if (!this.api) throw new Error("API not initialized");
|
|
4448
|
-
const updateTime = await this.api.query.ismp.stateMachineUpdateTime(stateMachineHeight);
|
|
4449
|
-
return BigInt(updateTime.toString());
|
|
4165
|
+
const data = await response.json();
|
|
4166
|
+
const key = mappedIdentifier.toLowerCase();
|
|
4167
|
+
if (!data[key]?.usd) {
|
|
4168
|
+
throw new Error(`Price not found for token: ${mappedIdentifier}`);
|
|
4450
4169
|
}
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4170
|
+
return data[key].usd;
|
|
4171
|
+
}
|
|
4172
|
+
async function fetchFromDefillama(identifier) {
|
|
4173
|
+
const mappedIdentifier = mapTestnetToMainnet(identifier);
|
|
4174
|
+
const coinId = mappedIdentifier.startsWith("0x") ? `ethereum:${mappedIdentifier}` : `coingecko:${mappedIdentifier}`;
|
|
4175
|
+
const url = `https://coins.llama.fi/prices/current/${coinId}`;
|
|
4176
|
+
const response = await fetch(url);
|
|
4177
|
+
if (!response.ok) {
|
|
4178
|
+
throw new Error(`Defillama API error: ${response.status} ${response.statusText}`);
|
|
4460
4179
|
}
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
*/
|
|
4466
|
-
encode(message) {
|
|
4467
|
-
const palletIndex = this.getPalletIndex("Ismp");
|
|
4468
|
-
const args = encodeISMPMessage(message);
|
|
4469
|
-
const call = Vector(u8, 2).enc([palletIndex, 0]);
|
|
4470
|
-
return toHex(new Uint8Array([...call, ...args]));
|
|
4180
|
+
const data = await response.json();
|
|
4181
|
+
const price = data.coins?.[coinId]?.price;
|
|
4182
|
+
if (!price && price !== 0) {
|
|
4183
|
+
throw new Error(`Price not found for token: ${mappedIdentifier}`);
|
|
4471
4184
|
}
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4185
|
+
return price;
|
|
4186
|
+
}
|
|
4187
|
+
var ERC20Method = /* @__PURE__ */ ((ERC20Method2) => {
|
|
4188
|
+
ERC20Method2["BALANCE_OF"] = "0x70a08231";
|
|
4189
|
+
ERC20Method2["ALLOWANCE"] = "0xdd62ed3e";
|
|
4190
|
+
return ERC20Method2;
|
|
4191
|
+
})(ERC20Method || {});
|
|
4192
|
+
async function getStorageSlot(client, contractAddress, data) {
|
|
4193
|
+
const traceCallClient = client.extend((client2) => ({
|
|
4194
|
+
async traceCall(args) {
|
|
4195
|
+
return client2.request({
|
|
4196
|
+
// @ts-ignore
|
|
4197
|
+
method: "debug_traceCall",
|
|
4198
|
+
// @ts-ignore
|
|
4199
|
+
params: [args, "latest", {}]
|
|
4200
|
+
});
|
|
4201
|
+
}
|
|
4202
|
+
}));
|
|
4203
|
+
const response = await traceCallClient.traceCall({
|
|
4204
|
+
to: contractAddress,
|
|
4205
|
+
data
|
|
4206
|
+
});
|
|
4207
|
+
const methodSignature = data.slice(0, 10);
|
|
4208
|
+
const logs = response.structLogs;
|
|
4209
|
+
for (let i = logs.length - 1; i >= 0; i--) {
|
|
4210
|
+
const log = logs[i];
|
|
4211
|
+
if (log.op === "SLOAD" && log.stack?.length >= 3) {
|
|
4212
|
+
const sigHash = log.stack[0];
|
|
4213
|
+
const slotHex = log.stack[log.stack.length - 1];
|
|
4214
|
+
if (sigHash === methodSignature && slotHex.length === 66) {
|
|
4215
|
+
return slotHex;
|
|
4484
4216
|
}
|
|
4485
4217
|
}
|
|
4486
|
-
throw new Error(`${name} not found in runtime`);
|
|
4487
4218
|
}
|
|
4488
|
-
};
|
|
4489
|
-
function requestCommitmentStorageKey(key) {
|
|
4490
|
-
const prefix = new TextEncoder().encode("RequestCommitments");
|
|
4491
|
-
const keyBytes = hexToBytes(key);
|
|
4492
|
-
return Array.from(new Uint8Array([...prefix, ...keyBytes]));
|
|
4493
|
-
}
|
|
4494
|
-
function responseCommitmentStorageKey(key) {
|
|
4495
|
-
const prefix = new TextEncoder().encode("ResponseCommitments");
|
|
4496
|
-
const keyBytes = hexToBytes(key);
|
|
4497
|
-
return Array.from(new Uint8Array([...prefix, ...keyBytes]));
|
|
4219
|
+
throw new Error(`Storage slot not found for data: ${methodSignature}`);
|
|
4498
4220
|
}
|
|
4499
|
-
function
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4221
|
+
function adjustFeeDecimals(feeInFeeToken, fromDecimals, toDecimals) {
|
|
4222
|
+
if (fromDecimals === toDecimals) return feeInFeeToken;
|
|
4223
|
+
if (fromDecimals < toDecimals) {
|
|
4224
|
+
const scaleFactor = BigInt(10 ** (toDecimals - fromDecimals));
|
|
4225
|
+
return feeInFeeToken * scaleFactor;
|
|
4504
4226
|
} else {
|
|
4505
|
-
|
|
4227
|
+
const scaleFactor = BigInt(10 ** (fromDecimals - toDecimals));
|
|
4228
|
+
return (feeInFeeToken + scaleFactor - 1n) / scaleFactor;
|
|
4506
4229
|
}
|
|
4507
|
-
return { tag, value };
|
|
4508
|
-
}
|
|
4509
|
-
function convertIPostRequestToCodec(request) {
|
|
4510
|
-
return {
|
|
4511
|
-
tag: "Post",
|
|
4512
|
-
value: {
|
|
4513
|
-
source: convertStateMachineIdToEnum(request.source),
|
|
4514
|
-
dest: convertStateMachineIdToEnum(request.dest),
|
|
4515
|
-
from: Array.from(hexToBytes(request.from)),
|
|
4516
|
-
to: Array.from(hexToBytes(request.to)),
|
|
4517
|
-
nonce: request.nonce,
|
|
4518
|
-
body: Array.from(hexToBytes(request.body)),
|
|
4519
|
-
timeoutTimestamp: request.timeoutTimestamp
|
|
4520
|
-
}
|
|
4521
|
-
};
|
|
4522
4230
|
}
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4231
|
+
|
|
4232
|
+
// src/utils/exceptions.ts
|
|
4233
|
+
var AbortSignalInternal = class _AbortSignalInternal extends Error {
|
|
4234
|
+
constructor(message) {
|
|
4235
|
+
super();
|
|
4236
|
+
this.name = "Hyperbridge/SDK/AbortSignalInternal";
|
|
4237
|
+
this.message = message;
|
|
4238
|
+
}
|
|
4239
|
+
static isError(error) {
|
|
4240
|
+
return error instanceof _AbortSignalInternal;
|
|
4241
|
+
}
|
|
4242
|
+
};
|
|
4243
|
+
var ExpectedError = class _ExpectedError extends Error {
|
|
4244
|
+
constructor(message) {
|
|
4245
|
+
super();
|
|
4246
|
+
this.name = "Hyperbridge/SDK/ExpectedError";
|
|
4247
|
+
this.message = message;
|
|
4248
|
+
}
|
|
4249
|
+
static isError(error) {
|
|
4250
|
+
return error instanceof _ExpectedError;
|
|
4251
|
+
}
|
|
4252
|
+
};
|
|
4253
|
+
var Chains = /* @__PURE__ */ ((Chains2) => {
|
|
4254
|
+
Chains2["BSC_CHAPEL"] = "EVM-97";
|
|
4255
|
+
Chains2["GNOSIS_CHIADO"] = "EVM-10200";
|
|
4256
|
+
Chains2["HYPERBRIDGE_GARGANTUA"] = "KUSAMA-4009";
|
|
4257
|
+
Chains2["SEPOLIA"] = "EVM-11155111";
|
|
4258
|
+
Chains2["MAINNET"] = "EVM-1";
|
|
4259
|
+
Chains2["BSC_MAINNET"] = "EVM-56";
|
|
4260
|
+
Chains2["ARBITRUM_MAINNET"] = "EVM-42161";
|
|
4261
|
+
Chains2["BASE_MAINNET"] = "EVM-8453";
|
|
4262
|
+
return Chains2;
|
|
4263
|
+
})(Chains || {});
|
|
4264
|
+
var chainIds = {
|
|
4265
|
+
["EVM-97" /* BSC_CHAPEL */]: 97,
|
|
4266
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: 10200,
|
|
4267
|
+
["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */]: 4009,
|
|
4268
|
+
["EVM-11155111" /* SEPOLIA */]: 11155111,
|
|
4269
|
+
["EVM-1" /* MAINNET */]: 1,
|
|
4270
|
+
["EVM-56" /* BSC_MAINNET */]: 56,
|
|
4271
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: 42161,
|
|
4272
|
+
["EVM-8453" /* BASE_MAINNET */]: 8453
|
|
4273
|
+
};
|
|
4274
|
+
var viemChains = {
|
|
4275
|
+
"97": bscTestnet,
|
|
4276
|
+
"10200": gnosisChiado,
|
|
4277
|
+
"11155111": sepolia,
|
|
4278
|
+
"1": mainnet,
|
|
4279
|
+
"56": bsc,
|
|
4280
|
+
"42161": arbitrum,
|
|
4281
|
+
"8453": base
|
|
4282
|
+
};
|
|
4283
|
+
var WrappedNativeDecimals = {
|
|
4284
|
+
["EVM-97" /* BSC_CHAPEL */]: 18,
|
|
4285
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: 18,
|
|
4286
|
+
["EVM-11155111" /* SEPOLIA */]: 18,
|
|
4287
|
+
["EVM-1" /* MAINNET */]: 18,
|
|
4288
|
+
["EVM-56" /* BSC_MAINNET */]: 18,
|
|
4289
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: 18,
|
|
4290
|
+
["EVM-8453" /* BASE_MAINNET */]: 18
|
|
4291
|
+
};
|
|
4292
|
+
var assets = {
|
|
4293
|
+
["EVM-97" /* BSC_CHAPEL */]: {
|
|
4294
|
+
WETH: "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase(),
|
|
4295
|
+
DAI: "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase(),
|
|
4296
|
+
USDC: "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase(),
|
|
4297
|
+
USDT: "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase()
|
|
4298
|
+
},
|
|
4299
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: {
|
|
4300
|
+
WETH: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
4301
|
+
DAI: "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase(),
|
|
4302
|
+
USDC: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
4303
|
+
USDT: "0x0000000000000000000000000000000000000000".toLowerCase()
|
|
4304
|
+
},
|
|
4305
|
+
["EVM-11155111" /* SEPOLIA */]: {
|
|
4306
|
+
WETH: "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9".toLowerCase(),
|
|
4307
|
+
USDC: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
4308
|
+
USDT: "0x0000000000000000000000000000000000000000".toLowerCase(),
|
|
4309
|
+
DAI: "0x0000000000000000000000000000000000000000".toLowerCase()
|
|
4310
|
+
},
|
|
4311
|
+
["EVM-1" /* MAINNET */]: {
|
|
4312
|
+
WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".toLowerCase(),
|
|
4313
|
+
DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F".toLowerCase(),
|
|
4314
|
+
USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".toLowerCase(),
|
|
4315
|
+
USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7".toLowerCase()
|
|
4316
|
+
},
|
|
4317
|
+
["EVM-56" /* BSC_MAINNET */]: {
|
|
4318
|
+
WETH: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c".toLowerCase(),
|
|
4319
|
+
DAI: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3".toLowerCase(),
|
|
4320
|
+
USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d".toLowerCase(),
|
|
4321
|
+
USDT: "0x55d398326f99059fF775485246999027B3197955".toLowerCase()
|
|
4322
|
+
},
|
|
4323
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: {
|
|
4324
|
+
WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1".toLowerCase(),
|
|
4325
|
+
DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1".toLowerCase(),
|
|
4326
|
+
USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831".toLowerCase(),
|
|
4327
|
+
USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9".toLowerCase()
|
|
4328
|
+
},
|
|
4329
|
+
["EVM-8453" /* BASE_MAINNET */]: {
|
|
4330
|
+
WETH: "0x4200000000000000000000000000000000000006".toLowerCase(),
|
|
4331
|
+
DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb".toLowerCase(),
|
|
4332
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913".toLowerCase(),
|
|
4333
|
+
USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2".toLowerCase()
|
|
4334
|
+
}
|
|
4335
|
+
};
|
|
4336
|
+
var addresses = {
|
|
4337
|
+
IntentGateway: {
|
|
4338
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
|
|
4339
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
|
|
4340
|
+
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
4341
|
+
["EVM-1" /* MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA",
|
|
4342
|
+
["EVM-56" /* BSC_MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA",
|
|
4343
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA",
|
|
4344
|
+
["EVM-8453" /* BASE_MAINNET */]: "0xd54165e45926720b062C192a5bacEC64d5bB08DA"
|
|
4345
|
+
},
|
|
4346
|
+
Host: {
|
|
4347
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7",
|
|
4348
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: "0x58a41b89f4871725e5d898d98ef4bf917601c5eb",
|
|
4349
|
+
["EVM-11155111" /* SEPOLIA */]: "0x2EdB74C269948b60ec1000040E104cef0eABaae8",
|
|
4350
|
+
["EVM-1" /* MAINNET */]: "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20",
|
|
4351
|
+
["EVM-56" /* BSC_MAINNET */]: "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7",
|
|
4352
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0xE05AFD4Eb2ce6d65c40e1048381BD0Ef8b4B299e",
|
|
4353
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x6FFe92e4d7a9D589549644544780e6725E84b248"
|
|
4354
|
+
},
|
|
4355
|
+
UniswapRouter02: {
|
|
4356
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
|
|
4357
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: "0x0000000000000000000000000000000000000000",
|
|
4358
|
+
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
4359
|
+
["EVM-1" /* MAINNET */]: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
|
|
4360
|
+
["EVM-56" /* BSC_MAINNET */]: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
|
|
4361
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4362
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4363
|
+
},
|
|
4364
|
+
UniswapV2Factory: {
|
|
4365
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x12e036669DA18F4A2777853d6e2136b32AceEC86",
|
|
4366
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: "0x0000000000000000000000000000000000000000",
|
|
4367
|
+
["EVM-11155111" /* SEPOLIA */]: "0x0000000000000000000000000000000000000000",
|
|
4368
|
+
["EVM-1" /* MAINNET */]: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
|
|
4369
|
+
["EVM-56" /* BSC_MAINNET */]: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6",
|
|
4370
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4371
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4372
|
+
},
|
|
4373
|
+
BatchExecutor: {
|
|
4374
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x4CC58B5D8FBf838d062E4b21F75C327835B5F0ef",
|
|
4375
|
+
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4376
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4377
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4378
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4379
|
+
},
|
|
4380
|
+
UniversalRouter: {
|
|
4381
|
+
["EVM-97" /* BSC_CHAPEL */]: "0xcc6d5ece3d4a57245bf5a2f64f3ed9179b81f714",
|
|
4382
|
+
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4383
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4384
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4385
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4386
|
+
},
|
|
4387
|
+
UniswapV3Router: {
|
|
4388
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
4389
|
+
["EVM-1" /* MAINNET */]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
4390
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4391
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4392
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4393
|
+
},
|
|
4394
|
+
UniswapV3Factory: {
|
|
4395
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
4396
|
+
["EVM-1" /* MAINNET */]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
4397
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4398
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4399
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4400
|
+
},
|
|
4401
|
+
UniswapV3Quoter: {
|
|
4402
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
4403
|
+
["EVM-1" /* MAINNET */]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e",
|
|
4404
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4405
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4406
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4407
|
+
},
|
|
4408
|
+
UniswapV4PoolManager: {
|
|
4409
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
4410
|
+
["EVM-1" /* MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4411
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4412
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4413
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4414
|
+
},
|
|
4415
|
+
UniswapV4Quoter: {
|
|
4416
|
+
["EVM-97" /* BSC_CHAPEL */]: "0x0000000000000000000000000000000000000000",
|
|
4417
|
+
["EVM-1" /* MAINNET */]: "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",
|
|
4418
|
+
["EVM-56" /* BSC_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4419
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "0x0000000000000000000000000000000000000000",
|
|
4420
|
+
["EVM-8453" /* BASE_MAINNET */]: "0x0000000000000000000000000000000000000000"
|
|
4421
|
+
},
|
|
4422
|
+
Calldispatcher: {
|
|
4423
|
+
["EVM-11155111" /* SEPOLIA */]: "0xC7f13b6D03A0A7F3239d38897503E90553ABe155"
|
|
4574
4424
|
}
|
|
4575
|
-
}
|
|
4425
|
+
};
|
|
4426
|
+
var createRpcUrls = (env2) => ({
|
|
4427
|
+
["EVM-97" /* BSC_CHAPEL */]: env2.BSC_CHAPEL || "https://bnb-testnet.api.onfinality.io/public",
|
|
4428
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: env2.GNOSIS_CHIADO || "https://gnosis-chiado-rpc.publicnode.com",
|
|
4429
|
+
["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */]: env2.HYPERBRIDGE_GARGANTUA || "",
|
|
4430
|
+
["EVM-11155111" /* SEPOLIA */]: env2.SEPOLIA || "https://1rpc.io/sepolia",
|
|
4431
|
+
["EVM-1" /* MAINNET */]: env2.ETH_MAINNET || "https://eth-mainnet.g.alchemy.com/v2/demo",
|
|
4432
|
+
["EVM-56" /* BSC_MAINNET */]: env2.BSC_MAINNET || "https://binance.llamarpc.com",
|
|
4433
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: env2.ARBITRUM_MAINNET || "https://arbitrum-one.public.blastapi.io",
|
|
4434
|
+
["EVM-8453" /* BASE_MAINNET */]: env2.BASE_MAINNET || "https://base-mainnet.public.blastapi.io"
|
|
4435
|
+
});
|
|
4436
|
+
var consensusStateIds = {
|
|
4437
|
+
["EVM-97" /* BSC_CHAPEL */]: "BSC0",
|
|
4438
|
+
["EVM-10200" /* GNOSIS_CHIADO */]: "GNO0",
|
|
4439
|
+
["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */]: "PAS0",
|
|
4440
|
+
["EVM-11155111" /* SEPOLIA */]: "ETH0",
|
|
4441
|
+
["EVM-1" /* MAINNET */]: "ETH0",
|
|
4442
|
+
["EVM-56" /* BSC_MAINNET */]: "BSC0",
|
|
4443
|
+
["EVM-42161" /* ARBITRUM_MAINNET */]: "ETH0",
|
|
4444
|
+
["EVM-8453" /* BASE_MAINNET */]: "ETH0"
|
|
4445
|
+
};
|
|
4576
4446
|
|
|
4577
|
-
// src/
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
const evmChain = new EvmChain({
|
|
4583
|
-
chainId,
|
|
4584
|
-
url: config.rpcUrl,
|
|
4585
|
-
host: config.host
|
|
4586
|
-
});
|
|
4587
|
-
return evmChain;
|
|
4447
|
+
// src/configs/ChainConfigService.ts
|
|
4448
|
+
var ChainConfigService = class {
|
|
4449
|
+
rpcUrls;
|
|
4450
|
+
constructor(env2 = process.env) {
|
|
4451
|
+
this.rpcUrls = createRpcUrls(env2);
|
|
4588
4452
|
}
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
}
|
|
4595
|
-
await substrateChain.connect();
|
|
4596
|
-
return substrateChain;
|
|
4453
|
+
getChainConfig(chain) {
|
|
4454
|
+
return {
|
|
4455
|
+
chainId: chainIds[chain],
|
|
4456
|
+
rpcUrl: this.rpcUrls[chain],
|
|
4457
|
+
intentGatewayAddress: addresses.IntentGateway[chain]
|
|
4458
|
+
};
|
|
4597
4459
|
}
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
function getPeakPosByHeight(height) {
|
|
4601
|
-
return (1n << BigInt(height + 1)) - 2n;
|
|
4602
|
-
}
|
|
4603
|
-
function leftPeakHeightPos(mmrSize) {
|
|
4604
|
-
let height = 1;
|
|
4605
|
-
let prevPos = 0n;
|
|
4606
|
-
let pos = getPeakPosByHeight(height);
|
|
4607
|
-
while (pos < mmrSize) {
|
|
4608
|
-
height += 1;
|
|
4609
|
-
prevPos = pos;
|
|
4610
|
-
pos = getPeakPosByHeight(height);
|
|
4460
|
+
getIntentGatewayAddress(chain) {
|
|
4461
|
+
return addresses.IntentGateway[chain];
|
|
4611
4462
|
}
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
function getRightPeak(initialHeight, initialPos, mmrSize) {
|
|
4615
|
-
let height = initialHeight;
|
|
4616
|
-
let pos = initialPos;
|
|
4617
|
-
pos += siblingOffset(height);
|
|
4618
|
-
while (pos > mmrSize - 1n) {
|
|
4619
|
-
if (height === 0) {
|
|
4620
|
-
return null;
|
|
4621
|
-
}
|
|
4622
|
-
pos -= parentOffset(height - 1);
|
|
4623
|
-
height -= 1;
|
|
4463
|
+
getHostAddress(chain) {
|
|
4464
|
+
return addresses.Host[chain];
|
|
4624
4465
|
}
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
positions.push(pos);
|
|
4631
|
-
while (height > 0) {
|
|
4632
|
-
const peak = getRightPeak(height, pos, mmrSize);
|
|
4633
|
-
if (!peak) break;
|
|
4634
|
-
[height, pos] = peak;
|
|
4635
|
-
positions.push(pos);
|
|
4466
|
+
getWrappedNativeAssetWithDecimals(chain) {
|
|
4467
|
+
return {
|
|
4468
|
+
asset: assets[chain].WETH,
|
|
4469
|
+
decimals: WrappedNativeDecimals[chain]
|
|
4470
|
+
};
|
|
4636
4471
|
}
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
function allOnes(num) {
|
|
4640
|
-
if (num === 0n) return false;
|
|
4641
|
-
return num.toString(2).split("").every((bit) => bit === "1");
|
|
4642
|
-
}
|
|
4643
|
-
function jumpLeft(pos) {
|
|
4644
|
-
const bitLength = pos.toString(2).length;
|
|
4645
|
-
const mostSignificantBits = 1n << BigInt(bitLength - 1);
|
|
4646
|
-
return pos - (mostSignificantBits - 1n);
|
|
4647
|
-
}
|
|
4648
|
-
function posHeightInTree(initialPos) {
|
|
4649
|
-
let pos = initialPos + 1n;
|
|
4650
|
-
while (!allOnes(pos)) {
|
|
4651
|
-
pos = jumpLeft(pos);
|
|
4472
|
+
getDaiAsset(chain) {
|
|
4473
|
+
return assets[chain].DAI;
|
|
4652
4474
|
}
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
function parentOffset(height) {
|
|
4656
|
-
return 2n << BigInt(height);
|
|
4657
|
-
}
|
|
4658
|
-
function siblingOffset(height) {
|
|
4659
|
-
return (2n << BigInt(height)) - 1n;
|
|
4660
|
-
}
|
|
4661
|
-
function takeWhileVec(v, p) {
|
|
4662
|
-
const index = v.findIndex((item) => !p(item));
|
|
4663
|
-
if (index === -1) {
|
|
4664
|
-
const result = [...v];
|
|
4665
|
-
v.length = 0;
|
|
4666
|
-
return result;
|
|
4475
|
+
getUsdtAsset(chain) {
|
|
4476
|
+
return assets[chain].USDT;
|
|
4667
4477
|
}
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
function mmrPositionToKIndex(initialLeaves, mmrSize) {
|
|
4671
|
-
const leaves = [...initialLeaves];
|
|
4672
|
-
const peaks = getPeaks(mmrSize);
|
|
4673
|
-
const leavesWithKIndices = [];
|
|
4674
|
-
for (const peak of peaks) {
|
|
4675
|
-
const peakLeaves = takeWhileVec(leaves, (pos) => pos <= peak);
|
|
4676
|
-
if (peakLeaves.length > 0) {
|
|
4677
|
-
for (const pos of peakLeaves) {
|
|
4678
|
-
const height = posHeightInTree(peak);
|
|
4679
|
-
let index = 0n;
|
|
4680
|
-
let parentPos = peak;
|
|
4681
|
-
for (let h = height; h >= 1; h--) {
|
|
4682
|
-
const leftChild = parentPos - parentOffset(h - 1);
|
|
4683
|
-
const rightChild = leftChild + siblingOffset(h - 1);
|
|
4684
|
-
index *= 2n;
|
|
4685
|
-
if (leftChild >= pos) {
|
|
4686
|
-
parentPos = leftChild;
|
|
4687
|
-
} else {
|
|
4688
|
-
parentPos = rightChild;
|
|
4689
|
-
index += 1n;
|
|
4690
|
-
}
|
|
4691
|
-
}
|
|
4692
|
-
leavesWithKIndices.push([pos, index]);
|
|
4693
|
-
}
|
|
4694
|
-
}
|
|
4478
|
+
getUsdcAsset(chain) {
|
|
4479
|
+
return assets[chain].USDC;
|
|
4695
4480
|
}
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
}
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4481
|
+
getChainId(chain) {
|
|
4482
|
+
return chainIds[chain];
|
|
4483
|
+
}
|
|
4484
|
+
getConsensusStateId(chain) {
|
|
4485
|
+
return toHex(consensusStateIds[chain]);
|
|
4486
|
+
}
|
|
4487
|
+
getHyperbridgeChainId() {
|
|
4488
|
+
return chainIds["KUSAMA-4009" /* HYPERBRIDGE_GARGANTUA */];
|
|
4489
|
+
}
|
|
4490
|
+
getRpcUrl(chain) {
|
|
4491
|
+
return this.rpcUrls[chain];
|
|
4492
|
+
}
|
|
4493
|
+
getUniswapRouterV2Address(chain) {
|
|
4494
|
+
return addresses.UniswapRouter02[chain];
|
|
4495
|
+
}
|
|
4496
|
+
getUniswapV2FactoryAddress(chain) {
|
|
4497
|
+
return addresses.UniswapV2Factory[chain];
|
|
4498
|
+
}
|
|
4499
|
+
getBatchExecutorAddress(chain) {
|
|
4500
|
+
return addresses.BatchExecutor[chain];
|
|
4501
|
+
}
|
|
4502
|
+
getUniversalRouterAddress(chain) {
|
|
4503
|
+
return addresses.UniversalRouter[chain];
|
|
4504
|
+
}
|
|
4505
|
+
getUniswapV3RouterAddress(chain) {
|
|
4506
|
+
return addresses.UniswapV3Router[chain];
|
|
4507
|
+
}
|
|
4508
|
+
getUniswapV3FactoryAddress(chain) {
|
|
4509
|
+
return addresses.UniswapV3Factory[chain];
|
|
4510
|
+
}
|
|
4511
|
+
getUniswapV3QuoterAddress(chain) {
|
|
4512
|
+
return addresses.UniswapV3Quoter[chain];
|
|
4513
|
+
}
|
|
4514
|
+
getUniswapV4PoolManagerAddress(chain) {
|
|
4515
|
+
return addresses.UniswapV4PoolManager[chain];
|
|
4516
|
+
}
|
|
4517
|
+
getUniswapV4QuoterAddress(chain) {
|
|
4518
|
+
return addresses.UniswapV4Quoter[chain];
|
|
4519
|
+
}
|
|
4520
|
+
};
|
|
4521
|
+
|
|
4522
|
+
// src/chains/evm.ts
|
|
4523
|
+
var chains = {
|
|
4524
|
+
[mainnet.id]: mainnet,
|
|
4525
|
+
[arbitrum.id]: arbitrum,
|
|
4526
|
+
[arbitrumSepolia.id]: arbitrumSepolia,
|
|
4527
|
+
[optimism.id]: optimism,
|
|
4528
|
+
[optimismSepolia.id]: optimismSepolia,
|
|
4529
|
+
[base.id]: base,
|
|
4530
|
+
[baseSepolia.id]: baseSepolia,
|
|
4531
|
+
[soneium.id]: soneium,
|
|
4532
|
+
[bsc.id]: bsc,
|
|
4533
|
+
[bscTestnet.id]: bscTestnet,
|
|
4534
|
+
[gnosis.id]: gnosis,
|
|
4535
|
+
[gnosisChiado.id]: gnosisChiado
|
|
4536
|
+
};
|
|
4537
|
+
var DEFAULT_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4538
|
+
var EvmChain = class {
|
|
4539
|
+
constructor(params) {
|
|
4540
|
+
this.params = params;
|
|
4541
|
+
this.publicClient = createPublicClient({
|
|
4542
|
+
// @ts-ignore
|
|
4543
|
+
chain: chains[params.chainId],
|
|
4544
|
+
transport: http(params.url)
|
|
4545
|
+
});
|
|
4546
|
+
this.chainConfigService = new ChainConfigService();
|
|
4711
4547
|
}
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
kIndex,
|
|
4718
|
-
treeSize,
|
|
4719
|
-
mmrSize: mmr_size
|
|
4720
|
-
};
|
|
4721
|
-
}
|
|
4722
|
-
async function load_ckb_mmr() {
|
|
4723
|
-
if (hasWindow) {
|
|
4724
|
-
const wasm2 = await Promise.resolve().then(() => (init_node(), node_exports));
|
|
4725
|
-
await wasm2.default();
|
|
4726
|
-
return wasm2;
|
|
4548
|
+
publicClient;
|
|
4549
|
+
chainConfigService;
|
|
4550
|
+
// Expose minimal getters for external helpers/classes
|
|
4551
|
+
get client() {
|
|
4552
|
+
return this.publicClient;
|
|
4727
4553
|
}
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4554
|
+
get host() {
|
|
4555
|
+
return this.params.host;
|
|
4556
|
+
}
|
|
4557
|
+
get config() {
|
|
4558
|
+
return this.chainConfigService;
|
|
4731
4559
|
}
|
|
4732
|
-
throw new Error(`SDK not setup for ${env}`);
|
|
4733
|
-
}
|
|
4734
|
-
async function __test() {
|
|
4735
|
-
const { generate_root_with_proof: generate_root_with_proof2 } = await load_ckb_mmr();
|
|
4736
|
-
return generate_root_with_proof2(new Uint8Array(), 120n);
|
|
4737
|
-
}
|
|
4738
|
-
var H256 = Vector(u8, 32);
|
|
4739
|
-
var EvmStateProof = Struct({
|
|
4740
|
-
/**
|
|
4741
|
-
* Proof of the contract state.
|
|
4742
|
-
*/
|
|
4743
|
-
contractProof: Vector(Vector(u8)),
|
|
4744
|
-
/**
|
|
4745
|
-
* Proof of the storage state.
|
|
4746
|
-
*/
|
|
4747
|
-
storageProof: Vector(Tuple(Vector(u8), Vector(Vector(u8))))
|
|
4748
|
-
});
|
|
4749
|
-
var SubstrateHashing = Enum({
|
|
4750
|
-
/* For chains that use keccak as their hashing algo */
|
|
4751
|
-
Keccak: _void,
|
|
4752
|
-
/* For chains that use blake2b as their hashing algo */
|
|
4753
|
-
Blake2: _void
|
|
4754
|
-
});
|
|
4755
|
-
var SubstrateStateMachineProof = Struct({
|
|
4756
4560
|
/**
|
|
4757
|
-
*
|
|
4561
|
+
* Derives the key for the request receipt.
|
|
4562
|
+
* @param {HexString} commitment - The commitment to derive the key from.
|
|
4563
|
+
* @returns {HexString} The derived key.
|
|
4758
4564
|
*/
|
|
4759
|
-
|
|
4565
|
+
requestReceiptKey(commitment) {
|
|
4566
|
+
return deriveMapKey(hexToBytes(commitment), REQUEST_RECEIPTS_SLOT);
|
|
4567
|
+
}
|
|
4760
4568
|
/**
|
|
4761
|
-
*
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
});
|
|
4765
|
-
var SubstrateStateProof = Enum({
|
|
4766
|
-
/*
|
|
4767
|
-
* Uses overlay root for verification
|
|
4768
|
-
*/
|
|
4769
|
-
OverlayProof: SubstrateStateMachineProof,
|
|
4770
|
-
/*
|
|
4771
|
-
* Uses state root for verification
|
|
4772
|
-
*/
|
|
4773
|
-
StateProof: SubstrateStateMachineProof
|
|
4774
|
-
});
|
|
4775
|
-
var BasicProof = Vector(Vector(u8));
|
|
4776
|
-
var LeafIndexAndPos = Struct({
|
|
4777
|
-
/*
|
|
4778
|
-
* Leaf index
|
|
4779
|
-
*/
|
|
4780
|
-
leafIndex: u64,
|
|
4781
|
-
/*
|
|
4782
|
-
* Leaf position in the MMR
|
|
4783
|
-
*/
|
|
4784
|
-
pos: u64
|
|
4785
|
-
});
|
|
4786
|
-
var MmrProof = Struct({
|
|
4787
|
-
/*
|
|
4788
|
-
* Proof of the leaf index and position.
|
|
4789
|
-
*/
|
|
4790
|
-
leafIndexAndPos: Vector(LeafIndexAndPos),
|
|
4791
|
-
/*
|
|
4792
|
-
* Proof of the leaf data.
|
|
4793
|
-
*/
|
|
4794
|
-
leafCount: u64,
|
|
4795
|
-
/*
|
|
4796
|
-
* Proof elements (hashes of siblings of inner nodes on the path to the leaf).
|
|
4797
|
-
*/
|
|
4798
|
-
items: Vector(H256)
|
|
4799
|
-
});
|
|
4800
|
-
var ConsensusStateId = Vector(u8, 4);
|
|
4801
|
-
var ConsensusMessage = Struct({
|
|
4802
|
-
/*
|
|
4803
|
-
* Consensus message data.
|
|
4804
|
-
*/
|
|
4805
|
-
consensusProof: Vector(u8),
|
|
4806
|
-
/*
|
|
4807
|
-
* Consensus state Id
|
|
4808
|
-
*/
|
|
4809
|
-
consensusStateId: ConsensusStateId,
|
|
4810
|
-
/*
|
|
4811
|
-
* Public key of the sender
|
|
4812
|
-
*/
|
|
4813
|
-
signer: Vector(u8)
|
|
4814
|
-
});
|
|
4815
|
-
var FraudProofMessage = Struct({
|
|
4816
|
-
/*
|
|
4817
|
-
* The first valid consensus proof
|
|
4818
|
-
*/
|
|
4819
|
-
proof1: Vector(u8),
|
|
4820
|
-
/*
|
|
4821
|
-
* The second valid consensus proof
|
|
4822
|
-
*/
|
|
4823
|
-
proof2: Vector(u8),
|
|
4824
|
-
/*
|
|
4825
|
-
* Consensus state Id
|
|
4826
|
-
*/
|
|
4827
|
-
consensusStateId: ConsensusStateId
|
|
4828
|
-
});
|
|
4829
|
-
var StateMachine = Enum({
|
|
4830
|
-
/*
|
|
4831
|
-
* Evm state machines
|
|
4832
|
-
*/
|
|
4833
|
-
Evm: u32,
|
|
4834
|
-
/*
|
|
4835
|
-
* Polkadot parachains
|
|
4836
|
-
*/
|
|
4837
|
-
Polkadot: u32,
|
|
4838
|
-
/*
|
|
4839
|
-
* Kusama parachains
|
|
4840
|
-
*/
|
|
4841
|
-
Kusama: u32,
|
|
4842
|
-
/*
|
|
4843
|
-
* Substrate-based standalone chain
|
|
4844
|
-
*/
|
|
4845
|
-
Substrate: ConsensusStateId,
|
|
4846
|
-
/*
|
|
4847
|
-
* Tendermint chains
|
|
4848
|
-
*/
|
|
4849
|
-
Tendermint: ConsensusStateId
|
|
4850
|
-
});
|
|
4851
|
-
var StateMachineId = Struct({
|
|
4852
|
-
/*
|
|
4853
|
-
* The state machine id
|
|
4854
|
-
*/
|
|
4855
|
-
id: StateMachine,
|
|
4856
|
-
/*
|
|
4857
|
-
* The consensus state id
|
|
4858
|
-
*/
|
|
4859
|
-
consensusStateId: ConsensusStateId
|
|
4860
|
-
});
|
|
4861
|
-
var StateMachineHeight = Struct({
|
|
4862
|
-
/*
|
|
4863
|
-
* The state machine id
|
|
4864
|
-
*/
|
|
4865
|
-
id: StateMachineId,
|
|
4866
|
-
/*
|
|
4867
|
-
* The height of the state machine
|
|
4868
|
-
*/
|
|
4869
|
-
height: u64
|
|
4870
|
-
});
|
|
4871
|
-
var Proof = Struct({
|
|
4872
|
-
/*
|
|
4873
|
-
* The height of the state machine
|
|
4874
|
-
*/
|
|
4875
|
-
height: StateMachineHeight,
|
|
4876
|
-
/*
|
|
4877
|
-
* The proof
|
|
4878
|
-
*/
|
|
4879
|
-
proof: Vector(u8)
|
|
4880
|
-
});
|
|
4881
|
-
var PostRequest = Struct({
|
|
4882
|
-
/*
|
|
4883
|
-
* The source state machine of this request.
|
|
4884
|
-
*/
|
|
4885
|
-
source: StateMachine,
|
|
4886
|
-
/*
|
|
4887
|
-
* The destination state machine of this request.
|
|
4888
|
-
*/
|
|
4889
|
-
dest: StateMachine,
|
|
4890
|
-
/*
|
|
4891
|
-
* The nonce of this request on the source chain
|
|
4892
|
-
*/
|
|
4893
|
-
nonce: u64,
|
|
4894
|
-
/*
|
|
4895
|
-
* Module identifier of the sending module
|
|
4896
|
-
*/
|
|
4897
|
-
from: Vector(u8),
|
|
4898
|
-
/*
|
|
4899
|
-
* Module identifier of the receiving module
|
|
4900
|
-
*/
|
|
4901
|
-
to: Vector(u8),
|
|
4902
|
-
/*
|
|
4903
|
-
* Timestamp which this request expires in seconds.
|
|
4904
|
-
*/
|
|
4905
|
-
timeoutTimestamp: u64,
|
|
4906
|
-
/*
|
|
4907
|
-
* Encoded request body
|
|
4908
|
-
*/
|
|
4909
|
-
body: Vector(u8)
|
|
4910
|
-
});
|
|
4911
|
-
var PostResponse = Struct({
|
|
4912
|
-
/*
|
|
4913
|
-
* The request that triggered this response.
|
|
4914
|
-
*/
|
|
4915
|
-
post: PostRequest,
|
|
4916
|
-
/*
|
|
4917
|
-
* The response message.
|
|
4918
|
-
*/
|
|
4919
|
-
response: Vector(u8),
|
|
4920
|
-
/*
|
|
4921
|
-
* Timestamp at which this response expires in seconds.
|
|
4922
|
-
*/
|
|
4923
|
-
timeoutTimestamp: u64
|
|
4924
|
-
});
|
|
4925
|
-
var GetRequest = Struct({
|
|
4926
|
-
/*
|
|
4927
|
-
* The source state machine of this request.
|
|
4928
|
-
*/
|
|
4929
|
-
source: StateMachine,
|
|
4930
|
-
/*
|
|
4931
|
-
* The destination state machine of this request.
|
|
4932
|
-
*/
|
|
4933
|
-
dest: StateMachine,
|
|
4934
|
-
/*
|
|
4935
|
-
* The nonce of this request on the source chain
|
|
4936
|
-
*/
|
|
4937
|
-
nonce: u64,
|
|
4938
|
-
/*
|
|
4939
|
-
* Module identifier of the sending module
|
|
4940
|
-
*/
|
|
4941
|
-
from: Vector(u8),
|
|
4942
|
-
/*
|
|
4943
|
-
* Raw Storage keys that would be used to fetch the values from the counterparty
|
|
4944
|
-
* For deriving storage keys for ink contract fields follow the guide in the link below
|
|
4945
|
-
* `<https://use.ink/datastructures/storage-in-metadata#a-full-example>`
|
|
4946
|
-
* Substrate Keys
|
|
4947
|
-
*/
|
|
4948
|
-
keys: Vector(Vector(u8)),
|
|
4949
|
-
/*
|
|
4950
|
-
* Some application-specific metadata relating to this request
|
|
4951
|
-
*/
|
|
4952
|
-
context: Vector(u8),
|
|
4953
|
-
/*
|
|
4954
|
-
* Host timestamp at which this request expires in seconds
|
|
4569
|
+
* Queries the request receipt.
|
|
4570
|
+
* @param {HexString} commitment - The commitment to query.
|
|
4571
|
+
* @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
|
|
4955
4572
|
*/
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4573
|
+
async queryRequestReceipt(commitment) {
|
|
4574
|
+
const relayer = await this.publicClient.readContract({
|
|
4575
|
+
address: this.params.host,
|
|
4576
|
+
abi: evmHost_default.ABI,
|
|
4577
|
+
functionName: "requestReceipts",
|
|
4578
|
+
args: [commitment]
|
|
4579
|
+
});
|
|
4580
|
+
return relayer === DEFAULT_ADDRESS ? void 0 : relayer;
|
|
4581
|
+
}
|
|
4582
|
+
/**
|
|
4583
|
+
* Queries the proof of the commitments.
|
|
4584
|
+
* @param {IMessage} message - The message to query.
|
|
4585
|
+
* @param {string} counterparty - The counterparty address.
|
|
4586
|
+
* @param {bigint} [at] - The block number to query at.
|
|
4587
|
+
* @returns {Promise<HexString>} The proof.
|
|
4961
4588
|
*/
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4589
|
+
async queryProof(message, counterparty, at) {
|
|
4590
|
+
const commitmentKeys = "Requests" in message ? message.Requests.map((key) => requestCommitmentKey(key)) : message.Responses.map((key) => responseCommitmentKey(key));
|
|
4591
|
+
const config = {
|
|
4592
|
+
address: this.params.host,
|
|
4593
|
+
storageKeys: commitmentKeys
|
|
4594
|
+
};
|
|
4595
|
+
if (!at) {
|
|
4596
|
+
config.blockTag = "latest";
|
|
4597
|
+
} else {
|
|
4598
|
+
config.blockNumber = at;
|
|
4599
|
+
}
|
|
4600
|
+
const proof = await this.publicClient.getProof(config);
|
|
4601
|
+
const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
|
|
4602
|
+
const encoded = EvmStateProof.enc({
|
|
4603
|
+
contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
|
|
4604
|
+
storageProof: [
|
|
4605
|
+
[Array.from(hexToBytes(this.params.host)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
4606
|
+
]
|
|
4607
|
+
});
|
|
4608
|
+
return toHex(encoded);
|
|
4609
|
+
}
|
|
4610
|
+
/**
|
|
4611
|
+
* Query and return the encoded storage proof for the provided keys at the given height.
|
|
4612
|
+
* @param {bigint} at - The block height at which to query the storage proof.
|
|
4613
|
+
* @param {HexString[]} keys - The keys for which to query the storage proof.
|
|
4614
|
+
* @returns {Promise<HexString>} The encoded storage proof.
|
|
4965
4615
|
*/
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4616
|
+
async queryStateProof(at, keys) {
|
|
4617
|
+
const config = {
|
|
4618
|
+
address: this.params.host,
|
|
4619
|
+
storageKeys: keys
|
|
4620
|
+
};
|
|
4621
|
+
if (!at) {
|
|
4622
|
+
config.blockTag = "latest";
|
|
4623
|
+
} else {
|
|
4624
|
+
config.blockNumber = at;
|
|
4625
|
+
}
|
|
4626
|
+
const proof = await this.publicClient.getProof(config);
|
|
4627
|
+
const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
|
|
4628
|
+
const encoded = EvmStateProof.enc({
|
|
4629
|
+
contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
|
|
4630
|
+
storageProof: [
|
|
4631
|
+
[Array.from(hexToBytes(this.params.host)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
4632
|
+
]
|
|
4633
|
+
});
|
|
4634
|
+
return toHex(encoded);
|
|
4635
|
+
}
|
|
4636
|
+
/**
|
|
4637
|
+
* Returns the current timestamp of the chain.
|
|
4638
|
+
* @returns {Promise<bigint>} The current timestamp.
|
|
4971
4639
|
*/
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4640
|
+
async timestamp() {
|
|
4641
|
+
const data = await this.publicClient.readContract({
|
|
4642
|
+
address: this.params.host,
|
|
4643
|
+
abi: evmHost_default.ABI,
|
|
4644
|
+
functionName: "timestamp"
|
|
4645
|
+
});
|
|
4646
|
+
return BigInt(data);
|
|
4647
|
+
}
|
|
4648
|
+
/**
|
|
4649
|
+
* Get the latest state machine height for a given state machine ID.
|
|
4650
|
+
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
4651
|
+
* @returns {Promise<bigint>} The latest state machine height.
|
|
4975
4652
|
*/
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4653
|
+
async latestStateMachineHeight(stateMachineId) {
|
|
4654
|
+
if (!this.publicClient) throw new Error("API not initialized");
|
|
4655
|
+
const id = stateMachineId.stateId.Polkadot || stateMachineId.stateId.Kusama;
|
|
4656
|
+
if (!id)
|
|
4657
|
+
throw new Error(
|
|
4658
|
+
"Expected Polakdot or Kusama State machine id when reading latest state machine height on evm"
|
|
4659
|
+
);
|
|
4660
|
+
const data = await this.publicClient.readContract({
|
|
4661
|
+
address: this.params.host,
|
|
4662
|
+
abi: evmHost_default.ABI,
|
|
4663
|
+
functionName: "latestStateMachineHeight",
|
|
4664
|
+
args: [BigInt(id)]
|
|
4665
|
+
});
|
|
4666
|
+
return data;
|
|
4667
|
+
}
|
|
4668
|
+
/**
|
|
4669
|
+
* Get the state machine update time for a given state machine height.
|
|
4670
|
+
* @param {StateMachineHeight} stateMachineHeight - The state machine height.
|
|
4671
|
+
* @returns {Promise<bigint>} The statemachine update time in seconds.
|
|
4982
4672
|
*/
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4673
|
+
async stateMachineUpdateTime(stateMachineHeight) {
|
|
4674
|
+
if (!this.publicClient) throw new Error("API not initialized");
|
|
4675
|
+
const id = stateMachineHeight.id.stateId.Polkadot || stateMachineHeight.id.stateId.Kusama;
|
|
4676
|
+
if (!id) throw new Error("Expected Polkadot or Kusama State machine id when reading state machine update time");
|
|
4677
|
+
const data = await this.publicClient.readContract({
|
|
4678
|
+
address: this.params.host,
|
|
4679
|
+
abi: evmHost_default.ABI,
|
|
4680
|
+
functionName: "stateMachineCommitmentUpdateTime",
|
|
4681
|
+
args: [{ stateMachineId: BigInt(id), height: stateMachineHeight.height }]
|
|
4682
|
+
});
|
|
4683
|
+
return data;
|
|
4684
|
+
}
|
|
4685
|
+
/**
|
|
4686
|
+
* Get the challenge period for a given state machine id.
|
|
4687
|
+
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
4688
|
+
* @returns {Promise<bigint>} The challenge period in seconds.
|
|
4987
4689
|
*/
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4690
|
+
async challengePeriod(stateMachineId) {
|
|
4691
|
+
if (!this.publicClient) throw new Error("API not initialized");
|
|
4692
|
+
const id = stateMachineId.stateId.Polkadot || stateMachineId.stateId.Kusama;
|
|
4693
|
+
if (!id)
|
|
4694
|
+
throw new Error(
|
|
4695
|
+
"Expected Polkadot or Kusama State machine id when reading latest state machine height on evm"
|
|
4696
|
+
);
|
|
4697
|
+
const data = await this.publicClient.readContract({
|
|
4698
|
+
address: this.params.host,
|
|
4699
|
+
abi: evmHost_default.ABI,
|
|
4700
|
+
functionName: "challengePeriod"
|
|
4701
|
+
});
|
|
4702
|
+
return data;
|
|
4703
|
+
}
|
|
4704
|
+
/**
|
|
4705
|
+
* Encodes an ISMP message for the EVM chain.
|
|
4706
|
+
* @param {IIsmpMessage} message The ISMP message to encode.
|
|
4707
|
+
* @returns {HexString} The encoded calldata.
|
|
4708
|
+
*/
|
|
4709
|
+
encode(message) {
|
|
4710
|
+
const encoded = match(message).with({ kind: "PostRequest" }, (request) => {
|
|
4711
|
+
const mmrProof = MmrProof.dec(request.proof.proof);
|
|
4712
|
+
const requests = zip(request.requests, mmrProof.leafIndexAndPos).map(([req, leafIndexAndPos]) => {
|
|
4713
|
+
if (!req || !leafIndexAndPos) return;
|
|
4714
|
+
const [[, kIndex]] = mmrPositionToKIndex(
|
|
4715
|
+
[leafIndexAndPos?.pos],
|
|
4716
|
+
calculateMMRSize(mmrProof.leafCount)
|
|
4717
|
+
);
|
|
4718
|
+
return {
|
|
4719
|
+
request: {
|
|
4720
|
+
source: toHex(req.source),
|
|
4721
|
+
dest: toHex(req.dest),
|
|
4722
|
+
to: req.to,
|
|
4723
|
+
from: req.from,
|
|
4724
|
+
nonce: req.nonce,
|
|
4725
|
+
timeoutTimestamp: req.timeoutTimestamp,
|
|
4726
|
+
body: req.body
|
|
4727
|
+
},
|
|
4728
|
+
index: leafIndexAndPos?.leafIndex,
|
|
4729
|
+
kIndex
|
|
4730
|
+
};
|
|
4731
|
+
}).filter((item) => !!item);
|
|
4732
|
+
const proof = {
|
|
4733
|
+
height: {
|
|
4734
|
+
stateMachineId: BigInt(Number.parseInt(request.proof.stateMachine.split("-")[1])),
|
|
4735
|
+
height: request.proof.height
|
|
4736
|
+
},
|
|
4737
|
+
multiproof: mmrProof.items.map((item) => bytesToHex(new Uint8Array(item))),
|
|
4738
|
+
leafCount: mmrProof.leafCount
|
|
4739
|
+
};
|
|
4740
|
+
const encoded2 = encodeFunctionData({
|
|
4741
|
+
abi: handler_default.ABI,
|
|
4742
|
+
functionName: "handlePostRequests",
|
|
4743
|
+
args: [
|
|
4744
|
+
this.params.host,
|
|
4745
|
+
{
|
|
4746
|
+
proof,
|
|
4747
|
+
requests
|
|
4748
|
+
}
|
|
4749
|
+
]
|
|
4750
|
+
});
|
|
4751
|
+
return encoded2;
|
|
4752
|
+
}).with({ kind: "TimeoutPostRequest" }, (timeout) => {
|
|
4753
|
+
const proof = SubstrateStateProof.dec(timeout.proof.proof).value.storageProof.map(
|
|
4754
|
+
(item) => toHex(new Uint8Array(item))
|
|
4755
|
+
);
|
|
4756
|
+
const encoded2 = encodeFunctionData({
|
|
4757
|
+
abi: handler_default.ABI,
|
|
4758
|
+
functionName: "handlePostRequestTimeouts",
|
|
4759
|
+
args: [
|
|
4760
|
+
this.params.host,
|
|
4761
|
+
{
|
|
4762
|
+
height: {
|
|
4763
|
+
stateMachineId: BigInt(Number.parseInt(timeout.proof.stateMachine.split("-")[1])),
|
|
4764
|
+
height: timeout.proof.height
|
|
4765
|
+
},
|
|
4766
|
+
timeouts: timeout.requests.map((req) => ({
|
|
4767
|
+
source: toHex(req.source),
|
|
4768
|
+
dest: toHex(req.dest),
|
|
4769
|
+
to: req.to,
|
|
4770
|
+
from: req.from,
|
|
4771
|
+
nonce: req.nonce,
|
|
4772
|
+
timeoutTimestamp: req.timeoutTimestamp,
|
|
4773
|
+
body: req.body
|
|
4774
|
+
})),
|
|
4775
|
+
proof
|
|
4776
|
+
}
|
|
4777
|
+
]
|
|
4778
|
+
});
|
|
4779
|
+
return encoded2;
|
|
4780
|
+
}).with({ kind: "GetResponse" }, (request) => {
|
|
4781
|
+
const mmrProof = MmrProof.dec(request.proof.proof);
|
|
4782
|
+
const responses = zip(request.responses, mmrProof.leafIndexAndPos).map(([req, leafIndexAndPos]) => {
|
|
4783
|
+
if (!req || !leafIndexAndPos) return;
|
|
4784
|
+
const [[, kIndex]] = mmrPositionToKIndex(
|
|
4785
|
+
[leafIndexAndPos?.pos],
|
|
4786
|
+
calculateMMRSize(mmrProof.leafCount)
|
|
4787
|
+
);
|
|
4788
|
+
return {
|
|
4789
|
+
response: {
|
|
4790
|
+
request: {
|
|
4791
|
+
source: toHex(req.get.source),
|
|
4792
|
+
dest: toHex(req.get.dest),
|
|
4793
|
+
from: req.get.from,
|
|
4794
|
+
nonce: req.get.nonce,
|
|
4795
|
+
timeoutTimestamp: req.get.timeoutTimestamp,
|
|
4796
|
+
keys: req.get.keys,
|
|
4797
|
+
context: req.get.context,
|
|
4798
|
+
height: req.get.height
|
|
4799
|
+
},
|
|
4800
|
+
values: req.values
|
|
4801
|
+
},
|
|
4802
|
+
index: leafIndexAndPos?.leafIndex,
|
|
4803
|
+
kIndex
|
|
4804
|
+
};
|
|
4805
|
+
}).filter((item) => !!item);
|
|
4806
|
+
const proof = {
|
|
4807
|
+
height: {
|
|
4808
|
+
stateMachineId: BigInt(Number.parseInt(request.proof.stateMachine.split("-")[1])),
|
|
4809
|
+
height: request.proof.height
|
|
4810
|
+
},
|
|
4811
|
+
multiproof: mmrProof.items.map((item) => bytesToHex(new Uint8Array(item))),
|
|
4812
|
+
leafCount: mmrProof.leafCount
|
|
4813
|
+
};
|
|
4814
|
+
const encoded2 = encodeFunctionData({
|
|
4815
|
+
abi: handler_default.ABI,
|
|
4816
|
+
functionName: "handleGetResponses",
|
|
4817
|
+
args: [
|
|
4818
|
+
this.params.host,
|
|
4819
|
+
{
|
|
4820
|
+
proof,
|
|
4821
|
+
responses
|
|
4822
|
+
}
|
|
4823
|
+
]
|
|
4824
|
+
});
|
|
4825
|
+
return encoded2;
|
|
4826
|
+
}).exhaustive();
|
|
4827
|
+
return encoded;
|
|
4828
|
+
}
|
|
4829
|
+
/**
|
|
4830
|
+
* Calculates the fee required to send a post request to the destination chain.
|
|
4831
|
+
* The fee is calculated based on the per-byte fee for the destination chain
|
|
4832
|
+
* multiplied by the size of the request body.
|
|
4833
|
+
*
|
|
4834
|
+
* @param request - The post request to calculate the fee for
|
|
4835
|
+
* @returns The total fee in wei required to send the post request
|
|
4993
4836
|
*/
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4837
|
+
async quote(request) {
|
|
4838
|
+
const perByteFee = await this.publicClient.readContract({
|
|
4839
|
+
address: this.params.host,
|
|
4840
|
+
abi: evmHost_default.ABI,
|
|
4841
|
+
functionName: "perByteFee",
|
|
4842
|
+
args: [toHex(request.dest)]
|
|
4843
|
+
});
|
|
4844
|
+
const bodyByteLength = Math.floor((request.body.length - 2) / 2);
|
|
4845
|
+
const length = bodyByteLength < 32 ? 32 : bodyByteLength;
|
|
4846
|
+
return perByteFee * BigInt(length);
|
|
4847
|
+
}
|
|
4848
|
+
/**
|
|
4849
|
+
* Estimates the gas required for a post request execution on this chain.
|
|
4850
|
+
* This function generates mock proofs for the post request, creates a state override
|
|
4851
|
+
* with the necessary overlay root, and estimates the gas cost for executing the
|
|
4852
|
+
* handlePostRequests transaction on the handler contract.
|
|
4853
|
+
*
|
|
4854
|
+
* @param request - The post request to estimate gas for
|
|
4855
|
+
* @param paraId - The ID of the parachain (Hyperbridge) that will process the request
|
|
4856
|
+
* @returns The estimated gas amount in gas units and the generated calldata
|
|
4997
4857
|
*/
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
4858
|
+
async estimateGas(request) {
|
|
4859
|
+
const hostParams = await this.publicClient.readContract({
|
|
4860
|
+
address: this.params.host,
|
|
4861
|
+
abi: evmHost_default.ABI,
|
|
4862
|
+
functionName: "hostParams"
|
|
4863
|
+
});
|
|
4864
|
+
const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(request, 2n ** 10n);
|
|
4865
|
+
const latestStateMachineHeight = 6291991n;
|
|
4866
|
+
const paraId = 4009n;
|
|
4867
|
+
const overlayRootSlot = getStateCommitmentFieldSlot(
|
|
4868
|
+
paraId,
|
|
4869
|
+
// Hyperbridge chain id
|
|
4870
|
+
latestStateMachineHeight,
|
|
4871
|
+
// Hyperbridge chain height
|
|
4872
|
+
1
|
|
4873
|
+
// For overlayRoot
|
|
4874
|
+
);
|
|
4875
|
+
const postParams = {
|
|
4876
|
+
height: {
|
|
4877
|
+
stateMachineId: BigInt(paraId),
|
|
4878
|
+
height: latestStateMachineHeight
|
|
4879
|
+
},
|
|
4880
|
+
multiproof: proof,
|
|
4881
|
+
leafCount: treeSize
|
|
4882
|
+
};
|
|
4883
|
+
const formattedRequest = {
|
|
4884
|
+
...request,
|
|
4885
|
+
source: toHex(request.source),
|
|
4886
|
+
dest: toHex(request.dest)
|
|
4887
|
+
};
|
|
4888
|
+
const contractArgs = [
|
|
4889
|
+
this.params.host,
|
|
4890
|
+
{
|
|
4891
|
+
proof: postParams,
|
|
4892
|
+
requests: [
|
|
4893
|
+
{
|
|
4894
|
+
request: formattedRequest,
|
|
4895
|
+
index,
|
|
4896
|
+
kIndex
|
|
4897
|
+
}
|
|
4898
|
+
]
|
|
4899
|
+
}
|
|
4900
|
+
];
|
|
4901
|
+
const postRequestCalldata = encodeFunctionData({
|
|
4902
|
+
abi: handler_default.ABI,
|
|
4903
|
+
functionName: "handlePostRequests",
|
|
4904
|
+
args: contractArgs
|
|
4905
|
+
});
|
|
4906
|
+
const gas = await this.publicClient.estimateContractGas({
|
|
4907
|
+
address: hostParams.handler,
|
|
4908
|
+
abi: handler_default.ABI,
|
|
4909
|
+
functionName: "handlePostRequests",
|
|
4910
|
+
args: contractArgs,
|
|
4911
|
+
stateOverride: [
|
|
4912
|
+
{
|
|
4913
|
+
address: this.params.host,
|
|
4914
|
+
stateDiff: [
|
|
4915
|
+
{
|
|
4916
|
+
slot: overlayRootSlot,
|
|
4917
|
+
value: root
|
|
4918
|
+
}
|
|
4919
|
+
]
|
|
4920
|
+
}
|
|
4921
|
+
]
|
|
4922
|
+
});
|
|
4923
|
+
return { gas, postRequestCalldata };
|
|
4924
|
+
}
|
|
4925
|
+
/**
|
|
4926
|
+
* Gets the fee token address and decimals for the chain.
|
|
4927
|
+
* This function gets the fee token address and decimals for the chain.
|
|
4928
|
+
*
|
|
4929
|
+
* @returns The fee token address and decimals
|
|
5003
4930
|
*/
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
4931
|
+
async getFeeTokenWithDecimals() {
|
|
4932
|
+
const hostParams = await this.publicClient.readContract({
|
|
4933
|
+
abi: evmHost_default.ABI,
|
|
4934
|
+
address: this.params.host,
|
|
4935
|
+
functionName: "hostParams"
|
|
4936
|
+
});
|
|
4937
|
+
const feeTokenAddress = hostParams.feeToken;
|
|
4938
|
+
const feeTokenDecimals = await this.publicClient.readContract({
|
|
4939
|
+
address: feeTokenAddress,
|
|
4940
|
+
abi: erc20Abi,
|
|
4941
|
+
functionName: "decimals"
|
|
4942
|
+
});
|
|
4943
|
+
return { address: feeTokenAddress, decimals: feeTokenDecimals };
|
|
4944
|
+
}
|
|
4945
|
+
/**
|
|
4946
|
+
* Gets the nonce of the host.
|
|
4947
|
+
* This function gets the nonce of the host.
|
|
4948
|
+
*
|
|
4949
|
+
* @returns The nonce of the host
|
|
5007
4950
|
*/
|
|
5008
|
-
|
|
4951
|
+
async getHostNonce() {
|
|
4952
|
+
const nonce = await this.publicClient.readContract({
|
|
4953
|
+
abi: evmHost_default.ABI,
|
|
4954
|
+
address: this.params.host,
|
|
4955
|
+
functionName: "nonce"
|
|
4956
|
+
});
|
|
4957
|
+
return nonce;
|
|
4958
|
+
}
|
|
4959
|
+
};
|
|
4960
|
+
var REQUEST_COMMITMENTS_SLOT = 0n;
|
|
4961
|
+
var RESPONSE_COMMITMENTS_SLOT = 1n;
|
|
4962
|
+
var REQUEST_RECEIPTS_SLOT = 2n;
|
|
4963
|
+
var RESPONSE_RECEIPTS_SLOT = 3n;
|
|
4964
|
+
var STATE_COMMITMENTS_SLOT = 5n;
|
|
4965
|
+
function requestCommitmentKey(key) {
|
|
4966
|
+
const keyBytes = hexToBytes(key);
|
|
4967
|
+
const slot = REQUEST_COMMITMENTS_SLOT;
|
|
4968
|
+
const mappedKey = deriveMapKey(keyBytes, slot);
|
|
4969
|
+
const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n;
|
|
4970
|
+
return pad(`0x${number.toString(16)}`, { size: 32 });
|
|
4971
|
+
}
|
|
4972
|
+
function responseCommitmentKey(key) {
|
|
4973
|
+
const keyBytes = hexToBytes(key);
|
|
4974
|
+
const slot = RESPONSE_COMMITMENTS_SLOT;
|
|
4975
|
+
const mappedKey = deriveMapKey(keyBytes, slot);
|
|
4976
|
+
const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n;
|
|
4977
|
+
return pad(`0x${number.toString(16)}`, { size: 32 });
|
|
4978
|
+
}
|
|
4979
|
+
function deriveMapKey(key, slot) {
|
|
4980
|
+
const slotBytes = pad(`0x${slot.toString(16)}`, { size: 32 });
|
|
4981
|
+
const combined = new Uint8Array([...key, ...toBytes(slotBytes)]);
|
|
4982
|
+
return keccak256(combined);
|
|
4983
|
+
}
|
|
4984
|
+
function getStateCommitmentFieldSlot(stateMachineId, height, field) {
|
|
4985
|
+
const baseSlot = getStateCommitmentSlot(stateMachineId, height);
|
|
4986
|
+
const slotNumber = bytesToBigInt(toBytes(baseSlot)) + BigInt(field);
|
|
4987
|
+
return pad(`0x${slotNumber.toString(16)}`, { size: 32 });
|
|
4988
|
+
}
|
|
4989
|
+
function getStateCommitmentSlot(stateMachineId, height) {
|
|
4990
|
+
const firstLevelSlot = deriveFirstLevelSlot(stateMachineId, STATE_COMMITMENTS_SLOT);
|
|
4991
|
+
return deriveSecondLevelSlot(height, firstLevelSlot);
|
|
4992
|
+
}
|
|
4993
|
+
function deriveFirstLevelSlot(key, slot) {
|
|
4994
|
+
const keyHex = pad(`0x${key.toString(16)}`, { size: 32 });
|
|
4995
|
+
const keyBytes = toBytes(keyHex);
|
|
4996
|
+
const slotBytes = toBytes(pad(`0x${slot.toString(16)}`, { size: 32 }));
|
|
4997
|
+
const combined = new Uint8Array([...keyBytes, ...slotBytes]);
|
|
4998
|
+
return keccak256(combined);
|
|
4999
|
+
}
|
|
5000
|
+
function deriveSecondLevelSlot(key, firstLevelSlot) {
|
|
5001
|
+
const keyHex = pad(`0x${key.toString(16)}`, { size: 32 });
|
|
5002
|
+
const keyBytes = toBytes(keyHex);
|
|
5003
|
+
const slotBytes = toBytes(firstLevelSlot);
|
|
5004
|
+
const combined = new Uint8Array([...keyBytes, ...slotBytes]);
|
|
5005
|
+
return keccak256(combined);
|
|
5006
|
+
}
|
|
5007
|
+
var SubstrateChain = class {
|
|
5008
|
+
constructor(params) {
|
|
5009
|
+
this.params = params;
|
|
5010
|
+
}
|
|
5009
5011
|
/*
|
|
5010
|
-
*
|
|
5012
|
+
* api: The Polkadot API instance for the Substrate chain.
|
|
5011
5013
|
*/
|
|
5012
|
-
|
|
5013
|
-
});
|
|
5014
|
-
var RequestResponse = Enum({
|
|
5014
|
+
api;
|
|
5015
5015
|
/*
|
|
5016
|
-
*
|
|
5016
|
+
* connect: Connects to the Substrate chain using the provided WebSocket URL.
|
|
5017
5017
|
*/
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5018
|
+
async connect() {
|
|
5019
|
+
const wsProvider = new WsProvider(this.params.ws);
|
|
5020
|
+
const typesBundle = this.params.hasher === "Keccak" ? {
|
|
5021
|
+
spec: {
|
|
5022
|
+
nexus: {
|
|
5023
|
+
hasher: keccakAsU8a
|
|
5024
|
+
},
|
|
5025
|
+
gargantua: {
|
|
5026
|
+
hasher: keccakAsU8a
|
|
5027
|
+
}
|
|
5028
|
+
}
|
|
5029
|
+
} : {};
|
|
5030
|
+
this.api = await ApiPromise.create({
|
|
5031
|
+
provider: wsProvider,
|
|
5032
|
+
typesBundle
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
5035
|
+
/**
|
|
5036
|
+
* Disconnects the Substrate chain connection.
|
|
5021
5037
|
*/
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5038
|
+
async disconnect() {
|
|
5039
|
+
if (this.api) {
|
|
5040
|
+
await this.api.disconnect();
|
|
5041
|
+
this.api = void 0;
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
/**
|
|
5045
|
+
* Returns the storage key for a request receipt in the child trie
|
|
5046
|
+
* The request commitment is the key
|
|
5047
|
+
* @param key - The H256 hash key (as a 0x-prefixed hex string)
|
|
5048
|
+
* @returns The storage key as a hex string
|
|
5027
5049
|
*/
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5050
|
+
requestReceiptKey(key) {
|
|
5051
|
+
const prefix = new TextEncoder().encode("RequestReceipts");
|
|
5052
|
+
const keyBytes = hexToBytes(key);
|
|
5053
|
+
return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
|
|
5054
|
+
}
|
|
5055
|
+
/**
|
|
5056
|
+
* Returns the storage key for a request commitment in the child trie
|
|
5057
|
+
* The request commitment is the key
|
|
5058
|
+
* @param key - The H256 hash key (as a 0x-prefixed hex string)
|
|
5059
|
+
* @returns The storage key as a hex string
|
|
5031
5060
|
*/
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5061
|
+
requestCommitmentKey(key) {
|
|
5062
|
+
const prefix = new TextEncoder().encode("RequestCommitments");
|
|
5063
|
+
const keyBytes = hexToBytes(key);
|
|
5064
|
+
return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
|
|
5065
|
+
}
|
|
5066
|
+
/**
|
|
5067
|
+
* Queries a request commitment from the ISMP child trie storage.
|
|
5068
|
+
* @param {HexString} commitment - The commitment hash to look up.
|
|
5069
|
+
* @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise.
|
|
5035
5070
|
*/
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5071
|
+
async queryRequestCommitment(commitment) {
|
|
5072
|
+
const prefix = toHex(":child_storage:default:ISMP");
|
|
5073
|
+
const key = this.requestCommitmentKey(commitment);
|
|
5074
|
+
const rpc = new RpcWebSocketClient();
|
|
5075
|
+
await rpc.connect(this.params.ws);
|
|
5076
|
+
const item = await rpc.call("childstate_getStorage", [prefix, key]);
|
|
5077
|
+
return item;
|
|
5078
|
+
}
|
|
5079
|
+
/**
|
|
5080
|
+
* Queries the request receipt.
|
|
5081
|
+
* @param {HexString} commitment - The commitment to query.
|
|
5082
|
+
* @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
|
|
5041
5083
|
*/
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
* A non memership proof for POST responses
|
|
5084
|
+
async queryRequestReceipt(commitment) {
|
|
5085
|
+
const prefix = toHex(":child_storage:default:ISMP");
|
|
5086
|
+
const key = this.requestReceiptKey(commitment);
|
|
5087
|
+
const rpc = new RpcWebSocketClient();
|
|
5088
|
+
await rpc.connect(this.params.ws);
|
|
5089
|
+
const item = await rpc.call("childstate_getStorage", [prefix, key]);
|
|
5090
|
+
return item;
|
|
5091
|
+
}
|
|
5092
|
+
/**
|
|
5093
|
+
* Returns the current timestamp of the chain.
|
|
5094
|
+
* @returns {Promise<bigint>} The current timestamp.
|
|
5054
5095
|
*/
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
* There are no proofs for Get timeouts
|
|
5096
|
+
async timestamp() {
|
|
5097
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5098
|
+
const now = await this.api.query.timestamp.now();
|
|
5099
|
+
return BigInt(now.toJSON()) / BigInt(1e3);
|
|
5100
|
+
}
|
|
5101
|
+
/**
|
|
5102
|
+
* Queries the proof of the commitments.
|
|
5103
|
+
* @param {IMessage} message - The message to query.
|
|
5104
|
+
* @param {string} counterparty - The counterparty address.
|
|
5105
|
+
* @param {bigint} [at] - The block number to query at.
|
|
5106
|
+
* @returns {Promise<HexString>} The proof.
|
|
5067
5107
|
*/
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
}
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5108
|
+
async queryProof(message, counterparty, at) {
|
|
5109
|
+
const rpc = new RpcWebSocketClient();
|
|
5110
|
+
await rpc.connect(this.params.ws);
|
|
5111
|
+
if (isEvmChain(counterparty)) {
|
|
5112
|
+
const proof = await rpc.call("mmr_queryProof", [Number(at), message]);
|
|
5113
|
+
return toHex(proof.proof);
|
|
5114
|
+
}
|
|
5115
|
+
if (isSubstrateChain(counterparty)) {
|
|
5116
|
+
const childTrieKeys = "Requests" in message ? message.Requests.map(requestCommitmentStorageKey) : message.Responses.map(responseCommitmentStorageKey);
|
|
5117
|
+
const proof = await rpc.call("ismp_queryChildTrieProof", [Number(at), childTrieKeys]);
|
|
5118
|
+
const basicProof = BasicProof.dec(toHex(proof.proof));
|
|
5119
|
+
const encoded = SubstrateStateProof.enc({
|
|
5120
|
+
tag: "OverlayProof",
|
|
5121
|
+
value: {
|
|
5122
|
+
hasher: {
|
|
5123
|
+
tag: this.params.hasher,
|
|
5124
|
+
value: void 0
|
|
5125
|
+
},
|
|
5126
|
+
storageProof: basicProof
|
|
5127
|
+
}
|
|
5128
|
+
});
|
|
5129
|
+
return toHex(encoded);
|
|
5130
|
+
}
|
|
5131
|
+
throw new ExpectedError(`Unsupported chain type for counterparty: ${counterparty}`);
|
|
5132
|
+
}
|
|
5133
|
+
/**
|
|
5134
|
+
* Submit an unsigned ISMP transaction to the chain. Resolves when the transaction is finalized.
|
|
5135
|
+
* @param message - The message to be submitted.
|
|
5136
|
+
* @returns A promise that resolves to an object containing the transaction hash, block hash, and block number.
|
|
5078
5137
|
*/
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5138
|
+
async submitUnsigned(message) {
|
|
5139
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5140
|
+
const { api } = this;
|
|
5141
|
+
const args = hexToBytes(this.encode(message)).slice(2);
|
|
5142
|
+
const tx = api.tx.ismp.handleUnsigned(args);
|
|
5143
|
+
return new Promise((resolve, reject) => {
|
|
5144
|
+
let unsub = () => {
|
|
5145
|
+
};
|
|
5146
|
+
tx.send(async ({ isInBlock, isFinalized, isError, dispatchError, txHash, status }) => {
|
|
5147
|
+
if (isFinalized || isInBlock) {
|
|
5148
|
+
unsub();
|
|
5149
|
+
const blockHash = isInBlock ? status.asInBlock.toHex() : status.asFinalized.toHex();
|
|
5150
|
+
const header = await api.rpc.chain.getHeader(blockHash);
|
|
5151
|
+
const apiAt = await api.at(blockHash);
|
|
5152
|
+
const timestamp = await apiAt.query.timestamp.now();
|
|
5153
|
+
resolve({
|
|
5154
|
+
transactionHash: txHash.toHex(),
|
|
5155
|
+
blockHash,
|
|
5156
|
+
blockNumber: header.number.toNumber(),
|
|
5157
|
+
timestamp: Number(timestamp.toJSON()) / 1e3
|
|
5158
|
+
});
|
|
5159
|
+
} else if (isError) {
|
|
5160
|
+
unsub();
|
|
5161
|
+
console.error("Unsigned transaction failed: ", dispatchError);
|
|
5162
|
+
reject(dispatchError);
|
|
5163
|
+
}
|
|
5164
|
+
}).then((unsubscribe) => {
|
|
5165
|
+
unsub = unsubscribe;
|
|
5166
|
+
}).catch(reject);
|
|
5167
|
+
});
|
|
5168
|
+
}
|
|
5169
|
+
/**
|
|
5170
|
+
* Query the state proof for a given set of keys at a specific block height.
|
|
5171
|
+
* @param at The block height to query the state proof at.
|
|
5172
|
+
* @param keys The keys to query the state proof for.
|
|
5173
|
+
* @returns The state proof as a hexadecimal string.
|
|
5082
5174
|
*/
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5175
|
+
async queryStateProof(at, keys) {
|
|
5176
|
+
const rpc = new RpcWebSocketClient();
|
|
5177
|
+
await rpc.connect(this.params.ws);
|
|
5178
|
+
const encodedKeys = keys.map((key) => Array.from(hexToBytes(key)));
|
|
5179
|
+
const proof = await rpc.call("ismp_queryChildTrieProof", [Number(at), encodedKeys]);
|
|
5180
|
+
const basicProof = BasicProof.dec(toHex(proof.proof));
|
|
5181
|
+
const encoded = SubstrateStateProof.enc({
|
|
5182
|
+
tag: "OverlayProof",
|
|
5183
|
+
value: {
|
|
5184
|
+
hasher: {
|
|
5185
|
+
tag: this.params.hasher,
|
|
5186
|
+
value: void 0
|
|
5187
|
+
},
|
|
5188
|
+
storageProof: basicProof
|
|
5189
|
+
}
|
|
5190
|
+
});
|
|
5191
|
+
return toHex(encoded);
|
|
5192
|
+
}
|
|
5193
|
+
/**
|
|
5194
|
+
* Get the latest state machine height for a given state machine ID.
|
|
5195
|
+
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
5196
|
+
* @returns {Promise<bigint>} The latest state machine height.
|
|
5086
5197
|
*/
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5198
|
+
async latestStateMachineHeight(stateMachineId) {
|
|
5199
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5200
|
+
const latestHeight = await this.api.query.ismp.latestStateMachineHeight(stateMachineId);
|
|
5201
|
+
return BigInt(latestHeight.toString());
|
|
5202
|
+
}
|
|
5203
|
+
/**
|
|
5204
|
+
* Get the state machine update time for a given state machine height.
|
|
5205
|
+
* @param {StateMachineHeight} stateMachineHeight - The state machine height.
|
|
5206
|
+
* @returns {Promise<bigint>} The statemachine update time in seconds.
|
|
5090
5207
|
*/
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5208
|
+
async stateMachineUpdateTime(stateMachineHeight) {
|
|
5209
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5210
|
+
const updateTime = await this.api.query.ismp.stateMachineUpdateTime(stateMachineHeight);
|
|
5211
|
+
return BigInt(updateTime.toString());
|
|
5212
|
+
}
|
|
5213
|
+
/**
|
|
5214
|
+
* Get the challenge period for a given state machine id.
|
|
5215
|
+
* @param {StateMachineIdParams} stateMachineId - The state machine ID.
|
|
5216
|
+
* @returns {Promise<bigint>} The challenge period in seconds.
|
|
5094
5217
|
*/
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
var DEFAULT_POLL_INTERVAL = 5e3;
|
|
5100
|
-
var ADDRESS_ZERO2 = "0x0000000000000000000000000000000000000000";
|
|
5101
|
-
var MOCK_ADDRESS2 = "0x1234567890123456789012345678901234567890";
|
|
5102
|
-
var DUMMY_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
5103
|
-
function sleep(ms) {
|
|
5104
|
-
return new Promise((resolve) => setTimeout(resolve, ms || DEFAULT_POLL_INTERVAL));
|
|
5105
|
-
}
|
|
5106
|
-
async function waitForChallengePeriod(chain, stateMachineHeight) {
|
|
5107
|
-
const challengePeriod = await chain.challengePeriod(stateMachineHeight.id);
|
|
5108
|
-
if (challengePeriod === BigInt(0)) return;
|
|
5109
|
-
const updateTime = await chain.stateMachineUpdateTime(stateMachineHeight);
|
|
5110
|
-
let currentTimestamp = await chain.timestamp();
|
|
5111
|
-
let timeElapsed = currentTimestamp - updateTime;
|
|
5112
|
-
if (timeElapsed > challengePeriod) return;
|
|
5113
|
-
await sleep(Number(challengePeriod) * 1e3);
|
|
5114
|
-
while (timeElapsed <= challengePeriod) {
|
|
5115
|
-
const remainingTime = challengePeriod - timeElapsed;
|
|
5116
|
-
await sleep(Number(remainingTime) * 1e3);
|
|
5117
|
-
currentTimestamp = await chain.timestamp();
|
|
5118
|
-
timeElapsed = currentTimestamp - updateTime;
|
|
5218
|
+
async challengePeriod(stateMachineId) {
|
|
5219
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5220
|
+
const challengePeriod = await this.api.query.ismp.challengePeriod(stateMachineId);
|
|
5221
|
+
return BigInt(challengePeriod.toString());
|
|
5119
5222
|
}
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
throw new Error(
|
|
5131
|
-
`Invalid state machine ID format: ${stateMachineId}. Expected format like "EVM-97" or "SUBSTRATE-cere"`
|
|
5132
|
-
);
|
|
5223
|
+
/**
|
|
5224
|
+
* Encode an ISMP calldata for a substrate chain.
|
|
5225
|
+
* @param message The ISMP message to encode.
|
|
5226
|
+
* @returns The encoded message as a hexadecimal string.
|
|
5227
|
+
*/
|
|
5228
|
+
encode(message) {
|
|
5229
|
+
const palletIndex = this.getPalletIndex("Ismp");
|
|
5230
|
+
const args = encodeISMPMessage(message);
|
|
5231
|
+
const call = Vector(u8, 2).enc([palletIndex, 0]);
|
|
5232
|
+
return toHex(new Uint8Array([...call, ...args]));
|
|
5133
5233
|
}
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
stateId.Substrate = `0x${bytes.toString("hex")}`;
|
|
5147
|
-
break;
|
|
5148
|
-
}
|
|
5149
|
-
case "POLKADOT": {
|
|
5150
|
-
const polkadotChainId = Number.parseInt(value, 10);
|
|
5151
|
-
if (Number.isNaN(polkadotChainId)) {
|
|
5152
|
-
throw new Error(`Invalid Polkadot chain ID: ${value}. Expected a number.`);
|
|
5153
|
-
}
|
|
5154
|
-
stateId.Polkadot = polkadotChainId;
|
|
5155
|
-
break;
|
|
5156
|
-
}
|
|
5157
|
-
case "KUSAMA": {
|
|
5158
|
-
const kusamaChainId = Number.parseInt(value, 10);
|
|
5159
|
-
if (Number.isNaN(kusamaChainId)) {
|
|
5160
|
-
throw new Error(`Invalid Kusama chain ID: ${value}. Expected a number.`);
|
|
5234
|
+
/**
|
|
5235
|
+
* Returns the index of a pallet by its name, by looking up the pallets in the runtime metadata.
|
|
5236
|
+
* @param {string} name - The name of the pallet.
|
|
5237
|
+
* @returns {number} The index of the pallet.
|
|
5238
|
+
*/
|
|
5239
|
+
getPalletIndex(name) {
|
|
5240
|
+
if (!this.api) throw new Error("API not initialized");
|
|
5241
|
+
const pallets = this.api.runtimeMetadata.asLatest.pallets.entries();
|
|
5242
|
+
for (const p of pallets) {
|
|
5243
|
+
if (p[1].name.toString() === name) {
|
|
5244
|
+
const index = p[1].index.toNumber();
|
|
5245
|
+
return index;
|
|
5161
5246
|
}
|
|
5162
|
-
stateId.Kusama = kusamaChainId;
|
|
5163
|
-
break;
|
|
5164
5247
|
}
|
|
5165
|
-
|
|
5166
|
-
throw new Error(`Unsupported chain type: ${type}. Expected one of: EVM, SUBSTRATE, POLKADOT, KUSAMA.`);
|
|
5167
|
-
}
|
|
5168
|
-
return { stateId };
|
|
5169
|
-
}
|
|
5170
|
-
function postRequestCommitment(post) {
|
|
5171
|
-
const data = encodePacked(
|
|
5172
|
-
["bytes", "bytes", "uint64", "uint64", "bytes", "bytes", "bytes"],
|
|
5173
|
-
[toHex(post.source), toHex(post.dest), post.nonce, post.timeoutTimestamp, post.from, post.to, post.body]
|
|
5174
|
-
);
|
|
5175
|
-
return {
|
|
5176
|
-
commitment: keccak256(data),
|
|
5177
|
-
encodePacked: data
|
|
5178
|
-
};
|
|
5179
|
-
}
|
|
5180
|
-
function orderCommitment2(order) {
|
|
5181
|
-
const encodedOrder = encodeAbiParameters(
|
|
5182
|
-
[
|
|
5183
|
-
{
|
|
5184
|
-
name: "order",
|
|
5185
|
-
type: "tuple",
|
|
5186
|
-
components: [
|
|
5187
|
-
{ name: "user", type: "bytes32" },
|
|
5188
|
-
{ name: "sourceChain", type: "bytes" },
|
|
5189
|
-
{ name: "destChain", type: "bytes" },
|
|
5190
|
-
{ name: "deadline", type: "uint256" },
|
|
5191
|
-
{ name: "nonce", type: "uint256" },
|
|
5192
|
-
{ name: "fees", type: "uint256" },
|
|
5193
|
-
{
|
|
5194
|
-
name: "outputs",
|
|
5195
|
-
type: "tuple[]",
|
|
5196
|
-
components: [
|
|
5197
|
-
{ name: "token", type: "bytes32" },
|
|
5198
|
-
{ name: "amount", type: "uint256" },
|
|
5199
|
-
{ name: "beneficiary", type: "bytes32" }
|
|
5200
|
-
]
|
|
5201
|
-
},
|
|
5202
|
-
{
|
|
5203
|
-
name: "inputs",
|
|
5204
|
-
type: "tuple[]",
|
|
5205
|
-
components: [
|
|
5206
|
-
{ name: "token", type: "bytes32" },
|
|
5207
|
-
{ name: "amount", type: "uint256" }
|
|
5208
|
-
]
|
|
5209
|
-
},
|
|
5210
|
-
{ name: "callData", type: "bytes" }
|
|
5211
|
-
]
|
|
5212
|
-
}
|
|
5213
|
-
],
|
|
5214
|
-
[
|
|
5215
|
-
{
|
|
5216
|
-
user: order.user,
|
|
5217
|
-
sourceChain: order.sourceChain.startsWith("0x") ? order.sourceChain : toHex(order.sourceChain),
|
|
5218
|
-
destChain: order.destChain.startsWith("0x") ? order.destChain : toHex(order.destChain),
|
|
5219
|
-
deadline: order.deadline,
|
|
5220
|
-
nonce: order.nonce,
|
|
5221
|
-
fees: order.fees,
|
|
5222
|
-
outputs: order.outputs,
|
|
5223
|
-
inputs: order.inputs,
|
|
5224
|
-
callData: order.callData
|
|
5225
|
-
}
|
|
5226
|
-
]
|
|
5227
|
-
);
|
|
5228
|
-
return keccak256(encodedOrder);
|
|
5229
|
-
}
|
|
5230
|
-
function bytes32ToBytes202(bytes32Address) {
|
|
5231
|
-
if (bytes32Address === ADDRESS_ZERO2) {
|
|
5232
|
-
return ADDRESS_ZERO2;
|
|
5248
|
+
throw new Error(`${name} not found in runtime`);
|
|
5233
5249
|
}
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5250
|
+
};
|
|
5251
|
+
function requestCommitmentStorageKey(key) {
|
|
5252
|
+
const prefix = new TextEncoder().encode("RequestCommitments");
|
|
5253
|
+
const keyBytes = hexToBytes(key);
|
|
5254
|
+
return Array.from(new Uint8Array([...prefix, ...keyBytes]));
|
|
5237
5255
|
}
|
|
5238
|
-
function
|
|
5239
|
-
|
|
5256
|
+
function responseCommitmentStorageKey(key) {
|
|
5257
|
+
const prefix = new TextEncoder().encode("ResponseCommitments");
|
|
5258
|
+
const keyBytes = hexToBytes(key);
|
|
5259
|
+
return Array.from(new Uint8Array([...prefix, ...keyBytes]));
|
|
5240
5260
|
}
|
|
5241
|
-
function
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5261
|
+
function convertStateMachineIdToEnum(id) {
|
|
5262
|
+
let [tag, value] = id.split("-");
|
|
5263
|
+
tag = capitalize(tag);
|
|
5264
|
+
if (["Evm", "Polkadot", "Kusama"].includes(tag)) {
|
|
5265
|
+
value = Number.parseInt(value);
|
|
5266
|
+
} else {
|
|
5267
|
+
value = Array.from(toBytes(value));
|
|
5246
5268
|
}
|
|
5247
|
-
return
|
|
5269
|
+
return { tag, value };
|
|
5248
5270
|
}
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
lastError = error;
|
|
5261
|
-
await new Promise((resolve) => setTimeout(resolve, retryConfig.backoffMs * 2 ** i));
|
|
5271
|
+
function convertIPostRequestToCodec(request) {
|
|
5272
|
+
return {
|
|
5273
|
+
tag: "Post",
|
|
5274
|
+
value: {
|
|
5275
|
+
source: convertStateMachineIdToEnum(request.source),
|
|
5276
|
+
dest: convertStateMachineIdToEnum(request.dest),
|
|
5277
|
+
from: Array.from(hexToBytes(request.from)),
|
|
5278
|
+
to: Array.from(hexToBytes(request.to)),
|
|
5279
|
+
nonce: request.nonce,
|
|
5280
|
+
body: Array.from(hexToBytes(request.body)),
|
|
5281
|
+
timeoutTimestamp: request.timeoutTimestamp
|
|
5262
5282
|
}
|
|
5263
|
-
}
|
|
5264
|
-
throw lastError;
|
|
5265
|
-
}
|
|
5266
|
-
function getRequestCommitment(get) {
|
|
5267
|
-
const keysEncoding = "0x".concat(get.keys.map((key) => key.slice(2)).join(""));
|
|
5268
|
-
return keccak256(
|
|
5269
|
-
encodePacked(
|
|
5270
|
-
["bytes", "bytes", "uint64", "uint64", "uint64", "bytes", "bytes", "bytes"],
|
|
5271
|
-
[
|
|
5272
|
-
toHex(get.source),
|
|
5273
|
-
toHex(get.dest),
|
|
5274
|
-
get.nonce,
|
|
5275
|
-
get.height,
|
|
5276
|
-
get.timeoutTimestamp,
|
|
5277
|
-
get.from,
|
|
5278
|
-
keysEncoding,
|
|
5279
|
-
get.context
|
|
5280
|
-
]
|
|
5281
|
-
)
|
|
5282
|
-
);
|
|
5283
|
-
}
|
|
5284
|
-
var REQUEST_STATUS_WEIGHTS = {
|
|
5285
|
-
[RequestStatus.SOURCE]: 0,
|
|
5286
|
-
[RequestStatus.SOURCE_FINALIZED]: 1,
|
|
5287
|
-
[RequestStatus.HYPERBRIDGE_DELIVERED]: 2,
|
|
5288
|
-
[RequestStatus.HYPERBRIDGE_FINALIZED]: 3,
|
|
5289
|
-
[RequestStatus.DESTINATION]: 4,
|
|
5290
|
-
[RequestStatus.HYPERBRIDGE_TIMED_OUT]: 5,
|
|
5291
|
-
[RequestStatus.TIMED_OUT]: 6
|
|
5292
|
-
};
|
|
5293
|
-
var TIMEOUT_STATUS_WEIGHTS = {
|
|
5294
|
-
[TimeoutStatus.PENDING_TIMEOUT]: 1,
|
|
5295
|
-
[TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 2,
|
|
5296
|
-
[TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 3,
|
|
5297
|
-
[TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 4,
|
|
5298
|
-
[TimeoutStatus.TIMED_OUT]: 5
|
|
5299
|
-
};
|
|
5300
|
-
var COMBINED_STATUS_WEIGHTS = {
|
|
5301
|
-
[RequestStatus.SOURCE]: 0,
|
|
5302
|
-
[RequestStatus.SOURCE_FINALIZED]: 1,
|
|
5303
|
-
[RequestStatus.HYPERBRIDGE_DELIVERED]: 2,
|
|
5304
|
-
[RequestStatus.HYPERBRIDGE_FINALIZED]: 3,
|
|
5305
|
-
[RequestStatus.DESTINATION]: 4,
|
|
5306
|
-
[TimeoutStatus.PENDING_TIMEOUT]: 5,
|
|
5307
|
-
[TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 6,
|
|
5308
|
-
[TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 7,
|
|
5309
|
-
[TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 8,
|
|
5310
|
-
[TimeoutStatus.TIMED_OUT]: 9
|
|
5311
|
-
};
|
|
5312
|
-
async function estimateGasForPost(params) {
|
|
5313
|
-
const hostParams = await params.sourceClient.readContract({
|
|
5314
|
-
address: params.hostAddress,
|
|
5315
|
-
abi: evmHost_default.ABI,
|
|
5316
|
-
functionName: "hostParams"
|
|
5317
|
-
});
|
|
5318
|
-
const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(params.postRequest, 2n ** 10n);
|
|
5319
|
-
const latestStateMachineHeight = params.hostLatestStateMachineHeight;
|
|
5320
|
-
const overlayRootSlot = getStateCommitmentFieldSlot(
|
|
5321
|
-
BigInt(4009n),
|
|
5322
|
-
// Hyperbridge chain id
|
|
5323
|
-
latestStateMachineHeight,
|
|
5324
|
-
// Hyperbridge chain height
|
|
5325
|
-
1
|
|
5326
|
-
// For overlayRoot
|
|
5327
|
-
);
|
|
5328
|
-
const postParams = {
|
|
5329
|
-
height: {
|
|
5330
|
-
stateMachineId: BigInt(4009n),
|
|
5331
|
-
height: latestStateMachineHeight
|
|
5332
|
-
},
|
|
5333
|
-
multiproof: proof,
|
|
5334
|
-
leafCount: treeSize
|
|
5335
5283
|
};
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5284
|
+
}
|
|
5285
|
+
function encodeISMPMessage(message) {
|
|
5286
|
+
try {
|
|
5287
|
+
return match(message).with({ kind: "PostRequest" }, (message2) => {
|
|
5288
|
+
return Vector(Message).enc([
|
|
5289
|
+
{
|
|
5290
|
+
tag: "RequestMessage",
|
|
5291
|
+
value: {
|
|
5292
|
+
requests: message2.requests.map(
|
|
5293
|
+
(post_request) => convertIPostRequestToCodec(post_request).value
|
|
5294
|
+
),
|
|
5295
|
+
proof: {
|
|
5296
|
+
height: {
|
|
5297
|
+
height: message2.proof.height,
|
|
5298
|
+
id: {
|
|
5299
|
+
consensusStateId: Array.from(toBytes(message2.proof.consensusStateId)),
|
|
5300
|
+
id: convertStateMachineIdToEnum(message2.proof.stateMachine)
|
|
5301
|
+
}
|
|
5302
|
+
},
|
|
5303
|
+
proof: Array.from(hexToBytes(message2.proof.proof))
|
|
5350
5304
|
},
|
|
5351
|
-
|
|
5352
|
-
kIndex
|
|
5353
|
-
}
|
|
5354
|
-
]
|
|
5355
|
-
}
|
|
5356
|
-
],
|
|
5357
|
-
stateOverride: [
|
|
5358
|
-
{
|
|
5359
|
-
address: params.hostAddress,
|
|
5360
|
-
stateDiff: [
|
|
5361
|
-
{
|
|
5362
|
-
slot: overlayRootSlot,
|
|
5363
|
-
value: root
|
|
5305
|
+
signer: Array.from(hexToBytes(message2.signer))
|
|
5364
5306
|
}
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
{
|
|
5389
|
-
name: "tokens",
|
|
5390
|
-
type: "tuple[]",
|
|
5391
|
-
components: [
|
|
5392
|
-
{ name: "token", type: "bytes32" },
|
|
5393
|
-
{ name: "amount", type: "uint256" }
|
|
5394
|
-
]
|
|
5307
|
+
}
|
|
5308
|
+
]);
|
|
5309
|
+
}).with({ kind: "GetResponse" }, (message2) => {
|
|
5310
|
+
throw new Error("GetResponse is not yet supported on Substrate chains");
|
|
5311
|
+
}).with({ kind: "TimeoutPostRequest" }, (message2) => {
|
|
5312
|
+
return Vector(Message).enc([
|
|
5313
|
+
{
|
|
5314
|
+
tag: "TimeoutMessage",
|
|
5315
|
+
value: {
|
|
5316
|
+
tag: "Post",
|
|
5317
|
+
value: {
|
|
5318
|
+
requests: message2.requests.map((r) => convertIPostRequestToCodec(r)),
|
|
5319
|
+
proof: {
|
|
5320
|
+
height: {
|
|
5321
|
+
height: message2.proof.height,
|
|
5322
|
+
id: {
|
|
5323
|
+
consensusStateId: Array.from(toBytes(message2.proof.consensusStateId)),
|
|
5324
|
+
id: convertStateMachineIdToEnum(message2.proof.stateMachine)
|
|
5325
|
+
}
|
|
5326
|
+
},
|
|
5327
|
+
proof: Array.from(hexToBytes(message2.proof.proof))
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5395
5330
|
}
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5331
|
+
}
|
|
5332
|
+
]);
|
|
5333
|
+
}).exhaustive();
|
|
5334
|
+
} catch (error) {
|
|
5335
|
+
throw new Error("Failed to encode ISMP message", { cause: error });
|
|
5336
|
+
}
|
|
5402
5337
|
}
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5338
|
+
|
|
5339
|
+
// src/chain.ts
|
|
5340
|
+
async function getChain(chainConfig) {
|
|
5341
|
+
if (isEvmChain(chainConfig.stateMachineId)) {
|
|
5342
|
+
const config = chainConfig;
|
|
5343
|
+
const chainId = Number.parseInt(chainConfig.stateMachineId.split("-")[1]);
|
|
5344
|
+
const evmChain = new EvmChain({
|
|
5345
|
+
chainId,
|
|
5346
|
+
url: config.rpcUrl,
|
|
5347
|
+
host: config.host
|
|
5348
|
+
});
|
|
5349
|
+
return evmChain;
|
|
5406
5350
|
}
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
return "weth";
|
|
5416
|
-
case "tbnb":
|
|
5417
|
-
return "wbnb";
|
|
5418
|
-
case "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase():
|
|
5419
|
-
return "dai";
|
|
5420
|
-
case "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase():
|
|
5421
|
-
return "wbnb";
|
|
5422
|
-
case "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase():
|
|
5423
|
-
return "dai";
|
|
5424
|
-
case "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase():
|
|
5425
|
-
return "dai";
|
|
5426
|
-
case "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase():
|
|
5427
|
-
return "dai";
|
|
5428
|
-
case "0xa801da100bf16d07f668f4a49e1f71fc54d05177".toLowerCase():
|
|
5429
|
-
return "dai";
|
|
5430
|
-
default:
|
|
5431
|
-
return identifier;
|
|
5351
|
+
if (isSubstrateChain(chainConfig.stateMachineId)) {
|
|
5352
|
+
const config = chainConfig;
|
|
5353
|
+
const substrateChain = new SubstrateChain({
|
|
5354
|
+
ws: config.wsUrl,
|
|
5355
|
+
hasher: config.hasher
|
|
5356
|
+
});
|
|
5357
|
+
await substrateChain.connect();
|
|
5358
|
+
return substrateChain;
|
|
5432
5359
|
}
|
|
5360
|
+
throw new ExpectedError(`Unsupported chain: ${chainConfig.stateMachineId}`);
|
|
5433
5361
|
}
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5362
|
+
|
|
5363
|
+
// src/queries.ts
|
|
5364
|
+
var POST_REQUEST_STATUS = `
|
|
5365
|
+
query RequestStatusM($hash: String!) {
|
|
5366
|
+
requests(
|
|
5367
|
+
filter: { commitment: { equalTo: $hash } }
|
|
5368
|
+
) {
|
|
5369
|
+
nodes {
|
|
5370
|
+
commitment
|
|
5371
|
+
timeoutTimestamp
|
|
5372
|
+
source
|
|
5373
|
+
dest
|
|
5374
|
+
to
|
|
5375
|
+
from
|
|
5376
|
+
nonce
|
|
5377
|
+
body
|
|
5378
|
+
statusMetadata {
|
|
5379
|
+
nodes {
|
|
5380
|
+
blockHash
|
|
5381
|
+
blockNumber
|
|
5382
|
+
timestamp
|
|
5383
|
+
chain
|
|
5384
|
+
status
|
|
5385
|
+
transactionHash
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5447
5388
|
}
|
|
5448
5389
|
}
|
|
5449
5390
|
}
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5391
|
+
`;
|
|
5392
|
+
var GET_REQUEST_STATUS = `
|
|
5393
|
+
query GetRequestDetails($commitment: String!) {
|
|
5394
|
+
getRequests(
|
|
5395
|
+
filter: { commitment: { equalTo: $commitment } }
|
|
5396
|
+
) {
|
|
5397
|
+
nodes {
|
|
5398
|
+
id
|
|
5399
|
+
source
|
|
5400
|
+
dest
|
|
5401
|
+
from
|
|
5402
|
+
keys
|
|
5403
|
+
nonce
|
|
5404
|
+
height
|
|
5405
|
+
context
|
|
5406
|
+
timeoutTimestamp
|
|
5407
|
+
fee
|
|
5408
|
+
blockNumber
|
|
5409
|
+
blockHash
|
|
5410
|
+
transactionHash
|
|
5411
|
+
blockTimestamp
|
|
5412
|
+
status
|
|
5413
|
+
chain
|
|
5414
|
+
commitment
|
|
5415
|
+
statusMetadata {
|
|
5416
|
+
nodes {
|
|
5417
|
+
status
|
|
5418
|
+
chain
|
|
5419
|
+
timestamp
|
|
5420
|
+
blockNumber
|
|
5421
|
+
blockHash
|
|
5422
|
+
transactionHash
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
}
|
|
5427
|
+
}`;
|
|
5428
|
+
var STATE_MACHINE_UPDATES_BY_HEIGHT = `
|
|
5429
|
+
query StateMachineUpdatesByHeight($statemachineId: String!, $height: Int!, $chain: String!) {
|
|
5430
|
+
stateMachineUpdateEvents(
|
|
5431
|
+
filter: {
|
|
5432
|
+
and: [
|
|
5433
|
+
{ stateMachineId: { equalTo: $statemachineId } }
|
|
5434
|
+
{ height: { greaterThanOrEqualTo: $height } }
|
|
5435
|
+
{ chain: { equalTo: $chain } }
|
|
5436
|
+
]
|
|
5437
|
+
}
|
|
5438
|
+
orderBy: HEIGHT_ASC
|
|
5439
|
+
first: 1
|
|
5440
|
+
) {
|
|
5441
|
+
nodes {
|
|
5442
|
+
height
|
|
5443
|
+
stateMachineId
|
|
5444
|
+
chain
|
|
5445
|
+
blockHash
|
|
5446
|
+
blockNumber
|
|
5447
|
+
transactionHash
|
|
5448
|
+
createdAt
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
}
|
|
5452
|
+
`;
|
|
5453
|
+
var STATE_MACHINE_UPDATES_BY_TIMESTAMP = `
|
|
5454
|
+
query StateMachineUpdatesByTimestamp($statemachineId: String!, $commitmentTimestamp: BigFloat!, $chain: String!) {
|
|
5455
|
+
stateMachineUpdateEvents(
|
|
5456
|
+
filter: {
|
|
5457
|
+
and: [
|
|
5458
|
+
{ stateMachineId: { equalTo: $statemachineId } }
|
|
5459
|
+
{ commitmentTimestamp: { greaterThanOrEqualTo: $commitmentTimestamp } }
|
|
5460
|
+
{ chain: { equalTo: $chain } }
|
|
5461
|
+
]
|
|
5462
|
+
}
|
|
5463
|
+
orderBy: COMMITMENT_TIMESTAMP_DESC
|
|
5464
|
+
first: 1
|
|
5465
|
+
) {
|
|
5466
|
+
nodes {
|
|
5467
|
+
height
|
|
5468
|
+
stateMachineId
|
|
5469
|
+
chain
|
|
5470
|
+
blockHash
|
|
5471
|
+
blockNumber
|
|
5472
|
+
transactionHash
|
|
5473
|
+
commitmentTimestamp
|
|
5474
|
+
createdAt
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5456
5477
|
}
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5478
|
+
`;
|
|
5479
|
+
var ASSET_TELEPORTED_BY_PARAMS = `
|
|
5480
|
+
query AssetTeleportedByParams($from: String!, $to: String!, $dest: String!, $blockNumber: Int!) {
|
|
5481
|
+
assetTeleporteds(
|
|
5482
|
+
filter: {
|
|
5483
|
+
and: [
|
|
5484
|
+
{ from: { equalTo: $from } }
|
|
5485
|
+
{ to: { equalTo: $to } }
|
|
5486
|
+
{ dest: { includes: $dest } }
|
|
5487
|
+
{ blockNumber: { greaterThanOrEqualTo: $blockNumber } }
|
|
5488
|
+
]
|
|
5489
|
+
}
|
|
5490
|
+
orderBy: CREATED_AT_DESC
|
|
5491
|
+
first: 1
|
|
5492
|
+
) {
|
|
5493
|
+
nodes {
|
|
5494
|
+
id
|
|
5495
|
+
from
|
|
5496
|
+
to
|
|
5497
|
+
amount
|
|
5498
|
+
dest
|
|
5499
|
+
commitment
|
|
5500
|
+
createdAt
|
|
5501
|
+
blockNumber
|
|
5502
|
+
}
|
|
5461
5503
|
}
|
|
5462
|
-
return data[key].usd;
|
|
5463
5504
|
}
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
const price = data.coins?.[coinId]?.price;
|
|
5474
|
-
if (!price && price !== 0) {
|
|
5475
|
-
throw new Error(`Price not found for token: ${mappedIdentifier}`);
|
|
5505
|
+
`;
|
|
5506
|
+
var GET_RESPONSE_BY_REQUEST_ID = `
|
|
5507
|
+
query GetResponseByRequestId($requestId: String!) {
|
|
5508
|
+
getResponses(filter: {requestId: {equalTo: $requestId}}) {
|
|
5509
|
+
nodes {
|
|
5510
|
+
id
|
|
5511
|
+
commitment
|
|
5512
|
+
responseMessage
|
|
5513
|
+
}
|
|
5476
5514
|
}
|
|
5477
|
-
return price;
|
|
5478
5515
|
}
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5516
|
+
`;
|
|
5517
|
+
var ORDER_STATUS = `
|
|
5518
|
+
query OrderStatus($commitment: String!) {
|
|
5519
|
+
orderPlaceds(
|
|
5520
|
+
filter: { commitment: { equalTo: $commitment } }
|
|
5521
|
+
) {
|
|
5522
|
+
nodes {
|
|
5523
|
+
id
|
|
5524
|
+
user
|
|
5525
|
+
sourceChain
|
|
5526
|
+
destChain
|
|
5527
|
+
commitment
|
|
5528
|
+
deadline
|
|
5529
|
+
nonce
|
|
5530
|
+
fees
|
|
5531
|
+
inputTokens
|
|
5532
|
+
inputAmounts
|
|
5533
|
+
inputValuesUSD
|
|
5534
|
+
inputUSD
|
|
5535
|
+
outputTokens
|
|
5536
|
+
outputAmounts
|
|
5537
|
+
outputBeneficiaries
|
|
5538
|
+
calldata
|
|
5539
|
+
status
|
|
5540
|
+
createdAt
|
|
5541
|
+
blockNumber
|
|
5542
|
+
blockTimestamp
|
|
5543
|
+
transactionHash
|
|
5544
|
+
statusMetadata {
|
|
5545
|
+
nodes {
|
|
5546
|
+
status
|
|
5547
|
+
chain
|
|
5548
|
+
timestamp
|
|
5549
|
+
blockNumber
|
|
5550
|
+
transactionHash
|
|
5551
|
+
filler
|
|
5552
|
+
}
|
|
5508
5553
|
}
|
|
5509
5554
|
}
|
|
5510
5555
|
}
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5556
|
+
}`;
|
|
5557
|
+
var TOKEN_GATEWAY_ASSET_TELEPORTED_STATUS = `
|
|
5558
|
+
query TokenGatewayAssetTeleportedStatus($commitment: String!) {
|
|
5559
|
+
tokenGatewayAssetTeleporteds(
|
|
5560
|
+
filter: { commitment: { equalTo: $commitment } }
|
|
5561
|
+
) {
|
|
5562
|
+
nodes {
|
|
5563
|
+
id
|
|
5564
|
+
from
|
|
5565
|
+
to
|
|
5566
|
+
sourceChain
|
|
5567
|
+
destChain
|
|
5568
|
+
commitment
|
|
5569
|
+
amount
|
|
5570
|
+
usdValue
|
|
5571
|
+
assetId
|
|
5572
|
+
redeem
|
|
5573
|
+
status
|
|
5574
|
+
createdAt
|
|
5575
|
+
blockNumber
|
|
5576
|
+
blockTimestamp
|
|
5577
|
+
transactionHash
|
|
5578
|
+
statusMetadata {
|
|
5579
|
+
nodes {
|
|
5580
|
+
status
|
|
5581
|
+
chain
|
|
5582
|
+
timestamp
|
|
5583
|
+
blockNumber
|
|
5584
|
+
transactionHash
|
|
5585
|
+
}
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5521
5588
|
}
|
|
5522
|
-
}
|
|
5589
|
+
}`;
|
|
5523
5590
|
function createQueryClient(config) {
|
|
5524
5591
|
return new GraphQLClient(config.url);
|
|
5525
5592
|
}
|
|
@@ -6155,7 +6222,7 @@ var IndexerClient = class {
|
|
|
6155
6222
|
switch (status) {
|
|
6156
6223
|
// request has been dispatched from source chain
|
|
6157
6224
|
case RequestStatus.SOURCE: {
|
|
6158
|
-
|
|
6225
|
+
const sourceUpdate = await this.waitOrAbort({
|
|
6159
6226
|
signal,
|
|
6160
6227
|
promise: () => this.queryStateMachineUpdateByHeight({
|
|
6161
6228
|
statemachineId: request.source,
|
|
@@ -6197,7 +6264,7 @@ var IndexerClient = class {
|
|
|
6197
6264
|
}
|
|
6198
6265
|
// the request has been verified and aggregated on Hyperbridge
|
|
6199
6266
|
case RequestStatus.HYPERBRIDGE_DELIVERED: {
|
|
6200
|
-
|
|
6267
|
+
const hyperbridgeFinalized = await this.waitOrAbort({
|
|
6201
6268
|
signal,
|
|
6202
6269
|
promise: () => {
|
|
6203
6270
|
const stateMachineId = this.config.hyperbridge.stateMachineId;
|
|
@@ -6214,17 +6281,36 @@ var IndexerClient = class {
|
|
|
6214
6281
|
...this.config.hyperbridge,
|
|
6215
6282
|
hasher: "Keccak"
|
|
6216
6283
|
});
|
|
6217
|
-
const
|
|
6218
|
-
{
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6284
|
+
const safeFetchProof = async () => {
|
|
6285
|
+
try {
|
|
6286
|
+
const proof_hex = await hyperbridge.queryProof(
|
|
6287
|
+
{ Requests: [postRequestCommitment(request).commitment] },
|
|
6288
|
+
request.dest,
|
|
6289
|
+
BigInt(hyperbridgeFinalized.height)
|
|
6290
|
+
);
|
|
6291
|
+
return { data: proof_hex, error: null };
|
|
6292
|
+
} catch (err) {
|
|
6293
|
+
return { error: err, data: null };
|
|
6294
|
+
}
|
|
6295
|
+
};
|
|
6296
|
+
const proof = await this.waitOrAbort({
|
|
6297
|
+
signal,
|
|
6298
|
+
promise: () => this.withRetry(safeFetchProof, {
|
|
6299
|
+
backoffMs: 2e3,
|
|
6300
|
+
maxRetries: 6
|
|
6301
|
+
// <-- should fail after 2mins
|
|
6302
|
+
})
|
|
6303
|
+
});
|
|
6304
|
+
if (proof.data === null) {
|
|
6305
|
+
this.logger.error("Failed to fetch proof:", proof.error);
|
|
6306
|
+
throw proof.error;
|
|
6307
|
+
}
|
|
6222
6308
|
const calldata = destChain.encode({
|
|
6223
6309
|
kind: "PostRequest",
|
|
6224
6310
|
proof: {
|
|
6225
6311
|
stateMachine: this.config.hyperbridge.stateMachineId,
|
|
6226
6312
|
consensusStateId: this.config.hyperbridge.consensusStateId,
|
|
6227
|
-
proof,
|
|
6313
|
+
proof: proof.data,
|
|
6228
6314
|
height: BigInt(hyperbridgeFinalized.height)
|
|
6229
6315
|
},
|
|
6230
6316
|
requests: [request],
|
|
@@ -6313,7 +6399,7 @@ var IndexerClient = class {
|
|
|
6313
6399
|
async *getRequestStatusStream(hash) {
|
|
6314
6400
|
const controller = new AbortController();
|
|
6315
6401
|
try {
|
|
6316
|
-
|
|
6402
|
+
const request = await this.waitOrAbort({
|
|
6317
6403
|
signal: controller.signal,
|
|
6318
6404
|
promise: () => this.queryGetRequest(hash)
|
|
6319
6405
|
});
|
|
@@ -6349,7 +6435,7 @@ var IndexerClient = class {
|
|
|
6349
6435
|
switch (status) {
|
|
6350
6436
|
// request has been dispatched from source chain
|
|
6351
6437
|
case RequestStatus.SOURCE: {
|
|
6352
|
-
|
|
6438
|
+
const sourceUpdate = await this.waitOrAbort({
|
|
6353
6439
|
signal,
|
|
6354
6440
|
promise: () => this.queryStateMachineUpdateByHeight({
|
|
6355
6441
|
statemachineId: request.source,
|
|
@@ -6394,7 +6480,7 @@ var IndexerClient = class {
|
|
|
6394
6480
|
if (request.source === this.config.hyperbridge.stateMachineId) {
|
|
6395
6481
|
return;
|
|
6396
6482
|
}
|
|
6397
|
-
|
|
6483
|
+
const hyperbridgeFinalized = await this.waitOrAbort({
|
|
6398
6484
|
signal,
|
|
6399
6485
|
promise: () => this.queryStateMachineUpdateByHeight({
|
|
6400
6486
|
statemachineId: this.config.hyperbridge.stateMachineId,
|
|
@@ -6645,7 +6731,7 @@ var IndexerClient = class {
|
|
|
6645
6731
|
})
|
|
6646
6732
|
});
|
|
6647
6733
|
} else {
|
|
6648
|
-
|
|
6734
|
+
const timeout = await this.waitOrAbort({
|
|
6649
6735
|
signal,
|
|
6650
6736
|
promise: async () => {
|
|
6651
6737
|
const req = await this.queryPostRequest(hash);
|
|
@@ -7989,6 +8075,11 @@ var ABI3 = [
|
|
|
7989
8075
|
internalType: "struct Order",
|
|
7990
8076
|
name: "order",
|
|
7991
8077
|
type: "tuple"
|
|
8078
|
+
},
|
|
8079
|
+
{
|
|
8080
|
+
internalType: "bytes32",
|
|
8081
|
+
name: "graffiti",
|
|
8082
|
+
type: "bytes32"
|
|
7992
8083
|
}
|
|
7993
8084
|
],
|
|
7994
8085
|
name: "placeOrder",
|
|
@@ -11315,21 +11406,21 @@ var IntentGateway = class {
|
|
|
11315
11406
|
* protocol fees, and swap operations.
|
|
11316
11407
|
*
|
|
11317
11408
|
* @param order - The order to estimate fill costs for
|
|
11318
|
-
* @returns
|
|
11409
|
+
* @returns An object containing the estimated cost in both fee token and native token, plus the post request calldata
|
|
11319
11410
|
*/
|
|
11320
11411
|
async estimateFillOrder(order) {
|
|
11321
11412
|
const postRequest = {
|
|
11322
11413
|
source: order.destChain,
|
|
11323
11414
|
dest: order.sourceChain,
|
|
11324
|
-
body:
|
|
11415
|
+
body: constructRedeemEscrowRequestBody(order, MOCK_ADDRESS),
|
|
11325
11416
|
timeoutTimestamp: 0n,
|
|
11326
11417
|
nonce: await this.source.getHostNonce(),
|
|
11327
11418
|
from: this.source.config.getIntentGatewayAddress(order.destChain),
|
|
11328
11419
|
to: this.source.config.getIntentGatewayAddress(order.sourceChain)
|
|
11329
11420
|
};
|
|
11330
|
-
const { decimals: sourceChainFeeTokenDecimals } = await this.source.getFeeTokenWithDecimals();
|
|
11421
|
+
const { decimals: sourceChainFeeTokenDecimals, address: sourceChainFeeTokenAddress } = await this.source.getFeeTokenWithDecimals();
|
|
11331
11422
|
const { address: destChainFeeTokenAddress, decimals: destChainFeeTokenDecimals } = await this.dest.getFeeTokenWithDecimals();
|
|
11332
|
-
const postGasEstimate = await this.source.estimateGas(postRequest);
|
|
11423
|
+
const { gas: postGasEstimate, postRequestCalldata } = await this.source.estimateGas(postRequest);
|
|
11333
11424
|
const postGasEstimateInSourceFeeToken = await this.convertGasToFeeToken(
|
|
11334
11425
|
postGasEstimate,
|
|
11335
11426
|
this.source.client,
|
|
@@ -11345,23 +11436,23 @@ var IntentGateway = class {
|
|
|
11345
11436
|
const fillOptions = {
|
|
11346
11437
|
relayerFee: relayerFeeInDestFeeToken
|
|
11347
11438
|
};
|
|
11348
|
-
const totalEthValue = order.outputs.filter((output) =>
|
|
11439
|
+
const totalEthValue = order.outputs.filter((output) => bytes32ToBytes20(output.token) === ADDRESS_ZERO).reduce((sum, output) => sum + output.amount, 0n);
|
|
11349
11440
|
const intentGatewayAddress = this.source.config.getIntentGatewayAddress(order.destChain);
|
|
11350
11441
|
const testValue = toHex(maxUint256 / 2n);
|
|
11351
11442
|
const orderOverrides = await Promise.all(
|
|
11352
11443
|
order.outputs.map(async (output) => {
|
|
11353
|
-
const tokenAddress =
|
|
11354
|
-
if (tokenAddress ===
|
|
11444
|
+
const tokenAddress = bytes32ToBytes20(output.token);
|
|
11445
|
+
if (tokenAddress === ADDRESS_ZERO) {
|
|
11355
11446
|
return null;
|
|
11356
11447
|
}
|
|
11357
11448
|
try {
|
|
11358
11449
|
const stateDiffs = [];
|
|
11359
|
-
const balanceData = "0x70a08231" /* BALANCE_OF */ + bytes20ToBytes32(
|
|
11360
|
-
const balanceSlot = await
|
|
11450
|
+
const balanceData = "0x70a08231" /* BALANCE_OF */ + bytes20ToBytes32(MOCK_ADDRESS).slice(2);
|
|
11451
|
+
const balanceSlot = await getStorageSlot(this.dest.client, tokenAddress, balanceData);
|
|
11361
11452
|
stateDiffs.push({ slot: balanceSlot, value: testValue });
|
|
11362
11453
|
try {
|
|
11363
|
-
const allowanceData = "0xdd62ed3e" /* ALLOWANCE */ + bytes20ToBytes32(
|
|
11364
|
-
const allowanceSlot = await
|
|
11454
|
+
const allowanceData = "0xdd62ed3e" /* ALLOWANCE */ + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + bytes20ToBytes32(intentGatewayAddress).slice(2);
|
|
11455
|
+
const allowanceSlot = await getStorageSlot(
|
|
11365
11456
|
this.dest.client,
|
|
11366
11457
|
tokenAddress,
|
|
11367
11458
|
allowanceData
|
|
@@ -11377,31 +11468,11 @@ var IntentGateway = class {
|
|
|
11377
11468
|
}
|
|
11378
11469
|
})
|
|
11379
11470
|
).then((results) => results.filter(Boolean));
|
|
11380
|
-
|
|
11381
|
-
const destFeeTokenBalanceSlot = await getStorageSlot2(
|
|
11382
|
-
this.dest.client,
|
|
11383
|
-
destChainFeeTokenAddress,
|
|
11384
|
-
destFeeTokenBalanceData
|
|
11385
|
-
);
|
|
11386
|
-
const destFeeTokenAllowanceData = "0xdd62ed3e" /* ALLOWANCE */ + bytes20ToBytes32(MOCK_ADDRESS2).slice(2) + bytes20ToBytes32(intentGatewayAddress).slice(2);
|
|
11387
|
-
const destFeeTokenAllowanceSlot = await getStorageSlot2(
|
|
11388
|
-
this.dest.client,
|
|
11389
|
-
destChainFeeTokenAddress,
|
|
11390
|
-
destFeeTokenAllowanceData
|
|
11391
|
-
);
|
|
11392
|
-
const feeTokenStateDiffs = [
|
|
11393
|
-
{ slot: destFeeTokenBalanceSlot, value: testValue },
|
|
11394
|
-
{ slot: destFeeTokenAllowanceSlot, value: testValue }
|
|
11395
|
-
];
|
|
11396
|
-
orderOverrides.push({
|
|
11397
|
-
address: destChainFeeTokenAddress,
|
|
11398
|
-
stateDiff: feeTokenStateDiffs
|
|
11399
|
-
});
|
|
11400
|
-
const stateOverride = [
|
|
11471
|
+
let stateOverrides = [
|
|
11401
11472
|
// Mock address with ETH balance so that any chain estimation runs
|
|
11402
11473
|
// even when the address doesn't hold any native token in that chain
|
|
11403
11474
|
{
|
|
11404
|
-
address:
|
|
11475
|
+
address: MOCK_ADDRESS,
|
|
11405
11476
|
balance: maxUint256
|
|
11406
11477
|
},
|
|
11407
11478
|
...orderOverrides.map((override) => ({
|
|
@@ -11409,15 +11480,52 @@ var IntentGateway = class {
|
|
|
11409
11480
|
stateDiff: override.stateDiff
|
|
11410
11481
|
}))
|
|
11411
11482
|
];
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11483
|
+
let destChainFillGas = 0n;
|
|
11484
|
+
try {
|
|
11485
|
+
const protocolFeeInNativeToken = await this.quoteNative(postRequest, relayerFeeInDestFeeToken);
|
|
11486
|
+
destChainFillGas = await this.dest.client.estimateContractGas({
|
|
11487
|
+
abi: IntentGateway_default.ABI,
|
|
11488
|
+
address: intentGatewayAddress,
|
|
11489
|
+
functionName: "fillOrder",
|
|
11490
|
+
args: [transformOrderForContract(order), fillOptions],
|
|
11491
|
+
account: MOCK_ADDRESS,
|
|
11492
|
+
value: totalEthValue + protocolFeeInNativeToken,
|
|
11493
|
+
stateOverride: stateOverrides
|
|
11494
|
+
});
|
|
11495
|
+
} catch {
|
|
11496
|
+
console.warn(
|
|
11497
|
+
`Could not estimate gas for fill order with native token as fees for chain ${order.destChain}, now trying with fee token as fees`
|
|
11498
|
+
);
|
|
11499
|
+
const destFeeTokenBalanceData = "0x70a08231" /* BALANCE_OF */ + bytes20ToBytes32(MOCK_ADDRESS).slice(2);
|
|
11500
|
+
const destFeeTokenBalanceSlot = await getStorageSlot(
|
|
11501
|
+
this.dest.client,
|
|
11502
|
+
destChainFeeTokenAddress,
|
|
11503
|
+
destFeeTokenBalanceData
|
|
11504
|
+
);
|
|
11505
|
+
const destFeeTokenAllowanceData = "0xdd62ed3e" /* ALLOWANCE */ + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + bytes20ToBytes32(intentGatewayAddress).slice(2);
|
|
11506
|
+
const destFeeTokenAllowanceSlot = await getStorageSlot(
|
|
11507
|
+
this.dest.client,
|
|
11508
|
+
destChainFeeTokenAddress,
|
|
11509
|
+
destFeeTokenAllowanceData
|
|
11510
|
+
);
|
|
11511
|
+
const feeTokenStateDiffs = [
|
|
11512
|
+
{ slot: destFeeTokenBalanceSlot, value: testValue },
|
|
11513
|
+
{ slot: destFeeTokenAllowanceSlot, value: testValue }
|
|
11514
|
+
];
|
|
11515
|
+
stateOverrides.push({
|
|
11516
|
+
address: destChainFeeTokenAddress,
|
|
11517
|
+
stateDiff: feeTokenStateDiffs
|
|
11518
|
+
});
|
|
11519
|
+
destChainFillGas = await this.dest.client.estimateContractGas({
|
|
11520
|
+
abi: IntentGateway_default.ABI,
|
|
11521
|
+
address: intentGatewayAddress,
|
|
11522
|
+
functionName: "fillOrder",
|
|
11523
|
+
args: [transformOrderForContract(order), fillOptions],
|
|
11524
|
+
account: MOCK_ADDRESS,
|
|
11525
|
+
value: totalEthValue,
|
|
11526
|
+
stateOverride: stateOverrides
|
|
11527
|
+
});
|
|
11528
|
+
}
|
|
11421
11529
|
const fillGasInSourceFeeToken = await this.convertGasToFeeToken(
|
|
11422
11530
|
destChainFillGas,
|
|
11423
11531
|
this.dest.client,
|
|
@@ -11432,17 +11540,88 @@ var IntentGateway = class {
|
|
|
11432
11540
|
const totalEstimate = fillGasInSourceFeeToken + protocolFeeInSourceFeeToken + relayerFeeInSourceFeeToken;
|
|
11433
11541
|
const SWAP_OPERATIONS_BPS = 2500n;
|
|
11434
11542
|
const swapOperationsInFeeToken = totalEstimate * SWAP_OPERATIONS_BPS / 10000n;
|
|
11435
|
-
|
|
11543
|
+
const totalFeeTokenAmount = totalEstimate + swapOperationsInFeeToken;
|
|
11544
|
+
const totalNativeTokenAmount = await this.convertFeeTokenToNative(
|
|
11545
|
+
totalFeeTokenAmount,
|
|
11546
|
+
this.source.client,
|
|
11547
|
+
sourceChainFeeTokenDecimals
|
|
11548
|
+
);
|
|
11549
|
+
return {
|
|
11550
|
+
feeTokenAmount: totalFeeTokenAmount,
|
|
11551
|
+
nativeTokenAmount: totalNativeTokenAmount,
|
|
11552
|
+
postRequestCalldata
|
|
11553
|
+
};
|
|
11554
|
+
}
|
|
11555
|
+
/**
|
|
11556
|
+
* Converts fee token amounts back to the equivalent amount in native token.
|
|
11557
|
+
* Uses USD pricing to convert between fee token amounts and native token costs.
|
|
11558
|
+
*
|
|
11559
|
+
* @param feeTokenAmount - The amount in fee token (DAI)
|
|
11560
|
+
* @param publicClient - The client for the chain to get native token info
|
|
11561
|
+
* @param feeTokenDecimals - The decimal places of the fee token
|
|
11562
|
+
* @returns The fee token amount converted to native token amount
|
|
11563
|
+
* @private
|
|
11564
|
+
*/
|
|
11565
|
+
async convertFeeTokenToNative(feeTokenAmount, publicClient, feeTokenDecimals) {
|
|
11566
|
+
const nativeToken = publicClient.chain?.nativeCurrency;
|
|
11567
|
+
if (!nativeToken?.symbol || !nativeToken?.decimals) {
|
|
11568
|
+
throw new Error("Chain native currency information not available");
|
|
11569
|
+
}
|
|
11570
|
+
const feeTokenAmountNumber = Number(feeTokenAmount) / Math.pow(10, feeTokenDecimals);
|
|
11571
|
+
const nativeTokenPriceUsd = await fetchTokenUsdPrice(nativeToken.symbol);
|
|
11572
|
+
const totalCostInNativeToken = feeTokenAmountNumber / nativeTokenPriceUsd;
|
|
11573
|
+
return BigInt(Math.floor(totalCostInNativeToken * Math.pow(10, nativeToken.decimals)));
|
|
11574
|
+
}
|
|
11575
|
+
/**
|
|
11576
|
+
* Converts gas costs to the equivalent amount in the fee token (DAI).
|
|
11577
|
+
* Uses USD pricing to convert between native token gas costs and fee token amounts.
|
|
11578
|
+
*
|
|
11579
|
+
* @param gasEstimate - The estimated gas units
|
|
11580
|
+
* @param publicClient - The client for the chain to get gas prices
|
|
11581
|
+
* @param targetDecimals - The decimal places of the target fee token
|
|
11582
|
+
* @returns The gas cost converted to fee token amount
|
|
11583
|
+
* @private
|
|
11584
|
+
*/
|
|
11585
|
+
async convertGasToFeeToken(gasEstimate, publicClient, targetDecimals) {
|
|
11586
|
+
const gasPrice = await publicClient.getGasPrice();
|
|
11587
|
+
const gasCostInWei = gasEstimate * gasPrice;
|
|
11588
|
+
const nativeToken = publicClient.chain?.nativeCurrency;
|
|
11589
|
+
if (!nativeToken?.symbol || !nativeToken?.decimals) {
|
|
11590
|
+
throw new Error("Chain native currency information not available");
|
|
11591
|
+
}
|
|
11592
|
+
const gasCostInToken = Number(gasCostInWei) / Math.pow(10, nativeToken.decimals);
|
|
11593
|
+
const tokenPriceUsd = await fetchTokenUsdPrice(nativeToken.symbol);
|
|
11594
|
+
const gasCostUsd = gasCostInToken * tokenPriceUsd;
|
|
11595
|
+
const feeTokenPriceUsd = await fetchTokenUsdPrice("DAI");
|
|
11596
|
+
const gasCostInFeeToken = gasCostUsd / feeTokenPriceUsd;
|
|
11597
|
+
return BigInt(Math.floor(gasCostInFeeToken * Math.pow(10, targetDecimals)));
|
|
11598
|
+
}
|
|
11599
|
+
async quoteNative(postRequest, fee) {
|
|
11600
|
+
const dispatchPost = {
|
|
11601
|
+
dest: toHex(postRequest.dest),
|
|
11602
|
+
to: postRequest.to,
|
|
11603
|
+
body: postRequest.body,
|
|
11604
|
+
timeout: postRequest.timeoutTimestamp,
|
|
11605
|
+
fee,
|
|
11606
|
+
payer: postRequest.from
|
|
11607
|
+
};
|
|
11608
|
+
const quoteNative = await this.dest.client.readContract({
|
|
11609
|
+
address: this.dest.config.getIntentGatewayAddress(postRequest.dest),
|
|
11610
|
+
abi: IntentGateway_default.ABI,
|
|
11611
|
+
functionName: "quoteNative",
|
|
11612
|
+
args: [dispatchPost]
|
|
11613
|
+
});
|
|
11614
|
+
return quoteNative;
|
|
11436
11615
|
}
|
|
11437
11616
|
/**
|
|
11438
|
-
* Finds the best Uniswap protocol (V2 or
|
|
11617
|
+
* Finds the best Uniswap protocol (V2, V3, or V4) for swapping tokens given a desired output amount.
|
|
11439
11618
|
* Compares liquidity and pricing across different protocols and fee tiers.
|
|
11440
11619
|
*
|
|
11441
11620
|
* @param chain - The chain identifier where the swap will occur
|
|
11442
11621
|
* @param tokenIn - The address of the input token
|
|
11443
11622
|
* @param tokenOut - The address of the output token
|
|
11444
11623
|
* @param amountOut - The desired output amount
|
|
11445
|
-
* @returns Object containing the best protocol, required input amount, and fee tier (for V3)
|
|
11624
|
+
* @returns Object containing the best protocol, required input amount, and fee tier (for V3/V4)
|
|
11446
11625
|
*/
|
|
11447
11626
|
async findBestProtocolWithAmountOut(chain, tokenIn, tokenOut, amountOut) {
|
|
11448
11627
|
const destClient = this.dest.client;
|
|
@@ -11458,8 +11637,8 @@ var IntentGateway = class {
|
|
|
11458
11637
|
const v3Quoter = this.source.config.getUniswapV3QuoterAddress(chain);
|
|
11459
11638
|
const v4Quoter = this.source.config.getUniswapV4QuoterAddress(chain);
|
|
11460
11639
|
const wethAsset = this.source.config.getWrappedNativeAssetWithDecimals(chain).asset;
|
|
11461
|
-
const tokenInForQuote = tokenIn ===
|
|
11462
|
-
const tokenOutForQuote = tokenOut ===
|
|
11640
|
+
const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn;
|
|
11641
|
+
const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut;
|
|
11463
11642
|
try {
|
|
11464
11643
|
const v2PairExists = await destClient.readContract({
|
|
11465
11644
|
address: v2Factory,
|
|
@@ -11467,7 +11646,7 @@ var IntentGateway = class {
|
|
|
11467
11646
|
functionName: "getPair",
|
|
11468
11647
|
args: [tokenInForQuote, tokenOutForQuote]
|
|
11469
11648
|
});
|
|
11470
|
-
if (v2PairExists !==
|
|
11649
|
+
if (v2PairExists !== ADDRESS_ZERO) {
|
|
11471
11650
|
const v2AmountIn = await destClient.readContract({
|
|
11472
11651
|
address: v2Router,
|
|
11473
11652
|
abi: uniswapRouterV2_default.ABI,
|
|
@@ -11488,7 +11667,7 @@ var IntentGateway = class {
|
|
|
11488
11667
|
functionName: "getPool",
|
|
11489
11668
|
args: [tokenInForQuote, tokenOutForQuote, fee]
|
|
11490
11669
|
});
|
|
11491
|
-
if (pool !==
|
|
11670
|
+
if (pool !== ADDRESS_ZERO) {
|
|
11492
11671
|
const liquidity = await destClient.readContract({
|
|
11493
11672
|
address: pool,
|
|
11494
11673
|
abi: uniswapV3Pool_default.ABI,
|
|
@@ -11532,7 +11711,7 @@ var IntentGateway = class {
|
|
|
11532
11711
|
currency1,
|
|
11533
11712
|
fee,
|
|
11534
11713
|
tickSpacing: this.getTickSpacing(fee),
|
|
11535
|
-
hooks:
|
|
11714
|
+
hooks: ADDRESS_ZERO
|
|
11536
11715
|
// No hooks
|
|
11537
11716
|
};
|
|
11538
11717
|
const quoteResult = (await destClient.simulateContract({
|
|
@@ -11599,14 +11778,14 @@ var IntentGateway = class {
|
|
|
11599
11778
|
}
|
|
11600
11779
|
}
|
|
11601
11780
|
/**
|
|
11602
|
-
* Finds the best Uniswap protocol (V2 or
|
|
11781
|
+
* Finds the best Uniswap protocol (V2, V3, or V4) for swapping tokens given an input amount.
|
|
11603
11782
|
* Compares liquidity and pricing across different protocols and fee tiers.
|
|
11604
11783
|
*
|
|
11605
11784
|
* @param chain - The chain identifier where the swap will occur
|
|
11606
11785
|
* @param tokenIn - The address of the input token
|
|
11607
11786
|
* @param tokenOut - The address of the output token
|
|
11608
11787
|
* @param amountIn - The input amount to swap
|
|
11609
|
-
* @returns Object containing the best protocol, expected output amount, and fee tier (for V3)
|
|
11788
|
+
* @returns Object containing the best protocol, expected output amount, and fee tier (for V3/V4)
|
|
11610
11789
|
*/
|
|
11611
11790
|
async findBestProtocolWithAmountIn(chain, tokenIn, tokenOut, amountIn) {
|
|
11612
11791
|
const destClient = this.dest.client;
|
|
@@ -11622,8 +11801,8 @@ var IntentGateway = class {
|
|
|
11622
11801
|
const v3Quoter = this.source.config.getUniswapV3QuoterAddress(chain);
|
|
11623
11802
|
const v4Quoter = this.source.config.getUniswapV4QuoterAddress(chain);
|
|
11624
11803
|
const wethAsset = this.source.config.getWrappedNativeAssetWithDecimals(chain).asset;
|
|
11625
|
-
const tokenInForQuote = tokenIn ===
|
|
11626
|
-
const tokenOutForQuote = tokenOut ===
|
|
11804
|
+
const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn;
|
|
11805
|
+
const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut;
|
|
11627
11806
|
try {
|
|
11628
11807
|
const v2PairExists = await destClient.readContract({
|
|
11629
11808
|
address: v2Factory,
|
|
@@ -11631,7 +11810,7 @@ var IntentGateway = class {
|
|
|
11631
11810
|
functionName: "getPair",
|
|
11632
11811
|
args: [tokenInForQuote, tokenOutForQuote]
|
|
11633
11812
|
});
|
|
11634
|
-
if (v2PairExists !==
|
|
11813
|
+
if (v2PairExists !== ADDRESS_ZERO) {
|
|
11635
11814
|
const v2AmountOut = await destClient.readContract({
|
|
11636
11815
|
address: v2Router,
|
|
11637
11816
|
abi: uniswapRouterV2_default.ABI,
|
|
@@ -11652,7 +11831,7 @@ var IntentGateway = class {
|
|
|
11652
11831
|
functionName: "getPool",
|
|
11653
11832
|
args: [tokenInForQuote, tokenOutForQuote, fee]
|
|
11654
11833
|
});
|
|
11655
|
-
if (pool !==
|
|
11834
|
+
if (pool !== ADDRESS_ZERO) {
|
|
11656
11835
|
const liquidity = await destClient.readContract({
|
|
11657
11836
|
address: pool,
|
|
11658
11837
|
abi: uniswapV3Pool_default.ABI,
|
|
@@ -11696,7 +11875,7 @@ var IntentGateway = class {
|
|
|
11696
11875
|
currency1,
|
|
11697
11876
|
fee,
|
|
11698
11877
|
tickSpacing: this.getTickSpacing(fee),
|
|
11699
|
-
hooks:
|
|
11878
|
+
hooks: ADDRESS_ZERO
|
|
11700
11879
|
// No hooks
|
|
11701
11880
|
};
|
|
11702
11881
|
const quoteResult = (await destClient.simulateContract({
|
|
@@ -11762,30 +11941,6 @@ var IntentGateway = class {
|
|
|
11762
11941
|
};
|
|
11763
11942
|
}
|
|
11764
11943
|
}
|
|
11765
|
-
/**
|
|
11766
|
-
* Converts gas costs to the equivalent amount in the fee token (DAI).
|
|
11767
|
-
* Uses USD pricing to convert between native token gas costs and fee token amounts.
|
|
11768
|
-
*
|
|
11769
|
-
* @param gasEstimate - The estimated gas units
|
|
11770
|
-
* @param publicClient - The client for the chain to get gas prices
|
|
11771
|
-
* @param targetDecimals - The decimal places of the target fee token
|
|
11772
|
-
* @returns The gas cost converted to fee token amount
|
|
11773
|
-
* @private
|
|
11774
|
-
*/
|
|
11775
|
-
async convertGasToFeeToken(gasEstimate, publicClient, targetDecimals) {
|
|
11776
|
-
const gasPrice = await publicClient.getGasPrice();
|
|
11777
|
-
const gasCostInWei = gasEstimate * gasPrice;
|
|
11778
|
-
const nativeToken = publicClient.chain?.nativeCurrency;
|
|
11779
|
-
if (!nativeToken?.symbol || !nativeToken?.decimals) {
|
|
11780
|
-
throw new Error("Chain native currency information not available");
|
|
11781
|
-
}
|
|
11782
|
-
const gasCostInToken = Number(gasCostInWei) / Math.pow(10, nativeToken.decimals);
|
|
11783
|
-
const tokenPriceUsd = await fetchTokenUsdPrice2(nativeToken.symbol);
|
|
11784
|
-
const gasCostUsd = gasCostInToken * tokenPriceUsd;
|
|
11785
|
-
const feeTokenPriceUsd = await fetchTokenUsdPrice2("DAI");
|
|
11786
|
-
const gasCostInFeeToken = gasCostUsd / feeTokenPriceUsd;
|
|
11787
|
-
return BigInt(Math.floor(gasCostInFeeToken * Math.pow(10, targetDecimals)));
|
|
11788
|
-
}
|
|
11789
11944
|
/**
|
|
11790
11945
|
* Checks if an order has been filled by verifying the commitment status on-chain.
|
|
11791
11946
|
* Reads the storage slot corresponding to the order's commitment hash.
|
|
@@ -12150,6 +12305,6 @@ async function teleportDot(param_) {
|
|
|
12150
12305
|
return stream;
|
|
12151
12306
|
}
|
|
12152
12307
|
|
|
12153
|
-
export {
|
|
12308
|
+
export { ADDRESS_ZERO, ChainConfigService, Chains, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DUMMY_PRIVATE_KEY, ERC20Method, EvmChain, HyperClientStatus, IndexerClient, IntentGateway, OrderStatus, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, STATE_COMMITMENTS_SLOT, SubstrateChain, TeleportStatus, TimeoutStatus, WrappedNativeDecimals, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, consensusStateIds, constructRedeemEscrowRequestBody, convertStateMachineIdToEnum, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchTokenUsdPrice, generateRootWithProof, getChain, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, orderCommitment, postRequestCommitment, queryGetRequest, queryPostRequest, teleport, teleportDot, viemChains };
|
|
12154
12309
|
//# sourceMappingURL=index.js.map
|
|
12155
12310
|
//# sourceMappingURL=index.js.map
|