@hyperbridge/sdk 2.2.3 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { createConsola, LogLevels } from 'consola';
2
- import { defineChain, keccak256, toHex, createPublicClient, http, hexToBytes, toFunctionSelector, bytesToHex, encodeFunctionData, erc20Abi, bytesToBigInt, pad, toBytes, numberToBytes, getAddress, encodeAbiParameters, isHex, maxUint256, parseAbiParameters, encodePacked, parseAbiItem, concat, decodeFunctionData, decodeAbiParameters, hexToString as hexToString$1, decodeEventLog, parseEventLogs, parseUnits, concatHex, zeroAddress, decodeFunctionResult, formatUnits } from 'viem';
2
+ import { defineChain, keccak256, toHex, createPublicClient, http, hexToBytes, toFunctionSelector, bytesToHex, encodeFunctionData, erc20Abi, bytesToBigInt, pad, toBytes, numberToBytes, decodeAbiParameters, getAddress, encodeAbiParameters, isHex, maxUint256, parseAbiParameters, encodePacked, parseAbiItem, concat, decodeFunctionData, hexToString as hexToString$1, decodeEventLog, parseEventLogs, parseUnits, concatHex, zeroAddress, decodeFunctionResult, formatUnits } from 'viem';
3
3
  import { baseSepolia, optimismSepolia, arbitrumSepolia, soneium, gnosis, optimism, polygonAmoy, polygon, base, arbitrum, bsc, mainnet, sepolia, gnosisChiado, bscTestnet, tron, unichain } from 'viem/chains';
4
4
  import { TronWeb } from 'tronweb';
5
5
  import { flatten, zip, capitalize, maxBy, isNil } from 'lodash-es';
@@ -8,6 +8,7 @@ import { WsProvider, ApiPromise, Keyring } from '@polkadot/api';
8
8
  import { Struct, Vector, u8, Bytes, Enum, Tuple, _void, u64, u32, Option, bool, u128 } from 'scale-ts';
9
9
  import { keccakAsU8a, decodeAddress, keccakAsHex, xxhashAsU8a, blake2AsU8a } from '@polkadot/util-crypto';
10
10
  import { hexToU8a, u8aToHex, u8aConcat } from '@polkadot/util';
11
+ import PQueue from 'p-queue';
11
12
  import { hasWindow, isNode, env } from 'std-env';
12
13
  import mergeRace from '@async-generator/merge-race';
13
14
  import { GraphQLClient } from 'graphql-request';
@@ -564,6 +565,11 @@ var ABI = [
564
565
  name: "context",
565
566
  type: "bytes",
566
567
  internalType: "bytes"
568
+ },
569
+ {
570
+ name: "payer",
571
+ type: "address",
572
+ internalType: "address"
567
573
  }
568
574
  ]
569
575
  }
