@metamask-previews/perps-controller 13.1.0-preview-965e373 → 13.1.0-preview-8c2a2eeb2

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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Fixed
11
+
12
+ - Stop reporting `TPSL_UPDATE_FAILED` from `updatePositionTPSL` when HyperLiquid accepts a trigger with `waitingForTrigger`; accepted triggers without response order IDs are reconciled before mixed-failure cleanup
13
+
10
14
  ## [13.1.0]
11
15
 
12
16
  ### Added
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _HyperLiquidProvider_instances, _a, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_orderCapabilitiesMarketsByDex, _HyperLiquidProvider_orderCapabilitiesRefreshByDex, _HyperLiquidProvider_isDisconnected, _HyperLiquidProvider_disconnectOperationsInFlight, _HyperLiquidProvider_disconnectOperationPromise, _HyperLiquidProvider_lifecycleGeneration, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_subscriptionBuilderApprovalEpoch, _HyperLiquidProvider_approvedBuilderAddresses, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_userFeeResolution, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_scaleOrderGroups, _HyperLiquidProvider_cancelledScaleOrderGroups, _HyperLiquidProvider_trackedTwapOrdersByMessenger, _HyperLiquidProvider_trackedTwapOrders, _HyperLiquidProvider_chaseSessions, _HyperLiquidProvider_chaseTerminations, _HyperLiquidProvider_terminatedChaseHandles, _HyperLiquidProvider_chasePlacementsInFlight, _HyperLiquidProvider_chasePlacementWaiters, _HyperLiquidProvider_chaseTickQueue, _HyperLiquidProvider_strategyGeneration, _HyperLiquidProvider_chasePlacementBlockers, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_subscriptionBuilderAddressTestnet, _HyperLiquidProvider_subscriptionBuilderAddressMainnet, _HyperLiquidProvider_priceDeviationLimit, _HyperLiquidProvider_onChaseOrderMaxDistanceReached, _HyperLiquidProvider_resolveOrderFeePolicy, _HyperLiquidProvider_assertProviderLifecycleCurrent, _HyperLiquidProvider_assertCacheWriteLifecycleCurrent, _HyperLiquidProvider_isCacheWriteLifecycleCurrent, _HyperLiquidProvider_getFreshOrderCapabilityMarkets, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_isWalletOnHyperliquid, _HyperLiquidProvider_isHyperliquidMultiSigAccount, _HyperLiquidProvider_ensureUnifiedAccountEnabled, _HyperLiquidProvider_ensureReady, _HyperLiquidProvider_tradingSetupPromise, _HyperLiquidProvider_tradingSetupComplete, _HyperLiquidProvider_builderFeeSetupPromises, _HyperLiquidProvider_ensureBuilderFeeSetup, _HyperLiquidProvider_ensureReadyForTrading, _HyperLiquidProvider_getOrFetchPrice, _HyperLiquidProvider_filterFills, _HyperLiquidProvider_getAllAvailableDexs, _HyperLiquidProvider_getValidatedDexs, _HyperLiquidProvider_fetchValidatedDexsInternal, _HyperLiquidProvider_getCachedMeta, _HyperLiquidProvider_fetchMeta, _HyperLiquidProvider_cacheDexMetadata, _HyperLiquidProvider_cacheDexMetadataFromRead, _HyperLiquidProvider_backfillAssetMapForDex, _HyperLiquidProvider_getAssetIdWithRepair, _HyperLiquidProvider_getCachedSpotMeta, _HyperLiquidProvider_getCachedPerpDexs, _HyperLiquidProvider_calculateHip3FeeMultiplier, _HyperLiquidProvider_getCacheKey, _HyperLiquidProvider_getApprovedBuilderKey, _HyperLiquidProvider_fetchMarketsForDex, _HyperLiquidProvider_getUsdcTokenId, _HyperLiquidProvider_isUsdcCollateralDex, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _HyperLiquidProvider_isMappedAccountModeExchangeError, _HyperLiquidProvider_getTradingErrorContext, _HyperLiquidProvider_checkBuilderFeeApproval, _HyperLiquidProvider_ensureBuilderFeeApproval, _HyperLiquidProvider_checkBuilderFeeStatus, _HyperLiquidProvider_getBalanceForDex, _HyperLiquidProvider_findSourceDexWithBalance, _HyperLiquidProvider_autoTransferForHip3Order, _HyperLiquidProvider_autoTransferBackAfterClose, _HyperLiquidProvider_calculateHip3RequiredMargin, _HyperLiquidProvider_handleHip3PostOrderRebalance, _HyperLiquidProvider_handleHip3OrderRollback, _HyperLiquidProvider_validateOrderBeforePlacement, _HyperLiquidProvider_getAssetInfo, _HyperLiquidProvider_prepareAssetForTrading, _HyperLiquidProvider_handleHip3PreOrder, _HyperLiquidProvider_submitOrderWithRollback, _HyperLiquidProvider_handleOrderError, _HyperLiquidProvider_placeStrategyOrder, _HyperLiquidProvider_submitPreparedStrategy, _HyperLiquidProvider_prepareStrategyPlacement, _HyperLiquidProvider_getMinimumOrderSize, _HyperLiquidProvider_buildScaleLadder, _HyperLiquidProvider_placeTwapOrder, _HyperLiquidProvider_placeScaleOrder, _HyperLiquidProvider_startChaseSession, _HyperLiquidProvider_getChaseQuotePrice, _HyperLiquidProvider_restChaseOrder, _HyperLiquidProvider_scheduleChaseTick, _HyperLiquidProvider_pauseChaseTicksForPlacement, _HyperLiquidProvider_resumeChaseTicksAfterPlacement, _HyperLiquidProvider_recoverFailedChaseTick, _HyperLiquidProvider_runChaseTick, _HyperLiquidProvider_resolveOwnRestingSizes, _HyperLiquidProvider_readOrderRemainder, _HyperLiquidProvider_cancelChaseChild, _HyperLiquidProvider_retractOrphanedChaseOrder, _HyperLiquidProvider_stopChaseSession, _HyperLiquidProvider_rebalanceChaseSession, _HyperLiquidProvider_adaptTwapOrder, _HyperLiquidProvider_rebalanceTrackedTwapOrder, _HyperLiquidProvider_rebalanceTerminalHip3Twaps, _HyperLiquidProvider_cancelStrategyOrder, _HyperLiquidProvider_cancelTwapOrder, _HyperLiquidProvider_cancelScaleOrder, _HyperLiquidProvider_cancelChaseOrder, _HyperLiquidProvider_performChaseTermination, _HyperLiquidProvider_cancelOrderRequests, _HyperLiquidProvider_cancelOrderRequestBatch, _HyperLiquidProvider_readOrderPlacementOutcome, _HyperLiquidProvider_readOrderIdFromStatus, _HyperLiquidProvider_getDiscountedBuilderFee, _HyperLiquidProvider_getBuilderOrderContext, _HyperLiquidProvider_fetchOpenOrders, _HyperLiquidProvider_resolveReplacementOrderId, _HyperLiquidProvider_getStandaloneValidatedDexs, _HyperLiquidProvider_queryDexPositions, _HyperLiquidProvider_restoreScaleOrderGroups, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _HyperLiquidProvider_excludeNonUsdcCollateralResults, _HyperLiquidProvider_mergeDexResultsInto, _HyperLiquidProvider_cacheFreshMarketDataSnapshot, _HyperLiquidProvider_getStaleMarketDataSnapshot, _HyperLiquidProvider_isFeeCacheValid, _HyperLiquidProvider_performDisconnect, _HyperLiquidProvider_getBuilderAddress, _HyperLiquidProvider_getSubscriptionBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
13
+ var _HyperLiquidProvider_instances, _a, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_orderCapabilitiesMarketsByDex, _HyperLiquidProvider_orderCapabilitiesRefreshByDex, _HyperLiquidProvider_isDisconnected, _HyperLiquidProvider_disconnectOperationsInFlight, _HyperLiquidProvider_disconnectOperationPromise, _HyperLiquidProvider_lifecycleGeneration, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_subscriptionBuilderApprovalEpoch, _HyperLiquidProvider_approvedBuilderAddresses, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_userFeeResolution, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_scaleOrderGroups, _HyperLiquidProvider_cancelledScaleOrderGroups, _HyperLiquidProvider_trackedTwapOrdersByMessenger, _HyperLiquidProvider_trackedTwapOrders, _HyperLiquidProvider_chaseSessions, _HyperLiquidProvider_chaseTerminations, _HyperLiquidProvider_terminatedChaseHandles, _HyperLiquidProvider_chasePlacementsInFlight, _HyperLiquidProvider_chasePlacementWaiters, _HyperLiquidProvider_chaseTickQueue, _HyperLiquidProvider_strategyGeneration, _HyperLiquidProvider_chasePlacementBlockers, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_subscriptionBuilderAddressTestnet, _HyperLiquidProvider_subscriptionBuilderAddressMainnet, _HyperLiquidProvider_priceDeviationLimit, _HyperLiquidProvider_onChaseOrderMaxDistanceReached, _HyperLiquidProvider_resolveOrderFeePolicy, _HyperLiquidProvider_assertProviderLifecycleCurrent, _HyperLiquidProvider_assertCacheWriteLifecycleCurrent, _HyperLiquidProvider_isCacheWriteLifecycleCurrent, _HyperLiquidProvider_getFreshOrderCapabilityMarkets, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_isWalletOnHyperliquid, _HyperLiquidProvider_isHyperliquidMultiSigAccount, _HyperLiquidProvider_ensureUnifiedAccountEnabled, _HyperLiquidProvider_ensureReady, _HyperLiquidProvider_tradingSetupPromise, _HyperLiquidProvider_tradingSetupComplete, _HyperLiquidProvider_builderFeeSetupPromises, _HyperLiquidProvider_ensureBuilderFeeSetup, _HyperLiquidProvider_ensureReadyForTrading, _HyperLiquidProvider_getOrFetchPrice, _HyperLiquidProvider_filterFills, _HyperLiquidProvider_getAllAvailableDexs, _HyperLiquidProvider_getValidatedDexs, _HyperLiquidProvider_fetchValidatedDexsInternal, _HyperLiquidProvider_getCachedMeta, _HyperLiquidProvider_fetchMeta, _HyperLiquidProvider_cacheDexMetadata, _HyperLiquidProvider_cacheDexMetadataFromRead, _HyperLiquidProvider_backfillAssetMapForDex, _HyperLiquidProvider_getAssetIdWithRepair, _HyperLiquidProvider_getCachedSpotMeta, _HyperLiquidProvider_getCachedPerpDexs, _HyperLiquidProvider_calculateHip3FeeMultiplier, _HyperLiquidProvider_getCacheKey, _HyperLiquidProvider_getApprovedBuilderKey, _HyperLiquidProvider_fetchMarketsForDex, _HyperLiquidProvider_getUsdcTokenId, _HyperLiquidProvider_isUsdcCollateralDex, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _HyperLiquidProvider_isMappedAccountModeExchangeError, _HyperLiquidProvider_getTradingErrorContext, _HyperLiquidProvider_checkBuilderFeeApproval, _HyperLiquidProvider_ensureBuilderFeeApproval, _HyperLiquidProvider_checkBuilderFeeStatus, _HyperLiquidProvider_getBalanceForDex, _HyperLiquidProvider_findSourceDexWithBalance, _HyperLiquidProvider_autoTransferForHip3Order, _HyperLiquidProvider_autoTransferBackAfterClose, _HyperLiquidProvider_calculateHip3RequiredMargin, _HyperLiquidProvider_handleHip3PostOrderRebalance, _HyperLiquidProvider_handleHip3OrderRollback, _HyperLiquidProvider_validateOrderBeforePlacement, _HyperLiquidProvider_getAssetInfo, _HyperLiquidProvider_prepareAssetForTrading, _HyperLiquidProvider_handleHip3PreOrder, _HyperLiquidProvider_submitOrderWithRollback, _HyperLiquidProvider_handleOrderError, _HyperLiquidProvider_placeStrategyOrder, _HyperLiquidProvider_submitPreparedStrategy, _HyperLiquidProvider_prepareStrategyPlacement, _HyperLiquidProvider_getMinimumOrderSize, _HyperLiquidProvider_buildScaleLadder, _HyperLiquidProvider_placeTwapOrder, _HyperLiquidProvider_placeScaleOrder, _HyperLiquidProvider_startChaseSession, _HyperLiquidProvider_getChaseQuotePrice, _HyperLiquidProvider_restChaseOrder, _HyperLiquidProvider_scheduleChaseTick, _HyperLiquidProvider_pauseChaseTicksForPlacement, _HyperLiquidProvider_resumeChaseTicksAfterPlacement, _HyperLiquidProvider_recoverFailedChaseTick, _HyperLiquidProvider_runChaseTick, _HyperLiquidProvider_resolveOwnRestingSizes, _HyperLiquidProvider_readOrderRemainder, _HyperLiquidProvider_cancelChaseChild, _HyperLiquidProvider_retractOrphanedChaseOrder, _HyperLiquidProvider_stopChaseSession, _HyperLiquidProvider_rebalanceChaseSession, _HyperLiquidProvider_adaptTwapOrder, _HyperLiquidProvider_rebalanceTrackedTwapOrder, _HyperLiquidProvider_rebalanceTerminalHip3Twaps, _HyperLiquidProvider_cancelStrategyOrder, _HyperLiquidProvider_cancelTwapOrder, _HyperLiquidProvider_cancelScaleOrder, _HyperLiquidProvider_cancelChaseOrder, _HyperLiquidProvider_performChaseTermination, _HyperLiquidProvider_cancelOrderRequests, _HyperLiquidProvider_cancelOrderRequestBatch, _HyperLiquidProvider_readOrderPlacementOutcome, _HyperLiquidProvider_readTpslOrderPlacementOutcome, _HyperLiquidProvider_reconcileTpslOrderPlacementOutcomes, _HyperLiquidProvider_readOrderIdFromStatus, _HyperLiquidProvider_getDiscountedBuilderFee, _HyperLiquidProvider_getBuilderOrderContext, _HyperLiquidProvider_fetchOpenOrders, _HyperLiquidProvider_resolveReplacementOrderId, _HyperLiquidProvider_getStandaloneValidatedDexs, _HyperLiquidProvider_queryDexPositions, _HyperLiquidProvider_restoreScaleOrderGroups, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _HyperLiquidProvider_excludeNonUsdcCollateralResults, _HyperLiquidProvider_mergeDexResultsInto, _HyperLiquidProvider_cacheFreshMarketDataSnapshot, _HyperLiquidProvider_getStaleMarketDataSnapshot, _HyperLiquidProvider_isFeeCacheValid, _HyperLiquidProvider_performDisconnect, _HyperLiquidProvider_getBuilderAddress, _HyperLiquidProvider_getSubscriptionBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.HyperLiquidProvider = void 0;
16
16
  const utils_1 = require("@metamask/utils");
