@hyperbridge/sdk 2.3.2 → 2.3.3

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.
@@ -7044,6 +7044,11 @@ var ExpectedError = class _ExpectedError extends Error {
7044
7044
  return error instanceof _ExpectedError;
7045
7045
  }
7046
7046
  };
7047
+
7048
+ // src/configs/constants.ts
7049
+ var ISMP_PREFIX = ":child_storage:default:ISMPv2";
7050
+
7051
+ // src/chains/substrate.ts
7047
7052
  var HttpRpcClient = class {
7048
7053
  constructor(url) {
7049
7054
  this.url = url;
@@ -7167,7 +7172,7 @@ var SubstrateChain = class _SubstrateChain {
7167
7172
  * @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise.
7168
7173
  */
7169
7174
  async queryRequestCommitment(commitment) {
7170
- const prefix = viem.toHex(":child_storage:default:ISMP");
7175
+ const prefix = viem.toHex(ISMP_PREFIX);
7171
7176
  const key = this.requestCommitmentKey(commitment);
7172
7177
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7173
7178
  return item;
@@ -7178,7 +7183,7 @@ var SubstrateChain = class _SubstrateChain {
7178
7183
  * @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
7179
7184
  */
7180
7185
  async queryRequestReceipt(commitment) {
7181
- const prefix = viem.toHex(":child_storage:default:ISMP");
7186
+ const prefix = viem.toHex(ISMP_PREFIX);
7182
7187
  const key = this.requestReceiptKey(commitment);
7183
7188
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7184
7189
  return item;
@@ -7202,7 +7207,7 @@ var SubstrateChain = class _SubstrateChain {
7202
7207
  * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7203
7208
  */
7204
7209
  async queryResponseReceipt(commitment) {
7205
- const prefix = viem.toHex(":child_storage:default:ISMP");
7210
+ const prefix = viem.toHex(ISMP_PREFIX);
7206
7211
  const key = this.responseReceiptKey(commitment);
7207
7212
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7208
7213
  return item;
@@ -15310,7 +15315,11 @@ var OrderExecutor = class {
15310
15315
  */
15311
15316
  async fetchBids(params) {
15312
15317
  const { commitment, solver, solverLockStartTime } = params;
15313
- const fetchedBids = await this.ctx.intentsCoprocessor.getBidsForOrder(commitment);
15318
+ const intentsCoprocessor = this.ctx.intentsCoprocessor;
15319
+ if (!intentsCoprocessor) {
15320
+ throw new Error("IntentsCoprocessor required for order execution");
15321
+ }
15322
+ const fetchedBids = await intentsCoprocessor.getBidsForOrder(commitment);
15314
15323
  if (solver) {
15315
15324
  const { address, timeoutMs } = solver;
15316
15325
  const solverLockActive = Date.now() - solverLockStartTime < timeoutMs;
@@ -15399,7 +15408,7 @@ var OrderExecutor = class {
15399
15408
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
15400
15409
  *
15401
15410
  * **Cross-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
15402
- * (terminates — settlement is confirmed async via Hyperbridge)
15411
+ * `FILLED`
15403
15412
  */
15404
15413
  async *executeOrder(options) {
15405
15414
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
@@ -15538,7 +15547,13 @@ var OrderExecutor = class {
15538
15547
  userOp: result.userOp,
15539
15548
  transactionHash: result.txnHash
15540
15549
  };
15541
- const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15550
+ const fill = this.processFillResult(
15551
+ result,
15552
+ commitment,
15553
+ targetAssets,
15554
+ totalFilledAssets,
15555
+ remainingAssets
15556
+ );
15542
15557
  totalFilledAssets = fill.totalFilledAssets;
15543
15558
  remainingAssets = fill.remainingAssets;
15544
15559
  if (fill.update) {
@@ -15564,6 +15579,10 @@ var OrderCanceller = class {
15564
15579
  this.ctx = ctx;
15565
15580
  }
15566
15581
  ctx;
15582
+ logger = consola.createConsola({
15583
+ level: consola.LogLevels.info,
15584
+ formatOptions: { columns: 80, colors: true, compact: true, date: false }
15585
+ }).withTag("[OrderCanceller]");
15567
15586
  /**
15568
15587
  * Returns both the native token cost and the relayer fee for cancelling an
15569
15588
  * order. Frontends can use `relayerFee` to approve the ERC-20 spend before
@@ -15979,32 +15998,55 @@ var OrderCanceller = class {
15979
15998
  }
15980
15999
  /**
15981
16000
  * Submits an unsigned GET request message to Hyperbridge and waits until
15982
- * the request receipt is confirmed on-chain.
16001
+ * the GET response receipt is confirmed on-chain.
15983
16002
  *
15984
- * If the initial submission fails, the method waits 30 seconds and then
15985
- * retries querying for the receipt up to 10 times with 5-second back-off.
16003
+ * GET handling on Hyperbridge creates a response receipt keyed by the
16004
+ * request commitment. That receipt is the durable delivery signal, so a
16005
+ * duplicate unsigned submission is considered successful only if the
16006
+ * response receipt can be observed.
15986
16007
  *
15987
16008
  * @param hyperbridge - Hyperbridge Substrate chain client.
15988
16009
  * @param commitment - The GET request commitment hash used to poll for the receipt.
15989
16010
  * @param message - The fully constructed GET request message to submit.
15990
16011
  */
15991
16012
  async submitAndConfirmReceipt(hyperbridge, commitment, message) {
15992
- let storageValue = await hyperbridge.queryRequestReceipt(commitment);
15993
- if (!storageValue) {
15994
- try {
15995
- await hyperbridge.submitUnsigned(message);
15996
- } catch {
15997
- }
16013
+ this.logger.info(`Checking GET response receipt before Hyperbridge delivery (${commitment})`);
16014
+ if (await this.queryDeliveredReceipt(hyperbridge, commitment)) {
16015
+ this.logger.info(`GET ${commitment} already delivered to Hyperbridge; skipping unsigned submission`);
16016
+ return;
16017
+ }
16018
+ try {
16019
+ this.logger.info(`Submitting unsigned GET ${commitment} to Hyperbridge`);
16020
+ await hyperbridge.submitUnsigned(message);
16021
+ this.logger.info(`Unsigned GET ${commitment} submitted; waiting for Hyperbridge response receipt`);
15998
16022
  await sleep(3e4);
15999
- storageValue = await retryPromise(
16000
- async () => {
16001
- const value = await hyperbridge.queryRequestReceipt(commitment);
16002
- if (!value) throw new Error("Receipt not found");
16003
- return value;
16004
- },
16005
- { maxRetries: 10, backoffMs: 5e3, logMessage: "Checking for receipt" }
16023
+ } catch (error) {
16024
+ this.logger.warn(
16025
+ `Unsigned GET submit failed for ${commitment}; polling response receipt before failing: ${String(error)}`
16006
16026
  );
16007
16027
  }
16028
+ try {
16029
+ await this.pollDeliveredReceipt(hyperbridge, commitment);
16030
+ this.logger.info(`Confirmed Hyperbridge GET delivery for ${commitment}`);
16031
+ } catch (error) {
16032
+ const message2 = `Failed to deliver GET request to Hyperbridge; no response receipt found for ${commitment}: ${String(error)}`;
16033
+ this.logger.error(message2);
16034
+ throw new Error(message2);
16035
+ }
16036
+ }
16037
+ async queryDeliveredReceipt(hyperbridge, commitment) {
16038
+ return hyperbridge.queryResponseReceipt(commitment);
16039
+ }
16040
+ async pollDeliveredReceipt(hyperbridge, commitment) {
16041
+ this.logger.info(`Polling Hyperbridge GET response receipt for ${commitment}`);
16042
+ return retryPromise(
16043
+ async () => {
16044
+ const value = await this.queryDeliveredReceipt(hyperbridge, commitment);
16045
+ if (!value) throw new Error(`GET response receipt not found for ${commitment}`);
16046
+ return value;
16047
+ },
16048
+ { maxRetries: 10, backoffMs: 5e3, logMessage: `Checking GET response receipt ${commitment}` }
16049
+ );
16008
16050
  }
16009
16051
  /**
16010
16052
  * Estimates the relayer fee for delivering a POST from dest to source.
@@ -16075,7 +16117,7 @@ var BidImpl = class {
16075
16117
  const sessionKeyAddress = this.order.session;
16076
16118
  const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
16077
16119
  if (!sessionKeyData) {
16078
- throw new Error("SessionKey not found for commitment: " + commitment);
16120
+ throw new Error(`SessionKey not found for commitment: ${commitment}`);
16079
16121
  }
16080
16122
  const signature = await CryptoUtils.signSolverSelection(
16081
16123
  commitment,
@@ -16135,8 +16177,8 @@ var BidImpl = class {
16135
16177
  /**
16136
16178
  * Signs the `SelectSolver` message with the session key, appends it to the
16137
16179
  * solver's existing UserOp signature, and submits the UserOperation to the
16138
- * bundler. For same-chain orders, waits for the receipt and reads
16139
- * `OrderFilled` / `PartialFill` logs to determine fill status.
16180
+ * bundler. Waits for the receipt and reads `OrderFilled` / `PartialFill`
16181
+ * logs to determine fill status.
16140
16182
  *
16141
16183
  * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
16142
16184
  * the solver address, transaction hash, and fill status.
@@ -16176,33 +16218,31 @@ var BidImpl = class {
16176
16218
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
16177
16219
  );
16178
16220
  txnHash = receipt.receipt.transactionHash;
16179
- if (this.order.source === this.order.destination) {
16180
- try {
16181
- const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16182
- hash: txnHash,
16183
- confirmations: 1
16184
- });
16185
- const events = viem.parseEventLogs({
16186
- abi: ABI3,
16187
- logs: chainReceipt.logs,
16188
- eventName: ["OrderFilled", "PartialFill"]
16189
- });
16190
- const matched = events.find((e) => {
16191
- if (e.eventName === "OrderFilled")
16192
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16193
- if (e.eventName === "PartialFill")
16194
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16195
- return false;
16196
- });
16197
- if (matched?.eventName === "OrderFilled") {
16198
- fillStatus = "full";
16199
- } else if (matched?.eventName === "PartialFill") {
16200
- fillStatus = "partial";
16201
- filledAssets = matched.args.outputs ?? [];
16202
- }
16203
- } catch {
16204
- throw new Error("Failed to determine fill status from logs");
16221
+ try {
16222
+ const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16223
+ hash: txnHash,
16224
+ confirmations: 1
16225
+ });
16226
+ const events = viem.parseEventLogs({
16227
+ abi: ABI3,
16228
+ logs: chainReceipt.logs,
16229
+ eventName: ["OrderFilled", "PartialFill"]
16230
+ });
16231
+ const matched = events.find((e) => {
16232
+ if (e.eventName === "OrderFilled")
16233
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16234
+ if (e.eventName === "PartialFill")
16235
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16236
+ return false;
16237
+ });
16238
+ if (matched?.eventName === "OrderFilled") {
16239
+ fillStatus = "full";
16240
+ } else if (matched?.eventName === "PartialFill") {
16241
+ fillStatus = "partial";
16242
+ filledAssets = matched.args.outputs ?? [];
16205
16243
  }
16244
+ } catch {
16245
+ throw new Error("Failed to determine fill status from logs");
16206
16246
  }
16207
16247
  } catch (err) {
16208
16248
  throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);