@hyperbridge/sdk 1.8.8 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -556,7 +556,6 @@ var IntentOrderStatus = Object.freeze({
556
556
  AWAITING_BIDS: "AWAITING_BIDS",
557
557
  BIDS_RECEIVED: "BIDS_RECEIVED",
558
558
  BID_SELECTED: "BID_SELECTED",
559
- USEROP_SUBMITTED: "USEROP_SUBMITTED",
560
559
  FILLED: "FILLED",
561
560
  PARTIAL_FILL: "PARTIAL_FILL",
562
561
  EXPIRED: "EXPIRED",
@@ -5533,6 +5532,7 @@ var EvmChain = class _EvmChain {
5533
5532
  });
5534
5533
  this.chainConfigService = new ChainConfigService();
5535
5534
  }
5535
+ params;
5536
5536
  publicClient;
5537
5537
  chainConfigService;
5538
5538
  /**
@@ -6133,6 +6133,7 @@ var HttpRpcClient = class {
6133
6133
  constructor(url) {
6134
6134
  this.url = url;
6135
6135
  }
6136
+ url;
6136
6137
  /**
6137
6138
  * Make an RPC call over HTTP
6138
6139
  * @param method - The RPC method name
@@ -6170,6 +6171,7 @@ var SubstrateChain = class _SubstrateChain {
6170
6171
  const httpUrl = replaceWebsocketWithHttp(url);
6171
6172
  this.rpcClient = new HttpRpcClient(httpUrl);
6172
6173
  }
6174
+ params;
6173
6175
  /*
6174
6176
  * api: The Polkadot API instance for the Substrate chain.
6175
6177
  */
@@ -6687,6 +6689,9 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
6687
6689
  this.substratePrivateKey = substratePrivateKey;
6688
6690
  this.ownsConnection = ownsConnection;
6689
6691
  }
6692
+ api;
6693
+ substratePrivateKey;
6694
+ ownsConnection;
6690
6695
  /** Cached result of whether the node exposes intents_* RPC methods */
6691
6696
  hasIntentsRpc = null;
6692
6697
  /**
@@ -6964,6 +6969,7 @@ var TronChain = class _TronChain {
6964
6969
  this.evm = evm;
6965
6970
  this.tronWebInstance = new TronWeb({ fullHost: params.rpcUrl });
6966
6971
  }
6972
+ params;
6967
6973
  evm;
6968
6974
  tronWebInstance;
6969
6975
  /**
@@ -7504,6 +7510,7 @@ var SubstrateHttpRpc = class {
7504
7510
  constructor(url) {
7505
7511
  this.url = url;
7506
7512
  }
7513
+ url;
7507
7514
  async call(method, params = []) {
7508
7515
  const body = JSON.stringify({
7509
7516
  jsonrpc: "2.0",
@@ -7548,6 +7555,7 @@ var PolkadotHubChain = class _PolkadotHubChain {
7548
7555
  this.evm = evm;
7549
7556
  this.substrateRpc = new SubstrateHttpRpc(replaceWebsocketWithHttp(params.substrateRpcUrl));
7550
7557
  }
7558
+ params;
7551
7559
  evm;
7552
7560
  substrateRpc;
7553
7561
  static fromParams(params) {
@@ -12629,6 +12637,7 @@ var CryptoUtils = class {
12629
12637
  constructor(ctx) {
12630
12638
  this.ctx = ctx;
12631
12639
  }
12640
+ ctx;
12632
12641
  /**
12633
12642
  * Computes an EIP-712 domain separator for a given contract.
12634
12643
  *
@@ -15164,6 +15173,7 @@ var OrderPlacer = class {
15164
15173
  constructor(ctx) {
15165
15174
  this.ctx = ctx;
15166
15175
  }
15176
+ ctx;
15167
15177
  /**
15168
15178
  * Bidirectional async generator that orchestrates order placement.
15169
15179
  *
@@ -15241,67 +15251,40 @@ var OrderPlacer = class {
15241
15251
  return { order, receipt };
15242
15252
  }
15243
15253
  };
15244
-
15245
- // src/protocols/intents/OrderExecutor.ts
15246
15254
  var USED_USEROPS_STORAGE_KEY = (commitment) => `used-userops:${commitment.toLowerCase()}`;
15247
15255
  var OrderExecutor = class {
15248
- /**
15249
- * @param ctx - Shared IntentsV2 context providing the destination chain
15250
- * client, coprocessor, bundler URL, and storage adapters.
15251
- * @param bidManager - Handles bid validation, sorting, simulation, and
15252
- * UserOperation submission.
15253
- * @param crypto - Crypto utilities used to compute UserOperation hashes for
15254
- * deduplication.
15255
- */
15256
15256
  constructor(ctx, bidManager, crypto) {
15257
15257
  this.ctx = ctx;
15258
15258
  this.bidManager = bidManager;
15259
15259
  this.crypto = crypto;
15260
15260
  }