@@ -2119,6 +2119,7 @@ class HyperLiquidProvider {
2119
2119
  // OPTIMIZATION: Use WebSocket cache first (0 weight), fall back to single-DEX REST (20 weight)
2120
2120
  // Previously: queryUserDataAcrossDexs queried ALL DEXs (20 weight × N DEXs = 40+ weight)
2121
2121
  let cancelRequests = [];
2122
+ const orderIdsBeforePlacement = new Set();
2122
2123
  const restorablePositionTpslOrders = [];
2123
2124
  const restorableStandaloneTpslOrders = [];
2124
2125
  // Every replacement must cancel first so old and new reduce-only triggers
@@ -2205,6 +2206,7 @@ class HyperLiquidProvider {
2205
2206
  user: userAddress,
2206
2207
  dex: dexName ?? undefined,
2207
2208
  });
2209
+ openOrders.forEach((order) => orderIdsBeforePlacement.add(order.oid.toString()));
2208
2210
  // Orders that belong to a pending parent order (normalTpsl children) are
2209
2211
  // also listed at the top level, so collect their IDs to exclude them:
2210
2212
  // they protect that pending order, not this position.
@@ -2231,6 +2233,7 @@ class HyperLiquidProvider {
2231
2233
  else {
2232
2234
  // WebSocket cache available - use it (no API call, 0 weight)
2233
2235
  __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Using WebSocket cache for TP/SL orders lookup', { cachedOrdersCount: cachedOrders.length });
2236
+ cachedOrders.forEach((order) => orderIdsBeforePlacement.add(order.orderId));
2234
2237
  // Filter using normalized Order type properties, matching the REST fallback criteria:
2235
2238
  // - symbol matches
2236
2239
  // - isTrigger === true
@@ -2344,13 +2347,23 @@ class HyperLiquidProvider {
2344
2347
  builderOrderContext && { builder: builderOrderContext }),
2345
2348
  });
