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