@hyperbridge/sdk 2.3.0 → 2.3.2

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.
@@ -2100,7 +2100,7 @@ var ABI2 = [
2100
2100
  { internalType: "bytes", name: "source", type: "bytes" },
2101
2101
  { internalType: "bytes", name: "dest", type: "bytes" },
2102
2102
  { internalType: "uint64", name: "nonce", type: "uint64" },
2103
- { internalType: "address", name: "from", type: "address" },
2103
+ { internalType: "bytes", name: "from", type: "bytes" },
2104
2104
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2105
2105
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2106
2106
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -2167,7 +2167,7 @@ var ABI2 = [
2167
2167
  { internalType: "bytes", name: "source", type: "bytes" },
2168
2168
  { internalType: "bytes", name: "dest", type: "bytes" },
2169
2169
  { internalType: "uint64", name: "nonce", type: "uint64" },
2170
- { internalType: "address", name: "from", type: "address" },
2170
+ { internalType: "bytes", name: "from", type: "bytes" },
2171
2171
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2172
2172
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2173
2173
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -6392,28 +6392,60 @@ var EvmChain = class _EvmChain {
6392
6392
  }
6393
6393
  /**
6394
6394
  * Query and return the encoded storage proof for the provided keys at the given height.
6395
+ *
6396
+ * Keys may be either:
6397
+ * - 32-byte storage slots — read from `address` (or the host contract when omitted), or
6398
+ * - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
6399
+ * contract is embedded in the key. These may span multiple contracts.
6400
+ *
6395
6401
  * @param {bigint} at - The block height at which to query the storage proof.
6396
6402
  * @param {HexString[]} keys - The keys for which to query the storage proof.
6397
- * @param {HexString} address - Optional contract address to fetch storage proof else default to host contract
6403
+ * @param {HexString} address - Optional contract address; forces all keys to be read as slots
6404
+ * of this contract. Omit to let 52-byte keys carry their own contract address.
6398
6405
  * @returns {Promise<HexString>} The encoded storage proof.
6399
6406
  */
6400
6407
  async queryStateProof(at, keys, address) {
6401
- const config = {
6402
- address: address ?? this.params.host,
6403
- storageKeys: keys
6404
- };
6405
- if (!at) {
6406
- config.blockTag = "latest";
6407
- } else {
6408
- config.blockNumber = at;
6409
- }
6410
- const proof = await this.publicClient.getProof(config);
6411
- const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
6408
+ const slotsByContract = /* @__PURE__ */ new Map();
6409
+ for (const key of keys) {
6410
+ let contract;
6411
+ let slot;
6412
+ if (address) {
6413
+ contract = address.toLowerCase();
6414
+ slot = key;
6415
+ } else if ((key.length - 2) / 2 === 52) {
6416
+ contract = key.slice(0, 42).toLowerCase();
6417
+ slot = `0x${key.slice(42)}`;
6418
+ } else {
6419
+ contract = this.params.host.toLowerCase();
6420
+ slot = key;
6421
+ }
6422
+ const slots = slotsByContract.get(contract) ?? [];
6423
+ slots.push(slot);
6424
+ slotsByContract.set(contract, slots);
6425
+ }
6426
+ const contracts = Array.from(slotsByContract.entries());
6427
+ const proofs = await Promise.all(
6428
+ contracts.map(([contract, slots]) => {
6429
+ const config = { address: contract, storageKeys: slots };
6430
+ if (!at) {
6431
+ config.blockTag = "latest";
6432
+ } else {
6433
+ config.blockNumber = at;
6434
+ }
6435
+ return this.publicClient.getProof(config);
6436
+ })
6437
+ );
6438
+ const contractProof = Array.from(new Set(flatten(proofs.map((proof) => proof.accountProof))));
6439
+ const storageProof = contracts.map(([contract], i) => {
6440
+ const flattened = Array.from(new Set(flatten(proofs[i].storageProof.map((item) => item.proof))));
6441
+ return [
6442
+ Array.from(hexToBytes(contract)),
6443
+ flattened.map((item) => Array.from(hexToBytes(item)))
6444
+ ];
6445
+ });
6412
6446
  const encoded = EvmStateProof.enc({
6413
- contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
6414
- storageProof: [
6415
- [Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
6416
- ]
6447
+ contractProof: contractProof.map((item) => Array.from(hexToBytes(item))),
6448
+ storageProof
6417
6449
  });
6418
6450
  return toHex(encoded);
6419
6451
  }
@@ -6743,15 +6775,20 @@ var EvmChain = class _EvmChain {
6743
6775
  async quoteNative(request, fee) {
6744
6776
  const totalFee = await this.quote(request) + fee;
6745
6777
  const feeToken = await this.getFeeTokenWithDecimals();
6746
- return this.getAmountsIn(totalFee, feeToken.address, request.source);
6778
+ const hostRouter = await this.publicClient.readContract({
6779
+ address: this.params.host,
6780
+ abi: evmHost_default.ABI,
6781
+ functionName: "uniswapV2Router"
6782
+ });
6783
+ return this.getAmountsIn(totalFee, feeToken.address, request.source, hostRouter);
6747
6784
  }
6748
6785
  /**
6749
6786
  * Given a desired output amount of a token, returns how much native is needed as input.
6750
- * Uses the chain's Uniswap V2 router: WETH → tokenOut path.
6787
+ * Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
6751
6788
  */
6752
- async getAmountsIn(amountOut, tokenOutForQuote, chain) {
6789
+ async getAmountsIn(amountOut, tokenOutForQuote, chain, router) {
6753
6790
  const chainId = chain ?? `EVM-${this.params.chainId}`;
6754
- const v2Router = this.configService.getUniswapRouterV2Address(chainId);
6791
+ const v2Router = router ?? this.configService.getUniswapRouterV2Address(chainId);
6755
6792
  const WETH = this.configService.getWrappedNativeAssetWithDecimals(chainId).asset;
6756
6793
  const v2AmountIn = await this.publicClient.simulateContract({
6757
6794
  address: v2Router,
@@ -7135,6 +7172,49 @@ var SubstrateChain = class _SubstrateChain {
7135
7172
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7136
7173
  return item;
7137
7174
  }
7175
+ /**
7176
+ * Returns the storage key for a response receipt in the child trie.
7177
+ * A response receipt is keyed by the originating *request* commitment.
7178
+ * @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
7179
+ * @returns {HexString} The storage key as a hex string
7180
+ */
7181
+ responseReceiptKey(key) {
7182
+ const prefix = new TextEncoder().encode("ResponseReceipts");
7183
+ const keyBytes = hexToBytes(key);
7184
+ return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
7185
+ }
7186
+ /**
7187
+ * Queries the response receipt for a request commitment. For a GET, Hyperbridge
7188
+ * produces the response as it processes the request, so the presence of a response
7189
+ * receipt indicates the request has already been delivered and handled.
7190
+ * @param {HexString} commitment - The originating request commitment to query.
7191
+ * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7192
+ */
7193
+ async queryResponseReceipt(commitment) {
7194
+ const prefix = toHex(":child_storage:default:ISMP");
7195
+ const key = this.responseReceiptKey(commitment);
7196
+ const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7197
+ return item;
7198
+ }
7199
+ /**
7200
+ * Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
7201
+ * exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
7202
+ * proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
7203
+ * has not finalized that chain at exactly that height.
7204
+ * @param {StateMachineHeight} height - The counterparty state machine id + height.
7205
+ * @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
7206
+ */
7207
+ async queryStateMachineCommitment(height) {
7208
+ if (!this.api) throw new Error("API not initialized");
7209
+ const id = {
7210
+ stateId: height.id.stateId,
7211
+ // on-chain StateMachineId encodes consensusStateId as [u8; 4]
7212
+ consensusStateId: toHex(toBytes(height.id.consensusStateId))
7213
+ };
7214
+ const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
7215
+ if (commitment.isNone) return void 0;
7216
+ return commitment.toJSON()?.stateRoot;
7217
+ }
7138
7218
  /**
7139
7219
  * Returns the current timestamp of the chain.
7140
7220
  * @returns {Promise<bigint>} The current timestamp.
@@ -7762,6 +7842,23 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7762
7842
  } else if (result.status.isInBlock || result.status.isFinalized) {
7763
7843
  resolved = true;
7764
7844
  clearTimeout(timeoutId);
7845
+ const interrupted = result.events.find(
7846
+ ({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
7847
+ );
7848
+ if (interrupted) {
7849
+ const [indexCodec, dispatchError] = interrupted.event.data;
7850
+ if (Number(indexCodec.toString()) === 0) {
7851
+ let errorMsg;
7852
+ if (dispatchError?.isModule) {
7853
+ const decoded = this.api.registry.findMetaError(dispatchError.asModule);
7854
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7855
+ } else {
7856
+ errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
7857
+ }
7858
+ resolve({ success: false, error: errorMsg });
7859
+ return;
7860
+ }
7861
+ }
7765
7862
  resolve({
7766
7863
  success: true,
7767
7864
  blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
@@ -7821,10 +7918,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7821
7918
  }
7822
7919
  }
7823
7920
  /**
7824
- * Retracts a previous bid and places a new one in a single transaction via utility.batch.
7825
- * The retraction runs first, so the old deposit is reclaimed even if the new bid then fails
7826
- * (batch is non-atomic a failing call interrupts the batch without reverting the calls that
7827
- * already succeeded, unlike batchAll which would roll the retraction back too).
7921
+ * Places a new bid and retracts a previous one in a single transaction via utility.batch.
7922
+ *
7923
+ * The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
7924
+ * non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
7925
+ * reverting the calls that already succeeded. Placing first guarantees the new bid lands even
7926
+ * when the retraction then fails — which it routinely does, because a previous commitment's bid
7927
+ * may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
7928
+ *
7929
+ * Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
7930
+ * `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
7931
+ * landed, so the *next* interval's retract of that never-placed commitment also failed, and so
7932
+ * on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
7933
+ * best-effort; landing the bid is not.
7828
7934
  *
7829
7935
  * @param retractCommitment - The order commitment of the bid to retract (bytes32)
7830
7936
  * @param bidCommitment - The order commitment of the new bid (bytes32)
@@ -7834,8 +7940,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7834
7940
  async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
7835
7941
  try {
7836
7942
  const batch = this.api.tx.utility.batch([
7837
- this.api.tx.intentsCoprocessor.retractBid(retractCommitment),
7838
- this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp)
7943
+ this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
7944
+ this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
7839
7945
  ]);
7840
7946
  return await this.signAndSendExtrinsic(batch);
7841
7947
  } catch (error) {
@@ -9941,6 +10047,7 @@ var GetRequestClient = class {
9941
10047
  const latestMetadata = request.statuses[request.statuses.length - 1];
9942
10048
  status = maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
9943
10049
  if (!status) return;
10050
+ let sourceFinalizedHeight;
9944
10051
  while (true) {
9945
10052
  switch (status) {
9946
10053
  case RequestStatus.SOURCE: {
@@ -9952,6 +10059,7 @@ var GetRequestClient = class {
9952
10059
  chain: this.ctx.config.hyperbridge.config.stateMachineId
9953
10060
  })
9954
10061
  });
10062
+ sourceFinalizedHeight = BigInt(sourceUpdate.height);
9955
10063
  yield {
9956
10064
  status: RequestStatus.SOURCE_FINALIZED,
9957
10065
  metadata: {
@@ -9965,6 +10073,15 @@ var GetRequestClient = class {
9965
10073
  break;
9966
10074
  }
9967
10075
  case RequestStatus.SOURCE_FINALIZED: {
10076
+ if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
10077
+ try {
10078
+ await this.deliverToHyperbridge(request, sourceFinalizedHeight);
10079
+ } catch (error) {
10080
+ this.logger.warn(
10081
+ `Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
10082
+ );
10083
+ }
10084
+ }
9968
10085
  request = await waitOrAbort(this.ctx, {
9969
10086
  signal,
9970
10087
  promise: () => this.queries.queryGetRequest(hash),
@@ -9985,7 +10102,10 @@ var GetRequestClient = class {
9985
10102
  }
9986
10103
  case RequestStatus.HYPERBRIDGE_DELIVERED: {
9987
10104
  if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
9988
- const response = await this.queries.queryResponseByRequestId(hash);
10105
+ const response = await waitOrAbort(this.ctx, {
10106
+ signal,
10107
+ promise: () => this.queries.queryResponseByRequestId(hash)
10108
+ });
9989
10109
  yield await this.streamFinalized(signal, request, 1, response);
9990
10110
  status = RequestStatus.HYPERBRIDGE_FINALIZED;
9991
10111
  break;
@@ -10015,6 +10135,102 @@ var GetRequestClient = class {
10015
10135
  }
10016
10136
  }
10017
10137
  }
10138
+ /**
10139
+ * Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
10140
+ * otherwise require an external relayer.
10141
+ *
10142
+ * Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
10143
+ * the source chain at the Hyperbridge-finalized source height, prove the requested keys on
10144
+ * the destination chain at the request's height, wait out the source challenge period, then
10145
+ * submit an unsigned `GetRequest` message. Source and destination may each be EVM or
10146
+ * substrate — proofs are built via the chain-agnostic {@link IChain} methods.
10147
+ *
10148
+ * Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
10149
+ * wraps this best-effort, so a failure leaves the stream observing as before.
10150
+ */
10151
+ async deliverToHyperbridge(request, sourceFinalizedHeight) {
10152
+ const sourceChain = this.ctx.config.source;
10153
+ const destChain = this.ctx.config.dest;
10154
+ const hyperbridge = this.ctx.config.hyperbridge;
10155
+ const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
10156
+ const retry = { maxRetries: 5, backoffMs: 2e3 };
10157
+ if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
10158
+ this.logger.info(
10159
+ `Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
10160
+ );
10161
+ const sourceProof = {
10162
+ height: sourceFinalizedHeight,
10163
+ stateMachine: request.source,
10164
+ consensusStateId: sourceChain.config.consensusStateId,
10165
+ proof: await withRetry(
10166
+ this.ctx,
10167
+ () => sourceChain.queryProof(
10168
+ { Requests: [commitment] },
10169
+ this.ctx.config.hyperbridge.config.stateMachineId,
10170
+ sourceFinalizedHeight
10171
+ ),
10172
+ retry
10173
+ )
10174
+ };
10175
+ this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
10176
+ const destCommitment = await withRetry(
10177
+ this.ctx,
10178
+ () => hyperbridge.queryStateMachineCommitment({
10179
+ id: {
10180
+ stateId: parseStateMachineId(request.dest).stateId,
10181
+ consensusStateId: destChain.config.consensusStateId
10182
+ },
10183
+ height: request.height
10184
+ }),
10185
+ retry
10186
+ );
10187
+ if (!destCommitment) {
10188
+ throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
10189
+ }
10190
+ const responseProof = {
10191
+ height: request.height,
10192
+ stateMachine: request.dest,
10193
+ consensusStateId: destChain.config.consensusStateId,
10194
+ proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
10195
+ };
10196
+ this.logger.info(
10197
+ ` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
10198
+ );
10199
+ await withRetry(
10200
+ this.ctx,
10201
+ () => waitForChallengePeriod(hyperbridge, {
10202
+ height: sourceFinalizedHeight,
10203
+ id: {
10204
+ stateId: parseStateMachineId(request.source).stateId,
10205
+ consensusStateId: sourceChain.config.consensusStateId
10206
+ }
10207
+ }),
10208
+ retry
10209
+ );
10210
+ const message = {
10211
+ kind: "GetRequest",
10212
+ requests: [
10213
+ {
10214
+ source: request.source,
10215
+ dest: request.dest,
10216
+ nonce: request.nonce,
10217
+ from: request.from,
10218
+ timeoutTimestamp: request.timeoutTimestamp,
10219
+ keys: [...request.keys],
10220
+ height: request.height,
10221
+ context: request.context
10222
+ }
10223
+ ],
10224
+ source: sourceProof,
10225
+ response: responseProof,
10226
+ signer: pad("0x")
10227
+ };
10228
+ this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
10229
+ const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
10230
+ this.logger.info(
10231
+ ` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
10232
+ );
10233
+ }
10018
10234
  /**
10019
10235
  * Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
10020
10236
  * calldata if prerequisites are met, or `undefined` if we're still waiting
@@ -10028,7 +10244,7 @@ var GetRequestClient = class {
10028
10244
  const finality = await this.queries.queryStateMachineUpdateByHeight({
10029
10245
  statemachineId: config.stateMachineId,
10030
10246
  height: hyperbridgeDelivered.metadata.blockNumber,
10031
- chain: config.stateMachineId
10247
+ chain: request.source
10032
10248
  });
10033
10249
  if (finality) {
10034
10250
  const proof = await hyperbridge.queryProof(
@@ -10099,14 +10315,19 @@ var GetRequestClient = class {
10099
10315
  ],
10100
10316
  signer: pad("0x")
10101
10317
  });
10318
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
10319
+ statemachineId: config.stateMachineId,
10320
+ height: hyperbridgeDelivered.metadata.blockNumber,
10321
+ chain: config.stateMachineId
10322
+ });
10323
+ if (!hyperbridgeFinality) return void 0;
10102
10324
  return {
10103
10325
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10104
10326
  metadata: {
10105
- blockHash: hyperbridgeDelivered.metadata.blockHash,
10106
- blockNumber: Number(consensusResult.provenHeight),
10107
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10108
- // @ts-ignore
10109
- timestamp: hyperbridgeDelivered.metadata.timestamp,
10327
+ blockHash: hyperbridgeFinality.blockHash,
10328
+ blockNumber: hyperbridgeFinality.height,
10329
+ transactionHash: hyperbridgeFinality.transactionHash,
10330
+ timestamp: hyperbridgeFinality.timestamp,
10110
10331
  calldata
10111
10332
  }
10112
10333
  };
@@ -10126,12 +10347,44 @@ var GetRequestClient = class {
10126
10347
  const hyperbridge = this.ctx.config.hyperbridge;
10127
10348
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10128
10349
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10350
+ const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
10351
+ const encodeGetResponse = (height, proof2) => sourceChain.encode({
10352
+ kind: "GetResponse",
10353
+ proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
10354
+ responses: [
10355
+ {
10356
+ get: request,
10357
+ values: request.keys.map((key, index) => ({
10358
+ key,
10359
+ value: response?.values[index] || "0x"
10360
+ }))
10361
+ }
10362
+ ],
10363
+ signer: pad("0x")
10364
+ });
10129
10365
  let finality = await this.queries.queryStateMachineUpdateByHeight({
10130
10366
  statemachineId: stateMachineId,
10131
10367
  height: Number(neededHeight),
10132
- chain: stateMachineId
10368
+ chain: request.source
10133
10369
  });
10134
- if (!finality && sourceChain instanceof EvmChain) {
10370
+ if (finality) {
10371
+ const proof2 = await hyperbridge.queryProof(
10372
+ { Responses: [response?.commitment] },
10373
+ request.source,
10374
+ BigInt(finality.height)
10375
+ );
10376
+ return {
10377
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10378
+ metadata: {
10379
+ blockHash: finality.blockHash,
10380
+ blockNumber: finality.height,
10381
+ transactionHash: finality.transactionHash,
10382
+ timestamp: finality.timestamp,
10383
+ calldata: encodeGetResponse(BigInt(finality.height), proof2)
10384
+ }
10385
+ };
10386
+ }
10387
+ if (sourceChain instanceof EvmChain) {
10135
10388
  const hyperbridgeSubstrate = hyperbridge;
10136
10389
  const currentEpoch = await sourceChain.currentEpoch();
10137
10390
  const consensusResult = await waitOrAbort(this.ctx, {
@@ -10143,12 +10396,12 @@ var GetRequestClient = class {
10143
10396
  request.source,
10144
10397
  consensusResult.provenHeight
10145
10398
  );
10146
- const calldata2 = sourceChain.encode({
10399
+ const calldata = sourceChain.encode({
10147
10400
  kind: "BatchConsensusAndGetResponse",
10148
10401
  consensusProofs: consensusResult.proofs,
10149
10402
  proof: {
10150
10403
  stateMachine: stateMachineId,
10151
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10404
+ consensusStateId,
10152
10405
  proof: proof2,
10153
10406
  height: consensusResult.provenHeight
10154
10407
  },
@@ -10163,20 +10416,7 @@ var GetRequestClient = class {
10163
10416
  ],
10164
10417
  signer: pad("0x")
10165
10418
  });
10166
- return {
10167
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
10168
- metadata: {
10169
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10170
- blockNumber: Number(consensusResult.provenHeight),
10171
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10172
- // @ts-ignore
10173
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
10174
- calldata: calldata2
10175
- }
10176
- };
10177
- }
10178
- if (!finality) {
10179
- finality = await waitOrAbort(this.ctx, {
10419
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
10180
10420
  signal,
10181
10421
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10182
10422
  statemachineId: stateMachineId,
@@ -10184,31 +10424,30 @@ var GetRequestClient = class {
10184
10424
  chain: stateMachineId
10185
10425
  })
10186
10426
  });
10427
+ return {
10428
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10429
+ metadata: {
10430
+ blockHash: hyperbridgeFinality.blockHash,
10431
+ blockNumber: hyperbridgeFinality.height,
10432
+ transactionHash: hyperbridgeFinality.transactionHash,
10433
+ timestamp: hyperbridgeFinality.timestamp,
10434
+ calldata
10435
+ }
10436
+ };
10187
10437
  }
10438
+ finality = await waitOrAbort(this.ctx, {
10439
+ signal,
10440
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10441
+ statemachineId: stateMachineId,
10442
+ height: Number(neededHeight),
10443
+ chain: request.source
10444
+ })
10445
+ });
10188
10446
  const proof = await hyperbridge.queryProof(
10189
10447
  { Responses: [response?.commitment] },
10190
10448
  request.source,
10191
10449
  BigInt(finality.height)
10192
10450
  );
10193
- const calldata = sourceChain.encode({
10194
- kind: "GetResponse",
10195
- proof: {
10196
- stateMachine: stateMachineId,
10197
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10198
- proof,
10199
- height: BigInt(finality.height)
10200
- },
10201
- responses: [
10202
- {
10203
- get: request,
10204
- values: request.keys.map((key, index) => ({
10205
- key,
10206
- value: response?.values[index] || "0x"
10207
- }))
10208
- }
10209
- ],
10210
- signer: pad("0x")
10211
- });
10212
10451
  return {
10213
10452
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10214
10453
  metadata: {
@@ -10216,7 +10455,7 @@ var GetRequestClient = class {
10216
10455
  blockNumber: finality.height,
10217
10456
  transactionHash: finality.transactionHash,
10218
10457
  timestamp: finality.timestamp,
10219
- calldata
10458
+ calldata: encodeGetResponse(BigInt(finality.height), proof)
10220
10459
  }
10221
10460
  };
10222
10461
  }
@@ -10719,7 +10958,7 @@ var PostRequestClient = class {
10719
10958
  const finality = await this.queries.queryStateMachineUpdateByHeight({
10720
10959
  statemachineId: config.stateMachineId,
10721
10960
  height: hyperbridgeDelivered.metadata.blockNumber,
10722
- chain: config.stateMachineId
10961
+ chain: request.dest
10723
10962
  });
10724
10963
  if (finality) {
10725
10964
  const proof = await hyperbridge.queryProof(
@@ -10774,14 +11013,19 @@ var PostRequestClient = class {
10774
11013
  requests: [request],
10775
11014
  signer: pad("0x")
10776
11015
  });
11016
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
11017
+ statemachineId: config.stateMachineId,
11018
+ height: hyperbridgeDelivered.metadata.blockNumber,
11019
+ chain: config.stateMachineId
11020
+ });
11021
+ if (!hyperbridgeFinality) return void 0;
10777
11022
  return {
10778
11023
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10779
11024
  metadata: {
10780
- blockHash: hyperbridgeDelivered.metadata.blockHash,
10781
- blockNumber: Number(consensusResult.provenHeight),
10782
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10783
- // @ts-ignore
10784
- timestamp: hyperbridgeDelivered.metadata.timestamp,
11025
+ blockHash: hyperbridgeFinality.blockHash,
11026
+ blockNumber: hyperbridgeFinality.height,
11027
+ transactionHash: hyperbridgeFinality.transactionHash,
11028
+ timestamp: hyperbridgeFinality.timestamp,
10785
11029
  calldata
10786
11030
  }
10787
11031
  };
@@ -10804,7 +11048,7 @@ var PostRequestClient = class {
10804
11048
  let finality = await this.queries.queryStateMachineUpdateByHeight({
10805
11049
  statemachineId: stateMachineId,
10806
11050
  height: Number(neededHeight),
10807
- chain: stateMachineId
11051
+ chain: request.dest
10808
11052
  });
10809
11053
  if (!finality && destChain instanceof EvmChain) {
10810
11054
  const hyperbridgeSubstrate = hyperbridge;
@@ -10832,14 +11076,21 @@ var PostRequestClient = class {
10832
11076
  requests: [request],
10833
11077
  signer: pad("0x")
10834
11078
  });
11079
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
11080
+ signal,
11081
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
11082
+ statemachineId: stateMachineId,
11083
+ height: Number(neededHeight),
11084
+ chain: stateMachineId
11085
+ })
11086
+ });
10835
11087
  return {
10836
11088
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10837
11089
  metadata: {
10838
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10839
- blockNumber: Number(consensusResult.provenHeight),
10840
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10841
- // @ts-ignore
10842
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
11090
+ blockHash: hyperbridgeFinality.blockHash,
11091
+ blockNumber: hyperbridgeFinality.height,
11092
+ transactionHash: hyperbridgeFinality.transactionHash,
11093
+ timestamp: hyperbridgeFinality.timestamp,
10843
11094
  calldata: calldata2
10844
11095
  }
10845
11096
  };
@@ -10850,7 +11101,7 @@ var PostRequestClient = class {
10850
11101
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10851
11102
  statemachineId: stateMachineId,
10852
11103
  height: Number(neededHeight),
10853
- chain: stateMachineId
11104
+ chain: request.dest
10854
11105
  })
10855
11106
  });
10856
11107
  }
@@ -16742,9 +16993,9 @@ var GasEstimator = class {
16742
16993
  from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
16743
16994
  to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
16744
16995
  };
16996
+ postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
16745
16997
  let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
16746
16998
  protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
16747
- postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
16748
16999
  return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
16749
17000
  }
16750
17001
  /**