2346
2349
  const statuses = result.response?.data?.statuses ?? [];
2347
- const outcomes = statuses
2350
+ const rawOutcomes = statuses
2348
2351
  .slice(0, entries.length)
2349
- .map((status) => __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderPlacementOutcome).call(this, status));
2350
- restoredOrderIds.push(...outcomes.flatMap((outcome) => outcome ? [outcome.orderId] : []));
2352
+ .map((status) => __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readTpslOrderPlacementOutcome).call(this, status));
2353
+ const outcomes = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_reconcileTpslOrderPlacementOutcomes).call(this, {
2354
+ outcomes: rawOutcomes,
2355
+ orders: entries.map((entry) => entry.order),
2356
+ previousOrderIds: new Set([
2357
+ ...orderIdsBeforePlacement,
2358
+ ...Array.from(cancelledOrderIds, String),
2359
+ ]),
2360
+ dexName,
2361
+ symbol,
2362
+ });
2363
+ restoredOrderIds.push(...outcomes.flatMap((outcome) => outcome.orderId ? [outcome.orderId] : []));
2351
2364
  if (result.status !== 'ok' ||
2352
2365
  statuses.length !== entries.length ||
2353
- outcomes.some((outcome) => outcome === undefined)) {
2366
+ outcomes.some((outcome) => outcome.state === 'rejected' || outcome.state === 'unknown')) {
2354
2367
  success = false;
2355
2368
  __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").logger.error(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.TPSL_UPDATE_FAILED), __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getErrorContext).call(this, 'updatePositionTPSL > restoreCancelledProtection', { symbol, grouping: protection.grouping, statuses }));
2356
2369
  }
