@metamask-previews/perps-controller 4.0.0-preview-56dd1249f → 4.0.0-preview-c3dc0c91e
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 +0 -16
- package/dist/constants/eventNames.cjs +0 -5
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +0 -4
- package/dist/constants/eventNames.d.cts.map +1 -1
- package/dist/constants/eventNames.d.mts +0 -4
- package/dist/constants/eventNames.d.mts.map +1 -1
- package/dist/constants/eventNames.mjs +0 -5
- package/dist/constants/eventNames.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +57 -230
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +57 -230
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +20 -108
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts +0 -19
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts +0 -19
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +20 -108
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.cjs +0 -20
- package/dist/services/HyperLiquidWalletService.cjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.cts +0 -6
- package/dist/services/HyperLiquidWalletService.d.cts.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.mts +0 -6
- package/dist/services/HyperLiquidWalletService.d.mts.map +1 -1
- package/dist/services/HyperLiquidWalletService.mjs +2 -22
- package/dist/services/HyperLiquidWalletService.mjs.map +1 -1
- package/dist/services/TradingReadinessCache.cjs +16 -16
- package/dist/services/TradingReadinessCache.cjs.map +1 -1
- package/dist/services/TradingReadinessCache.d.cts +12 -12
- package/dist/services/TradingReadinessCache.d.mts +12 -12
- package/dist/services/TradingReadinessCache.mjs +16 -16
- package/dist/services/TradingReadinessCache.mjs.map +1 -1
- package/dist/types/hyperliquid-types.cjs +0 -39
- package/dist/types/hyperliquid-types.cjs.map +1 -1
- package/dist/types/hyperliquid-types.d.cts +2 -34
- package/dist/types/hyperliquid-types.d.cts.map +1 -1
- package/dist/types/hyperliquid-types.d.mts +2 -34
- package/dist/types/hyperliquid-types.d.mts.map +1 -1
- package/dist/types/hyperliquid-types.mjs +1 -37
- package/dist/types/hyperliquid-types.mjs.map +1 -1
- package/dist/types/index.cjs +0 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +1 -2
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +1 -2
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs +0 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/accountUtils.cjs +8 -20
- package/dist/utils/accountUtils.cjs.map +1 -1
- package/dist/utils/accountUtils.d.cts +5 -9
- package/dist/utils/accountUtils.d.cts.map +1 -1
- package/dist/utils/accountUtils.d.mts +5 -9
- package/dist/utils/accountUtils.d.mts.map +1 -1
- package/dist/utils/accountUtils.mjs +8 -20
- package/dist/utils/accountUtils.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -9,10 +9,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _HyperLiquidProvider_instances, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets,
|
|
12
|
+
var _HyperLiquidProvider_instances, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useDexAbstraction, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_ensureDexAbstractionEnabled, _HyperLiquidProvider_ensureReady, _HyperLiquidProvider_tradingSetupPromise, _HyperLiquidProvider_tradingSetupComplete, _HyperLiquidProvider_ensureReadyForTrading, _HyperLiquidProvider_getOrFetchPrice, _HyperLiquidProvider_filterFills, _HyperLiquidProvider_getAllAvailableDexs, _HyperLiquidProvider_getValidatedDexs, _HyperLiquidProvider_fetchValidatedDexsInternal, _HyperLiquidProvider_getCachedMeta, _HyperLiquidProvider_backfillAssetMapForDex, _HyperLiquidProvider_getAssetIdWithRepair, _HyperLiquidProvider_getCachedSpotMeta, _HyperLiquidProvider_getCachedPerpDexs, _HyperLiquidProvider_calculateHip3FeeMultiplier, _HyperLiquidProvider_getCacheKey, _HyperLiquidProvider_fetchMarketsForDex, _HyperLiquidProvider_getUsdcTokenId, _HyperLiquidProvider_isUsdhCollateralDex, _HyperLiquidProvider_getSpotUsdhBalance, _HyperLiquidProvider_getSpotUsdcBalance, _HyperLiquidProvider_transferUsdcToSpot, _HyperLiquidProvider_swapUsdcToUsdh, _HyperLiquidProvider_ensureUsdhCollateralForOrder, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _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_getStandaloneValidatedDexs, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _HyperLiquidProvider_mergeDexResultsInto, _HyperLiquidProvider_cacheFreshMarketDataSnapshot, _HyperLiquidProvider_getStaleMarketDataSnapshot, _HyperLiquidProvider_isFeeCacheValid, _HyperLiquidProvider_getBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
|
|
13
13
|
import { hasProperty } from "@metamask/utils";
|
|
14
14
|
import { v4 as uuidv4 } from "uuid";
|
|
15
|
-
import { PERPS_EVENT_PROPERTY, PERPS_EVENT_VALUE } from "../constants/eventNames.mjs";
|
|
16
15
|
import { BASIS_POINTS_DIVISOR, BUILDER_FEE_CONFIG, FEE_RATES, getBridgeInfo, getChainId, HIP3_ASSET_MARKET_TYPES, HIP3_FEE_CONFIG, HIP3_MARGIN_CONFIG, HYPERLIQUID_WITHDRAWAL_MINUTES, REFERRAL_CONFIG, SPOT_ASSET_ID_OFFSET, TRADING_DEFAULTS, USDC_DECIMALS, USDH_CONFIG } from "../constants/hyperLiquidConfig.mjs";
|
|
17
16
|
import { ORDER_SLIPPAGE_CONFIG, PERFORMANCE_CONFIG, PERPS_CONSTANTS, TP_SL_CONFIG, WITHDRAWAL_CONSTANTS } from "../constants/perpsConfig.mjs";
|
|
18
17
|
import { PERPS_TRANSACTIONS_HISTORY_CONSTANTS } from "../constants/transactionsHistoryConfig.mjs";
|
|
@@ -22,8 +21,6 @@ import { HyperLiquidClientService, WebSocketConnectionState } from "../services/
|
|
|
22
21
|
import { HyperLiquidSubscriptionService } from "../services/HyperLiquidSubscriptionService.mjs";
|
|
23
22
|
import { HyperLiquidWalletService } from "../services/HyperLiquidWalletService.mjs";
|
|
24
23
|
import { TradingReadinessCache, PerpsSigningCache } from "../services/TradingReadinessCache.mjs";
|
|
25
|
-
import { PerpsAnalyticsEvent } from "../types/index.mjs";
|
|
26
|
-
import { HL_ABSTRACTION_WIRE, HL_UNIFIED_ACCOUNT_MODE, hyperLiquidModeFoldsSpot } from "../types/hyperliquid-types.mjs";
|
|
27
24
|
import { addSpotBalanceToAccountState, aggregateAccountStates } from "../utils/accountUtils.mjs";
|
|
28
25
|
import { ensureError } from "../utils/errorUtils.mjs";
|
|
29
26
|
import { adaptAccountStateFromSDK, adaptHyperLiquidLedgerUpdateToUserHistoryItem, adaptMarketFromSDK, adaptOrderFromSDK, adaptPositionFromSDK, buildAssetMapping, formatHyperLiquidPrice, formatHyperLiquidSize, parseAssetName } from "../utils/hyperLiquidAdapter.mjs";
|
|
@@ -99,23 +96,11 @@ export class HyperLiquidProvider {
|
|
|
99
96
|
_HyperLiquidProvider_hip3Enabled.set(this, void 0);
|
|
100
97
|
_HyperLiquidProvider_allowlistMarkets.set(this, void 0);
|
|
101
98
|
_HyperLiquidProvider_blocklistMarkets.set(this, void 0);
|
|
102
|
-
|
|
103
|
-
// to true and is the expected production state after HL's DEX Abstraction
|
|
104
|
-
// deprecation. Kept as a constructor option (not removed) so we can
|
|
105
|
-
// disable the migration via a hot-fix release if a regression surfaces
|
|
106
|
-
// in the wild — flipping this to false reverts to the legacy programmatic
|
|
107
|
-
// HIP-3 transfer path that already lives in the codebase.
|
|
108
|
-
_HyperLiquidProvider_useUnifiedAccount.set(this, void 0);
|
|
99
|
+
_HyperLiquidProvider_useDexAbstraction.set(this, void 0);
|
|
109
100
|
// True once DEX discovery has succeeded with real data (not a fallback).
|
|
110
101
|
// When false, #ensureReadyPromise is reset after each init so the next
|
|
111
102
|
// caller retries DEX discovery instead of reusing a degraded mapping.
|
|
112
103
|
_HyperLiquidProvider_dexDiscoveryComplete.set(this, false);
|
|
113
|
-
// True when the most recent #ensureUnifiedAccountEnabled run ended in a
|
|
114
|
-
// transient state that warrants retry (silent agent-key failure, REST
|
|
115
|
-
// userAbstraction lookup failure, or keyring locked). #ensureReady resets
|
|
116
|
-
// its memoized promise when this is set so the next entry retries the
|
|
117
|
-
// migration instead of returning the cached resolved promise.
|
|
118
|
-
_HyperLiquidProvider_unifiedAccountSetupNeedsRetry.set(this, false);
|
|
119
104
|
// Pending promise to deduplicate concurrent getValidatedDexs() calls
|
|
120
105
|
_HyperLiquidProvider_pendingValidatedDexsPromise.set(this, null);
|
|
121
106
|
// Cache for USDC token ID from spot metadata
|
|
@@ -156,8 +141,8 @@ export class HyperLiquidProvider {
|
|
|
156
141
|
__classPrivateFieldSet(this, _HyperLiquidProvider_hip3Enabled, options.hip3Enabled ?? false, "f");
|
|
157
142
|
__classPrivateFieldSet(this, _HyperLiquidProvider_allowlistMarkets, options.allowlistMarkets ?? [], "f");
|
|
158
143
|
__classPrivateFieldSet(this, _HyperLiquidProvider_blocklistMarkets, options.blocklistMarkets ?? [], "f");
|
|
159
|
-
// Attempt
|
|
160
|
-
__classPrivateFieldSet(this,
|
|
144
|
+
// Attempt native balance abstraction, fallback to programmatic transfer if unsupported
|
|
145
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_useDexAbstraction, options.useDexAbstraction ?? true, "f");
|
|
161
146
|
// Initialize services with injected platform dependencies
|
|
162
147
|
__classPrivateFieldSet(this, _HyperLiquidProvider_clientService, new HyperLiquidClientService(__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f"), {
|
|
163
148
|
isTestnet,
|
|
@@ -756,7 +741,7 @@ export class HyperLiquidProvider {
|
|
|
756
741
|
const closeSize = Math.abs(positionSize);
|
|
757
742
|
const totalMarginUsed = parseFloat(position.marginUsed);
|
|
758
743
|
// Track HIP-3 transfers (full position close means all margin is freed)
|
|
759
|
-
if (isHip3Position && dexName && !__classPrivateFieldGet(this,
|
|
744
|
+
if (isHip3Position && dexName && !__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
760
745
|
hip3Transfers.push({
|
|
761
746
|
sourceDex: dexName,
|
|
762
747
|
freedMargin: totalMarginUsed,
|
|
@@ -810,7 +795,7 @@ export class HyperLiquidProvider {
|
|
|
810
795
|
(hasProperty(stat, 'filled') || hasProperty(stat, 'resting'))).length;
|
|
811
796
|
const failureCount = statuses.length - successCount;
|
|
812
797
|
// Handle HIP-3 margin transfers for successful closes
|
|
813
|
-
if (!__classPrivateFieldGet(this,
|
|
798
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
814
799
|
for (let i = 0; i < statuses.length; i++) {
|
|
815
800
|
const status = statuses[i];
|
|
816
801
|
const isSuccess = isStatusObject(status) &&
|
|
@@ -1178,7 +1163,7 @@ export class HyperLiquidProvider {
|
|
|
1178
1163
|
if (result.success &&
|
|
1179
1164
|
isHip3Position &&
|
|
1180
1165
|
hip3Dex &&
|
|
1181
|
-
!__classPrivateFieldGet(this,
|
|
1166
|
+
!__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
1182
1167
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed successfully, initiating manual auto-transfer back');
|
|
1183
1168
|
// Non-blocking: Transfer freed margin back to main DEX
|
|
1184
1169
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_autoTransferBackAfterClose).call(this, {
|
|
@@ -1189,8 +1174,8 @@ export class HyperLiquidProvider {
|
|
|
1189
1174
|
else if (result.success &&
|
|
1190
1175
|
isHip3Position &&
|
|
1191
1176
|
hip3Dex &&
|
|
1192
|
-
__classPrivateFieldGet(this,
|
|
1193
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed -
|
|
1177
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
1178
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed - DEX abstraction will auto-return freed margin', {
|
|
1194
1179
|
coin: params.symbol,
|
|
1195
1180
|
dex: hip3Dex,
|
|
1196
1181
|
note: 'HyperLiquid handles return automatically',
|
|
@@ -1947,7 +1932,7 @@ export class HyperLiquidProvider {
|
|
|
1947
1932
|
isTestnet: __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode(),
|
|
1948
1933
|
});
|
|
1949
1934
|
const dexs = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getStandaloneValidatedDexs).call(this);
|
|
1950
|
-
const [standaloneSpotStateResult, standalonePerpsResults
|
|
1935
|
+
const [standaloneSpotStateResult, standalonePerpsResults] = await Promise.all([
|
|
1951
1936
|
standaloneInfoClient
|
|
1952
1937
|
.spotClearinghouseState({ user: userAddress })
|
|
1953
1938
|
.catch((error) => {
|
|
@@ -1957,21 +1942,11 @@ export class HyperLiquidProvider {
|
|
|
1957
1942
|
return null;
|
|
1958
1943
|
}),
|
|
1959
1944
|
queryStandaloneClearinghouseStates(standaloneInfoClient, userAddress, dexs),
|
|
1960
|
-
standaloneInfoClient
|
|
1961
|
-
.userAbstraction({ user: userAddress })
|
|
1962
|
-
.catch((error) => {
|
|
1963
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Standalone userAbstraction fetch failed; spot fold disabled until the mode resolves', {
|
|
1964
|
-
error: ensureError(error, 'HyperLiquidProvider.getAccountState.standalone.abstraction').message,
|
|
1965
|
-
});
|
|
1966
|
-
return null;
|
|
1967
|
-
}),
|
|
1968
1945
|
]);
|
|
1969
1946
|
// Aggregate account states across all DEXs, then apply spot-backed
|
|
1970
1947
|
// adjustments so streamed/standalone/full paths report the same totals.
|
|
1971
1948
|
const dexAccountStates = standalonePerpsResults.map((perpsState) => adaptAccountStateFromSDK(perpsState));
|
|
1972
|
-
const aggregatedAccountState = addSpotBalanceToAccountState(aggregateAccountStates(dexAccountStates), standaloneSpotStateResult
|
|
1973
|
-
foldIntoCollateral: hyperLiquidModeFoldsSpot(standaloneAbstractionResult),
|
|
1974
|
-
});
|
|
1949
|
+
const aggregatedAccountState = addSpotBalanceToAccountState(aggregateAccountStates(dexAccountStates), standaloneSpotStateResult);
|
|
1975
1950
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: standalone account state fetched', { totalBalance: aggregatedAccountState.totalBalance });
|
|
1976
1951
|
return aggregatedAccountState;
|
|
1977
1952
|
}
|
|
@@ -1985,20 +1960,11 @@ export class HyperLiquidProvider {
|
|
|
1985
1960
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Network mode:', __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode() ? 'TESTNET' : 'MAINNET');
|
|
1986
1961
|
// Get Spot balance (global, not DEX-specific) and Perps states across all DEXs.
|
|
1987
1962
|
// One transient DEX failure should not blank the entire account state.
|
|
1988
|
-
const [spotStateResult, perpsStateResult
|
|
1963
|
+
const [spotStateResult, perpsStateResult] = await Promise.allSettled([
|
|
1989
1964
|
infoClient.spotClearinghouseState({ user: userAddress }),
|
|
1990
1965
|
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_queryUserDataAcrossDexs).call(this, { user: userAddress }, (userParam) => infoClient.clearinghouseState(userParam)),
|
|
1991
|
-
infoClient.userAbstraction({ user: userAddress }),
|
|
1992
1966
|
]);
|
|
1993
1967
|
const spotState = spotStateResult.status === 'fulfilled' ? spotStateResult.value : null;
|
|
1994
|
-
const abstractionMode = abstractionResult.status === 'fulfilled'
|
|
1995
|
-
? abstractionResult.value
|
|
1996
|
-
: null;
|
|
1997
|
-
if (abstractionResult.status === 'rejected') {
|
|
1998
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('User abstraction fetch failed; spot fold disabled until the mode resolves', {
|
|
1999
|
-
error: ensureError(abstractionResult.reason, 'HyperLiquidProvider.getAccountState.abstraction').message,
|
|
2000
|
-
});
|
|
2001
|
-
}
|
|
2002
1968
|
const perpsResponse = perpsStateResult.status === 'fulfilled'
|
|
2003
1969
|
? perpsStateResult.value
|
|
2004
1970
|
: {
|
|
@@ -2045,9 +2011,7 @@ export class HyperLiquidProvider {
|
|
|
2045
2011
|
});
|
|
2046
2012
|
return dexAccountState;
|
|
2047
2013
|
});
|
|
2048
|
-
const aggregatedAccountState = addSpotBalanceToAccountState(aggregateAccountStates(dexAccountStates), spotState
|
|
2049
|
-
foldIntoCollateral: hyperLiquidModeFoldsSpot(abstractionMode),
|
|
2050
|
-
});
|
|
2014
|
+
const aggregatedAccountState = addSpotBalanceToAccountState(aggregateAccountStates(dexAccountStates), spotState);
|
|
2051
2015
|
// Build per-sub-account breakdown (HIP-3 DEXs map to sub-accounts)
|
|
2052
2016
|
const subAccountBreakdown = {};
|
|
2053
2017
|
perpsStateResults.forEach((result) => {
|
|
@@ -2721,20 +2685,14 @@ export class HyperLiquidProvider {
|
|
|
2721
2685
|
// Step 4: Ensure client is ready
|
|
2722
2686
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: ENSURING CLIENT READY');
|
|
2723
2687
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReady).call(this);
|
|
2724
|
-
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, { allowUserSigning: true });
|
|
2725
2688
|
const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
2726
2689
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: CLIENT READY');
|
|
2727
2690
|
// Step 5: Validate amount against account balance
|
|
2728
2691
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: CHECKING ACCOUNT BALANCE');
|
|
2729
2692
|
const accountState = await this.getAccountState();
|
|
2730
|
-
|
|
2731
|
-
// includes collateral HL can draw in target mode. The larger balance
|
|
2732
|
-
// contract will replace this with an explicit withdrawableBalance field.
|
|
2733
|
-
const availableBalance = parseFloat(accountState.availableToTradeBalance ?? accountState.availableBalance);
|
|
2693
|
+
const availableBalance = parseFloat(accountState.availableBalance);
|
|
2734
2694
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: ACCOUNT BALANCE', {
|
|
2735
2695
|
availableBalance,
|
|
2736
|
-
clearinghouseAvailableBalance: accountState.availableBalance,
|
|
2737
|
-
availableToTradeBalance: accountState.availableToTradeBalance,
|
|
2738
2696
|
totalBalance: accountState.totalBalance,
|
|
2739
2697
|
marginUsed: accountState.marginUsed,
|
|
2740
2698
|
unrealizedPnl: accountState.unrealizedPnl,
|
|
@@ -3547,7 +3505,7 @@ export class HyperLiquidProvider {
|
|
|
3547
3505
|
// Clear session caches (ensures fresh state on reconnect/account switch)
|
|
3548
3506
|
__classPrivateFieldGet(this, _HyperLiquidProvider_referralCheckCache, "f").clear();
|
|
3549
3507
|
__classPrivateFieldGet(this, _HyperLiquidProvider_builderFeeCheckCache, "f").clear();
|
|
3550
|
-
// NOTE:
|
|
3508
|
+
// NOTE: DexAbstractionCache is global and NOT cleared on disconnect
|
|
3551
3509
|
// to prevent repeated signing requests across reconnections
|
|
3552
3510
|
__classPrivateFieldGet(this, _HyperLiquidProvider_cachedMetaByDex, "f").clear();
|
|
3553
3511
|
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedSpotMeta, null, "f");
|
|
@@ -3727,7 +3685,7 @@ export class HyperLiquidProvider {
|
|
|
3727
3685
|
return `${baseUrl}/explorer`;
|
|
3728
3686
|
}
|
|
3729
3687
|
}
|
|
3730
|
-
_HyperLiquidProvider_deps = new WeakMap(), _HyperLiquidProvider_clientService = new WeakMap(), _HyperLiquidProvider_walletService = new WeakMap(), _HyperLiquidProvider_subscriptionService = new WeakMap(), _HyperLiquidProvider_symbolToAssetId = new WeakMap(), _HyperLiquidProvider_userFeeCache = new WeakMap(), _HyperLiquidProvider_maxLeverageCache = new WeakMap(), _HyperLiquidProvider_cachedMetaByDex = new WeakMap(), _HyperLiquidProvider_cachedMarketDataWithPrices = new WeakMap(), _HyperLiquidProvider_cachedSpotMeta = new WeakMap(), _HyperLiquidProvider_dexDiscoveryCache = new WeakMap(), _HyperLiquidProvider_referralCheckCache = new WeakMap(), _HyperLiquidProvider_builderFeeCheckCache = new WeakMap(), _HyperLiquidProvider_ensureReadyPromise = new WeakMap(), _HyperLiquidProvider_pendingBuilderFeeApprovals = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_hip3Enabled = new WeakMap(), _HyperLiquidProvider_allowlistMarkets = new WeakMap(), _HyperLiquidProvider_blocklistMarkets = new WeakMap(),
|
|
3688
|
+
_HyperLiquidProvider_deps = new WeakMap(), _HyperLiquidProvider_clientService = new WeakMap(), _HyperLiquidProvider_walletService = new WeakMap(), _HyperLiquidProvider_subscriptionService = new WeakMap(), _HyperLiquidProvider_symbolToAssetId = new WeakMap(), _HyperLiquidProvider_userFeeCache = new WeakMap(), _HyperLiquidProvider_maxLeverageCache = new WeakMap(), _HyperLiquidProvider_cachedMetaByDex = new WeakMap(), _HyperLiquidProvider_cachedMarketDataWithPrices = new WeakMap(), _HyperLiquidProvider_cachedSpotMeta = new WeakMap(), _HyperLiquidProvider_dexDiscoveryCache = new WeakMap(), _HyperLiquidProvider_referralCheckCache = new WeakMap(), _HyperLiquidProvider_builderFeeCheckCache = new WeakMap(), _HyperLiquidProvider_ensureReadyPromise = new WeakMap(), _HyperLiquidProvider_pendingBuilderFeeApprovals = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_hip3Enabled = new WeakMap(), _HyperLiquidProvider_allowlistMarkets = new WeakMap(), _HyperLiquidProvider_blocklistMarkets = new WeakMap(), _HyperLiquidProvider_useDexAbstraction = new WeakMap(), _HyperLiquidProvider_dexDiscoveryComplete = new WeakMap(), _HyperLiquidProvider_pendingValidatedDexsPromise = new WeakMap(), _HyperLiquidProvider_cachedUsdcTokenId = new WeakMap(), _HyperLiquidProvider_errorMappings = new WeakMap(), _HyperLiquidProvider_clientsInitialized = new WeakMap(), _HyperLiquidProvider_initializationPromise = new WeakMap(), _HyperLiquidProvider_messenger = new WeakMap(), _HyperLiquidProvider_builderAddressTestnet = new WeakMap(), _HyperLiquidProvider_builderAddressMainnet = new WeakMap(), _HyperLiquidProvider_tradingSetupPromise = new WeakMap(), _HyperLiquidProvider_tradingSetupComplete = new WeakMap(), _HyperLiquidProvider_instances = new WeakSet(), _HyperLiquidProvider_compilePatternsSafely = function _HyperLiquidProvider_compilePatternsSafely(patterns, listName) {
|
|
3731
3689
|
const compiled = [];
|
|
3732
3690
|
for (const pattern of patterns) {
|
|
3733
3691
|
try {
|
|
@@ -3798,9 +3756,9 @@ async function _HyperLiquidProvider_ensureClientsInitialized() {
|
|
|
3798
3756
|
// so future calls can retry if needed
|
|
3799
3757
|
__classPrivateFieldSet(this, _HyperLiquidProvider_initializationPromise, null, "f");
|
|
3800
3758
|
}
|
|
3801
|
-
},
|
|
3759
|
+
}, _HyperLiquidProvider_ensureDexAbstractionEnabled =
|
|
3802
3760
|
/**
|
|
3803
|
-
* Attempt to enable
|
|
3761
|
+
* Attempt to enable HIP-3 native balance abstraction
|
|
3804
3762
|
*
|
|
3805
3763
|
* If successful, HyperLiquid automatically manages collateral transfers for HIP-3 orders.
|
|
3806
3764
|
* If not supported, disables the flag to trigger programmatic transfer fallback.
|
|
@@ -3808,24 +3766,10 @@ async function _HyperLiquidProvider_ensureClientsInitialized() {
|
|
|
3808
3766
|
* IMPORTANT: Uses global singleton cache to prevent repeated signing requests
|
|
3809
3767
|
* across provider reconnections (critical for hardware wallets).
|
|
3810
3768
|
*
|
|
3811
|
-
* @param options - Optional configuration.
|
|
3812
|
-
* @param options.allowUserSigning - When true, runs the EIP-712 user-signed migration for `dexAbstraction` accounts. Defaults to false so init does not surface a signing prompt; action-time entry points (trading, withdraw) pass true.
|
|
3813
3769
|
* @private
|
|
3814
3770
|
*/
|
|
3815
|
-
async function
|
|
3816
|
-
|
|
3817
|
-
// the agent path for that transition). Init calls with allowUserSigning=false so
|
|
3818
|
-
// viewing the Perps section never surfaces a signing dialog. Trading and
|
|
3819
|
-
// withdraw entry points pass allowUserSigning=true to drive the migration when
|
|
3820
|
-
// the user actually intends to act.
|
|
3821
|
-
const allowUserSigning = options?.allowUserSigning ?? false;
|
|
3822
|
-
// Optimistic reset — set true below only at the failure points that
|
|
3823
|
-
// warrant retry (silent agent failure, REST lookup failure, keyring
|
|
3824
|
-
// locked). Final-state outcomes (success, prompted-failure cached,
|
|
3825
|
-
// already-on-compatible, defer, unknown mode, feature off) leave it
|
|
3826
|
-
// false so #ensureReady can keep the memoized promise.
|
|
3827
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, false, "f");
|
|
3828
|
-
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
3771
|
+
async function _HyperLiquidProvider_ensureDexAbstractionEnabled() {
|
|
3772
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
3829
3773
|
return; // Feature disabled
|
|
3830
3774
|
}
|
|
3831
3775
|
const userAddress = await __classPrivateFieldGet(this, _HyperLiquidProvider_walletService, "f").getUserAddressWithDefault();
|
|
@@ -3834,7 +3778,7 @@ async function _HyperLiquidProvider_ensureUnifiedAccountEnabled(options) {
|
|
|
3834
3778
|
// This is CRITICAL for hardware wallets to prevent QR popup spam
|
|
3835
3779
|
const cachedStatus = TradingReadinessCache.get(network, userAddress);
|
|
3836
3780
|
if (cachedStatus?.attempted) {
|
|
3837
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3781
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: DEX abstraction already attempted (from global cache)', {
|
|
3838
3782
|
user: userAddress,
|
|
3839
3783
|
network,
|
|
3840
3784
|
enabled: cachedStatus.enabled,
|
|
@@ -3844,178 +3788,75 @@ async function _HyperLiquidProvider_ensureUnifiedAccountEnabled(options) {
|
|
|
3844
3788
|
}
|
|
3845
3789
|
// Check if another provider instance is currently attempting this operation
|
|
3846
3790
|
// This prevents concurrent signing attempts across providers during reconnection
|
|
3847
|
-
const inFlightPromise = PerpsSigningCache.isInFlight('
|
|
3791
|
+
const inFlightPromise = PerpsSigningCache.isInFlight('dexAbstraction', network, userAddress);
|
|
3848
3792
|
if (inFlightPromise) {
|
|
3849
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3793
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: DEX abstraction in-flight, waiting...', { network, userAddress });
|
|
3850
3794
|
await inFlightPromise;
|
|
3851
|
-
//
|
|
3852
|
-
// an init-time call deferred a dexAbstraction migration). If the cache
|
|
3853
|
-
// is still empty and we are an action-time caller (allowUserSigning=true),
|
|
3854
|
-
// we must run our own attempt — otherwise the trade/withdraw would
|
|
3855
|
-
// proceed in the deprecated mode.
|
|
3856
|
-
const postWaitCache = TradingReadinessCache.get(network, userAddress);
|
|
3857
|
-
if (postWaitCache?.attempted) {
|
|
3858
|
-
return;
|
|
3859
|
-
}
|
|
3860
|
-
// Fall through to acquire our own lock and retry.
|
|
3795
|
+
return; // After waiting, the cache should be set by the other provider
|
|
3861
3796
|
}
|
|
3862
3797
|
// Set in-flight lock to prevent concurrent attempts
|
|
3863
|
-
const completeInFlight = PerpsSigningCache.setInFlight('
|
|
3864
|
-
let currentMode;
|
|
3798
|
+
const completeInFlight = PerpsSigningCache.setInFlight('dexAbstraction', network, userAddress);
|
|
3865
3799
|
try {
|
|
3866
3800
|
// Re-check cache after acquiring lock (another provider might have finished)
|
|
3867
3801
|
const recheckCache = TradingReadinessCache.get(network, userAddress);
|
|
3868
3802
|
if (recheckCache?.attempted) {
|
|
3869
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3803
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: DEX abstraction completed by another provider', { network, userAddress });
|
|
3870
3804
|
completeInFlight();
|
|
3871
3805
|
return;
|
|
3872
3806
|
}
|
|
3873
3807
|
const infoClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient();
|
|
3874
|
-
// Check
|
|
3875
|
-
|
|
3808
|
+
// Check if already enabled on-chain (returns boolean | null)
|
|
3809
|
+
const isEnabled = await infoClient.userDexAbstraction({
|
|
3876
3810
|
user: userAddress,
|
|
3877
3811
|
});
|
|
3878
|
-
if (
|
|
3879
|
-
|
|
3880
|
-
//
|
|
3881
|
-
// auto-collateral management for HIP-3 orders and is more capital-efficient.
|
|
3882
|
-
// Downgrading portfolio margin users to unifiedAccount would be harmful,
|
|
3883
|
-
// so we treat both modes as already-enabled and skip migration.
|
|
3884
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Account already in a compatible mode, skipping migration', { user: userAddress, network, mode: currentMode });
|
|
3885
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(PerpsAnalyticsEvent.AccountSetup, {
|
|
3886
|
-
[PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: currentMode,
|
|
3887
|
-
[PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.ALREADY_ENABLED,
|
|
3888
|
-
});
|
|
3812
|
+
if (isEnabled === true) {
|
|
3813
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: DEX abstraction already enabled on-chain', { user: userAddress, network });
|
|
3814
|
+
// Cache the enabled status to skip future checks
|
|
3889
3815
|
TradingReadinessCache.set(network, userAddress, {
|
|
3890
3816
|
attempted: true,
|
|
3891
3817
|
enabled: true,
|
|
3892
3818
|
});
|
|
3893
|
-
// Record the resolved mode in the subscription service so the next
|
|
3894
|
-
// aggregation folds spot correctly without waiting for #refreshSpotState.
|
|
3895
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f").setUserAbstractionMode(userAddress, currentMode);
|
|
3896
|
-
completeInFlight();
|
|
3897
|
-
return;
|
|
3898
|
-
}
|
|
3899
|
-
// Defer the user-signed transition until the user attempts an action.
|
|
3900
|
-
// Cache is intentionally left untouched so the next entry re-evaluates;
|
|
3901
|
-
// the read-only userAbstraction call is cheap and gated by the in-flight
|
|
3902
|
-
// lock, preventing concurrent prompts.
|
|
3903
|
-
if (currentMode === 'dexAbstraction' && !allowUserSigning) {
|
|
3904
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Deferring dexAbstraction → unifiedAccount migration to action time', { user: userAddress, network });
|
|
3905
3819
|
completeInFlight();
|
|
3906
3820
|
return;
|
|
3907
3821
|
}
|
|
3908
|
-
//
|
|
3909
|
-
|
|
3910
|
-
// actually migrate) and avoids re-emitting on every reconnection.
|
|
3911
|
-
if (currentMode !== 'dexAbstraction' &&
|
|
3912
|
-
currentMode !== 'default' &&
|
|
3913
|
-
currentMode !== 'disabled') {
|
|
3914
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unknown abstraction mode, skipping Unified Account migration', { user: userAddress, network, mode: currentMode });
|
|
3915
|
-
completeInFlight();
|
|
3916
|
-
return;
|
|
3917
|
-
}
|
|
3918
|
-
// Track which mode users are currently on before we attempt migration.
|
|
3919
|
-
// This tells us the distribution of legacy modes across our user base.
|
|
3920
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(PerpsAnalyticsEvent.AccountSetup, {
|
|
3921
|
-
[PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: currentMode,
|
|
3922
|
-
[PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.MIGRATION_REQUIRED,
|
|
3923
|
-
});
|
|
3924
|
-
// Enable Unified Account mode.
|
|
3925
|
-
// - default / disabled: agent wallet can do this silently (no prompt)
|
|
3926
|
-
// - dexAbstraction: HL blocks the agent transition — requires the user's main
|
|
3927
|
-
// wallet to sign an EIP-712 action via userSetAbstraction (one-time prompt)
|
|
3928
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Enabling Unified Account mode', {
|
|
3822
|
+
// Enable DEX abstraction (one-time, irreversible, requires signature)
|
|
3823
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Enabling DEX abstraction (requires signature)', {
|
|
3929
3824
|
user: userAddress,
|
|
3930
3825
|
network,
|
|
3931
|
-
previousMode: currentMode,
|
|
3932
3826
|
note: 'HyperLiquid will auto-manage collateral for HIP-3 orders',
|
|
3933
3827
|
});
|
|
3934
3828
|
const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
// so userSetAbstraction (user-signed) is the only path for legacy users.
|
|
3939
|
-
await exchangeClient.userSetAbstraction({
|
|
3940
|
-
user: userAddress,
|
|
3941
|
-
abstraction: HL_UNIFIED_ACCOUNT_MODE,
|
|
3942
|
-
});
|
|
3943
|
-
}
|
|
3944
|
-
else {
|
|
3945
|
-
// default / disabled — silent agent transition, no user prompt
|
|
3946
|
-
await exchangeClient.agentSetAbstraction({
|
|
3947
|
-
abstraction: HL_ABSTRACTION_WIRE.unifiedAccount,
|
|
3948
|
-
});
|
|
3949
|
-
}
|
|
3950
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('✅ HyperLiquidProvider: Unified Account enabled successfully');
|
|
3951
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(PerpsAnalyticsEvent.AccountSetup, {
|
|
3952
|
-
[PERPS_EVENT_PROPERTY.PREVIOUS_ABSTRACTION_MODE]: currentMode,
|
|
3953
|
-
[PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: HL_UNIFIED_ACCOUNT_MODE,
|
|
3954
|
-
[PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.SUCCESS,
|
|
3955
|
-
});
|
|
3829
|
+
await exchangeClient.agentEnableDexAbstraction();
|
|
3830
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('✅ HyperLiquidProvider: DEX abstraction enabled successfully');
|
|
3831
|
+
// Cache success to prevent re-attempts on reconnection
|
|
3956
3832
|
TradingReadinessCache.set(network, userAddress, {
|
|
3957
3833
|
attempted: true,
|
|
3958
3834
|
enabled: true,
|
|
3959
3835
|
});
|
|
3960
|
-
// Record the post-migration mode in the subscription service so it
|
|
3961
|
-
// immediately re-aggregates with fold=true and surfaces the unified
|
|
3962
|
-
// balance rather than waiting for the next #refreshSpotState.
|
|
3963
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f").setUserAbstractionMode(userAddress, HL_UNIFIED_ACCOUNT_MODE);
|
|
3964
3836
|
completeInFlight();
|
|
3965
3837
|
}
|
|
3966
3838
|
catch (error) {
|
|
3967
3839
|
// If keyring is locked, don't cache so it retries when unlocked
|
|
3968
3840
|
if (ensureError(error).message === PERPS_ERROR_CODES.KEYRING_LOCKED) {
|
|
3969
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[
|
|
3970
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, true, "f");
|
|
3841
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[ensureDexAbstractionEnabled] Keyring locked, will retry later');
|
|
3971
3842
|
completeInFlight();
|
|
3972
3843
|
return;
|
|
3973
3844
|
}
|
|
3974
|
-
// Cache failure
|
|
3975
|
-
//
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
// outages and pinning them would leave users stuck in the
|
|
3982
|
-
// deprecated mode for the rest of the session).
|
|
3983
|
-
// Action-time retries pick up the unmigrated state and try again.
|
|
3984
|
-
if (currentMode === 'dexAbstraction') {
|
|
3985
|
-
TradingReadinessCache.set(network, userAddress, {
|
|
3986
|
-
attempted: true,
|
|
3987
|
-
enabled: false,
|
|
3988
|
-
});
|
|
3989
|
-
}
|
|
3990
|
-
else {
|
|
3991
|
-
// Silent agent-key failure (default/disabled) or read-only
|
|
3992
|
-
// userAbstraction lookup failure — neither is a final state, so
|
|
3993
|
-
// signal #ensureReady to drop its memoized promise and retry on
|
|
3994
|
-
// the next entry instead of pinning the user in the deprecated
|
|
3995
|
-
// mode for the provider's lifetime.
|
|
3996
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, true, "f");
|
|
3997
|
-
}
|
|
3998
|
-
const errorMessage = ensureError(error, 'HyperLiquidProvider.ensureUnifiedAccountEnabled').message;
|
|
3999
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unified Account setup failed', {
|
|
3845
|
+
// Cache the attempt (even on failure) to prevent repeated signing requests
|
|
3846
|
+
// This is CRITICAL for hardware wallets - if user rejects, don't ask again
|
|
3847
|
+
TradingReadinessCache.set(network, userAddress, {
|
|
3848
|
+
attempted: true,
|
|
3849
|
+
enabled: false,
|
|
3850
|
+
});
|
|
3851
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: DEX abstraction failed, cached to prevent retries', {
|
|
4000
3852
|
user: userAddress,
|
|
4001
3853
|
network,
|
|
4002
|
-
error:
|
|
4003
|
-
// Cache writes only happen on the user-prompted dexAbstraction
|
|
4004
|
-
// path (see P2-B logic above). Reflect that here so retry
|
|
4005
|
-
// behaviour is debuggable from the log alone.
|
|
4006
|
-
cached: currentMode === 'dexAbstraction',
|
|
4007
|
-
});
|
|
4008
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(PerpsAnalyticsEvent.AccountSetup, {
|
|
4009
|
-
...(currentMode && {
|
|
4010
|
-
[PERPS_EVENT_PROPERTY.PREVIOUS_ABSTRACTION_MODE]: currentMode,
|
|
4011
|
-
[PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: HL_UNIFIED_ACCOUNT_MODE,
|
|
4012
|
-
}),
|
|
4013
|
-
[PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,
|
|
4014
|
-
[PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,
|
|
3854
|
+
error: ensureError(error, 'HyperLiquidProvider.ensureDexAbstractionEnabled').message,
|
|
4015
3855
|
});
|
|
4016
3856
|
completeInFlight();
|
|
4017
|
-
|
|
4018
|
-
|
|
3857
|
+
// Don't blindly disable the flag on any error
|
|
3858
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").logger.error(ensureError(error, 'HyperLiquidProvider.ensureDexAbstractionEnabled'), __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getErrorContext).call(this, 'ensureDexAbstractionEnabled', {
|
|
3859
|
+
note: 'Could not enable DEX abstraction (may already be enabled, user rejected, or network error)',
|
|
4019
3860
|
}));
|
|
4020
3861
|
}
|
|
4021
3862
|
}, _HyperLiquidProvider_ensureReady =
|
|
@@ -4049,14 +3890,9 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
4049
3890
|
});
|
|
4050
3891
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_buildAssetMapping).call(this);
|
|
4051
3892
|
}
|
|
4052
|
-
//
|
|
4053
|
-
//
|
|
4054
|
-
//
|
|
4055
|
-
// trade sees the unified balance. Hardware wallets remain deferred to
|
|
4056
|
-
// action time to avoid QR / Ledger prompt spam while browsing.
|
|
4057
|
-
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, {
|
|
4058
|
-
allowUserSigning: !__classPrivateFieldGet(this, _HyperLiquidProvider_walletService, "f").isSelectedHardwareWallet(),
|
|
4059
|
-
});
|
|
3893
|
+
// NOTE: Signing operations (DEX abstraction, builder fee, referral) are now DEFERRED
|
|
3894
|
+
// They are called on-demand in ensureReadyForTrading() when user attempts to trade
|
|
3895
|
+
// This prevents QR popups when just viewing the Perps section (critical for hardware wallets)
|
|
4060
3896
|
})(), "f");
|
|
4061
3897
|
// Await initialization - keep the promise so subsequent calls resolve immediately
|
|
4062
3898
|
// The promise is only reset in disconnect() for clean reconnection,
|
|
@@ -4068,21 +3904,10 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
4068
3904
|
// will be re-discovered on the next #ensureReady() call.
|
|
4069
3905
|
__classPrivateFieldSet(this, _HyperLiquidProvider_ensureReadyPromise, null, "f");
|
|
4070
3906
|
}
|
|
4071
|
-
else if (__classPrivateFieldGet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, "f")) {
|
|
4072
|
-
// Silent migration / lookup / keyring-locked failure left the cache
|
|
4073
|
-
// empty. Without resetting the memoized promise, subsequent
|
|
4074
|
-
// #ensureReady calls would skip retry and the user would be stuck
|
|
4075
|
-
// in the deprecated mode for the provider's lifetime.
|
|
4076
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_ensureReadyPromise, null, "f");
|
|
4077
|
-
}
|
|
4078
3907
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[ensureReady] Initialization complete');
|
|
4079
3908
|
}, _HyperLiquidProvider_ensureReadyForTrading = async function _HyperLiquidProvider_ensureReadyForTrading() {
|
|
4080
3909
|
// First ensure basic initialization is complete
|
|
4081
3910
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReady).call(this);
|
|
4082
|
-
// dexAbstraction users were deferred during init to avoid an EIP-712 prompt
|
|
4083
|
-
// on Perps section open. Drive the migration here, gated by its own cache so
|
|
4084
|
-
// already-migrated or already-rejected users are not re-prompted.
|
|
4085
|
-
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, { allowUserSigning: true });
|
|
4086
3911
|
// If trading setup already complete, return immediately
|
|
4087
3912
|
if (__classPrivateFieldGet(this, _HyperLiquidProvider_tradingSetupComplete, "f")) {
|
|
4088
3913
|
return;
|
|
@@ -4106,6 +3931,8 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
4106
3931
|
// Don't throw - spotMeta will be fetched on-demand if needed
|
|
4107
3932
|
}
|
|
4108
3933
|
}
|
|
3934
|
+
// Attempt to enable native balance abstraction
|
|
3935
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureDexAbstractionEnabled).call(this);
|
|
4109
3936
|
// Set up builder fee approval
|
|
4110
3937
|
try {
|
|
4111
3938
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureBuilderFeeApproval).call(this);
|
|
@@ -5728,11 +5555,11 @@ async function _HyperLiquidProvider_handleHip3PreOrder(params) {
|
|
|
5728
5555
|
isBuy,
|
|
5729
5556
|
});
|
|
5730
5557
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUsdhCollateralForOrder).call(this, dexName, requiredMargin);
|
|
5731
|
-
//
|
|
5558
|
+
// DEX abstraction will pull USDH from spot automatically
|
|
5732
5559
|
return { transferInfo: null };
|
|
5733
5560
|
}
|
|
5734
|
-
if (__classPrivateFieldGet(this,
|
|
5735
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Using
|
|
5561
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_useDexAbstraction, "f")) {
|
|
5562
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Using DEX abstraction (no manual transfer)', {
|
|
5736
5563
|
symbol,
|
|
5737
5564
|
dex: dexName,
|
|
5738
5565
|
});
|
|
@@ -5761,7 +5588,7 @@ async function _HyperLiquidProvider_handleHip3PreOrder(params) {
|
|
|
5761
5588
|
const errorMsg = transferError?.message || '';
|
|
5762
5589
|
if (errorMsg.includes('Cannot transfer with DEX abstraction enabled')) {
|
|
5763
5590
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Detected DEX abstraction is enabled, switching mode');
|
|
5764
|
-
__classPrivateFieldSet(this,
|
|
5591
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_useDexAbstraction, true, "f");
|
|
5765
5592
|
return { transferInfo: null };
|
|
5766
5593
|
}
|
|
5767
5594
|
throw transferError;
|