15261
+ ctx;
15262
+ bidManager;
15263
+ crypto;
15261
15264
  /**
15262
- * Async generator that executes an intent order by polling for bids and
15263
- * submitting UserOperations until the order is filled, partially exhausted,
15264
- * or an unrecoverable error occurs.
15265
- *
15266
- * **Status progression (cross-chain orders):**
15267
- * `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED` → `USEROP_SUBMITTED`
15268
- * then terminates (settlement is confirmed off-chain via Hyperbridge).
15269
- *
15270
- * **Status progression (same-chain orders):**
15271
- * `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED` → `USEROP_SUBMITTED`
15272
- * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
15273
- *
15274
- * **Error statuses:** `FAILED` (retryable error during bid selection/submission,
15275
- * triggers automatic retry) or `EXPIRED` (deadline reached or no new bids —
15276
- * terminal, no further retries).
15277
- *
15278
- * @param options - Execution parameters including the placed order, its
15279
- * session private key, bid collection settings, and poll interval.
15280
- * @yields {@link IntentOrderStatusUpdate} objects describing each stage.
15281
- * @throws Never throws directly; all errors are reported as `FAILED` yields.
15265
+ * Sleeps until the order's block deadline is reached, then yields EXPIRED.
15266
+ * Uses the chain's block time to calculate the sleep duration.
15282
15267
  */