@@ -2443,48 +2456,69 @@ class HyperLiquidProvider {
2443
2456
  throw error;
2444
2457
  }
2445
2458
  const placementStatuses = result.response?.data?.statuses ?? [];
2446
- const placementOutcomes = placementStatuses
2459
+ const initialPlacementOutcomes = placementStatuses
2447
2460
  .slice(0, orders.length)
2448
- .map((status) => __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderPlacementOutcome).call(this, status));
2449
- const replacementOrderIds = placementOutcomes.flatMap((outcome) => outcome ? [outcome.orderId] : []);
2450
- const restingReplacementOrderIds = placementOutcomes.flatMap((outcome) => outcome?.state === 'resting' ? [outcome.orderId] : []);
2451
- const filledReplacementOrderIds = placementOutcomes.flatMap((outcome) => outcome?.state === 'filled' ? [outcome.orderId] : []);
2452
- if (result.status !== 'ok' ||
2453
- placementStatuses.length !== orders.length ||
2454
- replacementOrderIds.length !== orders.length) {
2455
- const remainingReplacementIds = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelOrderRequests).call(this, exchangeClient, restingReplacementOrderIds.map((orderId) => ({
2456
- a: assetId,
2457
- o: Number(orderId),
2458
- })));
2459
- const recoverableOrderIds = [
2460
- ...filledReplacementOrderIds,
2461
- ...remainingReplacementIds.map(String),
2462
- ];
2463
- if (recoverableOrderIds.length === 0) {
2464
- const restoration = await restoreCancelledProtection(confirmedCancelledOldOrderIds);
2465
- if (!restoration.success) {
2466
- return createProtectionLostResult(restoration.restoredOrderIds);
2467
- }
2461
+ .map((status) => __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readTpslOrderPlacementOutcome).call(this, status));
2462
+ const placementAccepted = result.status === 'ok' &&
2463
+ placementStatuses.length === orders.length &&
2464
+ initialPlacementOutcomes.every((outcome) => outcome.state === 'resting' ||
2465
+ outcome.state === 'filled' ||
2466
+ outcome.state === 'waitingForTrigger');
2467
+ if (placementAccepted) {
2468
+ return {
2469
+ success: true,
2470
+ orderId: 'TP/SL orders placed',
2471
+ };
2472
+ }
2473
+ const placementOutcomes = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_reconcileTpslOrderPlacementOutcomes).call(this, {
2474
+ outcomes: initialPlacementOutcomes,
2475
+ orders,
2476
+ previousOrderIds: new Set([
2477
+ ...orderIdsBeforePlacement,
2478
+ ...Array.from(confirmedCancelledOldOrderIds, String),
2479
+ ]),
2480
+ dexName,
2481
+ symbol,
2482
+ });
2483
+ const restingReplacementOrderIds = placementOutcomes.flatMap((outcome) => (outcome.state === 'resting' ||
2484
+ outcome.state === 'waitingForTrigger') &&
2485
+ outcome.orderId
2486
+ ? [outcome.orderId]
2487
+ : []);
2488
+ const filledReplacementOrderIds = placementOutcomes.flatMap((outcome) => outcome.state === 'filled' && outcome.orderId ? [outcome.orderId] : []);
2489
+ const hasUnresolvedWaitingTrigger = placementOutcomes.some((outcome) => outcome.state === 'waitingForTrigger' &&
2490
+ outcome.orderId === undefined);
2491
+ const remainingReplacementIds = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelOrderRequests).call(this, exchangeClient, restingReplacementOrderIds.map((orderId) => ({
2492
+ a: assetId,
2493
+ o: Number(orderId),
2494
+ })));
2495
+ const recoverableOrderIds = [
2496
+ ...filledReplacementOrderIds,
2497
+ ...remainingReplacementIds.map(String),
2498
+ ];
2499
+ if (hasUnresolvedWaitingTrigger) {
2500
+ return createProtectionLostResult(recoverableOrderIds);
2501
+ }
2502
+ if (recoverableOrderIds.length === 0) {
2503
+ const restoration = await restoreCancelledProtection(confirmedCancelledOldOrderIds);
2504
+ if (!restoration.success) {
2505
+ return createProtectionLostResult(restoration.restoredOrderIds);
2468
2506
  }
2469
- // A filled replacement may have changed or closed the position, while
2470
- // an uncancelled replacement may still protect it. Restoring the old
2471
- // whole-position triggers in either case risks stale or duplicate
2472
- // protection, so return those IDs for caller reconciliation instead.
2473
- if (recoverableOrderIds.length > 0) {
2474
- if (!isPartialTpsl) {
2475
- return createProtectionLostResult(recoverableOrderIds);
2476
- }
2477
- return (0, hyperLiquidValidation_js_1.createErrorResult)(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.TPSL_UPDATE_FAILED), {
2478
- success: false,
2479
- childOrderIds: recoverableOrderIds,
2480
- });
2507
+ }
2508
+ // A filled replacement may have changed or closed the position, while
2509
+ // an uncancelled replacement may still protect it. Restoring the old
2510
+ // whole-position triggers in either case risks stale or duplicate
2511
+ // protection, so return those IDs for caller reconciliation instead.
2512
+ if (recoverableOrderIds.length > 0) {
2513
+ if (!isPartialTpsl) {
2514
+ return createProtectionLostResult(recoverableOrderIds);
2481
2515
  }
2482
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.TPSL_UPDATE_FAILED);
2516
+ return (0, hyperLiquidValidation_js_1.createErrorResult)(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.TPSL_UPDATE_FAILED), {
2517
+ success: false,
2518
+ childOrderIds: recoverableOrderIds,
2519
+ });
2483
2520
  }