@@ -2144,7 +2150,7 @@ var ABI2 = [
2144
2150
  { internalType: "bytes", name: "source", type: "bytes" },
2145
2151
  { internalType: "bytes", name: "dest", type: "bytes" },
2146
2152
  { internalType: "uint64", name: "nonce", type: "uint64" },
2147
- { internalType: "address", name: "from", type: "address" },
2153
+ { internalType: "bytes", name: "from", type: "bytes" },
2148
2154
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2149
2155
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2150
2156
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -2211,7 +2217,7 @@ var ABI2 = [
2211
2217
  { internalType: "bytes", name: "source", type: "bytes" },
2212
2218
  { internalType: "bytes", name: "dest", type: "bytes" },
2213
2219
  { internalType: "uint64", name: "nonce", type: "uint64" },
2214
- { internalType: "address", name: "from", type: "address" },
2220
+ { internalType: "bytes", name: "from", type: "bytes" },
2215
2221
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2216
2222
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2217
2223
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -2619,9 +2625,9 @@ var chainConfigs = {
2619
2625
  USDT: { balanceSlot: 151, allowanceSlot: 152 }
2620
2626
  },
2621
2627
  addresses: {
2622
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2628
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
2623
2629
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2624
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2630
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2625
2631
  UniswapRouter02: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
2626
2632
  UniswapV2Factory: "0x12e036669DA18F4A2777853d6e2136b32AceEC86",
2627
2633
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2629,7 +2635,7 @@ var chainConfigs = {
2629
2635
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2630
2636
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2631
2637
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2632
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
2638
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
2633
2639
  },
2634
2640
  rpcEnvKey: "BSC_CHAPEL",
2635
2641
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2660,7 +2666,7 @@ var chainConfigs = {
2660
2666
  addresses: {
2661
2667
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2662
2668
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2663
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2669
+ Host: "0x58A41B89F4871725E5D898d98eF4BF917601c5eB",
2664
2670
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2665
2671
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2666
2672
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2699,7 +2705,7 @@ var chainConfigs = {
2699
2705
  addresses: {
2700
2706
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2701
2707
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2702
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2708
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2703
2709
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2704
2710
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2705
2711
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -3045,13 +3051,13 @@ var chainConfigs = {
3045
3051
  USDC: { balanceSlot: 1, allowanceSlot: 2 }
3046
3052
  },
3047
3053
  addresses: {
3048
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
3054
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
3049
3055
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
3050
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3056
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3051
3057
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3052
3058
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3053
3059
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3054
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
3060
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
3055
3061
  },
3056
3062
  rpcEnvKey: "POLYGON_AMOY",
3057
3063
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3167,7 +3173,7 @@ var chainConfigs = {
3167
3173
  },
3168
3174
  addresses: {
3169
3175
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3170
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3176
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3171
3177
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3172
3178
  },
3173
3179
  defaultRpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
@@ -3191,7 +3197,7 @@ var chainConfigs = {
3191
3197
  },
3192
3198
  addresses: {
3193
3199
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3194
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3200
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3195
3201
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3196
3202
  },
3197
3203
  defaultRpcUrl: "https://sepolia.optimism.io",
@@ -3215,7 +3221,7 @@ var chainConfigs = {
3215
3221
  },
3216
3222
  addresses: {
3217
3223
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3218
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3224
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3219
3225
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3220
3226
  },
3221
3227
  defaultRpcUrl: "https://sepolia.base.org",
@@ -3241,7 +3247,7 @@ var chainConfigs = {
3241
3247
  addresses: {
3242
3248
  IntentGateway: "0x606ba811aa6cb424ce2108e8977c5284686f0d1f",
3243
3249
  TokenGateway: "0x1c1e5be83df4a54c7a2230c337e4a3e8b7354b1c",
3244
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3250
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3245
3251
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3246
3252
  },
3247
3253
  defaultRpcUrl: "https://testnet-asset-hub-eth-rpc.polkadot.io",
@@ -3291,7 +3297,7 @@ var chainConfigs = {
3291
3297
  wrappedNativeDecimals: 18,
3292
3298
  addresses: {
3293
3299
  TokenGateway: "0x451bDd8273839AD0Ec7F4Fa798E8B3DABb223fD8",
3294
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3300
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3295
3301
  IntentGateway: "0xb8039832c6c9266F928d038eA49A8a169300C670"
3296
3302
  },
3297
3303
  consensusStateId: "PHAR",
@@ -4423,6 +4429,11 @@ var ABI3 = [
4423
4429
  name: "context",
4424
4430
  type: "bytes",
4425
4431
  internalType: "bytes"
4432
+ },
4433
+ {
4434
+ name: "payer",
4435
+ type: "address",
4436
+ internalType: "address"
4426
4437
  }
4427
4438
  ]
4428
4439
  }
@@ -6431,28 +6442,60 @@ var EvmChain = class _EvmChain {
6431
6442
  }
6432
6443
  /**
6433
6444
  * Query and return the encoded storage proof for the provided keys at the given height.
6445
+ *
6446
+ * Keys may be either:
6447
+ * - 32-byte storage slots — read from `address` (or the host contract when omitted), or
6448
+ * - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
6449
+ * contract is embedded in the key. These may span multiple contracts.
6450
+ *
6434
6451
  * @param {bigint} at - The block height at which to query the storage proof.
6435
6452
  * @param {HexString[]} keys - The keys for which to query the storage proof.
6436
- * @param {HexString} address - Optional contract address to fetch storage proof else default to host contract
6453
+ * @param {HexString} address - Optional contract address; forces all keys to be read as slots
6454
+ * of this contract. Omit to let 52-byte keys carry their own contract address.
6437
6455
  * @returns {Promise<HexString>} The encoded storage proof.
6438
6456
  */
6439
6457
  async queryStateProof(at, keys, address) {
6440
- const config = {
6441
- address: address ?? this.params.host,
6442
- storageKeys: keys
6443
- };
6444
- if (!at) {
6445
- config.blockTag = "latest";
6446
- } else {
6447
- config.blockNumber = at;
6448
- }
6449
- const proof = await this.publicClient.getProof(config);
6450
- const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
6458
+ const slotsByContract = /* @__PURE__ */ new Map();
6459
+ for (const key of keys) {
6460
+ let contract;
6461
+ let slot;
6462
+ if (address) {
6463
+ contract = address.toLowerCase();
6464
+ slot = key;
6465
+ } else if ((key.length - 2) / 2 === 52) {
6466
+ contract = key.slice(0, 42).toLowerCase();
6467
+ slot = `0x${key.slice(42)}`;
6468
+ } else {
6469
+ contract = this.params.host.toLowerCase();
6470
+ slot = key;
6471
+ }
6472
+ const slots = slotsByContract.get(contract) ?? [];
6473
+ slots.push(slot);
6474
+ slotsByContract.set(contract, slots);
6475
+ }
6476
+ const contracts = Array.from(slotsByContract.entries());
6477
+ const proofs = await Promise.all(
6478
+ contracts.map(([contract, slots]) => {
6479
+ const config = { address: contract, storageKeys: slots };
6480
+ if (!at) {
6481
+ config.blockTag = "latest";
6482
+ } else {
6483
+ config.blockNumber = at;
6484
+ }
6485
+ return this.publicClient.getProof(config);
6486
+ })
6487
+ );
6488
+ const contractProof = Array.from(new Set(flatten(proofs.map((proof) => proof.accountProof))));
6489
+ const storageProof = contracts.map(([contract], i) => {
6490
+ const flattened = Array.from(new Set(flatten(proofs[i].storageProof.map((item) => item.proof))));
6491
+ return [
6492
+ Array.from(hexToBytes(contract)),
6493
+ flattened.map((item) => Array.from(hexToBytes(item)))
6494
+ ];
6495
+ });
6451
6496
  const encoded = EvmStateProof.enc({
6452
- contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
6453
- storageProof: [
6454
- [Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
6455
- ]
6497
+ contractProof: contractProof.map((item) => Array.from(hexToBytes(item))),
6498
+ storageProof
6456
6499
  });
6457
6500
  return toHex(encoded);
6458
6501
  }
@@ -7174,6 +7217,49 @@ var SubstrateChain = class _SubstrateChain {
7174
7217
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7175
7218
  return item;
7176
7219
  }
7220
+ /**
7221
+ * Returns the storage key for a response receipt in the child trie.
7222
+ * A response receipt is keyed by the originating *request* commitment.
7223
+ * @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
7224
+ * @returns {HexString} The storage key as a hex string
7225
+ */
7226
+ responseReceiptKey(key) {
7227
+ const prefix = new TextEncoder().encode("ResponseReceipts");
7228
+ const keyBytes = hexToBytes(key);
7229
+ return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
7230
+ }
7231
+ /**
7232
+ * Queries the response receipt for a request commitment. For a GET, Hyperbridge
7233
+ * produces the response as it processes the request, so the presence of a response
7234
+ * receipt indicates the request has already been delivered and handled.
7235
+ * @param {HexString} commitment - The originating request commitment to query.
7236
+ * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7237
+ */
7238
+ async queryResponseReceipt(commitment) {
7239
+ const prefix = toHex(":child_storage:default:ISMP");
7240
+ const key = this.responseReceiptKey(commitment);
7241
+ const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7242
+ return item;
7243
+ }
7244
+ /**
7245
+ * Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
7246
+ * exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
7247
+ * proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
7248
+ * has not finalized that chain at exactly that height.
7249
+ * @param {StateMachineHeight} height - The counterparty state machine id + height.
7250
+ * @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
7251
+ */
7252
+ async queryStateMachineCommitment(height) {
7253
+ if (!this.api) throw new Error("API not initialized");
7254
+ const id = {
7255
+ stateId: height.id.stateId,
7256
+ // on-chain StateMachineId encodes consensusStateId as [u8; 4]
7257
+ consensusStateId: toHex(toBytes(height.id.consensusStateId))
7258
+ };
7259
+ const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
7260
+ if (commitment.isNone) return void 0;
7261
+ return commitment.toJSON()?.stateRoot;
7262
+ }
7177
7263
  /**
7178
7264
  * Returns the current timestamp of the chain.
7179
7265
  * @returns {Promise<bigint>} The current timestamp.
@@ -7583,6 +7669,7 @@ function encodeISMPMessage(message) {
7583
7669
  }
7584
7670
  }
7585
7671
  var OFFCHAIN_BID_PREFIX = new TextEncoder().encode("intents::bid::");
7672
+ var OFFCHAIN_PHANTOM_PREFIX = new TextEncoder().encode("intents::phantom::order::");
7586
7673
  var BidCodec = Struct({ filler: Bytes(32), user_op: Vector(u8) });
7587
7674
  var PackedUserOperationCodec = Struct({
7588
7675
  sender: Bytes(20),
@@ -7643,6 +7730,11 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7643
7730
  ownsConnection;
7644
7731
  /** Cached result of whether the node exposes intents_* RPC methods */
7645
7732
  hasIntentsRpc = null;
7733
+ // Serialises every extrinsic submission on this instance's substrate account. All submit/retract
7734
+ // methods funnel through signAndSendExtrinsic, each using the API's auto-nonce; fired in parallel
7735
+ // (bids for orders on different chains, or several phantom orders in one interval) they would grab
7736
+ // the same nonce and all but one would fail. Concurrency 1 sequences them.
7737
+ submissionQueue = new PQueue({ concurrency: 1 });
7646
7738
  /**
7647
7739
  * Creates and connects an IntentsCoprocessor to a Hyperbridge node.
7648
7740
  * This creates and manages its own API connection.
@@ -7695,14 +7787,17 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7695
7787
  }
7696
7788
  }
7697
7789
  /**
7698
- * Creates a Substrate keypair from the configured private key
7699
- * Supports both hex seed (without 0x prefix) and mnemonic phrases
7790
+ * Creates a Substrate keypair from the configured private key.
7791
+ * Supports hex seed (with or without 0x), mnemonic phrases, and URI derivation paths (//Alice).
7700
7792
  */
7701
7793
  getKeyPair() {
7702
7794
  if (!this.substratePrivateKey) {
7703
7795
  throw new Error("Substrate PrivateKey Required");
7704
7796
  }
7705
7797
  const keyring = new Keyring({ type: "sr25519" });
7798
+ if (this.substratePrivateKey.startsWith("//")) {
7799
+ return keyring.addFromUri(this.substratePrivateKey);
7800
+ }
7706
7801
  if (this.substratePrivateKey.includes(" ")) {
7707
7802
  return keyring.addFromMnemonic(this.substratePrivateKey);
7708
7803
  }
@@ -7711,10 +7806,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7711
7806
  return keyring.addFromSeed(seedBytes);
7712
7807
  }
7713
7808
  /**
7714
- * Signs and sends an extrinsic, handling status updates and errors
7715
- * Implements retry logic with progressive tip increases for stuck transactions
7809
+ * Signs and sends an extrinsic. Submissions are serialised through {@link submissionQueue} so
7810
+ * concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
7811
+ * before the next is signed.
7716
7812
  */
7717
7813
  async signAndSendExtrinsic(extrinsic, maxRetries = 3, timeoutMs = 3e4) {
7814
+ const result = await this.submissionQueue.add(() => this.sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs));
7815
+ return result ?? { success: false, error: "Submission queue returned no result" };
7816
+ }
7817
+ /**
7818
+ * Signs and sends an extrinsic, handling status updates and errors.
7819
+ * Implements retry logic with progressive tip increases for stuck transactions.
7820
+ */
7821
+ async sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs) {
7718
7822
  const keyPair = this.getKeyPair();
7719
7823
  let baseTip = 500000000000n;
7720
7824
  let attempt = 0;
@@ -7759,20 +7863,51 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7759
7863
  }, timeoutMs);
7760
7864
  extrinsic.signAndSend(keyPair, { tip }, (result) => {
7761
7865
  if (resolved) return;
7762
- if (result.status.isInBlock || result.status.isFinalized) {
7866
+ if (result.dispatchError && (result.status.isInBlock || result.status.isFinalized)) {
7763
7867
  resolved = true;
7764
7868
  clearTimeout(timeoutId);
7869
+ let errorMsg;
7870
+ if (result.dispatchError.isModule) {
7871
+ const decoded = this.api.registry.findMetaError(result.dispatchError.asModule);
7872
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7873
+ } else {
7874
+ errorMsg = `Dispatch error: ${result.dispatchError.toString()}`;
7875
+ }
7765
7876
  resolve({
7766
- success: true,
7767
- blockHash: result.status.asInBlock.toHex(),
7768
- extrinsicHash: extrinsic.hash.toHex()
7877
+ success: false,
7878
+ error: errorMsg
7769
7879
  });
7770
- } else if (result.dispatchError) {
7880
+ } else if (result.status.isDropped || result.status.isInvalid || result.status.isUsurped || result.status.isFinalityTimeout) {
7771
7881
  resolved = true;
7772
7882
  clearTimeout(timeoutId);
7773
7883
  resolve({
7774
7884
  success: false,
7775
- error: `Dispatch error: ${result.dispatchError.toString()}`
7885
+ error: `Transaction ${result.status.type.toLowerCase()}`
7886
+ });
7887
+ } else if (result.status.isInBlock || result.status.isFinalized) {
7888
+ resolved = true;
7889
+ clearTimeout(timeoutId);
7890
+ const interrupted = result.events.find(
7891
+ ({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
7892
+ );
7893
+ if (interrupted) {
7894
+ const [indexCodec, dispatchError] = interrupted.event.data;
7895
+ if (Number(indexCodec.toString()) === 0) {
7896
+ let errorMsg;
7897
+ if (dispatchError?.isModule) {
7898
+ const decoded = this.api.registry.findMetaError(dispatchError.asModule);
7899
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7900
+ } else {
7901
+ errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
7902
+ }
7903
+ resolve({ success: false, error: errorMsg });
7904
+ return;
7905
+ }
7906
+ }
7907
+ resolve({
7908
+ success: true,
7909
+ blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
7910
+ extrinsicHash: extrinsic.hash.toHex()
7776
7911
  });
7777
7912
  }
7778
7913
  }).then((unsub) => {
@@ -7827,6 +7962,40 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7827
7962
  };
7828
7963
  }
7829
7964
  }
7965
+ /**
7966
+ * Places a new bid and retracts a previous one in a single transaction via utility.batch.
7967
+ *
7968
+ * The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
7969
+ * non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
7970
+ * reverting the calls that already succeeded. Placing first guarantees the new bid lands even
7971
+ * when the retraction then fails — which it routinely does, because a previous commitment's bid
7972
+ * may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
7973
+ *
7974
+ * Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
7975
+ * `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
7976
+ * landed, so the *next* interval's retract of that never-placed commitment also failed, and so
7977
+ * on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
7978
+ * best-effort; landing the bid is not.
7979
+ *
7980
+ * @param retractCommitment - The order commitment of the bid to retract (bytes32)
7981
+ * @param bidCommitment - The order commitment of the new bid (bytes32)
7982
+ * @param userOp - The encoded PackedUserOperation as hex string
7983
+ * @returns BidSubmissionResult with success status and block/extrinsic hash
7984
+ */
7985
+ async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
7986
+ try {
7987
+ const batch = this.api.tx.utility.batch([
7988
+ this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
7989
+ this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
7990
+ ]);
7991
+ return await this.signAndSendExtrinsic(batch);
7992
+ } catch (error) {
7993
+ return {
7994
+ success: false,
7995
+ error: error instanceof Error ? error.message : "Unknown error"
7996
+ };
7997
+ }
7998
+ }
7830
7999
  /**
7831
8000
  * Fetches all bid storage entries for a given order commitment.
7832
8001
  * Returns the on-chain data only (filler addresses and deposits).
@@ -7911,6 +8080,80 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7911
8080
  buildOffchainBidKey(commitment, filler) {
7912
8081
  return u8aConcat(OFFCHAIN_BID_PREFIX, hexToU8a(commitment), decodeAddress(filler));
7913
8082
  }
8083
+ /**
8084
+ * Fetches the ABI-encoded phantom order from offchain storage and decodes it
8085
+ * into an `Order` object. The pallet writes the order bytes under the key
8086
+ * `intents::phantom::order::<commitment>` when it calls `on_initialize`.
8087
+ *
8088
+ * Returns `null` if the key is absent (e.g. the node is not an offchain worker
8089
+ * or the commitment has expired and been cleared).
8090
+ */
8091
+ async fetchPhantomOrder(commitment) {
8092
+ const key = u8aConcat(OFFCHAIN_PHANTOM_PREFIX, hexToU8a(commitment));
8093
+ const result = await this.api.rpc.offchain.localStorageGet("PERSISTENT", u8aToHex(key));
8094
+ if (!result || result.isNone) return null;
8095
+ const rawHex = result.unwrap().toHex();
8096
+ if (rawHex === "0x" || rawHex === "0x00") return null;
8097
+ const placeOrderAbi = IntentGatewayV2_default.ABI.find(
8098
+ (item) => item.type === "function" && item.name === "placeOrder"
8099
+ );
8100
+ const orderType = placeOrderAbi?.inputs?.[0];
8101
+ if (!orderType) return null;
8102
+ const [decoded] = decodeAbiParameters([orderType], rawHex);
8103
+ const d = decoded;
8104
+ const textDecoder = new TextDecoder();
8105
+ return {
8106
+ id: commitment,
8107
+ user: d.user,
8108
+ source: textDecoder.decode(hexToBytes(d.source)),
8109
+ destination: textDecoder.decode(hexToBytes(d.destination)),
8110
+ deadline: d.deadline,
8111
+ nonce: d.nonce,
8112
+ fees: d.fees,
8113
+ session: d.session,
8114
+ predispatch: {
8115
+ assets: d.predispatch.assets.map((a) => ({
8116
+ token: a.token,
8117
+ amount: a.amount
8118
+ })),
8119
+ call: d.predispatch.call
8120
+ },
8121
+ inputs: d.inputs.map((i) => ({
8122
+ token: i.token,
8123
+ amount: i.amount
8124
+ })),
8125
+ output: {
8126
+ beneficiary: d.output.beneficiary,
8127
+ assets: d.output.assets.map((a) => ({
8128
+ token: a.token,
8129
+ amount: a.amount
8130
+ })),
8131
+ call: d.output.call
8132
+ }
8133
+ };
8134
+ }
8135
+ /**
8136
+ * Subscribes to PhantomOrderRegistered events from the intents coprocessor pallet.
8137
+ * Calls the callback for each new phantom order as blocks arrive.
8138
+ * Returns an unsubscribe function to stop the subscription.
8139
+ */
8140
+ async subscribePhantomOrders(callback) {
8141
+ const unsub = await this.api.query.system.events((records) => {
8142
+ for (const { event } of records) {
8143
+ if (event.section !== "intentsCoprocessor" || event.method !== "PhantomOrderRegistered") continue;
8144
+ const [commitment, chain, createdAt, tokenA, tokenB, standardAmount] = event.data;
8145
+ callback({
8146
+ commitment: commitment.toHex(),
8147
+ chain: new TextDecoder().decode(hexToU8a(chain.toHex())),
8148
+ createdAt: createdAt.toNumber(),
8149
+ tokenA: tokenA.toHex(),
8150
+ tokenB: tokenB.toHex(),
8151
+ standardAmount: BigInt(standardAmount.toString())
8152
+ });
8153
+ }
8154
+ });
8155
+ return unsub;
8156
+ }
7914
8157
  };
7915
8158
  var TronChain = class _TronChain {
7916
8159
  constructor(params, evm) {
@@ -9849,6 +10092,7 @@ var GetRequestClient = class {
9849
10092
  const latestMetadata = request.statuses[request.statuses.length - 1];
9850
10093
  status = maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
9851
10094
  if (!status) return;
10095
+ let sourceFinalizedHeight;
9852
10096
  while (true) {
9853
10097
  switch (status) {
9854
10098
  case RequestStatus.SOURCE: {
@@ -9860,6 +10104,7 @@ var GetRequestClient = class {
9860
10104
  chain: this.ctx.config.hyperbridge.config.stateMachineId
9861
10105
  })
9862
10106
  });
10107
+ sourceFinalizedHeight = BigInt(sourceUpdate.height);
9863
10108
  yield {
9864
10109
  status: RequestStatus.SOURCE_FINALIZED,
9865
10110
  metadata: {
@@ -9873,6 +10118,15 @@ var GetRequestClient = class {
9873
10118
  break;
9874
10119
  }
9875
10120
  case RequestStatus.SOURCE_FINALIZED: {
10121
+ if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
10122
+ try {
10123
+ await this.deliverToHyperbridge(request, sourceFinalizedHeight);
10124
+ } catch (error) {
10125
+ this.logger.warn(
10126
+ `Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
10127
+ );
10128
+ }
10129
+ }
9876
10130
  request = await waitOrAbort(this.ctx, {
9877
10131
  signal,
9878
10132
  promise: () => this.queries.queryGetRequest(hash),
@@ -9893,7 +10147,10 @@ var GetRequestClient = class {
9893
10147
  }
9894
10148
  case RequestStatus.HYPERBRIDGE_DELIVERED: {
9895
10149
  if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
9896
- const response = await this.queries.queryResponseByRequestId(hash);
10150
+ const response = await waitOrAbort(this.ctx, {
10151
+ signal,
10152
+ promise: () => this.queries.queryResponseByRequestId(hash)
10153
+ });
9897
10154
  yield await this.streamFinalized(signal, request, 1, response);
9898
10155
  status = RequestStatus.HYPERBRIDGE_FINALIZED;
9899
10156
  break;
@@ -9923,6 +10180,102 @@ var GetRequestClient = class {
9923
10180
  }
9924
10181
  }
9925
10182
  }
10183
+ /**
10184
+ * Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
10185
+ * otherwise require an external relayer.
10186
+ *
10187
+ * Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
10188
+ * the source chain at the Hyperbridge-finalized source height, prove the requested keys on
10189
+ * the destination chain at the request's height, wait out the source challenge period, then
10190
+ * submit an unsigned `GetRequest` message. Source and destination may each be EVM or
10191
+ * substrate — proofs are built via the chain-agnostic {@link IChain} methods.
10192
+ *
10193
+ * Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
10194
+ * wraps this best-effort, so a failure leaves the stream observing as before.
10195
+ */
10196
+ async deliverToHyperbridge(request, sourceFinalizedHeight) {
10197
+ const sourceChain = this.ctx.config.source;
10198
+ const destChain = this.ctx.config.dest;
10199
+ const hyperbridge = this.ctx.config.hyperbridge;
10200
+ const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
10201
+ const retry = { maxRetries: 5, backoffMs: 2e3 };
10202
+ if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
10203
+ this.logger.info(
10204
+ `Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
10205
+ );
10206
+ const sourceProof = {
10207
+ height: sourceFinalizedHeight,
10208
+ stateMachine: request.source,
10209
+ consensusStateId: sourceChain.config.consensusStateId,
10210
+ proof: await withRetry(
10211
+ this.ctx,
10212
+ () => sourceChain.queryProof(
10213
+ { Requests: [commitment] },
10214
+ this.ctx.config.hyperbridge.config.stateMachineId,
10215
+ sourceFinalizedHeight
10216
+ ),
10217
+ retry
10218
+ )
10219
+ };
10220
+ this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
10221
+ const destCommitment = await withRetry(
10222
+ this.ctx,
10223
+ () => hyperbridge.queryStateMachineCommitment({
10224
+ id: {
10225
+ stateId: parseStateMachineId(request.dest).stateId,
10226
+ consensusStateId: destChain.config.consensusStateId
10227
+ },
10228
+ height: request.height
10229
+ }),
10230
+ retry
10231
+ );
10232
+ if (!destCommitment) {
10233
+ throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
10234
+ }
10235
+ const responseProof = {
10236
+ height: request.height,
10237
+ stateMachine: request.dest,
10238
+ consensusStateId: destChain.config.consensusStateId,
10239
+ proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
10240
+ };
10241
+ this.logger.info(
10242
+ ` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
10243
+ );
10244
+ await withRetry(
10245
+ this.ctx,
10246
+ () => waitForChallengePeriod(hyperbridge, {
10247
+ height: sourceFinalizedHeight,
10248
+ id: {
10249
+ stateId: parseStateMachineId(request.source).stateId,
10250
+ consensusStateId: sourceChain.config.consensusStateId
10251
+ }
10252
+ }),
10253
+ retry
10254
+ );
10255
+ const message = {
10256
+ kind: "GetRequest",
10257
+ requests: [
10258
+ {
10259
+ source: request.source,
10260
+ dest: request.dest,
10261
+ nonce: request.nonce,
10262
+ from: request.from,
10263
+ timeoutTimestamp: request.timeoutTimestamp,
10264
+ keys: [...request.keys],
10265
+ height: request.height,
10266
+ context: request.context
10267
+ }
10268
+ ],
10269
+ source: sourceProof,
10270
+ response: responseProof,
10271
+ signer: pad("0x")
10272
+ };
10273
+ this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
10274
+ const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
10275
+ this.logger.info(
10276
+ ` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
10277
+ );
10278
+ }
9926
10279
  /**
9927
10280
  * Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
9928
10281
  * calldata if prerequisites are met, or `undefined` if we're still waiting
@@ -9936,7 +10289,7 @@ var GetRequestClient = class {
9936
10289
  const finality = await this.queries.queryStateMachineUpdateByHeight({
9937
10290
  statemachineId: config.stateMachineId,
9938
10291
  height: hyperbridgeDelivered.metadata.blockNumber,
9939
- chain: config.stateMachineId
10292
+ chain: request.source
9940
10293
  });
9941
10294
  if (finality) {
9942
10295
  const proof = await hyperbridge.queryProof(
@@ -10007,14 +10360,19 @@ var GetRequestClient = class {
10007
10360
  ],
10008
10361
  signer: pad("0x")
10009
10362
  });
10363
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
10364
+ statemachineId: config.stateMachineId,
10365
+ height: hyperbridgeDelivered.metadata.blockNumber,
10366
+ chain: config.stateMachineId
10367
+ });
10368
+ if (!hyperbridgeFinality) return void 0;
10010
10369
  return {
10011
10370
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10012
10371
  metadata: {
10013
- blockHash: hyperbridgeDelivered.metadata.blockHash,
10014
- blockNumber: Number(consensusResult.provenHeight),
10015
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10016
- // @ts-ignore
10017
- timestamp: hyperbridgeDelivered.metadata.timestamp,
10372
+ blockHash: hyperbridgeFinality.blockHash,
10373
+ blockNumber: hyperbridgeFinality.height,
10374
+ transactionHash: hyperbridgeFinality.transactionHash,
10375
+ timestamp: hyperbridgeFinality.timestamp,
10018
10376
  calldata
10019
10377
  }
10020
10378
  };
@@ -10034,12 +10392,44 @@ var GetRequestClient = class {
10034
10392
  const hyperbridge = this.ctx.config.hyperbridge;
10035
10393
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10036
10394
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10395
+ const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
10396
+ const encodeGetResponse = (height, proof2) => sourceChain.encode({
10397
+ kind: "GetResponse",
10398
+ proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
10399
+ responses: [
10400
+ {
10401
+ get: request,
10402
+ values: request.keys.map((key, index) => ({
10403
+ key,
10404
+ value: response?.values[index] || "0x"
10405
+ }))
10406
+ }
10407
+ ],
10408
+ signer: pad("0x")
10409
+ });
10037
10410
  let finality = await this.queries.queryStateMachineUpdateByHeight({
10038
10411
  statemachineId: stateMachineId,
10039
10412
  height: Number(neededHeight),
10040
- chain: stateMachineId
10413
+ chain: request.source
10041
10414
  });
10042
- if (!finality && sourceChain instanceof EvmChain) {
10415
+ if (finality) {
10416
+ const proof2 = await hyperbridge.queryProof(
10417
+ { Responses: [response?.commitment] },
10418
+ request.source,
10419
+ BigInt(finality.height)
10420
+ );
10421
+ return {
10422
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10423
+ metadata: {
10424
+ blockHash: finality.blockHash,
10425
+ blockNumber: finality.height,
10426
+ transactionHash: finality.transactionHash,
10427
+ timestamp: finality.timestamp,
10428
+ calldata: encodeGetResponse(BigInt(finality.height), proof2)
10429
+ }
10430
+ };
10431
+ }
10432
+ if (sourceChain instanceof EvmChain) {
10043
10433
  const hyperbridgeSubstrate = hyperbridge;
10044
10434
  const currentEpoch = await sourceChain.currentEpoch();
10045
10435
  const consensusResult = await waitOrAbort(this.ctx, {
@@ -10051,12 +10441,12 @@ var GetRequestClient = class {
10051
10441
  request.source,
10052
10442
  consensusResult.provenHeight
10053
10443
  );
10054
- const calldata2 = sourceChain.encode({
10444
+ const calldata = sourceChain.encode({
10055
10445
  kind: "BatchConsensusAndGetResponse",
10056
10446
  consensusProofs: consensusResult.proofs,
10057
10447
  proof: {
10058
10448
  stateMachine: stateMachineId,
10059
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10449
+ consensusStateId,
10060
10450
  proof: proof2,
10061
10451
  height: consensusResult.provenHeight
10062
10452
  },
@@ -10071,20 +10461,7 @@ var GetRequestClient = class {
10071
10461
  ],
10072
10462
  signer: pad("0x")
10073
10463
  });
10074
- return {
10075
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
10076
- metadata: {
10077
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10078
- blockNumber: Number(consensusResult.provenHeight),
10079
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10080
- // @ts-ignore
10081
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
10082
- calldata: calldata2
10083
- }
10084
- };
10085
- }
10086
- if (!finality) {
10087
- finality = await waitOrAbort(this.ctx, {
10464
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
10088
10465
  signal,
10089
10466
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10090
10467
  statemachineId: stateMachineId,
@@ -10092,31 +10469,30 @@ var GetRequestClient = class {
10092
10469
  chain: stateMachineId
10093
10470
  })
10094
10471
  });
10472
+ return {
10473
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10474
+ metadata: {
10475
+ blockHash: hyperbridgeFinality.blockHash,
10476
+ blockNumber: hyperbridgeFinality.height,
10477
+ transactionHash: hyperbridgeFinality.transactionHash,
10478
+ timestamp: hyperbridgeFinality.timestamp,
10479
+ calldata
10480
+ }
10481
+ };
10095
10482
  }
10483
+ finality = await waitOrAbort(this.ctx, {
10484
+ signal,
10485
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10486
+ statemachineId: stateMachineId,
10487
+ height: Number(neededHeight),
10488
+ chain: request.source
10489
+ })
10490
+ });
10096
10491
  const proof = await hyperbridge.queryProof(
10097
10492
  { Responses: [response?.commitment] },
10098
10493
  request.source,
10099
10494
  BigInt(finality.height)
10100
10495
  );
10101
- const calldata = sourceChain.encode({
10102
- kind: "GetResponse",
10103
- proof: {
10104
- stateMachine: stateMachineId,
10105
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10106
- proof,
10107
- height: BigInt(finality.height)
10108
- },
10109
- responses: [
10110
- {
10111
- get: request,
10112
- values: request.keys.map((key, index) => ({
10113
- key,
10114
- value: response?.values[index] || "0x"
10115
- }))
10116
- }
10117
- ],
10118
- signer: pad("0x")
10119
- });
10120
10496
  return {
10121
10497
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10122
10498
  metadata: {
@@ -10124,7 +10500,7 @@ var GetRequestClient = class {
10124
10500
  blockNumber: finality.height,
10125
10501
  transactionHash: finality.transactionHash,
10126
10502
  timestamp: finality.timestamp,
10127
- calldata
10503
+ calldata: encodeGetResponse(BigInt(finality.height), proof)
10128
10504
  }
10129
10505
  };
10130
10506
  }
@@ -10627,7 +11003,7 @@ var PostRequestClient = class {
10627
11003
  const finality = await this.queries.queryStateMachineUpdateByHeight({
10628
11004
  statemachineId: config.stateMachineId,
10629
11005
  height: hyperbridgeDelivered.metadata.blockNumber,
10630
- chain: config.stateMachineId
11006
+ chain: request.dest
10631
11007
  });
10632
11008
  if (finality) {
10633
11009
  const proof = await hyperbridge.queryProof(
@@ -10682,14 +11058,19 @@ var PostRequestClient = class {
10682
11058
  requests: [request],
10683
11059
  signer: pad("0x")
10684
11060
  });
11061
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
11062
+ statemachineId: config.stateMachineId,
11063
+ height: hyperbridgeDelivered.metadata.blockNumber,
11064
+ chain: config.stateMachineId
11065
+ });
11066
+ if (!hyperbridgeFinality) return void 0;
10685
11067
  return {
10686
11068
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10687
11069
  metadata: {
10688
- blockHash: hyperbridgeDelivered.metadata.blockHash,
10689
- blockNumber: Number(consensusResult.provenHeight),
10690
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10691
- // @ts-ignore
10692
- timestamp: hyperbridgeDelivered.metadata.timestamp,
11070
+ blockHash: hyperbridgeFinality.blockHash,
11071
+ blockNumber: hyperbridgeFinality.height,
11072
+ transactionHash: hyperbridgeFinality.transactionHash,
11073
+ timestamp: hyperbridgeFinality.timestamp,
10693
11074
  calldata
10694
11075
  }
10695
11076
  };
@@ -10712,7 +11093,7 @@ var PostRequestClient = class {
10712
11093
  let finality = await this.queries.queryStateMachineUpdateByHeight({
10713
11094
  statemachineId: stateMachineId,
10714
11095
  height: Number(neededHeight),
10715
- chain: stateMachineId
11096
+ chain: request.dest
10716
11097
  });
10717
11098
  if (!finality && destChain instanceof EvmChain) {
10718
11099
  const hyperbridgeSubstrate = hyperbridge;
@@ -10740,14 +11121,21 @@ var PostRequestClient = class {
10740
11121
  requests: [request],
10741
11122
  signer: pad("0x")
10742
11123
  });
11124
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
11125
+ signal,
11126
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
11127
+ statemachineId: stateMachineId,
11128
+ height: Number(neededHeight),
11129
+ chain: stateMachineId
11130
+ })
11131
+ });
10743
11132
  return {
10744
11133
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10745
11134
  metadata: {
10746
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10747
- blockNumber: Number(consensusResult.provenHeight),
10748
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10749
- // @ts-ignore
10750
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
11135
+ blockHash: hyperbridgeFinality.blockHash,
11136
+ blockNumber: hyperbridgeFinality.height,
11137
+ transactionHash: hyperbridgeFinality.transactionHash,
11138
+ timestamp: hyperbridgeFinality.timestamp,
10751
11139
  calldata: calldata2
10752
11140
  }
10753
11141
  };
@@ -10758,7 +11146,7 @@ var PostRequestClient = class {
10758
11146
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10759
11147
  statemachineId: stateMachineId,
10760
11148
  height: Number(neededHeight),
10761
- chain: stateMachineId
11149
+ chain: request.dest
10762
11150
  })
10763
11151
  });
10764
11152
  }
@@ -14663,16 +15051,6 @@ var CryptoUtils = class _CryptoUtils {
14663
15051
  }
14664
15052
  }
14665
15053
  };
14666
- var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
14667
- async function getFeeToken(ctx, chainId, chain) {
14668
- const cached = ctx.feeTokenCache.get(chainId);
14669
- if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
14670
- return cached;
14671
- }
14672
- const fresh = await chain.getFeeTokenWithDecimals();
14673
- ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
14674
- return fresh;
14675
- }
14676
15054
  function encodeERC7821ExecuteBatch(calls) {
14677
15055
  const executionData = encodeAbiParameters(
14678
15056
  [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
@@ -14684,6 +15062,36 @@ function encodeERC7821ExecuteBatch(calls) {
14684
15062
  args: [ERC7821_BATCH_MODE, executionData]
14685
15063
  });
14686
15064
  }
15065
+ function decodeERC7821ExecuteBatch(callData) {
15066
+ try {
15067
+ const decoded = decodeFunctionData({ abi: erc7281_default.ABI, data: callData });
15068
+ if (decoded.functionName !== "execute" || !decoded.args || decoded.args.length < 2) return null;
15069
+ const executionData = decoded.args[1];
15070
+ const [calls] = decodeAbiParameters(
15071
+ [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
15072
+ executionData
15073
+ );
15074
+ return calls.map((call) => ({
15075
+ target: call.target,
15076
+ value: call.value,
15077
+ data: call.data
15078
+ }));
15079
+ } catch {
15080
+ return null;
15081
+ }
15082
+ }
15083
+
15084
+ // src/protocols/intents/utils.ts
15085
+ var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
15086
+ async function getFeeToken(ctx, chainId, chain) {
15087
+ const cached = ctx.feeTokenCache.get(chainId);
15088
+ if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
15089
+ return cached;
15090
+ }
15091
+ const fresh = await chain.getFeeTokenWithDecimals();
15092
+ ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
15093
+ return fresh;
15094
+ }
14687
15095
  async function fetchSourceProof(commitment, source, sourceStateMachine, sourceConsensusStateId, sourceHeight) {
14688
15096
  const { slot1, slot2 } = requestCommitmentKey(commitment);
14689
15097
  const proofHex = await source.queryStateProof(sourceHeight, [slot1, slot2]);
@@ -18563,6 +18971,11 @@ var HyperFungibleTokenABI = [
18563
18971
  name: "context",
18564
18972
  type: "bytes",
18565
18973
  internalType: "bytes"
18974
+ },
18975
+ {
18976
+ name: "payer",
18977
+ type: "address",
18978
+ internalType: "address"
18566
18979
  }
18567
18980
  ]
18568
18981
  }
@@ -19684,6 +20097,11 @@ var WrappedHyperFungibleTokenABI = [
19684
20097
  name: "context",
19685
20098
  type: "bytes",
19686
20099
  internalType: "bytes"
20100
+ },
20101
+ {
20102
+ name: "payer",
20103
+ type: "address",
20104
+ internalType: "address"
19687
20105
  }
19688
20106
  ]
19689
20107
  }
@@ -21521,6 +21939,11 @@ var ABI8 = [
21521
21939
  internalType: "bytes",
21522
21940
  name: "context",
21523
21941
  type: "bytes"
21942
+ },
21943
+ {
21944
+ internalType: "address",
21945
+ name: "payer",
21946
+ type: "address"
21524
21947
  }
21525
21948
  ],
21526
21949
  internalType: "struct DispatchGet",
@@ -21789,6 +22212,11 @@ var ABI8 = [
21789
22212
  internalType: "bytes",
21790
22213
  name: "context",
21791
22214
  type: "bytes"
22215
+ },
22216
+ {
22217
+ internalType: "address",
22218
+ name: "payer",
22219
+ type: "address"
21792
22220
  }
21793
22221
  ],
21794
22222
  internalType: "struct DispatchGet",
@@ -22151,6 +22579,6 @@ async function teleportDot(param_) {
22151
22579
  return stream;
22152
22580
  }
22153
22581
 
22154
- export { ADDRESS_ZERO2 as ADDRESS_ZERO, BundlerMethod, ChainConfigService, Chains, CryptoUtils, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DOMAIN_TYPEHASH, DUMMY_PRIVATE_KEY, ERC20Method, ERC7821_BATCH_MODE, EvmChain, ABI as EvmHostABI, EvmLanguage, HyperClientStatus, HyperFungibleToken, HyperFungibleTokenABI, IntentGateway, ABI3 as IntentGatewayABI, IntentOrderStatus, IntentsCoprocessor, IsmpClient, MOCK_ADDRESS, ORDER_V2_PARAM_TYPE, OrderStatus, OrderStatusChecker, PACKED_USEROP_TYPEHASH, PLACE_ORDER_SELECTOR, PharosChain, PolkadotHubChain, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, SELECT_SOLVER_TYPEHASH, STATE_COMMITMENTS_SLOT, SubstrateChain, Swap, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, TokenGateway, TronChain, USE_ETHERSCAN_CHAINS, UnsupportedIntentQuotePairError, UnsupportedIntentQuoteStrategyError, WrappedHyperFungibleTokenABI, __test, adjustDecimals, bytes20ToBytes32, bytes32ToBytes20, calculateAllowanceMappingLocation, calculateBalanceMappingLocation, chainConfigs, constructRedeemEscrowRequestBody, constructRefundEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createEvmChain, createQueryClient, decodeUserOpScale, encodeERC7821ExecuteBatch, encodeISMPMessage, encodeStateMachineId, encodeUserOpScale, encodeWithdrawalRequest, estimateGasForPost, fetchPrice, fetchSourceProof, generateRootWithProof, getChainId, getConfigByStateMachineId, getContractCallInput, getContractCallInputs, getGasPriceFromEtherscan, getOrFetchStorageSlot, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, getViemChain, hexToString, hyperbridgeAddress, maxBigInt, normalizeAddressForEvmBytes32, normalizeAddressForStateMachine, normalizeEvmChainId, normalizeStateMachineId, orderCommitment, parseStateMachineId, pharosAtlantic, pharosMainnet, polkadotAssetHubPaseo, polkadotHubMainnet, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, quoteUniswap, requestCommitmentKey, responseCommitmentKey, retryPromise, teleport, teleportDot, transformOrderForContract, tronChainIds, tronNile };
22582
+ export { ADDRESS_ZERO2 as ADDRESS_ZERO, BundlerMethod, ChainConfigService, Chains, CryptoUtils, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DOMAIN_TYPEHASH, DUMMY_PRIVATE_KEY, ERC20Method, ERC7821_BATCH_MODE, EvmChain, ABI as EvmHostABI, EvmLanguage, HyperClientStatus, HyperFungibleToken, HyperFungibleTokenABI, IntentGateway, ABI3 as IntentGatewayABI, IntentOrderStatus, IntentsCoprocessor, IsmpClient, MOCK_ADDRESS, ORDER_V2_PARAM_TYPE, OrderStatus, OrderStatusChecker, PACKED_USEROP_TYPEHASH, PLACE_ORDER_SELECTOR, PharosChain, PolkadotHubChain, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, SELECT_SOLVER_TYPEHASH, STATE_COMMITMENTS_SLOT, SubstrateChain, Swap, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, TokenGateway, TronChain, USE_ETHERSCAN_CHAINS, UnsupportedIntentQuotePairError, UnsupportedIntentQuoteStrategyError, WrappedHyperFungibleTokenABI, __test, adjustDecimals, bytes20ToBytes32, bytes32ToBytes20, calculateAllowanceMappingLocation, calculateBalanceMappingLocation, chainConfigs, constructRedeemEscrowRequestBody, constructRefundEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createEvmChain, createQueryClient, decodeERC7821ExecuteBatch, decodeUserOpScale, encodeERC7821ExecuteBatch, encodeISMPMessage, encodeStateMachineId, encodeUserOpScale, encodeWithdrawalRequest, estimateGasForPost, fetchPrice, fetchSourceProof, generateRootWithProof, getChainId, getConfigByStateMachineId, getContractCallInput, getContractCallInputs, getGasPriceFromEtherscan, getOrFetchStorageSlot, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, getViemChain, hexToString, hyperbridgeAddress, maxBigInt, normalizeAddressForEvmBytes32, normalizeAddressForStateMachine, normalizeEvmChainId, normalizeStateMachineId, orderCommitment, parseStateMachineId, pharosAtlantic, pharosMainnet, polkadotAssetHubPaseo, polkadotHubMainnet, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, quoteUniswap, requestCommitmentKey, responseCommitmentKey, retryPromise, teleport, teleportDot, transformOrderForContract, tronChainIds, tronNile };
22155
22583
  //# sourceMappingURL=index.js.map
22156
22584
  //# sourceMappingURL=index.js.map