@hyperbridge/sdk 1.2.2 → 1.3.0

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