15283
- async *executeIntentOrder(options) {
15284
- const {
15285
- order,
15286
- sessionPrivateKey,
15287
- minBids = 1,
15288
- bidTimeoutMs = 6e4,
15289
- pollIntervalMs = DEFAULT_POLL_INTERVAL,
15290
- solver
15291
- } = options;
15292
- const commitment = order.id;
15293
- const isSameChain = order.source === order.destination;
15294
- if (!this.ctx.intentsCoprocessor) {
15295
- yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
15296
- return;
15297
- }
15298
- if (!this.ctx.bundlerUrl) {
15299
- yield { status: "FAILED", error: "Bundler URL not configured" };
15300
- return;
15268
+ async *deadlineStream(deadline, commitment) {
15269
+ const client = this.ctx.dest.client;
15270
+ const blockTimeSeconds = client.chain?.blockTime ?? 2;
15271
+ while (true) {
15272
+ const currentBlock = await client.getBlockNumber();
15273
+ if (currentBlock >= deadline) break;
15274
+ const blocksRemaining = Number(deadline - currentBlock);
15275
+ const sleepMs = blocksRemaining * blockTimeSeconds * 1e3;
15276
+ await sleep(sleepMs);
15301
15277
  }
15278
+ yield {
15279
+ status: "EXPIRED",
15280
+ commitment,
15281
+ error: "Order deadline reached"
15282
+ };
15283
+ }
15284
+ /** Loads the persisted deduplication set of already-submitted UserOp hashes for a given order commitment. */
15285
+ async loadUsedUserOps(commitment) {
15302
15286
  const usedUserOps = /* @__PURE__ */ new Set();
15303
- const storageKey = USED_USEROPS_STORAGE_KEY(commitment);
15304
- const persisted = await this.ctx.usedUserOpsStorage.getItem(storageKey);
15287
+ const persisted = await this.ctx.usedUserOpsStorage.getItem(USED_USEROPS_STORAGE_KEY(commitment));
15305
15288
  if (persisted) {
15306
15289
  try {
15307
15290
  const parsed = JSON.parse(persisted);
@@ -15311,74 +15294,210 @@ var OrderExecutor = class {
15311
15294
  } catch {
15312
15295
  }
15313
15296
  }
15314
- const persistUsedUserOps = async () => {
15315
- await this.ctx.usedUserOpsStorage.setItem(storageKey, JSON.stringify([...usedUserOps]));
15316
- };
15297
+ return usedUserOps;
15298
+ }
15299
+ /** Persists the deduplication set of UserOp hashes to storage. */
15300
+ async persistUsedUserOps(commitment, usedUserOps) {
15301
+ await this.ctx.usedUserOpsStorage.setItem(
15302
+ USED_USEROPS_STORAGE_KEY(commitment),
15303
+ JSON.stringify([...usedUserOps])
15304
+ );
15305
+ }
15306
+ /**
15307
+ * Creates a closure that computes the deduplication hash key for a
15308
+ * UserOperation, pre-bound to the order's destination chain and entry point.
15309
+ */
15310
+ createUserOpHasher(order) {
15317
15311
  const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(hexToString(order.destination));
15318
15312
  const chainId = BigInt(
15319
15313
  this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15320
15314
  );
15321
- const userOpHashKey = (userOp) => this.crypto.computeUserOpHash(userOp, entryPointAddress, chainId);
15315
+ return (userOp) => this.crypto.computeUserOpHash(userOp, entryPointAddress, chainId);
15316
+ }
15317
+ /**
15318
+ * Fetches bids from the coprocessor for a given order commitment.
15319
+ * If a preferred solver is configured and the solver lock has not expired,
15320
+ * only bids from that solver are returned.
15321
+ */
15322
+ async fetchBids(params) {
15323
+ const { commitment, solver, solverLockStartTime } = params;
15324
+ const fetchedBids = await this.ctx.intentsCoprocessor.getBidsForOrder(commitment);
15325
+ if (solver) {
15326
+ const { address, timeoutMs } = solver;
15327
+ const solverLockActive = Date.now() - solverLockStartTime < timeoutMs;
15328
+ return solverLockActive ? fetchedBids.filter((bid) => bid.userOp.sender.toLowerCase() === address.toLowerCase()) : fetchedBids;
15329
+ }
15330
+ return fetchedBids;
15331
+ }
15332
+ /**
15333
+ * Selects the best bid from the provided candidates, submits the
15334
+ * UserOperation, and persists the dedup entry to prevent resubmission.
15335
+ */
15336
+ async submitBid(params) {
15337
+ const { order, freshBids, sessionPrivateKey, commitment, usedUserOps, userOpHashKey } = params;
15338
+ const result = await this.bidManager.selectBid(order, freshBids, sessionPrivateKey);
15339
+ usedUserOps.add(userOpHashKey(result.userOp));
15340
+ await this.persistUsedUserOps(commitment, usedUserOps);
15341
+ return result;
15342
+ }
15343
+ /**
15344
+ * Processes a fill result and returns updated fill accumulators,
15345
+ * the status update to yield (if any), and whether the order is
15346
+ * fully satisfied.
15347
+ */
15348
+ processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets) {
15349
+ if (result.fillStatus === "full") {
15350
+ totalFilledAssets = targetAssets.map((a) => ({ token: a.token, amount: a.amount }));
15351
+ remainingAssets = targetAssets.map((a) => ({ token: a.token, amount: 0n }));
15352
+ return {
15353
+ update: {
15354
+ status: "FILLED",
15355
+ commitment,
15356
+ userOpHash: result.userOpHash,
15357
+ selectedSolver: result.solverAddress,
15358
+ transactionHash: result.txnHash,
15359
+ totalFilledAssets,
15360
+ remainingAssets
15361
+ },
15362
+ done: true,
15363
+ totalFilledAssets,
15364
+ remainingAssets
15365
+ };
15366
+ }
15367
+ if (result.fillStatus === "partial") {
15368
+ const filledAssets = result.filledAssets ?? [];
15369
+ totalFilledAssets = totalFilledAssets.map((a) => {
15370
+ const filled = filledAssets.find((f) => f.token === a.token);
15371
+ return filled ? { token: a.token, amount: a.amount + filled.amount } : { ...a };
15372
+ });
15373
+ remainingAssets = targetAssets.map((target) => {
15374
+ const filled = totalFilledAssets.find((a) => a.token === target.token);
15375
+ const filledAmt = filled?.amount ?? 0n;
15376
+ return {
15377
+ token: target.token,
15378
+ amount: filledAmt >= target.amount ? 0n : target.amount - filledAmt
15379
+ };
15380
+ });
15381
+ const fullyFilled = remainingAssets.every((a) => a.amount === 0n);
15382
+ return {
15383
+ update: fullyFilled ? {
15384
+ status: "FILLED",
15385
+ commitment,
15386
+ userOpHash: result.userOpHash,
15387
+ selectedSolver: result.solverAddress,
15388
+ transactionHash: result.txnHash,
15389
+ totalFilledAssets,
15390
+ remainingAssets
15391
+ } : {
15392
+ status: "PARTIAL_FILL",
15393
+ commitment,
15394
+ userOpHash: result.userOpHash,
15395
+ selectedSolver: result.solverAddress,
15396
+ transactionHash: result.txnHash,
15397
+ filledAssets,
15398
+ totalFilledAssets,
15399
+ remainingAssets
15400
+ },
15401
+ done: fullyFilled,
15402
+ totalFilledAssets,
15403
+ remainingAssets
15404
+ };
15405
+ }
15406
+ return { update: null, done: false, totalFilledAssets, remainingAssets };
15407
+ }
15408
+ /**
15409
+ * Executes an intent order by racing bid polling against the order's
15410
+ * block deadline. Yields status updates at each lifecycle stage.
15411
+ *
15412
+ * **Same-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
15413
+ * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
15414
+ *
15415
+ * **Cross-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
15416
+ * (terminates — settlement is confirmed async via Hyperbridge)
15417
+ */
15418
+ async *executeOrder(options) {
15419
+ const { order, sessionPrivateKey, minBids = 1, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
15420
+ const commitment = order.id;
15421
+ const isSameChain = order.source === order.destination;
15422
+ if (!this.ctx.intentsCoprocessor) {
15423
+ yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
15424
+ return;
15425
+ }
15426
+ if (!this.ctx.bundlerUrl) {
15427
+ yield { status: "FAILED", error: "Bundler URL not configured" };
15428
+ return;
15429
+ }
15430
+ const usedUserOps = await this.loadUsedUserOps(commitment);
15431
+ const userOpHashKey = this.createUserOpHasher(order);
15322
15432
  const targetAssets = order.output.assets.map((a) => ({ token: a.token, amount: a.amount }));
15323
15433
  let totalFilledAssets = order.output.assets.map((a) => ({ token: a.token, amount: 0n }));
15324
15434
  let remainingAssets = order.output.assets.map((a) => ({ token: a.token, amount: a.amount }));
15435
+ const executionStream = this.executionStream({
15436
+ order,
15437
+ sessionPrivateKey,
15438
+ commitment,
15439
+ minBids,
15440
+ pollIntervalMs,
15441
+ solver,
15442
+ usedUserOps,
15443
+ userOpHashKey,
15444
+ targetAssets,
15445
+ totalFilledAssets,
15446
+ remainingAssets
15447
+ });
15448
+ const deadlineTimeout = this.deadlineStream(order.deadline, commitment);
15449
+ const combined = mergeRace(deadlineTimeout, executionStream);
15450
+ for await (const update of combined) {
15451
+ yield update;
15452
+ if (update.status === "EXPIRED" || update.status === "FILLED") return;
15453
+ if (update.status === "BID_SELECTED" && !isSameChain) return;
15454
+ }
15455
+ }
15456
+ /**
15457
+ * Core execution loop that polls for bids, submits UserOperations,
15458
+ * and tracks fill progress. Yields between each poll iteration so
15459
+ * that `mergeRace` can interleave the deadline stream.
15460
+ */
15461
+ async *executionStream(params) {
15462
+ const {
15463
+ order,
15464
+ sessionPrivateKey,
15465
+ commitment,
15466
+ minBids,
15467
+ pollIntervalMs,
15468
+ solver,
15469
+ usedUserOps,
15470
+ userOpHashKey,
15471
+ targetAssets
15472
+ } = params;
15473
+ let { totalFilledAssets, remainingAssets } = params;
15474
+ const solverLockStartTime = Date.now();
15475
+ yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15325
15476
  try {
15326
15477
  while (true) {
15327
- const currentBlock = await this.ctx.dest.client.getBlockNumber();
15328
- if (currentBlock >= order.deadline) {
15329
- const deadlineError = `Order deadline reached (block ${currentBlock} >= ${order.deadline})`;
15330
- yield {
15331
- status: "EXPIRED",
15332
- commitment,
15333
- totalFilledAssets,
15334
- remainingAssets,
15335
- error: deadlineError
15336
- };
15337
- return;
15338
- }
15339
- yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15340
- const startTime = Date.now();
15341
- let bids = [];
15342
- let solverLockExpired = false;
15343
- while (Date.now() - startTime < bidTimeoutMs) {
15344
- try {
15345
- const fetchedBids = await this.ctx.intentsCoprocessor.getBidsForOrder(commitment);
15346
- if (solver) {
15347
- const { address, timeoutMs } = solver;
15348
- const solverLockActive = Date.now() - startTime < timeoutMs;
15349
- if (!solverLockActive) solverLockExpired = true;
15350
- bids = solverLockActive ? fetchedBids.filter((bid) => bid.userOp.sender.toLowerCase() === address.toLowerCase()) : fetchedBids;
15351
- } else {
15352
- bids = fetchedBids;
15353
- }
15354
- if (bids.length >= minBids) {
15355
- break;
15356
- }
15357
- } catch {
15358
- }
15478
+ let freshBids;
15479
+ try {
15480
+ const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15481
+ freshBids = bids.filter((bid) => !usedUserOps.has(userOpHashKey(bid.userOp)));
15482
+ } catch {
15359
15483
  await sleep(pollIntervalMs);
15484
+ continue;
15360
15485
  }
15361
- const freshBids = bids.filter((bid) => {
15362
- const key = userOpHashKey(bid.userOp);
15363
- return !usedUserOps.has(key);
15364
- });
15365
- if (freshBids.length === 0) {
15366
- const solverClause = solver && !solverLockExpired ? ` for requested solver ${solver.address}` : "";
15367
- const isPartiallyFilled = totalFilledAssets.some((a) => a.amount > 0n);
15368
- const noBidsError = isPartiallyFilled ? `No new bids${solverClause} after partial fill` : `No new bids${solverClause} available within ${bidTimeoutMs}ms timeout`;
15369
- yield {
15370
- status: "EXPIRED",
15371
- commitment,
15372
- totalFilledAssets,
15373
- remainingAssets,
15374
- error: noBidsError
15375
- };
15376
- return;
15486
+ if (freshBids.length < minBids) {
15487
+ await sleep(pollIntervalMs);
15488
+ continue;
15377
15489
  }
15378
15490
  yield { status: "BIDS_RECEIVED", commitment, bidCount: freshBids.length, bids: freshBids };
15379
- let result;
15491
+ let submitResult;
15380
15492
  try {
15381
- result = await this.bidManager.selectBid(order, freshBids, sessionPrivateKey);
15493
+ submitResult = await this.submitBid({
15494
+ order,
15495
+ freshBids,
15496
+ sessionPrivateKey,
15497
+ commitment,
15498
+ usedUserOps,
15499
+ userOpHashKey
15500
+ });
15382
15501
  } catch (err) {
15383
15502
  yield {
15384
15503
  status: "FAILED",
@@ -15390,77 +15509,26 @@ var OrderExecutor = class {
15390
15509
  await sleep(pollIntervalMs);
15391
15510
  continue;
15392
15511
  }
15393
- const usedKey = userOpHashKey(result.userOp);
15394
- usedUserOps.add(usedKey);
15395
- await persistUsedUserOps();
15396
15512
  yield {
15397
15513
  status: "BID_SELECTED",
15398
15514
  commitment,
15399
- selectedSolver: result.solverAddress,
15400
- userOpHash: result.userOpHash,
15401
- userOp: result.userOp
15515
+ selectedSolver: submitResult.solverAddress,
15516
+ userOpHash: submitResult.userOpHash,
15517
+ userOp: submitResult.userOp,
15518
+ transactionHash: submitResult.txnHash
15402
15519
  };
15403
- yield {
15404
- status: "USEROP_SUBMITTED",
15520
+ const fill = this.processFillResult(
15521
+ submitResult,
15405
15522
  commitment,
15406
- userOpHash: result.userOpHash,
15407
- selectedSolver: result.solverAddress,
15408
- transactionHash: result.txnHash
15409
- };
15410
- if (!isSameChain) {
15411
- return;
15412
- }
15413
- if (result.fillStatus === "full") {
15414
- totalFilledAssets = targetAssets.map((a) => ({ token: a.token, amount: a.amount }));
15415
- remainingAssets = targetAssets.map((a) => ({ token: a.token, amount: 0n }));
15416
- yield {
15417
- status: "FILLED",
15418
- commitment,
15419
- userOpHash: result.userOpHash,
15420
- selectedSolver: result.solverAddress,
15421
- transactionHash: result.txnHash,
15422
- totalFilledAssets,
15423
- remainingAssets
15424
- };
15425
- return;
15426
- }
15427
- if (result.fillStatus === "partial") {
15428
- const filledAssets = result.filledAssets ?? [];
15429
- for (const filled of filledAssets) {
15430
- const entry = totalFilledAssets.find((a) => a.token === filled.token);
15431
- if (entry) entry.amount += filled.amount;
15432
- }
15433
- remainingAssets = targetAssets.map((target) => {
15434
- const filled = totalFilledAssets.find((a) => a.token === target.token);
15435
- const filledAmt = filled?.amount ?? 0n;
15436
- return {
15437
- token: target.token,
15438
- amount: filledAmt >= target.amount ? 0n : target.amount - filledAmt
15439
- };
15440
- });
15441
- const fullyFilled = remainingAssets.every((a) => a.amount === 0n);
15442
- if (fullyFilled) {
15443
- yield {
15444
- status: "FILLED",
15445
- commitment,
15446
- userOpHash: result.userOpHash,
15447
- selectedSolver: result.solverAddress,
15448
- transactionHash: result.txnHash,
15449
- totalFilledAssets,
15450
- remainingAssets
15451
- };
15452
- return;
15453
- }
15454
- yield {
15455
- status: "PARTIAL_FILL",
15456
- commitment,
15457
- userOpHash: result.userOpHash,
15458
- selectedSolver: result.solverAddress,
15459
- transactionHash: result.txnHash,
15460
- filledAssets,
15461
- totalFilledAssets,
15462
- remainingAssets
15463
- };
15523
+ targetAssets,
15524
+ totalFilledAssets,
15525
+ remainingAssets
15526
+ );
15527
+ totalFilledAssets = fill.totalFilledAssets;
15528
+ remainingAssets = fill.remainingAssets;
15529
+ if (fill.update) {
15530
+ yield fill.update;
15531
+ if (fill.done) return;
15464
15532
  }
15465
15533
  }
15466
15534
  } catch (err) {
@@ -15480,6 +15548,7 @@ var OrderCanceller = class {
15480
15548
  constructor(ctx) {
15481
15549
  this.ctx = ctx;
15482
15550
  }
15551
+ ctx;
15483
15552
  /**
15484
15553
  * Returns both the native token cost and the relayer fee for cancelling an
15485
15554
  * order. Frontends can use `relayerFee` to approve the ERC-20 spend before
@@ -15949,6 +16018,8 @@ var BidManager = class {
15949
16018
  this.ctx = ctx;
15950
16019
  this.crypto = crypto;
15951
16020
  }
16021
+ ctx;
16022
+ crypto;
15952
16023
  /**
15953
16024
  * Constructs a signed `PackedUserOperation` that a solver can submit to the
15954
16025
  * Hyperbridge coprocessor as a bid to fill an order.
@@ -18028,6 +18099,8 @@ var GasEstimator = class {
18028
18099
  this.ctx = ctx;
18029
18100
  this.crypto = crypto;
18030
18101
  }
18102
+ ctx;
18103
+ crypto;
18031
18104
  /**
18032
18105
  * Estimates the gas cost for a solver to fill the given order and returns
18033
18106
  * a structured estimate with individual gas components and total costs in
@@ -18449,6 +18522,7 @@ var OrderStatusChecker = class {
18449
18522
  constructor(ctx) {
18450
18523
  this.ctx = ctx;
18451
18524
  }
18525
+ ctx;
18452
18526
  /**
18453
18527
  * Checks if a V2 order has been filled by reading the commitment storage slot on the destination chain.
18454
18528
  *
@@ -18630,7 +18704,7 @@ var IntentGateway = class _IntentGateway {
18630
18704
  * The caller must sign the transaction and pass it back via `gen.next(signedTx)`.
18631
18705
  * 3. Yields `ORDER_PLACED` with the finalised order and transaction hash once
18632
18706
  * the `OrderPlaced` event is confirmed.
18633
- * 4. Delegates to {@link OrderExecutor.executeIntentOrder} and forwards all
18707
+ * 4. Delegates to {@link OrderExecutor.executeOrder} and forwards all
18634
18708
  * subsequent status updates until the order is filled, exhausted, or fails.
18635
18709
  *
18636
18710
  * @param order - The order to place and execute. `order.fees` may be 0; it
@@ -18641,7 +18715,6 @@ var IntentGateway = class _IntentGateway {
18641
18715
  * - `maxPriorityFeePerGasBumpPercent` — bump % for the priority fee estimate (default 8).
18642
18716
  * - `maxFeePerGasBumpPercent` — bump % for the max fee estimate (default 10).
18643
18717
  * - `minBids` — minimum bids to collect before selecting (default 1).
18644
- * - `bidTimeoutMs` — how long to poll for bids before giving up (default 60 000 ms).
18645
18718
  * - `pollIntervalMs` — interval between bid-polling attempts.
18646
18719
  * @yields {@link IntentOrderStatusUpdate} at each lifecycle stage.
18647
18720
  * @throws If the `placeOrder` generator behaves unexpectedly, or if gas
@@ -18674,11 +18747,10 @@ var IntentGateway = class _IntentGateway {
18674
18747
  }
18675
18748
  const { order: finalizedOrder, receipt: placementReceipt } = placeOrderSecond.value;
18676
18749
  yield { status: "ORDER_PLACED", order: finalizedOrder, receipt: placementReceipt };
18677
- for await (const status of this.orderExecutor.executeIntentOrder({
18750
+ for await (const status of this.orderExecutor.executeOrder({
18678
18751
  order: finalizedOrder,
18679
18752
  sessionPrivateKey,
18680
18753
  minBids: options?.minBids,
18681
- bidTimeoutMs: options?.bidTimeoutMs,
18682
18754
  pollIntervalMs: options?.pollIntervalMs,
18683
18755
  solver: options?.solver
18684
18756
  })) {
@@ -18686,6 +18758,52 @@ var IntentGateway = class _IntentGateway {
18686
18758
  }
18687
18759
  return;
18688
18760
  }
18761
+ /**
18762
+ * Validates that an order has the minimum fields required for post-placement
18763
+ * resume (i.e. it was previously placed and has an on-chain identity).
18764
+ *
18765
+ * @throws If `order.id` or `order.session` is missing or zero-valued.
18766
+ */
18767
+ assertOrderCanResume(order) {
18768
+ if (!order.id) {
18769
+ throw new Error("Cannot resume execution without order.id");
18770
+ }
18771
+ if (!order.session || order.session === ADDRESS_ZERO2) {
18772
+ throw new Error("Cannot resume execution without order.session");
18773
+ }
18774
+ }
18775
+ /**
18776
+ * Resumes execution of a previously placed order.
18777
+ *
18778
+ * Use this method after an app restart or crash to pick up where
18779
+ * {@link execute} left off. The order must already be placed on-chain
18780
+ * (i.e. it must have a valid `id` and `session`).
18781
+ *
18782
+ * Internally delegates to {@link OrderExecutor.executeOrder} and
18783
+ * yields the same status updates as the execution phase of {@link execute}:
18784
+ * `AWAITING_BIDS`, `BIDS_RECEIVED`, `BID_SELECTED`,
18785
+ * `FILLED`, `PARTIAL_FILL`, `EXPIRED`, or `FAILED`.
18786
+ *
18787
+ * Callers may check {@link isOrderFilled} or {@link isOrderRefunded} before
18788
+ * calling this method to avoid resuming an already-terminal order.
18789
+ *
18790
+ * @param order - A previously placed order with a valid `id` and `session`.
18791
+ * @param options - Optional tuning parameters for bid collection and execution.
18792
+ * @yields {@link IntentOrderStatusUpdate} at each execution stage.
18793
+ * @throws If the order is missing required fields for resumption.
18794
+ */
18795
+ async *resume(order, options) {
18796
+ this.assertOrderCanResume(order);
18797
+ for await (const status of this.orderExecutor.executeOrder({
18798
+ order,
18799
+ sessionPrivateKey: options?.sessionPrivateKey,
18800
+ minBids: options?.minBids,
18801
+ pollIntervalMs: options?.pollIntervalMs,
18802
+ solver: options?.solver
18803
+ })) {
18804
+ yield status;
18805
+ }
18806
+ }
18689
18807
  /**
18690
18808
  * Returns both the native token cost and the relayer fee for cancelling an
18691
18809
  * order. Use `relayerFee` to approve the ERC-20 spend before submitting.