@metamask-previews/perps-controller 2.0.0-preview-51571fe → 2.0.0-preview-27fa5d81d
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 -18
- package/dist/PerpsController.cjs +10 -87
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +2 -25
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +2 -25
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +10 -87
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.cjs +2 -2
- package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.mjs +2 -2
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +1 -8
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +0 -7
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +0 -7
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +0 -7
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +0 -31
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +0 -31
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/AccountService.cjs +35 -35
- package/dist/services/AccountService.cjs.map +1 -1
- package/dist/services/AccountService.d.cts.map +1 -1
- package/dist/services/AccountService.d.mts.map +1 -1
- package/dist/services/AccountService.mjs +35 -35
- package/dist/services/AccountService.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +19 -32
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +19 -32
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/TradingService.cjs +3 -4
- package/dist/services/TradingService.cjs.map +1 -1
- package/dist/services/TradingService.d.cts.map +1 -1
- package/dist/services/TradingService.d.mts.map +1 -1
- package/dist/services/TradingService.mjs +3 -4
- package/dist/services/TradingService.mjs.map +1 -1
- package/dist/utils/orderCalculations.cjs +1 -4
- package/dist/utils/orderCalculations.cjs.map +1 -1
- package/dist/utils/orderCalculations.d.cts.map +1 -1
- package/dist/utils/orderCalculations.d.mts.map +1 -1
- package/dist/utils/orderCalculations.mjs +2 -5
- package/dist/utils/orderCalculations.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -135,33 +135,7 @@ class AccountService {
|
|
|
135
135
|
context.stateManager.update((state) => {
|
|
136
136
|
state.lastError = null;
|
|
137
137
|
state.lastUpdateTimestamp = Date.now();
|
|
138
|
-
|
|
139
|
-
if (result.txHash) {
|
|
140
|
-
// Direct completion: remove from queue and record the txHash
|
|
141
|
-
// so the polling hook won't re-match this completion.
|
|
142
|
-
// We do NOT update lastCompletedWithdrawalTimestamp here
|
|
143
|
-
// because Date.now() is local device time while the FIFO guard
|
|
144
|
-
// compares against API server timestamps — mixing domains can
|
|
145
|
-
// poison the guard. The txHash exclusion alone prevents
|
|
146
|
-
// re-matching since the item is also spliced from the queue.
|
|
147
|
-
if (withdrawalRequestIndex !== -1) {
|
|
148
|
-
state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
|
|
149
|
-
}
|
|
150
|
-
state.lastCompletedWithdrawalTxHashes.push(result.txHash);
|
|
151
|
-
const hasOtherPending = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
152
|
-
state.withdrawInProgress = hasOtherPending;
|
|
153
|
-
}
|
|
154
|
-
else if (withdrawalRequestIndex !== -1) {
|
|
155
|
-
const requestToUpdate = state.withdrawalRequests[withdrawalRequestIndex];
|
|
156
|
-
// Withdrawal is bridging (no txHash yet)
|
|
157
|
-
requestToUpdate.status = 'bridging';
|
|
158
|
-
requestToUpdate.success = true;
|
|
159
|
-
if (result.withdrawalId) {
|
|
160
|
-
requestToUpdate.withdrawalId = result.withdrawalId;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
// Set lastWithdrawResult when submission is successful (even if bridging)
|
|
164
|
-
// This triggers the "confirmed" toast telling user funds arrive in ~5 mins
|
|
138
|
+
state.withdrawInProgress = false;
|
|
165
139
|
state.lastWithdrawResult = {
|
|
166
140
|
success: true,
|
|
167
141
|
txHash: result.txHash ?? '',
|
|
@@ -170,6 +144,24 @@ class AccountService {
|
|
|
170
144
|
timestamp: Date.now(),
|
|
171
145
|
error: '',
|
|
172
146
|
};
|
|
147
|
+
// Update the withdrawal request by request ID
|
|
148
|
+
if (state.withdrawalRequests.length > 0) {
|
|
149
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
150
|
+
if (requestToUpdate) {
|
|
151
|
+
if (result.txHash) {
|
|
152
|
+
requestToUpdate.status = 'completed';
|
|
153
|
+
requestToUpdate.success = true;
|
|
154
|
+
requestToUpdate.txHash = result.txHash;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
requestToUpdate.status = 'bridging';
|
|
158
|
+
requestToUpdate.success = true;
|
|
159
|
+
}
|
|
160
|
+
if (result.withdrawalId) {
|
|
161
|
+
requestToUpdate.withdrawalId = result.withdrawalId;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
173
165
|
});
|
|
174
166
|
}
|
|
175
167
|
__classPrivateFieldGet(this, _AccountService_deps, "f").debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {
|
|
@@ -209,6 +201,7 @@ class AccountService {
|
|
|
209
201
|
context.stateManager.update((state) => {
|
|
210
202
|
state.lastError = result.error ?? perpsErrorCodes_1.PERPS_ERROR_CODES.WITHDRAW_FAILED;
|
|
211
203
|
state.lastUpdateTimestamp = Date.now();
|
|
204
|
+
state.withdrawInProgress = false;
|
|
212
205
|
state.lastWithdrawResult = {
|
|
213
206
|
success: false,
|
|
214
207
|
error: result.error ?? perpsErrorCodes_1.PERPS_ERROR_CODES.WITHDRAW_FAILED,
|
|
@@ -217,11 +210,14 @@ class AccountService {
|
|
|
217
210
|
timestamp: Date.now(),
|
|
218
211
|
txHash: '',
|
|
219
212
|
};
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
state.withdrawalRequests.
|
|
213
|
+
// Update the withdrawal request by request ID
|
|
214
|
+
if (state.withdrawalRequests.length > 0) {
|
|
215
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
216
|
+
if (requestToUpdate) {
|
|
217
|
+
requestToUpdate.status = 'failed';
|
|
218
|
+
requestToUpdate.success = false;
|
|
219
|
+
}
|
|
223
220
|
}
|
|
224
|
-
state.withdrawInProgress = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
225
221
|
});
|
|
226
222
|
}
|
|
227
223
|
__classPrivateFieldGet(this, _AccountService_deps, "f").debugLogger.log('AccountService: WITHDRAWAL FAILED', {
|
|
@@ -257,6 +253,7 @@ class AccountService {
|
|
|
257
253
|
context.stateManager.update((state) => {
|
|
258
254
|
state.lastError = errorMessage;
|
|
259
255
|
state.lastUpdateTimestamp = Date.now();
|
|
256
|
+
state.withdrawInProgress = false;
|
|
260
257
|
state.lastWithdrawResult = {
|
|
261
258
|
success: false,
|
|
262
259
|
error: errorMessage,
|
|
@@ -265,11 +262,14 @@ class AccountService {
|
|
|
265
262
|
timestamp: Date.now(),
|
|
266
263
|
txHash: '',
|
|
267
264
|
};
|
|
268
|
-
|
|
269
|
-
if (
|
|
270
|
-
state.withdrawalRequests.
|
|
265
|
+
// Update the withdrawal request by request ID
|
|
266
|
+
if (state.withdrawalRequests.length > 0) {
|
|
267
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
268
|
+
if (requestToUpdate) {
|
|
269
|
+
requestToUpdate.status = 'failed';
|
|
270
|
+
requestToUpdate.success = false;
|
|
271
|
+
}
|
|
271
272
|
}
|
|
272
|
-
state.withdrawInProgress = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
// Track withdrawal transaction failed (catch block)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountService.cjs","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\n\nimport type { ServiceContext } from './ServiceContext';\nimport {\n PERPS_EVENT_PROPERTY,\n PERPS_EVENT_VALUE,\n} from '../constants/eventNames';\nimport { USDC_SYMBOL } from '../constants/hyperLiquidConfig';\nimport {\n PERPS_CONSTANTS,\n WITHDRAWAL_CONSTANTS,\n} from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport {\n PerpsAnalyticsEvent,\n PerpsTraceNames,\n PerpsTraceOperations,\n} from '../types';\nimport type {\n PerpsProvider,\n WithdrawParams,\n WithdrawResult,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { PerpsControllerMessengerBase } from '../types/messenger';\nimport type { TransactionStatus } from '../types/transactionTypes';\nimport { getSelectedEvmAccount } from '../utils/accountUtils';\nimport { ensureError } from '../utils/errorUtils';\n\n/**\n * AccountService\n *\n * Handles account operations (deposits, withdrawals).\n * Stateless service that delegates to provider.\n * Controller handles state updates and analytics.\n *\n * Instance-based service with constructor injection of platform dependencies\n * and messenger for inter-controller communication.\n */\nexport class AccountService {\n readonly #deps: PerpsPlatformDependencies;\n\n readonly #messenger: PerpsControllerMessengerBase;\n\n /**\n * Create a new AccountService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n * @param messenger - Controller messenger for cross-controller communication.\n */\n constructor(\n deps: PerpsPlatformDependencies,\n messenger: PerpsControllerMessengerBase,\n ) {\n this.#deps = deps;\n this.#messenger = messenger;\n }\n\n /**\n * Withdraw funds with full orchestration\n * Handles tracing, state management, analytics, and account refresh\n *\n * @param options - The withdrawal configuration.\n * @param options.provider - The perps provider to execute the withdrawal.\n * @param options.params - The withdrawal parameters (amount, destination, etc.).\n * @param options.context - The service context for tracing and dependencies.\n * @param options.refreshAccountState - Callback to refresh account state after withdrawal.\n * @returns The withdrawal result containing success status and transaction details.\n */\n async withdraw(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n context: ServiceContext;\n refreshAccountState: () => Promise<void>;\n }): Promise<WithdrawResult> {\n const { provider, params, context, refreshAccountState } = options;\n\n const traceId = uuidv4();\n const startTime = this.#deps.performance.now();\n let traceData:\n | {\n success: boolean;\n error?: string;\n txHash?: string;\n withdrawalId?: string;\n }\n | undefined;\n\n // Generate withdrawal request ID for tracking\n const currentWithdrawalId = `withdraw-${Date.now()}-${Math.random()\n .toString(36)\n .substring(2, 11)}`;\n\n try {\n this.#deps.tracer.trace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n op: PerpsTraceOperations.Operation,\n tags: {\n assetId: params.assetId ?? '',\n provider: context.tracingContext.provider,\n isTestnet: String(context.tracingContext.isTestnet),\n },\n });\n\n this.#deps.debugLogger.log('AccountService: STARTING WITHDRAWAL', {\n params,\n timestamp: new Date().toISOString(),\n assetId: params.assetId,\n amount: params.amount,\n destination: params.destination,\n activeProvider: context.tracingContext.provider,\n isTestnet: context.tracingContext.isTestnet,\n });\n\n // Set withdrawal in progress\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.withdrawInProgress = true;\n\n // Calculate net amount after fees\n const grossAmount = parseFloat(params.amount);\n const feeAmount = WITHDRAWAL_CONSTANTS.DefaultFeeAmount;\n const netAmount = Math.max(0, grossAmount - feeAmount);\n\n // Get current account address via messenger\n const evmAccount = getSelectedEvmAccount(\n this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n ),\n );\n const accountAddress = evmAccount?.address ?? 'unknown';\n\n this.#deps.debugLogger.log(\n 'AccountService: Creating withdrawal request',\n {\n accountAddress,\n hasEvmAccount: Boolean(evmAccount),\n evmAccountAddress: evmAccount?.address,\n amount: netAmount.toString(),\n },\n );\n\n // Add withdrawal request to tracking\n const withdrawalRequest = {\n id: currentWithdrawalId,\n timestamp: Date.now(),\n amount: netAmount.toString(), // Use net amount (after fees)\n asset: USDC_SYMBOL,\n accountAddress, // Track which account initiated withdrawal\n success: false, // Will be updated when transaction completes\n txHash: undefined,\n status: 'pending' as TransactionStatus,\n destination: params.destination,\n transactionId: undefined, // Will be set to withdrawalId when available\n };\n\n state.withdrawalRequests.unshift(withdrawalRequest);\n });\n }\n\n this.#deps.debugLogger.log('AccountService: DELEGATING TO PROVIDER', {\n provider: context.tracingContext.provider,\n providerReady: Boolean(provider),\n });\n\n // Execute withdrawal\n const result = await provider.withdraw(params);\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL RESULT', {\n success: result.success,\n error: result.error,\n txHash: result.txHash,\n timestamp: new Date().toISOString(),\n });\n\n // Update state based on result\n if (result.success) {\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = null;\n state.lastUpdateTimestamp = Date.now();\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n\n if (result.txHash) {\n // Direct completion: remove from queue and record the txHash\n // so the polling hook won't re-match this completion.\n // We do NOT update lastCompletedWithdrawalTimestamp here\n // because Date.now() is local device time while the FIFO guard\n // compares against API server timestamps — mixing domains can\n // poison the guard. The txHash exclusion alone prevents\n // re-matching since the item is also spliced from the queue.\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n\n state.lastCompletedWithdrawalTxHashes.push(result.txHash);\n\n const hasOtherPending = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n state.withdrawInProgress = hasOtherPending;\n } else if (withdrawalRequestIndex !== -1) {\n const requestToUpdate =\n state.withdrawalRequests[withdrawalRequestIndex];\n // Withdrawal is bridging (no txHash yet)\n requestToUpdate.status = 'bridging' as TransactionStatus;\n requestToUpdate.success = true;\n if (result.withdrawalId) {\n requestToUpdate.withdrawalId = result.withdrawalId;\n }\n }\n\n // Set lastWithdrawResult when submission is successful (even if bridging)\n // This triggers the \"confirmed\" toast telling user funds arrive in ~5 mins\n state.lastWithdrawResult = {\n success: true,\n txHash: result.txHash ?? '',\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n error: '',\n };\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {\n txHash: result.txHash,\n amount: params.amount,\n assetId: params.assetId,\n withdrawalId: result.withdrawalId,\n });\n\n // Track withdrawal transaction executed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.EXECUTED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n },\n );\n\n // Trigger account state refresh after withdrawal\n refreshAccountState().catch((refreshError) => {\n this.#deps.logger.error(\n ensureError(refreshError, 'AccountService.withdraw'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { operation: 'refreshAccountState' },\n },\n },\n );\n });\n\n // Invalidate standalone caches so external hooks (e.g., usePerpsPositionForAsset) refresh\n this.#deps.cacheInvalidator.invalidate({ cacheType: 'accountState' });\n\n traceData = {\n success: true,\n txHash: result.txHash ?? '',\n withdrawalId: result.withdrawalId ?? '',\n };\n\n return result;\n }\n\n // Handle failure\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED;\n state.lastUpdateTimestamp = Date.now();\n state.lastWithdrawResult = {\n success: false,\n error: result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED,\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n state.withdrawInProgress = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL FAILED', {\n error: result.error,\n params,\n });\n\n // Track withdrawal transaction failed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: result.error ?? 'Unknown error',\n },\n );\n\n traceData = {\n success: false,\n error: result.error ?? 'Unknown error',\n };\n\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : PERPS_ERROR_CODES.WITHDRAW_FAILED;\n\n this.#deps.logger.error(ensureError(error, 'AccountService.withdraw'), {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { assetId: params.assetId, amount: params.amount },\n },\n });\n\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = errorMessage;\n state.lastUpdateTimestamp = Date.now();\n state.lastWithdrawResult = {\n success: false,\n error: errorMessage,\n amount: '0',\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n state.withdrawInProgress = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n });\n }\n\n // Track withdrawal transaction failed (catch block)\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: params.amount,\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,\n },\n );\n\n traceData = {\n success: false,\n error: errorMessage,\n };\n\n return { success: false, error: errorMessage };\n } finally {\n this.#deps.tracer.endTrace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n data: traceData,\n });\n }\n }\n\n /**\n * Validate withdrawal parameters\n *\n * @param options - The validation configuration.\n * @param options.provider - The perps provider to validate against.\n * @param options.params - The withdrawal parameters to validate.\n * @returns An object indicating whether the withdrawal is valid, with an optional error message.\n */\n async validateWithdrawal(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n }): Promise<{ isValid: boolean; error?: string }> {\n const { provider, params } = options;\n\n try {\n return await provider.validateWithdrawal(params);\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'AccountService.validateWithdrawal'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.validateWithdrawal',\n data: { params },\n },\n },\n );\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AccountService.cjs","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\n\nimport type { ServiceContext } from './ServiceContext';\nimport {\n PERPS_EVENT_PROPERTY,\n PERPS_EVENT_VALUE,\n} from '../constants/eventNames';\nimport { USDC_SYMBOL } from '../constants/hyperLiquidConfig';\nimport {\n PERPS_CONSTANTS,\n WITHDRAWAL_CONSTANTS,\n} from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport {\n PerpsAnalyticsEvent,\n PerpsTraceNames,\n PerpsTraceOperations,\n} from '../types';\nimport type {\n PerpsProvider,\n WithdrawParams,\n WithdrawResult,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { PerpsControllerMessengerBase } from '../types/messenger';\nimport type { TransactionStatus } from '../types/transactionTypes';\nimport { getSelectedEvmAccount } from '../utils/accountUtils';\nimport { ensureError } from '../utils/errorUtils';\n\n/**\n * AccountService\n *\n * Handles account operations (deposits, withdrawals).\n * Stateless service that delegates to provider.\n * Controller handles state updates and analytics.\n *\n * Instance-based service with constructor injection of platform dependencies\n * and messenger for inter-controller communication.\n */\nexport class AccountService {\n readonly #deps: PerpsPlatformDependencies;\n\n readonly #messenger: PerpsControllerMessengerBase;\n\n /**\n * Create a new AccountService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n * @param messenger - Controller messenger for cross-controller communication.\n */\n constructor(\n deps: PerpsPlatformDependencies,\n messenger: PerpsControllerMessengerBase,\n ) {\n this.#deps = deps;\n this.#messenger = messenger;\n }\n\n /**\n * Withdraw funds with full orchestration\n * Handles tracing, state management, analytics, and account refresh\n *\n * @param options - The withdrawal configuration.\n * @param options.provider - The perps provider to execute the withdrawal.\n * @param options.params - The withdrawal parameters (amount, destination, etc.).\n * @param options.context - The service context for tracing and dependencies.\n * @param options.refreshAccountState - Callback to refresh account state after withdrawal.\n * @returns The withdrawal result containing success status and transaction details.\n */\n async withdraw(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n context: ServiceContext;\n refreshAccountState: () => Promise<void>;\n }): Promise<WithdrawResult> {\n const { provider, params, context, refreshAccountState } = options;\n\n const traceId = uuidv4();\n const startTime = this.#deps.performance.now();\n let traceData:\n | {\n success: boolean;\n error?: string;\n txHash?: string;\n withdrawalId?: string;\n }\n | undefined;\n\n // Generate withdrawal request ID for tracking\n const currentWithdrawalId = `withdraw-${Date.now()}-${Math.random()\n .toString(36)\n .substring(2, 11)}`;\n\n try {\n this.#deps.tracer.trace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n op: PerpsTraceOperations.Operation,\n tags: {\n assetId: params.assetId ?? '',\n provider: context.tracingContext.provider,\n isTestnet: String(context.tracingContext.isTestnet),\n },\n });\n\n this.#deps.debugLogger.log('AccountService: STARTING WITHDRAWAL', {\n params,\n timestamp: new Date().toISOString(),\n assetId: params.assetId,\n amount: params.amount,\n destination: params.destination,\n activeProvider: context.tracingContext.provider,\n isTestnet: context.tracingContext.isTestnet,\n });\n\n // Set withdrawal in progress\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.withdrawInProgress = true;\n\n // Calculate net amount after fees\n const grossAmount = parseFloat(params.amount);\n const feeAmount = WITHDRAWAL_CONSTANTS.DefaultFeeAmount;\n const netAmount = Math.max(0, grossAmount - feeAmount);\n\n // Get current account address via messenger\n const evmAccount = getSelectedEvmAccount(\n this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n ),\n );\n const accountAddress = evmAccount?.address ?? 'unknown';\n\n this.#deps.debugLogger.log(\n 'AccountService: Creating withdrawal request',\n {\n accountAddress,\n hasEvmAccount: Boolean(evmAccount),\n evmAccountAddress: evmAccount?.address,\n amount: netAmount.toString(),\n },\n );\n\n // Add withdrawal request to tracking\n const withdrawalRequest = {\n id: currentWithdrawalId,\n timestamp: Date.now(),\n amount: netAmount.toString(), // Use net amount (after fees)\n asset: USDC_SYMBOL,\n accountAddress, // Track which account initiated withdrawal\n success: false, // Will be updated when transaction completes\n txHash: undefined,\n status: 'pending' as TransactionStatus,\n destination: params.destination,\n transactionId: undefined, // Will be set to withdrawalId when available\n };\n\n state.withdrawalRequests.unshift(withdrawalRequest);\n });\n }\n\n this.#deps.debugLogger.log('AccountService: DELEGATING TO PROVIDER', {\n provider: context.tracingContext.provider,\n providerReady: Boolean(provider),\n });\n\n // Execute withdrawal\n const result = await provider.withdraw(params);\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL RESULT', {\n success: result.success,\n error: result.error,\n txHash: result.txHash,\n timestamp: new Date().toISOString(),\n });\n\n // Update state based on result\n if (result.success) {\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = null;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: true,\n txHash: result.txHash ?? '',\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n error: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n if (result.txHash) {\n requestToUpdate.status = 'completed' as TransactionStatus;\n requestToUpdate.success = true;\n requestToUpdate.txHash = result.txHash;\n } else {\n requestToUpdate.status = 'bridging' as TransactionStatus;\n requestToUpdate.success = true;\n }\n if (result.withdrawalId) {\n requestToUpdate.withdrawalId = result.withdrawalId;\n }\n }\n }\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {\n txHash: result.txHash,\n amount: params.amount,\n assetId: params.assetId,\n withdrawalId: result.withdrawalId,\n });\n\n // Track withdrawal transaction executed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.EXECUTED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n },\n );\n\n // Trigger account state refresh after withdrawal\n refreshAccountState().catch((refreshError) => {\n this.#deps.logger.error(\n ensureError(refreshError, 'AccountService.withdraw'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { operation: 'refreshAccountState' },\n },\n },\n );\n });\n\n // Invalidate standalone caches so external hooks (e.g., usePerpsPositionForAsset) refresh\n this.#deps.cacheInvalidator.invalidate({ cacheType: 'accountState' });\n\n traceData = {\n success: true,\n txHash: result.txHash ?? '',\n withdrawalId: result.withdrawalId ?? '',\n };\n\n return result;\n }\n\n // Handle failure\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: false,\n error: result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED,\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n requestToUpdate.status = 'failed' as TransactionStatus;\n requestToUpdate.success = false;\n }\n }\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL FAILED', {\n error: result.error,\n params,\n });\n\n // Track withdrawal transaction failed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: result.error ?? 'Unknown error',\n },\n );\n\n traceData = {\n success: false,\n error: result.error ?? 'Unknown error',\n };\n\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : PERPS_ERROR_CODES.WITHDRAW_FAILED;\n\n this.#deps.logger.error(ensureError(error, 'AccountService.withdraw'), {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { assetId: params.assetId, amount: params.amount },\n },\n });\n\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = errorMessage;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: false,\n error: errorMessage,\n amount: '0',\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n requestToUpdate.status = 'failed' as TransactionStatus;\n requestToUpdate.success = false;\n }\n }\n });\n }\n\n // Track withdrawal transaction failed (catch block)\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: params.amount,\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,\n },\n );\n\n traceData = {\n success: false,\n error: errorMessage,\n };\n\n return { success: false, error: errorMessage };\n } finally {\n this.#deps.tracer.endTrace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n data: traceData,\n });\n }\n }\n\n /**\n * Validate withdrawal parameters\n *\n * @param options - The validation configuration.\n * @param options.provider - The perps provider to validate against.\n * @param options.params - The withdrawal parameters to validate.\n * @returns An object indicating whether the withdrawal is valid, with an optional error message.\n */\n async validateWithdrawal(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n }): Promise<{ isValid: boolean; error?: string }> {\n const { provider, params } = options;\n\n try {\n return await provider.validateWithdrawal(params);\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'AccountService.validateWithdrawal'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.validateWithdrawal',\n data: { params },\n },\n },\n );\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountService.d.cts","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAAyB;AAgBvD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,2BAAiB;AAClB,OAAO,KAAK,EAAE,4BAA4B,EAAE,+BAA2B;AAKvE;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IAKzB;;;;;OAKG;gBAED,IAAI,EAAE,yBAAyB,EAC/B,SAAS,EAAE,4BAA4B;IAMzC;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,cAAc,CAAC;QACxB,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1C,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"AccountService.d.cts","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAAyB;AAgBvD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,2BAAiB;AAClB,OAAO,KAAK,EAAE,4BAA4B,EAAE,+BAA2B;AAKvE;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IAKzB;;;;;OAKG;gBAED,IAAI,EAAE,yBAAyB,EAC/B,SAAS,EAAE,4BAA4B;IAMzC;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,cAAc,CAAC;QACxB,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1C,GAAG,OAAO,CAAC,cAAc,CAAC;IA+S3B;;;;;;;OAOG;IACG,kBAAkB,CAAC,OAAO,EAAE;QAChC,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;KACxB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAmBlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountService.d.mts","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAAyB;AAgBvD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,2BAAiB;AAClB,OAAO,KAAK,EAAE,4BAA4B,EAAE,+BAA2B;AAKvE;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IAKzB;;;;;OAKG;gBAED,IAAI,EAAE,yBAAyB,EAC/B,SAAS,EAAE,4BAA4B;IAMzC;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,cAAc,CAAC;QACxB,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1C,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"AccountService.d.mts","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAAyB;AAgBvD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,2BAAiB;AAClB,OAAO,KAAK,EAAE,4BAA4B,EAAE,+BAA2B;AAKvE;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IAKzB;;;;;OAKG;gBAED,IAAI,EAAE,yBAAyB,EAC/B,SAAS,EAAE,4BAA4B;IAMzC;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,cAAc,CAAC;QACxB,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1C,GAAG,OAAO,CAAC,cAAc,CAAC;IA+S3B;;;;;;;OAOG;IACG,kBAAkB,CAAC,OAAO,EAAE;QAChC,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,cAAc,CAAC;KACxB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAmBlD"}
|
|
@@ -132,33 +132,7 @@ export class AccountService {
|
|
|
132
132
|
context.stateManager.update((state) => {
|
|
133
133
|
state.lastError = null;
|
|
134
134
|
state.lastUpdateTimestamp = Date.now();
|
|
135
|
-
|
|
136
|
-
if (result.txHash) {
|
|
137
|
-
// Direct completion: remove from queue and record the txHash
|
|
138
|
-
// so the polling hook won't re-match this completion.
|
|
139
|
-
// We do NOT update lastCompletedWithdrawalTimestamp here
|
|
140
|
-
// because Date.now() is local device time while the FIFO guard
|
|
141
|
-
// compares against API server timestamps — mixing domains can
|
|
142
|
-
// poison the guard. The txHash exclusion alone prevents
|
|
143
|
-
// re-matching since the item is also spliced from the queue.
|
|
144
|
-
if (withdrawalRequestIndex !== -1) {
|
|
145
|
-
state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
|
|
146
|
-
}
|
|
147
|
-
state.lastCompletedWithdrawalTxHashes.push(result.txHash);
|
|
148
|
-
const hasOtherPending = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
149
|
-
state.withdrawInProgress = hasOtherPending;
|
|
150
|
-
}
|
|
151
|
-
else if (withdrawalRequestIndex !== -1) {
|
|
152
|
-
const requestToUpdate = state.withdrawalRequests[withdrawalRequestIndex];
|
|
153
|
-
// Withdrawal is bridging (no txHash yet)
|
|
154
|
-
requestToUpdate.status = 'bridging';
|
|
155
|
-
requestToUpdate.success = true;
|
|
156
|
-
if (result.withdrawalId) {
|
|
157
|
-
requestToUpdate.withdrawalId = result.withdrawalId;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// Set lastWithdrawResult when submission is successful (even if bridging)
|
|
161
|
-
// This triggers the "confirmed" toast telling user funds arrive in ~5 mins
|
|
135
|
+
state.withdrawInProgress = false;
|
|
162
136
|
state.lastWithdrawResult = {
|
|
163
137
|
success: true,
|
|
164
138
|
txHash: result.txHash ?? '',
|
|
@@ -167,6 +141,24 @@ export class AccountService {
|
|
|
167
141
|
timestamp: Date.now(),
|
|
168
142
|
error: '',
|
|
169
143
|
};
|
|
144
|
+
// Update the withdrawal request by request ID
|
|
145
|
+
if (state.withdrawalRequests.length > 0) {
|
|
146
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
147
|
+
if (requestToUpdate) {
|
|
148
|
+
if (result.txHash) {
|
|
149
|
+
requestToUpdate.status = 'completed';
|
|
150
|
+
requestToUpdate.success = true;
|
|
151
|
+
requestToUpdate.txHash = result.txHash;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
requestToUpdate.status = 'bridging';
|
|
155
|
+
requestToUpdate.success = true;
|
|
156
|
+
}
|
|
157
|
+
if (result.withdrawalId) {
|
|
158
|
+
requestToUpdate.withdrawalId = result.withdrawalId;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
170
162
|
});
|
|
171
163
|
}
|
|
172
164
|
__classPrivateFieldGet(this, _AccountService_deps, "f").debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {
|
|
@@ -206,6 +198,7 @@ export class AccountService {
|
|
|
206
198
|
context.stateManager.update((state) => {
|
|
207
199
|
state.lastError = result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED;
|
|
208
200
|
state.lastUpdateTimestamp = Date.now();
|
|
201
|
+
state.withdrawInProgress = false;
|
|
209
202
|
state.lastWithdrawResult = {
|
|
210
203
|
success: false,
|
|
211
204
|
error: result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED,
|
|
@@ -214,11 +207,14 @@ export class AccountService {
|
|
|
214
207
|
timestamp: Date.now(),
|
|
215
208
|
txHash: '',
|
|
216
209
|
};
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
state.withdrawalRequests.
|
|
210
|
+
// Update the withdrawal request by request ID
|
|
211
|
+
if (state.withdrawalRequests.length > 0) {
|
|
212
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
213
|
+
if (requestToUpdate) {
|
|
214
|
+
requestToUpdate.status = 'failed';
|
|
215
|
+
requestToUpdate.success = false;
|
|
216
|
+
}
|
|
220
217
|
}
|
|
221
|
-
state.withdrawInProgress = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
222
218
|
});
|
|
223
219
|
}
|
|
224
220
|
__classPrivateFieldGet(this, _AccountService_deps, "f").debugLogger.log('AccountService: WITHDRAWAL FAILED', {
|
|
@@ -254,6 +250,7 @@ export class AccountService {
|
|
|
254
250
|
context.stateManager.update((state) => {
|
|
255
251
|
state.lastError = errorMessage;
|
|
256
252
|
state.lastUpdateTimestamp = Date.now();
|
|
253
|
+
state.withdrawInProgress = false;
|
|
257
254
|
state.lastWithdrawResult = {
|
|
258
255
|
success: false,
|
|
259
256
|
error: errorMessage,
|
|
@@ -262,11 +259,14 @@ export class AccountService {
|
|
|
262
259
|
timestamp: Date.now(),
|
|
263
260
|
txHash: '',
|
|
264
261
|
};
|
|
265
|
-
|
|
266
|
-
if (
|
|
267
|
-
state.withdrawalRequests.
|
|
262
|
+
// Update the withdrawal request by request ID
|
|
263
|
+
if (state.withdrawalRequests.length > 0) {
|
|
264
|
+
const requestToUpdate = state.withdrawalRequests.find((req) => req.id === currentWithdrawalId);
|
|
265
|
+
if (requestToUpdate) {
|
|
266
|
+
requestToUpdate.status = 'failed';
|
|
267
|
+
requestToUpdate.success = false;
|
|
268
|
+
}
|
|
268
269
|
}
|
|
269
|
-
state.withdrawInProgress = state.withdrawalRequests.some((req) => req.status === 'pending' || req.status === 'bridging');
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
272
|
// Track withdrawal transaction failed (catch block)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountService.mjs","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\n\nimport type { ServiceContext } from './ServiceContext';\nimport {\n PERPS_EVENT_PROPERTY,\n PERPS_EVENT_VALUE,\n} from '../constants/eventNames';\nimport { USDC_SYMBOL } from '../constants/hyperLiquidConfig';\nimport {\n PERPS_CONSTANTS,\n WITHDRAWAL_CONSTANTS,\n} from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport {\n PerpsAnalyticsEvent,\n PerpsTraceNames,\n PerpsTraceOperations,\n} from '../types';\nimport type {\n PerpsProvider,\n WithdrawParams,\n WithdrawResult,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { PerpsControllerMessengerBase } from '../types/messenger';\nimport type { TransactionStatus } from '../types/transactionTypes';\nimport { getSelectedEvmAccount } from '../utils/accountUtils';\nimport { ensureError } from '../utils/errorUtils';\n\n/**\n * AccountService\n *\n * Handles account operations (deposits, withdrawals).\n * Stateless service that delegates to provider.\n * Controller handles state updates and analytics.\n *\n * Instance-based service with constructor injection of platform dependencies\n * and messenger for inter-controller communication.\n */\nexport class AccountService {\n readonly #deps: PerpsPlatformDependencies;\n\n readonly #messenger: PerpsControllerMessengerBase;\n\n /**\n * Create a new AccountService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n * @param messenger - Controller messenger for cross-controller communication.\n */\n constructor(\n deps: PerpsPlatformDependencies,\n messenger: PerpsControllerMessengerBase,\n ) {\n this.#deps = deps;\n this.#messenger = messenger;\n }\n\n /**\n * Withdraw funds with full orchestration\n * Handles tracing, state management, analytics, and account refresh\n *\n * @param options - The withdrawal configuration.\n * @param options.provider - The perps provider to execute the withdrawal.\n * @param options.params - The withdrawal parameters (amount, destination, etc.).\n * @param options.context - The service context for tracing and dependencies.\n * @param options.refreshAccountState - Callback to refresh account state after withdrawal.\n * @returns The withdrawal result containing success status and transaction details.\n */\n async withdraw(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n context: ServiceContext;\n refreshAccountState: () => Promise<void>;\n }): Promise<WithdrawResult> {\n const { provider, params, context, refreshAccountState } = options;\n\n const traceId = uuidv4();\n const startTime = this.#deps.performance.now();\n let traceData:\n | {\n success: boolean;\n error?: string;\n txHash?: string;\n withdrawalId?: string;\n }\n | undefined;\n\n // Generate withdrawal request ID for tracking\n const currentWithdrawalId = `withdraw-${Date.now()}-${Math.random()\n .toString(36)\n .substring(2, 11)}`;\n\n try {\n this.#deps.tracer.trace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n op: PerpsTraceOperations.Operation,\n tags: {\n assetId: params.assetId ?? '',\n provider: context.tracingContext.provider,\n isTestnet: String(context.tracingContext.isTestnet),\n },\n });\n\n this.#deps.debugLogger.log('AccountService: STARTING WITHDRAWAL', {\n params,\n timestamp: new Date().toISOString(),\n assetId: params.assetId,\n amount: params.amount,\n destination: params.destination,\n activeProvider: context.tracingContext.provider,\n isTestnet: context.tracingContext.isTestnet,\n });\n\n // Set withdrawal in progress\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.withdrawInProgress = true;\n\n // Calculate net amount after fees\n const grossAmount = parseFloat(params.amount);\n const feeAmount = WITHDRAWAL_CONSTANTS.DefaultFeeAmount;\n const netAmount = Math.max(0, grossAmount - feeAmount);\n\n // Get current account address via messenger\n const evmAccount = getSelectedEvmAccount(\n this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n ),\n );\n const accountAddress = evmAccount?.address ?? 'unknown';\n\n this.#deps.debugLogger.log(\n 'AccountService: Creating withdrawal request',\n {\n accountAddress,\n hasEvmAccount: Boolean(evmAccount),\n evmAccountAddress: evmAccount?.address,\n amount: netAmount.toString(),\n },\n );\n\n // Add withdrawal request to tracking\n const withdrawalRequest = {\n id: currentWithdrawalId,\n timestamp: Date.now(),\n amount: netAmount.toString(), // Use net amount (after fees)\n asset: USDC_SYMBOL,\n accountAddress, // Track which account initiated withdrawal\n success: false, // Will be updated when transaction completes\n txHash: undefined,\n status: 'pending' as TransactionStatus,\n destination: params.destination,\n transactionId: undefined, // Will be set to withdrawalId when available\n };\n\n state.withdrawalRequests.unshift(withdrawalRequest);\n });\n }\n\n this.#deps.debugLogger.log('AccountService: DELEGATING TO PROVIDER', {\n provider: context.tracingContext.provider,\n providerReady: Boolean(provider),\n });\n\n // Execute withdrawal\n const result = await provider.withdraw(params);\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL RESULT', {\n success: result.success,\n error: result.error,\n txHash: result.txHash,\n timestamp: new Date().toISOString(),\n });\n\n // Update state based on result\n if (result.success) {\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = null;\n state.lastUpdateTimestamp = Date.now();\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n\n if (result.txHash) {\n // Direct completion: remove from queue and record the txHash\n // so the polling hook won't re-match this completion.\n // We do NOT update lastCompletedWithdrawalTimestamp here\n // because Date.now() is local device time while the FIFO guard\n // compares against API server timestamps — mixing domains can\n // poison the guard. The txHash exclusion alone prevents\n // re-matching since the item is also spliced from the queue.\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n\n state.lastCompletedWithdrawalTxHashes.push(result.txHash);\n\n const hasOtherPending = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n state.withdrawInProgress = hasOtherPending;\n } else if (withdrawalRequestIndex !== -1) {\n const requestToUpdate =\n state.withdrawalRequests[withdrawalRequestIndex];\n // Withdrawal is bridging (no txHash yet)\n requestToUpdate.status = 'bridging' as TransactionStatus;\n requestToUpdate.success = true;\n if (result.withdrawalId) {\n requestToUpdate.withdrawalId = result.withdrawalId;\n }\n }\n\n // Set lastWithdrawResult when submission is successful (even if bridging)\n // This triggers the \"confirmed\" toast telling user funds arrive in ~5 mins\n state.lastWithdrawResult = {\n success: true,\n txHash: result.txHash ?? '',\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n error: '',\n };\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {\n txHash: result.txHash,\n amount: params.amount,\n assetId: params.assetId,\n withdrawalId: result.withdrawalId,\n });\n\n // Track withdrawal transaction executed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.EXECUTED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n },\n );\n\n // Trigger account state refresh after withdrawal\n refreshAccountState().catch((refreshError) => {\n this.#deps.logger.error(\n ensureError(refreshError, 'AccountService.withdraw'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { operation: 'refreshAccountState' },\n },\n },\n );\n });\n\n // Invalidate standalone caches so external hooks (e.g., usePerpsPositionForAsset) refresh\n this.#deps.cacheInvalidator.invalidate({ cacheType: 'accountState' });\n\n traceData = {\n success: true,\n txHash: result.txHash ?? '',\n withdrawalId: result.withdrawalId ?? '',\n };\n\n return result;\n }\n\n // Handle failure\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED;\n state.lastUpdateTimestamp = Date.now();\n state.lastWithdrawResult = {\n success: false,\n error: result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED,\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n state.withdrawInProgress = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL FAILED', {\n error: result.error,\n params,\n });\n\n // Track withdrawal transaction failed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: result.error ?? 'Unknown error',\n },\n );\n\n traceData = {\n success: false,\n error: result.error ?? 'Unknown error',\n };\n\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : PERPS_ERROR_CODES.WITHDRAW_FAILED;\n\n this.#deps.logger.error(ensureError(error, 'AccountService.withdraw'), {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { assetId: params.assetId, amount: params.amount },\n },\n });\n\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = errorMessage;\n state.lastUpdateTimestamp = Date.now();\n state.lastWithdrawResult = {\n success: false,\n error: errorMessage,\n amount: '0',\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n const withdrawalRequestIndex = state.withdrawalRequests.findIndex(\n (req) => req.id === currentWithdrawalId,\n );\n if (withdrawalRequestIndex !== -1) {\n state.withdrawalRequests.splice(withdrawalRequestIndex, 1);\n }\n state.withdrawInProgress = state.withdrawalRequests.some(\n (req) => req.status === 'pending' || req.status === 'bridging',\n );\n });\n }\n\n // Track withdrawal transaction failed (catch block)\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: params.amount,\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,\n },\n );\n\n traceData = {\n success: false,\n error: errorMessage,\n };\n\n return { success: false, error: errorMessage };\n } finally {\n this.#deps.tracer.endTrace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n data: traceData,\n });\n }\n }\n\n /**\n * Validate withdrawal parameters\n *\n * @param options - The validation configuration.\n * @param options.provider - The perps provider to validate against.\n * @param options.params - The withdrawal parameters to validate.\n * @returns An object indicating whether the withdrawal is valid, with an optional error message.\n */\n async validateWithdrawal(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n }): Promise<{ isValid: boolean; error?: string }> {\n const { provider, params } = options;\n\n try {\n return await provider.validateWithdrawal(params);\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'AccountService.validateWithdrawal'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.validateWithdrawal',\n data: { params },\n },\n },\n );\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AccountService.mjs","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\n\nimport type { ServiceContext } from './ServiceContext';\nimport {\n PERPS_EVENT_PROPERTY,\n PERPS_EVENT_VALUE,\n} from '../constants/eventNames';\nimport { USDC_SYMBOL } from '../constants/hyperLiquidConfig';\nimport {\n PERPS_CONSTANTS,\n WITHDRAWAL_CONSTANTS,\n} from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport {\n PerpsAnalyticsEvent,\n PerpsTraceNames,\n PerpsTraceOperations,\n} from '../types';\nimport type {\n PerpsProvider,\n WithdrawParams,\n WithdrawResult,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { PerpsControllerMessengerBase } from '../types/messenger';\nimport type { TransactionStatus } from '../types/transactionTypes';\nimport { getSelectedEvmAccount } from '../utils/accountUtils';\nimport { ensureError } from '../utils/errorUtils';\n\n/**\n * AccountService\n *\n * Handles account operations (deposits, withdrawals).\n * Stateless service that delegates to provider.\n * Controller handles state updates and analytics.\n *\n * Instance-based service with constructor injection of platform dependencies\n * and messenger for inter-controller communication.\n */\nexport class AccountService {\n readonly #deps: PerpsPlatformDependencies;\n\n readonly #messenger: PerpsControllerMessengerBase;\n\n /**\n * Create a new AccountService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n * @param messenger - Controller messenger for cross-controller communication.\n */\n constructor(\n deps: PerpsPlatformDependencies,\n messenger: PerpsControllerMessengerBase,\n ) {\n this.#deps = deps;\n this.#messenger = messenger;\n }\n\n /**\n * Withdraw funds with full orchestration\n * Handles tracing, state management, analytics, and account refresh\n *\n * @param options - The withdrawal configuration.\n * @param options.provider - The perps provider to execute the withdrawal.\n * @param options.params - The withdrawal parameters (amount, destination, etc.).\n * @param options.context - The service context for tracing and dependencies.\n * @param options.refreshAccountState - Callback to refresh account state after withdrawal.\n * @returns The withdrawal result containing success status and transaction details.\n */\n async withdraw(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n context: ServiceContext;\n refreshAccountState: () => Promise<void>;\n }): Promise<WithdrawResult> {\n const { provider, params, context, refreshAccountState } = options;\n\n const traceId = uuidv4();\n const startTime = this.#deps.performance.now();\n let traceData:\n | {\n success: boolean;\n error?: string;\n txHash?: string;\n withdrawalId?: string;\n }\n | undefined;\n\n // Generate withdrawal request ID for tracking\n const currentWithdrawalId = `withdraw-${Date.now()}-${Math.random()\n .toString(36)\n .substring(2, 11)}`;\n\n try {\n this.#deps.tracer.trace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n op: PerpsTraceOperations.Operation,\n tags: {\n assetId: params.assetId ?? '',\n provider: context.tracingContext.provider,\n isTestnet: String(context.tracingContext.isTestnet),\n },\n });\n\n this.#deps.debugLogger.log('AccountService: STARTING WITHDRAWAL', {\n params,\n timestamp: new Date().toISOString(),\n assetId: params.assetId,\n amount: params.amount,\n destination: params.destination,\n activeProvider: context.tracingContext.provider,\n isTestnet: context.tracingContext.isTestnet,\n });\n\n // Set withdrawal in progress\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.withdrawInProgress = true;\n\n // Calculate net amount after fees\n const grossAmount = parseFloat(params.amount);\n const feeAmount = WITHDRAWAL_CONSTANTS.DefaultFeeAmount;\n const netAmount = Math.max(0, grossAmount - feeAmount);\n\n // Get current account address via messenger\n const evmAccount = getSelectedEvmAccount(\n this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n ),\n );\n const accountAddress = evmAccount?.address ?? 'unknown';\n\n this.#deps.debugLogger.log(\n 'AccountService: Creating withdrawal request',\n {\n accountAddress,\n hasEvmAccount: Boolean(evmAccount),\n evmAccountAddress: evmAccount?.address,\n amount: netAmount.toString(),\n },\n );\n\n // Add withdrawal request to tracking\n const withdrawalRequest = {\n id: currentWithdrawalId,\n timestamp: Date.now(),\n amount: netAmount.toString(), // Use net amount (after fees)\n asset: USDC_SYMBOL,\n accountAddress, // Track which account initiated withdrawal\n success: false, // Will be updated when transaction completes\n txHash: undefined,\n status: 'pending' as TransactionStatus,\n destination: params.destination,\n transactionId: undefined, // Will be set to withdrawalId when available\n };\n\n state.withdrawalRequests.unshift(withdrawalRequest);\n });\n }\n\n this.#deps.debugLogger.log('AccountService: DELEGATING TO PROVIDER', {\n provider: context.tracingContext.provider,\n providerReady: Boolean(provider),\n });\n\n // Execute withdrawal\n const result = await provider.withdraw(params);\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL RESULT', {\n success: result.success,\n error: result.error,\n txHash: result.txHash,\n timestamp: new Date().toISOString(),\n });\n\n // Update state based on result\n if (result.success) {\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = null;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: true,\n txHash: result.txHash ?? '',\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n error: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n if (result.txHash) {\n requestToUpdate.status = 'completed' as TransactionStatus;\n requestToUpdate.success = true;\n requestToUpdate.txHash = result.txHash;\n } else {\n requestToUpdate.status = 'bridging' as TransactionStatus;\n requestToUpdate.success = true;\n }\n if (result.withdrawalId) {\n requestToUpdate.withdrawalId = result.withdrawalId;\n }\n }\n }\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL SUCCESSFUL', {\n txHash: result.txHash,\n amount: params.amount,\n assetId: params.assetId,\n withdrawalId: result.withdrawalId,\n });\n\n // Track withdrawal transaction executed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.EXECUTED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n },\n );\n\n // Trigger account state refresh after withdrawal\n refreshAccountState().catch((refreshError) => {\n this.#deps.logger.error(\n ensureError(refreshError, 'AccountService.withdraw'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { operation: 'refreshAccountState' },\n },\n },\n );\n });\n\n // Invalidate standalone caches so external hooks (e.g., usePerpsPositionForAsset) refresh\n this.#deps.cacheInvalidator.invalidate({ cacheType: 'accountState' });\n\n traceData = {\n success: true,\n txHash: result.txHash ?? '',\n withdrawalId: result.withdrawalId ?? '',\n };\n\n return result;\n }\n\n // Handle failure\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: false,\n error: result.error ?? PERPS_ERROR_CODES.WITHDRAW_FAILED,\n amount: params.amount,\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n requestToUpdate.status = 'failed' as TransactionStatus;\n requestToUpdate.success = false;\n }\n }\n });\n }\n\n this.#deps.debugLogger.log('AccountService: WITHDRAWAL FAILED', {\n error: result.error,\n params,\n });\n\n // Track withdrawal transaction failed\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: parseFloat(params.amount),\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: result.error ?? 'Unknown error',\n },\n );\n\n traceData = {\n success: false,\n error: result.error ?? 'Unknown error',\n };\n\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : PERPS_ERROR_CODES.WITHDRAW_FAILED;\n\n this.#deps.logger.error(ensureError(error, 'AccountService.withdraw'), {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.withdraw',\n data: { assetId: params.assetId, amount: params.amount },\n },\n });\n\n if (context.stateManager) {\n context.stateManager.update((state) => {\n state.lastError = errorMessage;\n state.lastUpdateTimestamp = Date.now();\n state.withdrawInProgress = false;\n state.lastWithdrawResult = {\n success: false,\n error: errorMessage,\n amount: '0',\n asset: USDC_SYMBOL,\n timestamp: Date.now(),\n txHash: '',\n };\n\n // Update the withdrawal request by request ID\n if (state.withdrawalRequests.length > 0) {\n const requestToUpdate = state.withdrawalRequests.find(\n (req) => req.id === currentWithdrawalId,\n );\n if (requestToUpdate) {\n requestToUpdate.status = 'failed' as TransactionStatus;\n requestToUpdate.success = false;\n }\n }\n });\n }\n\n // Track withdrawal transaction failed (catch block)\n const completionDuration = this.#deps.performance.now() - startTime;\n this.#deps.metrics.trackPerpsEvent(\n PerpsAnalyticsEvent.WithdrawalTransaction,\n {\n [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,\n [PERPS_EVENT_PROPERTY.WITHDRAWAL_AMOUNT]: params.amount,\n [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,\n [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: errorMessage,\n },\n );\n\n traceData = {\n success: false,\n error: errorMessage,\n };\n\n return { success: false, error: errorMessage };\n } finally {\n this.#deps.tracer.endTrace({\n name: PerpsTraceNames.Withdraw,\n id: traceId,\n data: traceData,\n });\n }\n }\n\n /**\n * Validate withdrawal parameters\n *\n * @param options - The validation configuration.\n * @param options.provider - The perps provider to validate against.\n * @param options.params - The withdrawal parameters to validate.\n * @returns An object indicating whether the withdrawal is valid, with an optional error message.\n */\n async validateWithdrawal(options: {\n provider: PerpsProvider;\n params: WithdrawParams;\n }): Promise<{ isValid: boolean; error?: string }> {\n const { provider, params } = options;\n\n try {\n return await provider.validateWithdrawal(params);\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'AccountService.validateWithdrawal'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'AccountService.validateWithdrawal',\n data: { params },\n },\n },\n );\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1750,39 +1750,26 @@ async function _HyperLiquidSubscriptionService_ensureOrderFillISubscription(acco
|
|
|
1750
1750
|
const userAddress = await __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_walletService, "f").getUserAddressWithDefault(accountId);
|
|
1751
1751
|
// userFills returns a Promise<ISubscription>, need to await it
|
|
1752
1752
|
const subscription = await subscriptionClient.userFills({ user: userAddress }, (data) => {
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1753
|
+
const orderFills = data.fills.map((fill) => ({
|
|
1754
|
+
orderId: fill.oid.toString(),
|
|
1755
|
+
symbol: fill.coin,
|
|
1756
|
+
side: fill.side,
|
|
1757
|
+
size: fill.sz,
|
|
1758
|
+
price: fill.px,
|
|
1759
|
+
fee: fill.fee,
|
|
1760
|
+
timestamp: fill.time,
|
|
1761
|
+
pnl: fill.closedPnl,
|
|
1762
|
+
direction: fill.dir,
|
|
1763
|
+
feeToken: fill.feeToken,
|
|
1764
|
+
startPosition: fill.startPosition,
|
|
1765
|
+
liquidation: fill.liquidation
|
|
1766
|
+
? {
|
|
1767
|
+
liquidatedUser: fill.liquidation.liquidatedUser,
|
|
1768
|
+
markPx: fill.liquidation.markPx,
|
|
1769
|
+
method: fill.liquidation.method,
|
|
1759
1770
|
}
|
|
1760
|
-
|
|
1761
|
-
}
|
|
1762
|
-
const orderFills = data.fills.map((fill) => {
|
|
1763
|
-
const oid = fill.oid.toString();
|
|
1764
|
-
return {
|
|
1765
|
-
orderId: oid,
|
|
1766
|
-
symbol: fill.coin,
|
|
1767
|
-
side: fill.side,
|
|
1768
|
-
size: fill.sz,
|
|
1769
|
-
price: fill.px,
|
|
1770
|
-
fee: fill.fee,
|
|
1771
|
-
timestamp: fill.time,
|
|
1772
|
-
pnl: fill.closedPnl,
|
|
1773
|
-
direction: fill.dir,
|
|
1774
|
-
feeToken: fill.feeToken,
|
|
1775
|
-
startPosition: fill.startPosition,
|
|
1776
|
-
liquidation: fill.liquidation
|
|
1777
|
-
? {
|
|
1778
|
-
liquidatedUser: fill.liquidation.liquidatedUser,
|
|
1779
|
-
markPx: fill.liquidation.markPx,
|
|
1780
|
-
method: fill.liquidation.method,
|
|
1781
|
-
}
|
|
1782
|
-
: undefined,
|
|
1783
|
-
detailedOrderType: orderMap.get(oid),
|
|
1784
|
-
};
|
|
1785
|
-
});
|
|
1771
|
+
: undefined,
|
|
1772
|
+
}));
|
|
1786
1773
|
// Cache fills for cache-first pattern (similar to price caching)
|
|
1787
1774
|
// This allows getOrFetchFills() to return cached data without REST API calls
|
|
1788
1775
|
if (data.isSnapshot) {
|