@hyperbridge/simplex 0.18.2 → 0.18.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.
@@ -354596,8 +354596,10 @@ function budgetFromCache(budget) {
354596
354596
  }
354597
354597
  var CacheService = class {
354598
354598
  constructor(loggers = defaultLoggerContext()) {
354599
- this.CACHE_EXPIRY_MS = 1 * 60 * 1e3;
354600
- // 1 minute
354599
+ this.CACHE_EXPIRY_MS = 5 * 60 * 1e3;
354600
+ // 5 minutes
354601
+ /** How long each order's source confirmations take, for the orders still waiting for them. */
354602
+ this.confirmationWaits = /* @__PURE__ */ new Map();
354601
354603
  /** When each order's bid loop began, for the orders whose loop is still running. */
354602
354604
  this.pins = /* @__PURE__ */ new Map();
354603
354605
  this.logger = loggers.get("cache-service");
@@ -354617,13 +354619,32 @@ var CacheService = class {
354617
354619
  };
354618
354620
  }
354619
354621
  /**
354620
- * Whether an entry is still fresh. A pinned order's entries are aged as of the pin,
354621
- * so what was fresh when its bid loop began stays fresh until the loop ends, and
354622
+ * Whether an entry is still live. A pinned order's entries are judged as of the pin,
354623
+ * so what was live when its bid loop began stays live until the loop ends, and
354622
354624
  * what had already expired stays expired.
354623
354625
  */
354624
- isCacheValid(timestamp, orderId) {
354625
- const now = (orderId !== void 0 ? this.pins.get(orderId) : void 0) ?? Date.now();
354626
- return now - timestamp < this.CACHE_EXPIRY_MS;
354626
+ isCacheValid(expiresAt, orderId) {
354627
+ return (this.pins.get(orderId) ?? Date.now()) < expiresAt;
354628
+ }
354629
+ /**
354630
+ * When an entry written now for the order expires: `CACHE_EXPIRY_MS` from now, plus the
354631
+ * time the order's source confirmations take while it waits for them.
354632
+ */
354633
+ expiresAt(orderId) {
354634
+ return Date.now() + this.CACHE_EXPIRY_MS + (this.confirmationWaits.get(orderId) ?? 0);
354635
+ }
354636
+ /**
354637
+ * Lets what is cached for the order outlive `CACHE_EXPIRY_MS` by `waitMs`, the time its
354638
+ * source confirmations take, and returns the release.
354639
+ *
354640
+ * An order is evaluated while it waits for its confirmations, and its bids are signed after
354641
+ * them from what the evaluation cached, so that has to outlast the wait. Each entry takes
354642
+ * its expiry when it is written: the release does not shorten what is already cached, it
354643
+ * only stops later entries from getting the extra time.
354644
+ */
354645
+ extendForConfirmations(orderId, waitMs) {
354646
+ this.confirmationWaits.set(orderId, waitMs);
354647
+ return () => this.confirmationWaits.delete(orderId);
354627
354648
  }
354628
354649
  /**
354629
354650
  * Keeps the order's evaluation alive while its bids go out, and returns the release.
@@ -354640,37 +354661,37 @@ var CacheService = class {
354640
354661
  return () => this.pins.delete(orderId);
354641
354662
  }
354642
354663
  cleanupStaleData() {
354643
- const staleGasEstimateIds = Object.entries(this.cacheData.gasEstimates).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354664
+ const staleGasEstimateIds = Object.entries(this.cacheData.gasEstimates).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354644
354665
  staleGasEstimateIds.forEach((orderId) => {
354645
354666
  delete this.cacheData.gasEstimates[orderId];
354646
354667
  });
354647
354668
  for (const [orderId, data4] of Object.entries(this.cacheData.bidPlans)) {
354648
- if (!this.isCacheValid(data4.timestamp, orderId)) delete this.cacheData.bidPlans[orderId];
354669
+ if (!this.isCacheValid(data4.expiresAt, orderId)) delete this.cacheData.bidPlans[orderId];
354649
354670
  }
354650
354671
  for (const [orderId, data4] of Object.entries(this.cacheData.matchedLimitOrders)) {
354651
- if (!this.isCacheValid(data4.timestamp, orderId)) delete this.cacheData.matchedLimitOrders[orderId];
354672
+ if (!this.isCacheValid(data4.expiresAt, orderId)) delete this.cacheData.matchedLimitOrders[orderId];
354652
354673
  }
354653
- const staleSwapOperationIds = Object.entries(this.cacheData.swapOperations).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354674
+ const staleSwapOperationIds = Object.entries(this.cacheData.swapOperations).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354654
354675
  staleSwapOperationIds.forEach((orderId) => {
354655
354676
  delete this.cacheData.swapOperations[orderId];
354656
354677
  });
354657
- const staleFillerOutputIds = Object.entries(this.cacheData.fillerOutputs).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354678
+ const staleFillerOutputIds = Object.entries(this.cacheData.fillerOutputs).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354658
354679
  staleFillerOutputIds.forEach((orderId) => {
354659
354680
  delete this.cacheData.fillerOutputs[orderId];
354660
354681
  });
354661
- const stalePairIds = Object.entries(this.cacheData.pairClassifications).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354682
+ const stalePairIds = Object.entries(this.cacheData.pairClassifications).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354662
354683
  stalePairIds.forEach((orderId) => {
354663
354684
  delete this.cacheData.pairClassifications[orderId];
354664
354685
  });
354665
- const staleFundingIds = Object.entries(this.cacheData.fundingPrepends).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354686
+ const staleFundingIds = Object.entries(this.cacheData.fundingPrepends).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354666
354687
  staleFundingIds.forEach((orderId) => {
354667
354688
  delete this.cacheData.fundingPrepends[orderId];
354668
354689
  });
354669
- const stalePartialIds = Object.entries(this.cacheData.partialFills).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354690
+ const stalePartialIds = Object.entries(this.cacheData.partialFills).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354670
354691
  stalePartialIds.forEach((orderId) => {
354671
354692
  delete this.cacheData.partialFills[orderId];
354672
354693
  });
354673
- const staleWaivedIds = Object.entries(this.cacheData.feeChecksWaived).filter(([orderId, data4]) => !this.isCacheValid(data4.timestamp, orderId)).map(([orderId]) => orderId);
354694
+ const staleWaivedIds = Object.entries(this.cacheData.feeChecksWaived).filter(([orderId, data4]) => !this.isCacheValid(data4.expiresAt, orderId)).map(([orderId]) => orderId);
354674
354695
  staleWaivedIds.forEach((orderId) => {
354675
354696
  delete this.cacheData.feeChecksWaived[orderId];
354676
354697
  });
@@ -354678,7 +354699,7 @@ var CacheService = class {
354678
354699
  getGasEstimate(orderId) {
354679
354700
  try {
354680
354701
  const cache = this.cacheData.gasEstimates[orderId];
354681
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354702
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354682
354703
  return {
354683
354704
  totalCostInSourceFeeToken: BigInt(cache.totalCostInSourceFeeToken),
354684
354705
  relayerFeeInSourceFeeToken: BigInt(cache.relayerFeeInSourceFeeToken ?? "0"),
@@ -354713,7 +354734,7 @@ var CacheService = class {
354713
354734
  maxFeePerGas: maxFeePerGas.toString(),
354714
354735
  maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),
354715
354736
  totalGasCostWei: totalGasCostWei.toString(),
354716
- timestamp: Date.now()
354737
+ expiresAt: this.expiresAt(orderId)
354717
354738
  };
354718
354739
  } catch (error) {
354719
354740
  this.logger.error({ err: error }, "Error setting gas estimate");
@@ -354723,7 +354744,7 @@ var CacheService = class {
354723
354744
  getSwapOperations(orderId) {
354724
354745
  try {
354725
354746
  const cache = this.cacheData.swapOperations[orderId];
354726
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354747
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354727
354748
  return {
354728
354749
  calls: cache.calls,
354729
354750
  totalGasEstimate: BigInt(cache.totalGasEstimate)
@@ -354741,7 +354762,7 @@ var CacheService = class {
354741
354762
  this.cacheData.swapOperations[orderId] = {
354742
354763
  calls,
354743
354764
  totalGasEstimate: totalGasEstimate.toString(),
354744
- timestamp: Date.now()
354765
+ expiresAt: this.expiresAt(orderId)
354745
354766
  };
354746
354767
  } catch (error) {
354747
354768
  this.logger.error({ err: error }, "Error setting swap operations");
@@ -354751,7 +354772,7 @@ var CacheService = class {
354751
354772
  getFillerOutputs(orderId) {
354752
354773
  try {
354753
354774
  const cache = this.cacheData.fillerOutputs[orderId];
354754
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354775
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354755
354776
  return cache.outputs.map((o6) => ({
354756
354777
  token: o6.token,
354757
354778
  amount: BigInt(o6.amount)
@@ -354767,7 +354788,7 @@ var CacheService = class {
354767
354788
  getFillerInputs(orderId) {
354768
354789
  try {
354769
354790
  const cache = this.cacheData.fillerOutputs[orderId];
354770
- if (cache?.inputs && this.isCacheValid(cache.timestamp, orderId)) {
354791
+ if (cache?.inputs && this.isCacheValid(cache.expiresAt, orderId)) {
354771
354792
  return cache.inputs.map((o6) => ({
354772
354793
  token: o6.token,
354773
354794
  amount: BigInt(o6.amount)
@@ -354789,7 +354810,7 @@ var CacheService = class {
354789
354810
  getBidBudget(orderId) {
354790
354811
  try {
354791
354812
  const cache = this.cacheData.fillerOutputs[orderId];
354792
- if (cache?.budget && this.isCacheValid(cache.timestamp, orderId)) return budgetFromCache(cache.budget);
354813
+ if (cache?.budget && this.isCacheValid(cache.expiresAt, orderId)) return budgetFromCache(cache.budget);
354793
354814
  return null;
354794
354815
  } catch (error) {
354795
354816
  this.logger.error({ err: error }, "Error getting bid budget");
@@ -354809,7 +354830,7 @@ var CacheService = class {
354809
354830
  amount: o6.amount.toString()
354810
354831
  })),
354811
354832
  ...budget ? { budget: budgetToCache(budget) } : {},
354812
- timestamp: Date.now()
354833
+ expiresAt: this.expiresAt(orderId)
354813
354834
  };
354814
354835
  } catch (error) {
354815
354836
  this.logger.error({ err: error }, "Error setting filler outputs");
@@ -354826,7 +354847,7 @@ var CacheService = class {
354826
354847
  getMatchedLimitOrder(orderId) {
354827
354848
  try {
354828
354849
  const cache = this.cacheData.matchedLimitOrders[orderId];
354829
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354850
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354830
354851
  return cache.holds.map((hold) => ({ limitOrderId: hold.limitOrderId, payout: BigInt(hold.payout) }));
354831
354852
  }
354832
354853
  return [];
@@ -354838,7 +354859,7 @@ var CacheService = class {
354838
354859
  getBidPlans(orderId) {
354839
354860
  try {
354840
354861
  const cache = this.cacheData.bidPlans[orderId];
354841
- if (!cache || !this.isCacheValid(cache.timestamp, orderId)) return [];
354862
+ if (!cache || !this.isCacheValid(cache.expiresAt, orderId)) return [];
354842
354863
  return cache.plans.map((plan) => ({
354843
354864
  limitOrderId: plan.limitOrderId,
354844
354865
  leg: plan.leg ?? 0,
@@ -354889,7 +354910,7 @@ var CacheService = class {
354889
354910
  ...plan.inputDecimals !== void 0 ? { inputDecimals: plan.inputDecimals } : {},
354890
354911
  ...plan.budget ? { budget: budgetToCache(plan.budget) } : {}
354891
354912
  })),
354892
- timestamp: Date.now()
354913
+ expiresAt: this.expiresAt(orderId)
354893
354914
  };
354894
354915
  } catch (error) {
354895
354916
  this.logger.error({ err: error }, "Error setting bid plans");
@@ -354904,7 +354925,7 @@ var CacheService = class {
354904
354925
  this.cleanupStaleData();
354905
354926
  this.cacheData.matchedLimitOrders[orderId] = {
354906
354927
  holds: holds.map((hold) => ({ limitOrderId: hold.limitOrderId, payout: hold.payout.toString() })),
354907
- timestamp: Date.now()
354928
+ expiresAt: this.expiresAt(orderId)
354908
354929
  };
354909
354930
  } catch (error) {
354910
354931
  this.logger.error({ err: error }, "Error setting matched limit order");
@@ -354914,7 +354935,7 @@ var CacheService = class {
354914
354935
  getPairClassifications(orderId) {
354915
354936
  try {
354916
354937
  const cache = this.cacheData.pairClassifications[orderId];
354917
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354938
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354918
354939
  return cache.pairs;
354919
354940
  }
354920
354941
  return null;
@@ -354927,7 +354948,7 @@ var CacheService = class {
354927
354948
  try {
354928
354949
  this.cacheData.pairClassifications[orderId] = {
354929
354950
  pairs,
354930
- timestamp: Date.now()
354951
+ expiresAt: this.expiresAt(orderId)
354931
354952
  };
354932
354953
  } catch (error) {
354933
354954
  this.logger.error({ err: error }, "Error setting pair classifications");
@@ -354937,7 +354958,7 @@ var CacheService = class {
354937
354958
  getFundingPrepends(orderId) {
354938
354959
  try {
354939
354960
  const cache = this.cacheData.fundingPrepends[orderId];
354940
- if (cache && this.isCacheValid(cache.timestamp, orderId)) {
354961
+ if (cache && this.isCacheValid(cache.expiresAt, orderId)) {
354941
354962
  return {
354942
354963
  calls: cache.calls.map((c6) => ({
354943
354964
  target: c6.target,
@@ -354961,7 +354982,7 @@ var CacheService = class {
354961
354982
  value: c6.value.toString(),
354962
354983
  data: c6.data
354963
354984
  })),
354964
- timestamp: Date.now()
354985
+ expiresAt: this.expiresAt(orderId)
354965
354986
  };
354966
354987
  } catch (error) {
354967
354988
  this.logger.error({ err: error }, "Error setting funding prepends");
@@ -354980,10 +355001,10 @@ var CacheService = class {
354980
355001
  */
354981
355002
  isPartialFill(orderId) {
354982
355003
  const cache = this.cacheData.partialFills[orderId];
354983
- return cache !== void 0 && this.isCacheValid(cache.timestamp, orderId) && cache.partial;
355004
+ return cache !== void 0 && this.isCacheValid(cache.expiresAt, orderId) && cache.partial;
354984
355005
  }
354985
355006
  setPartialFill(orderId, partial) {
354986
- this.cacheData.partialFills[orderId] = { partial, timestamp: Date.now() };
355007
+ this.cacheData.partialFills[orderId] = { partial, expiresAt: this.expiresAt(orderId) };
354987
355008
  }
354988
355009
  clearPartialFill(orderId) {
354989
355010
  delete this.cacheData.partialFills[orderId];
@@ -354998,10 +355019,10 @@ var CacheService = class {
354998
355019
  */
354999
355020
  isFeeCheckWaived(orderId) {
355000
355021
  const cache = this.cacheData.feeChecksWaived[orderId];
355001
- return cache !== void 0 && this.isCacheValid(cache.timestamp, orderId) && cache.waived;
355022
+ return cache !== void 0 && this.isCacheValid(cache.expiresAt, orderId) && cache.waived;
355002
355023
  }
355003
355024
  setFeeCheckWaived(orderId, waived) {
355004
- this.cacheData.feeChecksWaived[orderId] = { waived, timestamp: Date.now() };
355025
+ this.cacheData.feeChecksWaived[orderId] = { waived, expiresAt: this.expiresAt(orderId) };
355005
355026
  }
355006
355027
  clearFeeCheckWaived(orderId) {
355007
355028
  delete this.cacheData.feeChecksWaived[orderId];
@@ -392153,6 +392174,10 @@ var IntentFiller = class {
392153
392174
  this.monitor.emit("orderSkipped", { orderId: order.id, reason: "Placement block unknown" });
392154
392175
  return;
392155
392176
  }
392177
+ const releaseWait = order.id && requiredConfirmations > 0 ? this.contractService.cacheService.extendForConfirmations(
392178
+ order.id,
392179
+ await this.confirmationWaitMs(order.source, requiredConfirmations)
392180
+ ) : void 0;
392156
392181
  const abortController = new AbortController();
392157
392182
  const confirmStartMs = Date.now();
392158
392183
  const confirmationPollMs = sourceQuorumClient.size > 1 ? 1e3 : 300;
@@ -392216,7 +392241,7 @@ var IntentFiller = class {
392216
392241
  if (!result) abortController.abort();
392217
392242
  return result;
392218
392243
  })
392219
- ]);
392244
+ ]).finally(() => releaseWait?.());
392220
392245
  const confirmDurationSec = (Date.now() - confirmStartMs) / 1e3;