2484
- return {
2485
- success: true,
2486
- orderId: 'TP/SL orders placed',
2487
- };
2521
+ throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.TPSL_UPDATE_FAILED);
2488
2522
  }
2489
2523
  catch (error) {
2490
2524
  __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").logger.error((0, errorUtils_js_1.ensureError)(error, 'HyperLiquidProvider.updatePositionTPSL'), __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getErrorContext).call(this, 'updatePositionTPSL', {
@@ -9561,6 +9595,84 @@ async function _HyperLiquidProvider_cancelOrderRequestBatch(exchangeClient, requ
9561
9595
  }
9562
9596
  }
9563
9597
  return undefined;
9598
+ }, _HyperLiquidProvider_readTpslOrderPlacementOutcome = function _HyperLiquidProvider_readTpslOrderPlacementOutcome(status) {
9599
+ const placement = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderPlacementOutcome).call(this, status);
9600
+ if (placement) {
9601
+ return placement;
9602
+ }
9603
+ if (status === 'waitingForTrigger') {
9604
+ return { state: 'waitingForTrigger' };
9605
+ }
9606
+ if (isStatusObject(status) && (0, utils_1.hasProperty)(status, 'error')) {
9607
+ return { state: 'rejected' };
9608
+ }
9609
+ return { state: 'unknown' };
9610
+ }, _HyperLiquidProvider_reconcileTpslOrderPlacementOutcomes =
9611
+ /**
9612
+ * Recover IDs omitted from waiting trigger acknowledgements.
9613
+ *
9614
+ * HyperLiquid does not preserve submission order in `frontendOpenOrders`, so
9615
+ * each unresolved leg is matched by its submitted trigger attributes and
9616
+ * accepted only when exactly one new order qualifies.
9617
+ *
9618
+ * @param params - Reconciliation parameters.
9619
+ * @param params.outcomes - Classified placement responses.
9620
+ * @param params.orders - Submitted TP/SL orders.
9621
+ * @param params.previousOrderIds - Order IDs observed before submission.
9622
+ * @param params.dexName - DEX queried for the placement.
9623
+ * @param params.symbol - Market the triggers protect.
9624
+ * @returns Outcomes enriched with unambiguous exchange order IDs.
9625
+ */
9626
+ async function _HyperLiquidProvider_reconcileTpslOrderPlacementOutcomes(params) {
9627
+ if (!params.outcomes.some((outcome) => outcome.state === 'waitingForTrigger' &&
9628
+ outcome.orderId === undefined)) {
9629
+ return params.outcomes;
9630
+ }
9631
+ try {
9632
+ const appearedOrders = (await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_fetchOpenOrders).call(this, { dexName: params.dexName })).filter((order) => order.coin === params.symbol &&
9633
+ order.reduceOnly &&
9634
+ order.isTrigger &&
9635
+ !params.previousOrderIds.has(order.oid.toString()));
9636
+ const claimedOrderIds = new Set();
9637
+ return params.outcomes.map((outcome, index) => {
9638
+ if (outcome.orderId !== undefined ||
9639
+ outcome.state !== 'waitingForTrigger') {
9640
+ return outcome;
9641
+ }
9642
+ const submittedOrder = params.orders[index];
9643
+ const trigger = (0, utils_1.hasProperty)(submittedOrder.t, 'trigger')
9644
+ ? submittedOrder.t.trigger
9645
+ : undefined;
9646
+ if (!isStatusObject(trigger) ||
9647
+ !(0, utils_1.hasProperty)(trigger, 'triggerPx') ||
9648
+ (typeof trigger.triggerPx !== 'string' &&
9649
+ typeof trigger.triggerPx !== 'number') ||
9650
+ !(0, utils_1.hasProperty)(trigger, 'tpsl') ||
9651
+ (trigger.tpsl !== 'tp' && trigger.tpsl !== 'sl')) {
9652
+ return outcome;
9653
+ }
9654
+ const submittedSize = parseFloat(String(submittedOrder.s));
9655
+ const submittedTriggerPrice = parseFloat(String(trigger.triggerPx));
9656
+ const expectedOrderType = trigger.tpsl === 'tp' ? 'Take Profit' : 'Stop';
9657
+ const candidates = appearedOrders.filter((order) => !claimedOrderIds.has(order.oid) &&
9658
+ (order.side === 'B') === submittedOrder.b &&
9659
+ parseFloat(order.sz) === submittedSize &&
9660
+ parseFloat(order.triggerPx) === submittedTriggerPrice &&
9661
+ order.orderType.includes(expectedOrderType));
9662
+ if (candidates.length !== 1) {
9663
+ return outcome;
9664
+ }
9665
+ claimedOrderIds.add(candidates[0].oid);
9666
+ return { ...outcome, orderId: candidates[0].oid.toString() };
9667
+ });
9668
+ }
9669
+ catch (error) {
9670
+ __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Could not reconcile TP/SL placement order IDs', {
9671
+ error: (0, errorUtils_js_1.ensureError)(error, 'HyperLiquidProvider.reconcileTpslOrderPlacementOutcomes').message,
9672
+ symbol: params.symbol,
9673
+ });
9674
+ return params.outcomes;
9675
+ }
9564
9676
  }, _HyperLiquidProvider_readOrderIdFromStatus = function _HyperLiquidProvider_readOrderIdFromStatus(status) {
9565
9677
  return __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderPlacementOutcome).call(this, status)?.orderId;
9566
9678
  }, _HyperLiquidProvider_getDiscountedBuilderFee = function _HyperLiquidProvider_getDiscountedBuilderFee() {