@metamask-previews/perps-controller 4.0.0-preview-e0eba6dbb → 4.0.0-preview-56dd1249f
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 +16 -0
- package/dist/constants/eventNames.cjs +5 -0
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +4 -0
- package/dist/constants/eventNames.d.cts.map +1 -1
- package/dist/constants/eventNames.d.mts +4 -0
- package/dist/constants/eventNames.d.mts.map +1 -1
- package/dist/constants/eventNames.mjs +5 -0
- package/dist/constants/eventNames.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +230 -57
- 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 +230 -57
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +108 -20
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts +19 -0
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts +19 -0
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +108 -20
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.cjs +20 -0
- package/dist/services/HyperLiquidWalletService.cjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.cts +6 -0
- package/dist/services/HyperLiquidWalletService.d.cts.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.mts +6 -0
- package/dist/services/HyperLiquidWalletService.d.mts.map +1 -1
- package/dist/services/HyperLiquidWalletService.mjs +22 -2
- 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 +39 -0
- package/dist/types/hyperliquid-types.cjs.map +1 -1
- package/dist/types/hyperliquid-types.d.cts +34 -2
- package/dist/types/hyperliquid-types.d.cts.map +1 -1
- package/dist/types/hyperliquid-types.d.mts +34 -2
- package/dist/types/hyperliquid-types.d.mts.map +1 -1
- package/dist/types/hyperliquid-types.mjs +37 -1
- package/dist/types/hyperliquid-types.mjs.map +1 -1
- package/dist/types/index.cjs +1 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +2 -1
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs +1 -0
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/accountUtils.cjs +20 -8
- package/dist/utils/accountUtils.cjs.map +1 -1
- package/dist/utils/accountUtils.d.cts +9 -5
- package/dist/utils/accountUtils.d.cts.map +1 -1
- package/dist/utils/accountUtils.d.mts +9 -5
- package/dist/utils/accountUtils.d.mts.map +1 -1
- package/dist/utils/accountUtils.mjs +20 -8
- package/dist/utils/accountUtils.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -10,11 +10,12 @@ 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, _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,
|
|
13
|
+
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_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_ensureUnifiedAccountEnabled, _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;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.HyperLiquidProvider = void 0;
|
|
16
16
|
const utils_1 = require("@metamask/utils");
|
|
17
17
|
const uuid_1 = require("uuid");
|
|
18
|
+
const eventNames_1 = require("../constants/eventNames.cjs");
|
|
18
19
|
const hyperLiquidConfig_1 = require("../constants/hyperLiquidConfig.cjs");
|
|
19
20
|
const perpsConfig_1 = require("../constants/perpsConfig.cjs");
|
|
20
21
|
const transactionsHistoryConfig_1 = require("../constants/transactionsHistoryConfig.cjs");
|
|
@@ -24,6 +25,8 @@ const HyperLiquidClientService_1 = require("../services/HyperLiquidClientService
|
|
|
24
25
|
const HyperLiquidSubscriptionService_1 = require("../services/HyperLiquidSubscriptionService.cjs");
|
|
25
26
|
const HyperLiquidWalletService_1 = require("../services/HyperLiquidWalletService.cjs");
|
|
26
27
|
const TradingReadinessCache_1 = require("../services/TradingReadinessCache.cjs");
|
|
28
|
+
const types_1 = require("../types/index.cjs");
|
|
29
|
+
const hyperliquid_types_1 = require("../types/hyperliquid-types.cjs");
|
|
27
30
|
const accountUtils_1 = require("../utils/accountUtils.cjs");
|
|
28
31
|
const errorUtils_1 = require("../utils/errorUtils.cjs");
|
|
29
32
|
const hyperLiquidAdapter_1 = require("../utils/hyperLiquidAdapter.cjs");
|
|
@@ -99,11 +102,23 @@ class HyperLiquidProvider {
|
|
|
99
102
|
_HyperLiquidProvider_hip3Enabled.set(this, void 0);
|
|
100
103
|
_HyperLiquidProvider_allowlistMarkets.set(this, void 0);
|
|
101
104
|
_HyperLiquidProvider_blocklistMarkets.set(this, void 0);
|
|
102
|
-
|
|
105
|
+
// Emergency kill-switch for the Unified Account migration flow. Defaults
|
|
106
|
+
// to true and is the expected production state after HL's DEX Abstraction
|
|
107
|
+
// deprecation. Kept as a constructor option (not removed) so we can
|
|
108
|
+
// disable the migration via a hot-fix release if a regression surfaces
|
|
109
|
+
// in the wild — flipping this to false reverts to the legacy programmatic
|
|
110
|
+
// HIP-3 transfer path that already lives in the codebase.
|
|
111
|
+
_HyperLiquidProvider_useUnifiedAccount.set(this, void 0);
|
|
103
112
|
// True once DEX discovery has succeeded with real data (not a fallback).
|
|
104
113
|
// When false, #ensureReadyPromise is reset after each init so the next
|
|
105
114
|
// caller retries DEX discovery instead of reusing a degraded mapping.
|
|
106
115
|
_HyperLiquidProvider_dexDiscoveryComplete.set(this, false);
|
|
116
|
+
// True when the most recent #ensureUnifiedAccountEnabled run ended in a
|
|
117
|
+
// transient state that warrants retry (silent agent-key failure, REST
|
|
118
|
+
// userAbstraction lookup failure, or keyring locked). #ensureReady resets
|
|
119
|
+
// its memoized promise when this is set so the next entry retries the
|
|
120
|
+
// migration instead of returning the cached resolved promise.
|
|
121
|
+
_HyperLiquidProvider_unifiedAccountSetupNeedsRetry.set(this, false);
|
|
107
122
|
// Pending promise to deduplicate concurrent getValidatedDexs() calls
|
|
108
123
|
_HyperLiquidProvider_pendingValidatedDexsPromise.set(this, null);
|
|
109
124
|
// Cache for USDC token ID from spot metadata
|
|
@@ -144,8 +159,8 @@ class HyperLiquidProvider {
|
|
|
144
159
|
__classPrivateFieldSet(this, _HyperLiquidProvider_hip3Enabled, options.hip3Enabled ?? false, "f");
|
|
145
160
|
__classPrivateFieldSet(this, _HyperLiquidProvider_allowlistMarkets, options.allowlistMarkets ?? [], "f");
|
|
146
161
|
__classPrivateFieldSet(this, _HyperLiquidProvider_blocklistMarkets, options.blocklistMarkets ?? [], "f");
|
|
147
|
-
// Attempt
|
|
148
|
-
__classPrivateFieldSet(this,
|
|
162
|
+
// Attempt unified account mode, fallback to programmatic transfer if unsupported
|
|
163
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_useUnifiedAccount, options.useUnifiedAccount ?? true, "f");
|
|
149
164
|
// Initialize services with injected platform dependencies
|
|
150
165
|
__classPrivateFieldSet(this, _HyperLiquidProvider_clientService, new HyperLiquidClientService_1.HyperLiquidClientService(__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f"), {
|
|
151
166
|
isTestnet,
|
|
@@ -744,7 +759,7 @@ class HyperLiquidProvider {
|
|
|
744
759
|
const closeSize = Math.abs(positionSize);
|
|
745
760
|
const totalMarginUsed = parseFloat(position.marginUsed);
|
|
746
761
|
// Track HIP-3 transfers (full position close means all margin is freed)
|
|
747
|
-
if (isHip3Position && dexName && !__classPrivateFieldGet(this,
|
|
762
|
+
if (isHip3Position && dexName && !__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
748
763
|
hip3Transfers.push({
|
|
749
764
|
sourceDex: dexName,
|
|
750
765
|
freedMargin: totalMarginUsed,
|
|
@@ -798,7 +813,7 @@ class HyperLiquidProvider {
|
|
|
798
813
|
((0, utils_1.hasProperty)(stat, 'filled') || (0, utils_1.hasProperty)(stat, 'resting'))).length;
|
|
799
814
|
const failureCount = statuses.length - successCount;
|
|
800
815
|
// Handle HIP-3 margin transfers for successful closes
|
|
801
|
-
if (!__classPrivateFieldGet(this,
|
|
816
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
802
817
|
for (let i = 0; i < statuses.length; i++) {
|
|
803
818
|
const status = statuses[i];
|
|
804
819
|
const isSuccess = isStatusObject(status) &&
|
|
@@ -1166,7 +1181,7 @@ class HyperLiquidProvider {
|
|
|
1166
1181
|
if (result.success &&
|
|
1167
1182
|
isHip3Position &&
|
|
1168
1183
|
hip3Dex &&
|
|
1169
|
-
!__classPrivateFieldGet(this,
|
|
1184
|
+
!__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
1170
1185
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed successfully, initiating manual auto-transfer back');
|
|
1171
1186
|
// Non-blocking: Transfer freed margin back to main DEX
|
|
1172
1187
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_autoTransferBackAfterClose).call(this, {
|
|
@@ -1177,8 +1192,8 @@ class HyperLiquidProvider {
|
|
|
1177
1192
|
else if (result.success &&
|
|
1178
1193
|
isHip3Position &&
|
|
1179
1194
|
hip3Dex &&
|
|
1180
|
-
__classPrivateFieldGet(this,
|
|
1181
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed -
|
|
1195
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
1196
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Position closed - Unified Account will auto-return freed margin', {
|
|
1182
1197
|
coin: params.symbol,
|
|
1183
1198
|
dex: hip3Dex,
|
|
1184
1199
|
note: 'HyperLiquid handles return automatically',
|
|
@@ -1935,7 +1950,7 @@ class HyperLiquidProvider {
|
|
|
1935
1950
|
isTestnet: __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode(),
|
|
1936
1951
|
});
|
|
1937
1952
|
const dexs = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getStandaloneValidatedDexs).call(this);
|
|
1938
|
-
const [standaloneSpotStateResult, standalonePerpsResults] = await Promise.all([
|
|
1953
|
+
const [standaloneSpotStateResult, standalonePerpsResults, standaloneAbstractionResult,] = await Promise.all([
|
|
1939
1954
|
standaloneInfoClient
|
|
1940
1955
|
.spotClearinghouseState({ user: userAddress })
|
|
1941
1956
|
.catch((error) => {
|
|
@@ -1945,11 +1960,21 @@ class HyperLiquidProvider {
|
|
|
1945
1960
|
return null;
|
|
1946
1961
|
}),
|
|
1947
1962
|
(0, standaloneInfoClient_1.queryStandaloneClearinghouseStates)(standaloneInfoClient, userAddress, dexs),
|
|
1963
|
+
standaloneInfoClient
|
|
1964
|
+
.userAbstraction({ user: userAddress })
|
|
1965
|
+
.catch((error) => {
|
|
1966
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Standalone userAbstraction fetch failed; spot fold disabled until the mode resolves', {
|
|
1967
|
+
error: (0, errorUtils_1.ensureError)(error, 'HyperLiquidProvider.getAccountState.standalone.abstraction').message,
|
|
1968
|
+
});
|
|
1969
|
+
return null;
|
|
1970
|
+
}),
|
|
1948
1971
|
]);
|
|
1949
1972
|
// Aggregate account states across all DEXs, then apply spot-backed
|
|
1950
1973
|
// adjustments so streamed/standalone/full paths report the same totals.
|
|
1951
1974
|
const dexAccountStates = standalonePerpsResults.map((perpsState) => (0, hyperLiquidAdapter_1.adaptAccountStateFromSDK)(perpsState));
|
|
1952
|
-
const aggregatedAccountState = (0, accountUtils_1.addSpotBalanceToAccountState)((0, accountUtils_1.aggregateAccountStates)(dexAccountStates), standaloneSpotStateResult
|
|
1975
|
+
const aggregatedAccountState = (0, accountUtils_1.addSpotBalanceToAccountState)((0, accountUtils_1.aggregateAccountStates)(dexAccountStates), standaloneSpotStateResult, {
|
|
1976
|
+
foldIntoCollateral: (0, hyperliquid_types_1.hyperLiquidModeFoldsSpot)(standaloneAbstractionResult),
|
|
1977
|
+
});
|
|
1953
1978
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: standalone account state fetched', { totalBalance: aggregatedAccountState.totalBalance });
|
|
1954
1979
|
return aggregatedAccountState;
|
|
1955
1980
|
}
|
|
@@ -1963,11 +1988,20 @@ class HyperLiquidProvider {
|
|
|
1963
1988
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Network mode:', __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode() ? 'TESTNET' : 'MAINNET');
|
|
1964
1989
|
// Get Spot balance (global, not DEX-specific) and Perps states across all DEXs.
|
|
1965
1990
|
// One transient DEX failure should not blank the entire account state.
|
|
1966
|
-
const [spotStateResult, perpsStateResult] = await Promise.allSettled([
|
|
1991
|
+
const [spotStateResult, perpsStateResult, abstractionResult] = await Promise.allSettled([
|
|
1967
1992
|
infoClient.spotClearinghouseState({ user: userAddress }),
|
|
1968
1993
|
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_queryUserDataAcrossDexs).call(this, { user: userAddress }, (userParam) => infoClient.clearinghouseState(userParam)),
|
|
1994
|
+
infoClient.userAbstraction({ user: userAddress }),
|
|
1969
1995
|
]);
|
|
1970
1996
|
const spotState = spotStateResult.status === 'fulfilled' ? spotStateResult.value : null;
|
|
1997
|
+
const abstractionMode = abstractionResult.status === 'fulfilled'
|
|
1998
|
+
? abstractionResult.value
|
|
1999
|
+
: null;
|
|
2000
|
+
if (abstractionResult.status === 'rejected') {
|
|
2001
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('User abstraction fetch failed; spot fold disabled until the mode resolves', {
|
|
2002
|
+
error: (0, errorUtils_1.ensureError)(abstractionResult.reason, 'HyperLiquidProvider.getAccountState.abstraction').message,
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
1971
2005
|
const perpsResponse = perpsStateResult.status === 'fulfilled'
|
|
1972
2006
|
? perpsStateResult.value
|
|
1973
2007
|
: {
|
|
@@ -2014,7 +2048,9 @@ class HyperLiquidProvider {
|
|
|
2014
2048
|
});
|
|
2015
2049
|
return dexAccountState;
|
|
2016
2050
|
});
|
|
2017
|
-
const aggregatedAccountState = (0, accountUtils_1.addSpotBalanceToAccountState)((0, accountUtils_1.aggregateAccountStates)(dexAccountStates), spotState
|
|
2051
|
+
const aggregatedAccountState = (0, accountUtils_1.addSpotBalanceToAccountState)((0, accountUtils_1.aggregateAccountStates)(dexAccountStates), spotState, {
|
|
2052
|
+
foldIntoCollateral: (0, hyperliquid_types_1.hyperLiquidModeFoldsSpot)(abstractionMode),
|
|
2053
|
+
});
|
|
2018
2054
|
// Build per-sub-account breakdown (HIP-3 DEXs map to sub-accounts)
|
|
2019
2055
|
const subAccountBreakdown = {};
|
|
2020
2056
|
perpsStateResults.forEach((result) => {
|
|
@@ -2688,14 +2724,20 @@ class HyperLiquidProvider {
|
|
|
2688
2724
|
// Step 4: Ensure client is ready
|
|
2689
2725
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: ENSURING CLIENT READY');
|
|
2690
2726
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReady).call(this);
|
|
2727
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, { allowUserSigning: true });
|
|
2691
2728
|
const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
2692
2729
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: CLIENT READY');
|
|
2693
2730
|
// Step 5: Validate amount against account balance
|
|
2694
2731
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: CHECKING ACCOUNT BALANCE');
|
|
2695
2732
|
const accountState = await this.getAccountState();
|
|
2696
|
-
|
|
2733
|
+
// Release-branch bridge for Unified Account: availableToTradeBalance
|
|
2734
|
+
// includes collateral HL can draw in target mode. The larger balance
|
|
2735
|
+
// contract will replace this with an explicit withdrawableBalance field.
|
|
2736
|
+
const availableBalance = parseFloat(accountState.availableToTradeBalance ?? accountState.availableBalance);
|
|
2697
2737
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: ACCOUNT BALANCE', {
|
|
2698
2738
|
availableBalance,
|
|
2739
|
+
clearinghouseAvailableBalance: accountState.availableBalance,
|
|
2740
|
+
availableToTradeBalance: accountState.availableToTradeBalance,
|
|
2699
2741
|
totalBalance: accountState.totalBalance,
|
|
2700
2742
|
marginUsed: accountState.marginUsed,
|
|
2701
2743
|
unrealizedPnl: accountState.unrealizedPnl,
|
|
@@ -3508,7 +3550,7 @@ class HyperLiquidProvider {
|
|
|
3508
3550
|
// Clear session caches (ensures fresh state on reconnect/account switch)
|
|
3509
3551
|
__classPrivateFieldGet(this, _HyperLiquidProvider_referralCheckCache, "f").clear();
|
|
3510
3552
|
__classPrivateFieldGet(this, _HyperLiquidProvider_builderFeeCheckCache, "f").clear();
|
|
3511
|
-
// NOTE:
|
|
3553
|
+
// NOTE: UnifiedAccountCache is global and NOT cleared on disconnect
|
|
3512
3554
|
// to prevent repeated signing requests across reconnections
|
|
3513
3555
|
__classPrivateFieldGet(this, _HyperLiquidProvider_cachedMetaByDex, "f").clear();
|
|
3514
3556
|
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedSpotMeta, null, "f");
|
|
@@ -3689,7 +3731,7 @@ class HyperLiquidProvider {
|
|
|
3689
3731
|
}
|
|
3690
3732
|
}
|
|
3691
3733
|
exports.HyperLiquidProvider = HyperLiquidProvider;
|
|
3692
|
-
_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(),
|
|
3734
|
+
_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_useUnifiedAccount = new WeakMap(), _HyperLiquidProvider_dexDiscoveryComplete = new WeakMap(), _HyperLiquidProvider_unifiedAccountSetupNeedsRetry = 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) {
|
|
3693
3735
|
const compiled = [];
|
|
3694
3736
|
for (const pattern of patterns) {
|
|
3695
3737
|
try {
|
|
@@ -3760,9 +3802,9 @@ async function _HyperLiquidProvider_ensureClientsInitialized() {
|
|
|
3760
3802
|
// so future calls can retry if needed
|
|
3761
3803
|
__classPrivateFieldSet(this, _HyperLiquidProvider_initializationPromise, null, "f");
|
|
3762
3804
|
}
|
|
3763
|
-
},
|
|
3805
|
+
}, _HyperLiquidProvider_ensureUnifiedAccountEnabled =
|
|
3764
3806
|
/**
|
|
3765
|
-
* Attempt to enable HIP-3
|
|
3807
|
+
* Attempt to enable HyperLiquid Unified Account mode for HIP-3 orders
|
|
3766
3808
|
*
|
|
3767
3809
|
* If successful, HyperLiquid automatically manages collateral transfers for HIP-3 orders.
|
|
3768
3810
|
* If not supported, disables the flag to trigger programmatic transfer fallback.
|
|
@@ -3770,10 +3812,24 @@ async function _HyperLiquidProvider_ensureClientsInitialized() {
|
|
|
3770
3812
|
* IMPORTANT: Uses global singleton cache to prevent repeated signing requests
|
|
3771
3813
|
* across provider reconnections (critical for hardware wallets).
|
|
3772
3814
|
*
|
|
3815
|
+
* @param options - Optional configuration.
|
|
3816
|
+
* @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.
|
|
3773
3817
|
* @private
|
|
3774
3818
|
*/
|
|
3775
|
-
async function
|
|
3776
|
-
|
|
3819
|
+
async function _HyperLiquidProvider_ensureUnifiedAccountEnabled(options) {
|
|
3820
|
+
// dexAbstraction → unifiedAccount requires an EIP-712 prompt (HL blocks
|
|
3821
|
+
// the agent path for that transition). Init calls with allowUserSigning=false so
|
|
3822
|
+
// viewing the Perps section never surfaces a signing dialog. Trading and
|
|
3823
|
+
// withdraw entry points pass allowUserSigning=true to drive the migration when
|
|
3824
|
+
// the user actually intends to act.
|
|
3825
|
+
const allowUserSigning = options?.allowUserSigning ?? false;
|
|
3826
|
+
// Optimistic reset — set true below only at the failure points that
|
|
3827
|
+
// warrant retry (silent agent failure, REST lookup failure, keyring
|
|
3828
|
+
// locked). Final-state outcomes (success, prompted-failure cached,
|
|
3829
|
+
// already-on-compatible, defer, unknown mode, feature off) leave it
|
|
3830
|
+
// false so #ensureReady can keep the memoized promise.
|
|
3831
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, false, "f");
|
|
3832
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
3777
3833
|
return; // Feature disabled
|
|
3778
3834
|
}
|
|
3779
3835
|
const userAddress = await __classPrivateFieldGet(this, _HyperLiquidProvider_walletService, "f").getUserAddressWithDefault();
|
|
@@ -3782,7 +3838,7 @@ async function _HyperLiquidProvider_ensureDexAbstractionEnabled() {
|
|
|
3782
3838
|
// This is CRITICAL for hardware wallets to prevent QR popup spam
|
|
3783
3839
|
const cachedStatus = TradingReadinessCache_1.TradingReadinessCache.get(network, userAddress);
|
|
3784
3840
|
if (cachedStatus?.attempted) {
|
|
3785
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3841
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unified Account setup already attempted (from global cache)', {
|
|
3786
3842
|
user: userAddress,
|
|
3787
3843
|
network,
|
|
3788
3844
|
enabled: cachedStatus.enabled,
|
|
@@ -3792,75 +3848,178 @@ async function _HyperLiquidProvider_ensureDexAbstractionEnabled() {
|
|
|
3792
3848
|
}
|
|
3793
3849
|
// Check if another provider instance is currently attempting this operation
|
|
3794
3850
|
// This prevents concurrent signing attempts across providers during reconnection
|
|
3795
|
-
const inFlightPromise = TradingReadinessCache_1.PerpsSigningCache.isInFlight('
|
|
3851
|
+
const inFlightPromise = TradingReadinessCache_1.PerpsSigningCache.isInFlight('unifiedAccount', network, userAddress);
|
|
3796
3852
|
if (inFlightPromise) {
|
|
3797
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3853
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unified Account setup in-flight, waiting...', { network, userAddress });
|
|
3798
3854
|
await inFlightPromise;
|
|
3799
|
-
|
|
3855
|
+
// The other instance may have finished without writing the cache (e.g.
|
|
3856
|
+
// an init-time call deferred a dexAbstraction migration). If the cache
|
|
3857
|
+
// is still empty and we are an action-time caller (allowUserSigning=true),
|
|
3858
|
+
// we must run our own attempt — otherwise the trade/withdraw would
|
|
3859
|
+
// proceed in the deprecated mode.
|
|
3860
|
+
const postWaitCache = TradingReadinessCache_1.TradingReadinessCache.get(network, userAddress);
|
|
3861
|
+
if (postWaitCache?.attempted) {
|
|
3862
|
+
return;
|
|
3863
|
+
}
|
|
3864
|
+
// Fall through to acquire our own lock and retry.
|
|
3800
3865
|
}
|
|
3801
3866
|
// Set in-flight lock to prevent concurrent attempts
|
|
3802
|
-
const completeInFlight = TradingReadinessCache_1.PerpsSigningCache.setInFlight('
|
|
3867
|
+
const completeInFlight = TradingReadinessCache_1.PerpsSigningCache.setInFlight('unifiedAccount', network, userAddress);
|
|
3868
|
+
let currentMode;
|
|
3803
3869
|
try {
|
|
3804
3870
|
// Re-check cache after acquiring lock (another provider might have finished)
|
|
3805
3871
|
const recheckCache = TradingReadinessCache_1.TradingReadinessCache.get(network, userAddress);
|
|
3806
3872
|
if (recheckCache?.attempted) {
|
|
3807
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider:
|
|
3873
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unified Account setup completed by another provider', { network, userAddress });
|
|
3808
3874
|
completeInFlight();
|
|
3809
3875
|
return;
|
|
3810
3876
|
}
|
|
3811
3877
|
const infoClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient();
|
|
3812
|
-
// Check
|
|
3813
|
-
|
|
3878
|
+
// Check current abstraction mode on-chain
|
|
3879
|
+
currentMode = await infoClient.userAbstraction({
|
|
3814
3880
|
user: userAddress,
|
|
3815
3881
|
});
|
|
3816
|
-
if (
|
|
3817
|
-
|
|
3818
|
-
//
|
|
3882
|
+
if (currentMode === 'unifiedAccount' ||
|
|
3883
|
+
currentMode === 'portfolioMargin') {
|
|
3884
|
+
// portfolioMargin is a superset of unifiedAccount — it already supports
|
|
3885
|
+
// auto-collateral management for HIP-3 orders and is more capital-efficient.
|
|
3886
|
+
// Downgrading portfolio margin users to unifiedAccount would be harmful,
|
|
3887
|
+
// so we treat both modes as already-enabled and skip migration.
|
|
3888
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Account already in a compatible mode, skipping migration', { user: userAddress, network, mode: currentMode });
|
|
3889
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(types_1.PerpsAnalyticsEvent.AccountSetup, {
|
|
3890
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: currentMode,
|
|
3891
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.STATUS]: eventNames_1.PERPS_EVENT_VALUE.STATUS.ALREADY_ENABLED,
|
|
3892
|
+
});
|
|
3819
3893
|
TradingReadinessCache_1.TradingReadinessCache.set(network, userAddress, {
|
|
3820
3894
|
attempted: true,
|
|
3821
3895
|
enabled: true,
|
|
3822
3896
|
});
|
|
3897
|
+
// Record the resolved mode in the subscription service so the next
|
|
3898
|
+
// aggregation folds spot correctly without waiting for #refreshSpotState.
|
|
3899
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f").setUserAbstractionMode(userAddress, currentMode);
|
|
3900
|
+
completeInFlight();
|
|
3901
|
+
return;
|
|
3902
|
+
}
|
|
3903
|
+
// Defer the user-signed transition until the user attempts an action.
|
|
3904
|
+
// Cache is intentionally left untouched so the next entry re-evaluates;
|
|
3905
|
+
// the read-only userAbstraction call is cheap and gated by the in-flight
|
|
3906
|
+
// lock, preventing concurrent prompts.
|
|
3907
|
+
if (currentMode === 'dexAbstraction' && !allowUserSigning) {
|
|
3908
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Deferring dexAbstraction → unifiedAccount migration to action time', { user: userAddress, network });
|
|
3823
3909
|
completeInFlight();
|
|
3824
3910
|
return;
|
|
3825
3911
|
}
|
|
3826
|
-
//
|
|
3827
|
-
|
|
3912
|
+
// Bail on unknown modes BEFORE firing analytics or attempting dispatch.
|
|
3913
|
+
// Keeps `migration_required` actionable (only fires for modes we can
|
|
3914
|
+
// actually migrate) and avoids re-emitting on every reconnection.
|
|
3915
|
+
if (currentMode !== 'dexAbstraction' &&
|
|
3916
|
+
currentMode !== 'default' &&
|
|
3917
|
+
currentMode !== 'disabled') {
|
|
3918
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unknown abstraction mode, skipping Unified Account migration', { user: userAddress, network, mode: currentMode });
|
|
3919
|
+
completeInFlight();
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3922
|
+
// Track which mode users are currently on before we attempt migration.
|
|
3923
|
+
// This tells us the distribution of legacy modes across our user base.
|
|
3924
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(types_1.PerpsAnalyticsEvent.AccountSetup, {
|
|
3925
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: currentMode,
|
|
3926
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.STATUS]: eventNames_1.PERPS_EVENT_VALUE.STATUS.MIGRATION_REQUIRED,
|
|
3927
|
+
});
|
|
3928
|
+
// Enable Unified Account mode.
|
|
3929
|
+
// - default / disabled: agent wallet can do this silently (no prompt)
|
|
3930
|
+
// - dexAbstraction: HL blocks the agent transition — requires the user's main
|
|
3931
|
+
// wallet to sign an EIP-712 action via userSetAbstraction (one-time prompt)
|
|
3932
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Enabling Unified Account mode', {
|
|
3828
3933
|
user: userAddress,
|
|
3829
3934
|
network,
|
|
3935
|
+
previousMode: currentMode,
|
|
3830
3936
|
note: 'HyperLiquid will auto-manage collateral for HIP-3 orders',
|
|
3831
3937
|
});
|
|
3832
3938
|
const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3939
|
+
if (currentMode === 'dexAbstraction') {
|
|
3940
|
+
// Requires EIP-712 signature from the user's main wallet (one-time migration).
|
|
3941
|
+
// HL blocks the dexAbstraction → unifiedAccount transition via the agent wallet,
|
|
3942
|
+
// so userSetAbstraction (user-signed) is the only path for legacy users.
|
|
3943
|
+
await exchangeClient.userSetAbstraction({
|
|
3944
|
+
user: userAddress,
|
|
3945
|
+
abstraction: hyperliquid_types_1.HL_UNIFIED_ACCOUNT_MODE,
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
else {
|
|
3949
|
+
// default / disabled — silent agent transition, no user prompt
|
|
3950
|
+
await exchangeClient.agentSetAbstraction({
|
|
3951
|
+
abstraction: hyperliquid_types_1.HL_ABSTRACTION_WIRE.unifiedAccount,
|
|
3952
|
+
});
|
|
3953
|
+
}
|
|
3954
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('✅ HyperLiquidProvider: Unified Account enabled successfully');
|
|
3955
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(types_1.PerpsAnalyticsEvent.AccountSetup, {
|
|
3956
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.PREVIOUS_ABSTRACTION_MODE]: currentMode,
|
|
3957
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: hyperliquid_types_1.HL_UNIFIED_ACCOUNT_MODE,
|
|
3958
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.STATUS]: eventNames_1.PERPS_EVENT_VALUE.STATUS.SUCCESS,
|
|
3959
|
+
});
|
|
3836
3960
|
TradingReadinessCache_1.TradingReadinessCache.set(network, userAddress, {
|
|
3837
3961
|
attempted: true,
|
|
3838
3962
|
enabled: true,
|
|
3839
3963
|
});
|
|
3964
|
+
// Record the post-migration mode in the subscription service so it
|
|
3965
|
+
// immediately re-aggregates with fold=true and surfaces the unified
|
|
3966
|
+
// balance rather than waiting for the next #refreshSpotState.
|
|
3967
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f").setUserAbstractionMode(userAddress, hyperliquid_types_1.HL_UNIFIED_ACCOUNT_MODE);
|
|
3840
3968
|
completeInFlight();
|
|
3841
3969
|
}
|
|
3842
3970
|
catch (error) {
|
|
3843
3971
|
// If keyring is locked, don't cache so it retries when unlocked
|
|
3844
3972
|
if ((0, errorUtils_1.ensureError)(error).message === perpsErrorCodes_1.PERPS_ERROR_CODES.KEYRING_LOCKED) {
|
|
3845
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[
|
|
3973
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[ensureUnifiedAccountEnabled] Keyring locked, will retry later');
|
|
3974
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, true, "f");
|
|
3846
3975
|
completeInFlight();
|
|
3847
3976
|
return;
|
|
3848
3977
|
}
|
|
3849
|
-
// Cache
|
|
3850
|
-
//
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3978
|
+
// Cache failure ONLY for the user-prompted path
|
|
3979
|
+
// (`dexAbstraction → unifiedAccount` via `userSetAbstraction`). The
|
|
3980
|
+
// rationale for caching is "don't re-prompt a user who already saw the
|
|
3981
|
+
// signature dialog and rejected it" — that doesn't apply to:
|
|
3982
|
+
// - Read-only userAbstraction lookup failures (no prompt; transient).
|
|
3983
|
+
// - Silent agent-key paths (`default`/`disabled` → `agentSetAbstraction`
|
|
3984
|
+
// does not show a UI prompt; failures are typically transient HL
|
|
3985
|
+
// outages and pinning them would leave users stuck in the
|
|
3986
|
+
// deprecated mode for the rest of the session).
|
|
3987
|
+
// Action-time retries pick up the unmigrated state and try again.
|
|
3988
|
+
if (currentMode === 'dexAbstraction') {
|
|
3989
|
+
TradingReadinessCache_1.TradingReadinessCache.set(network, userAddress, {
|
|
3990
|
+
attempted: true,
|
|
3991
|
+
enabled: false,
|
|
3992
|
+
});
|
|
3993
|
+
}
|
|
3994
|
+
else {
|
|
3995
|
+
// Silent agent-key failure (default/disabled) or read-only
|
|
3996
|
+
// userAbstraction lookup failure — neither is a final state, so
|
|
3997
|
+
// signal #ensureReady to drop its memoized promise and retry on
|
|
3998
|
+
// the next entry instead of pinning the user in the deprecated
|
|
3999
|
+
// mode for the provider's lifetime.
|
|
4000
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, true, "f");
|
|
4001
|
+
}
|
|
4002
|
+
const errorMessage = (0, errorUtils_1.ensureError)(error, 'HyperLiquidProvider.ensureUnifiedAccountEnabled').message;
|
|
4003
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Unified Account setup failed', {
|
|
3856
4004
|
user: userAddress,
|
|
3857
4005
|
network,
|
|
3858
|
-
error:
|
|
4006
|
+
error: errorMessage,
|
|
4007
|
+
// Cache writes only happen on the user-prompted dexAbstraction
|
|
4008
|
+
// path (see P2-B logic above). Reflect that here so retry
|
|
4009
|
+
// behaviour is debuggable from the log alone.
|
|
4010
|
+
cached: currentMode === 'dexAbstraction',
|
|
4011
|
+
});
|
|
4012
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").metrics.trackPerpsEvent(types_1.PerpsAnalyticsEvent.AccountSetup, {
|
|
4013
|
+
...(currentMode && {
|
|
4014
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.PREVIOUS_ABSTRACTION_MODE]: currentMode,
|
|
4015
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ABSTRACTION_MODE]: hyperliquid_types_1.HL_UNIFIED_ACCOUNT_MODE,
|
|
4016
|
+
}),
|
|
4017
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.STATUS]: eventNames_1.PERPS_EVENT_VALUE.STATUS.FAILED,
|
|
4018
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,
|
|
3859
4019
|
});
|
|
3860
4020
|
completeInFlight();
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
note: 'Could not enable DEX abstraction (may already be enabled, user rejected, or network error)',
|
|
4021
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").logger.error((0, errorUtils_1.ensureError)(error, 'HyperLiquidProvider.ensureUnifiedAccountEnabled'), __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getErrorContext).call(this, 'ensureUnifiedAccountEnabled', {
|
|
4022
|
+
note: 'Could not enable Unified Account (user rejected, or network error)',
|
|
3864
4023
|
}));
|
|
3865
4024
|
}
|
|
3866
4025
|
}, _HyperLiquidProvider_ensureReady =
|
|
@@ -3894,9 +4053,14 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
3894
4053
|
});
|
|
3895
4054
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_buildAssetMapping).call(this);
|
|
3896
4055
|
}
|
|
3897
|
-
//
|
|
3898
|
-
//
|
|
3899
|
-
//
|
|
4056
|
+
// Attempt Unified Account migration as early as possible so users aren't
|
|
4057
|
+
// blocked when they try to trade. Software-wallet dexAbstraction users can
|
|
4058
|
+
// complete the one-time EIP-712 migration during initial setup so the first
|
|
4059
|
+
// trade sees the unified balance. Hardware wallets remain deferred to
|
|
4060
|
+
// action time to avoid QR / Ledger prompt spam while browsing.
|
|
4061
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, {
|
|
4062
|
+
allowUserSigning: !__classPrivateFieldGet(this, _HyperLiquidProvider_walletService, "f").isSelectedHardwareWallet(),
|
|
4063
|
+
});
|
|
3900
4064
|
})(), "f");
|
|
3901
4065
|
// Await initialization - keep the promise so subsequent calls resolve immediately
|
|
3902
4066
|
// The promise is only reset in disconnect() for clean reconnection,
|
|
@@ -3908,10 +4072,21 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
3908
4072
|
// will be re-discovered on the next #ensureReady() call.
|
|
3909
4073
|
__classPrivateFieldSet(this, _HyperLiquidProvider_ensureReadyPromise, null, "f");
|
|
3910
4074
|
}
|
|
4075
|
+
else if (__classPrivateFieldGet(this, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, "f")) {
|
|
4076
|
+
// Silent migration / lookup / keyring-locked failure left the cache
|
|
4077
|
+
// empty. Without resetting the memoized promise, subsequent
|
|
4078
|
+
// #ensureReady calls would skip retry and the user would be stuck
|
|
4079
|
+
// in the deprecated mode for the provider's lifetime.
|
|
4080
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_ensureReadyPromise, null, "f");
|
|
4081
|
+
}
|
|
3911
4082
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[ensureReady] Initialization complete');
|
|
3912
4083
|
}, _HyperLiquidProvider_ensureReadyForTrading = async function _HyperLiquidProvider_ensureReadyForTrading() {
|
|
3913
4084
|
// First ensure basic initialization is complete
|
|
3914
4085
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReady).call(this);
|
|
4086
|
+
// dexAbstraction users were deferred during init to avoid an EIP-712 prompt
|
|
4087
|
+
// on Perps section open. Drive the migration here, gated by its own cache so
|
|
4088
|
+
// already-migrated or already-rejected users are not re-prompted.
|
|
4089
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUnifiedAccountEnabled).call(this, { allowUserSigning: true });
|
|
3915
4090
|
// If trading setup already complete, return immediately
|
|
3916
4091
|
if (__classPrivateFieldGet(this, _HyperLiquidProvider_tradingSetupComplete, "f")) {
|
|
3917
4092
|
return;
|
|
@@ -3935,8 +4110,6 @@ async function _HyperLiquidProvider_ensureReady() {
|
|
|
3935
4110
|
// Don't throw - spotMeta will be fetched on-demand if needed
|
|
3936
4111
|
}
|
|
3937
4112
|
}
|
|
3938
|
-
// Attempt to enable native balance abstraction
|
|
3939
|
-
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureDexAbstractionEnabled).call(this);
|
|
3940
4113
|
// Set up builder fee approval
|
|
3941
4114
|
try {
|
|
3942
4115
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureBuilderFeeApproval).call(this);
|
|
@@ -5559,11 +5732,11 @@ async function _HyperLiquidProvider_handleHip3PreOrder(params) {
|
|
|
5559
5732
|
isBuy,
|
|
5560
5733
|
});
|
|
5561
5734
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureUsdhCollateralForOrder).call(this, dexName, requiredMargin);
|
|
5562
|
-
//
|
|
5735
|
+
// Unified Account will pull USDH from spot automatically
|
|
5563
5736
|
return { transferInfo: null };
|
|
5564
5737
|
}
|
|
5565
|
-
if (__classPrivateFieldGet(this,
|
|
5566
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Using
|
|
5738
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_useUnifiedAccount, "f")) {
|
|
5739
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Using Unified Account (no manual transfer)', {
|
|
5567
5740
|
symbol,
|
|
5568
5741
|
dex: dexName,
|
|
5569
5742
|
});
|
|
@@ -5592,7 +5765,7 @@ async function _HyperLiquidProvider_handleHip3PreOrder(params) {
|
|
|
5592
5765
|
const errorMsg = transferError?.message || '';
|
|
5593
5766
|
if (errorMsg.includes('Cannot transfer with DEX abstraction enabled')) {
|
|
5594
5767
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Detected DEX abstraction is enabled, switching mode');
|
|
5595
|
-
__classPrivateFieldSet(this,
|
|
5768
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_useUnifiedAccount, true, "f");
|
|
5596
5769
|
return { transferInfo: null };
|
|
5597
5770
|
}
|
|
5598
5771
|
throw transferError;
|