392221
392246
  this.monitor.emit("orderTiming", {
392222
392247
  orderId: order.id,
@@ -392245,7 +392270,8 @@ var IntentFiller = class {
392245
392270
  evaluationResult.strategy,
392246
392271
  solverSelectionActive,
392247
392272
  inputUsdValue,
392248
- evaluationResult.profitability
392273
+ evaluationResult.profitability,
392274
+ () => this.evaluateOrder(order, canFillCache)
392249
392275
  );
392250
392276
  } catch (error) {
392251
392277
  this.logger.error({ orderId: order.id, err: error }, "Error processing order");
@@ -392326,6 +392352,19 @@ var IntentFiller = class {
392326
392352
  );
392327
392353
  return validStrategies[0];
392328
392354
  }
392355
+ /**
392356
+ * How long `confirmations` take on `chain`, at the block time measured when simplex started.
392357
+ * Zero when there is no block time to be had: the order then keeps the cache's own lifetime,
392358
+ * and an evaluation that expires before its bids is redone.
392359
+ */
392360
+ async confirmationWaitMs(chain2, confirmations) {
392361
+ try {
392362
+ return Math.ceil(confirmations * await this.contractService.blockTimeSeconds(chain2) * 1e3);
392363
+ } catch (err) {
392364
+ this.logger.warn({ chain: chain2, err }, "Could not read the block time to size the order's cache lifetime");
392365
+ return 0;
392366
+ }
392367
+ }
392329
392368
  /**
392330
392369
  * The destination chain's latest block number, the clock `order.deadline` is read on.
392331
392370
  *
@@ -392365,7 +392404,7 @@ var IntentFiller = class {
392365
392404
  if (!order.id) return false;
392366
392405
  return this.contractService.cacheService.isFeeCheckWaived(order.id);
392367
392406
  }
392368
- executeOrder(order, bestStrategy, solverSelectionActive, inputUsdValue, profitUsd) {
392407
+ executeOrder(order, bestStrategy, solverSelectionActive, inputUsdValue, profitUsd, reevaluate) {
392369
392408
  const chainQueue = this.chainQueues.get(getChainId3(order.destination));
392370
392409
  if (!chainQueue) {
392371
392410
  this.logger.error({ chain: order.destination }, "No queue configured for chain");
@@ -392376,12 +392415,19 @@ var IntentFiller = class {
392376
392415
  chainQueue.add(async () => {
392377
392416
  const queueDurationSec = (Date.now() - queuedAtMs) / 1e3;
392378
392417
  this.monitor.emit("orderTiming", { orderId: order.id, phase: "queue_wait", durationSec: queueDurationSec });
392418
+ const cache = this.contractService.cacheService;
392419
+ unpin = order.id ? cache.pinOrder(order.id) : void 0;
392420
+ if (order.id && reevaluate && !cache.getGasEstimate(order.id)) {
392421
+ this.logger.info({ orderId: order.id }, "Order evaluation expired before bidding, evaluating it again");
392422
+ const evaluation = await reevaluate();
392423
+ if (!evaluation) return;
392424
+ bestStrategy = evaluation.strategy;
392425
+ profitUsd = evaluation.profitability;
392426
+ }
392379
392427
  this.logger.info(
392380
392428
  { orderId: order.id, strategy: bestStrategy.name, chain: order.destination },
392381
392429
  "Executing order"
392382
392430
  );
392383
- const cache = this.contractService.cacheService;
392384
- unpin = order.id ? cache.pinOrder(order.id) : void 0;
392385
392431
  const plans = this.limitOrders && order.id ? cache.getBidPlans(order.id) : [];
392386
392432
  let lastResult;
392387
392433
  for (const plan of plans.length > 0 ? plans : [void 0]) {