@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +0 -18
  2. package/dist/PerpsController.cjs +10 -87
  3. package/dist/PerpsController.cjs.map +1 -1
  4. package/dist/PerpsController.d.cts +2 -25
  5. package/dist/PerpsController.d.cts.map +1 -1
  6. package/dist/PerpsController.d.mts +2 -25
  7. package/dist/PerpsController.d.mts.map +1 -1
  8. package/dist/PerpsController.mjs +10 -87
  9. package/dist/PerpsController.mjs.map +1 -1
  10. package/dist/constants/hyperLiquidConfig.cjs +2 -2
  11. package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
  12. package/dist/constants/hyperLiquidConfig.mjs +2 -2
  13. package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
  14. package/dist/constants/perpsConfig.cjs +1 -8
  15. package/dist/constants/perpsConfig.cjs.map +1 -1
  16. package/dist/constants/perpsConfig.d.cts +0 -7
  17. package/dist/constants/perpsConfig.d.cts.map +1 -1
  18. package/dist/constants/perpsConfig.d.mts +0 -7
  19. package/dist/constants/perpsConfig.d.mts.map +1 -1
  20. package/dist/constants/perpsConfig.mjs +0 -7
  21. package/dist/constants/perpsConfig.mjs.map +1 -1
  22. package/dist/providers/HyperLiquidProvider.cjs +0 -31
  23. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  24. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  25. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  26. package/dist/providers/HyperLiquidProvider.mjs +0 -31
  27. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  28. package/dist/services/AccountService.cjs +35 -35
  29. package/dist/services/AccountService.cjs.map +1 -1
  30. package/dist/services/AccountService.d.cts.map +1 -1
  31. package/dist/services/AccountService.d.mts.map +1 -1
  32. package/dist/services/AccountService.mjs +35 -35
  33. package/dist/services/AccountService.mjs.map +1 -1
  34. package/dist/services/HyperLiquidSubscriptionService.cjs +19 -32
  35. package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
  36. package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
  37. package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
  38. package/dist/services/HyperLiquidSubscriptionService.mjs +19 -32
  39. package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
  40. package/dist/services/TradingService.cjs +3 -4
  41. package/dist/services/TradingService.cjs.map +1 -1
  42. package/dist/services/TradingService.d.cts.map +1 -1
  43. package/dist/services/TradingService.d.mts.map +1 -1
  44. package/dist/services/TradingService.mjs +3 -4
  45. package/dist/services/TradingService.mjs.map +1 -1
  46. package/dist/utils/orderCalculations.cjs +1 -4
  47. package/dist/utils/orderCalculations.cjs.map +1 -1
  48. package/dist/utils/orderCalculations.d.cts.map +1 -1
  49. package/dist/utils/orderCalculations.d.mts.map +1 -1
  50. package/dist/utils/orderCalculations.mjs +2 -5
  51. package/dist/utils/orderCalculations.mjs.map +1 -1
  52. 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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
221
- if (withdrawalRequestIndex !== -1) {
222
- state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
269
- if (withdrawalRequestIndex !== -1) {
270
- state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
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;IA0T3B;;;;;;;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
+ {"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;IA0T3B;;;;;;;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
+ {"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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
218
- if (withdrawalRequestIndex !== -1) {
219
- state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
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
- const withdrawalRequestIndex = state.withdrawalRequests.findIndex((req) => req.id === currentWithdrawalId);
266
- if (withdrawalRequestIndex !== -1) {
267
- state.withdrawalRequests.splice(withdrawalRequestIndex, 1);
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":";;;;;;;;;;;;AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,aAAa;AAGpC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EAClB,oCAAgC;AACjC,OAAO,EAAE,WAAW,EAAE,2CAAuC;AAC7D,OAAO,EACL,eAAe,EACf,oBAAoB,EACrB,qCAAiC;AAClC,OAAO,EAAE,iBAAiB,EAAE,+BAA2B;AACvD,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACrB,2BAAiB;AASlB,OAAO,EAAE,qBAAqB,EAAE,kCAA8B;AAC9D,OAAO,EAAE,WAAW,EAAE,gCAA4B;AAElD;;;;;;;;;GASG;AACH,MAAM,OAAO,cAAc;IAKzB;;;;;OAKG;IACH,YACE,IAA+B,EAC/B,SAAuC;QAZhC,uCAAiC;QAEjC,4CAAyC;QAYhD,uBAAA,IAAI,wBAAS,IAAI,MAAA,CAAC;QAClB,uBAAA,IAAI,6BAAc,SAAS,MAAA,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,QAAQ,CAAC,OAKd;QACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC;QAEnE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAC/C,IAAI,SAOS,CAAC;QAEd,8CAA8C;QAC9C,MAAM,mBAAmB,GAAG,YAAY,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE;aAChE,QAAQ,CAAC,EAAE,CAAC;aACZ,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAEtB,IAAI,CAAC;YACH,uBAAA,IAAI,4BAAM,CAAC,MAAM,CAAC,KAAK,CAAC;gBACtB,IAAI,EAAE,eAAe,CAAC,QAAQ;gBAC9B,EAAE,EAAE,OAAO;gBACX,EAAE,EAAE,oBAAoB,CAAC,SAAS;gBAClC,IAAI,EAAE;oBACJ,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;oBAC7B,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,QAAQ;oBACzC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC;iBACpD;aACF,CAAC,CAAC;YAEH,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,qCAAqC,EAAE;gBAChE,MAAM;gBACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,cAAc,EAAE,OAAO,CAAC,cAAc,CAAC,QAAQ;gBAC/C,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS;aAC5C,CAAC,CAAC;YAEH,6BAA6B;YAC7B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpC,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC;oBAEhC,kCAAkC;oBAClC,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC9C,MAAM,SAAS,GAAG,oBAAoB,CAAC,gBAAgB,CAAC;oBACxD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,CAAC;oBAEvD,4CAA4C;oBAC5C,MAAM,UAAU,GAAG,qBAAqB,CACtC,uBAAA,IAAI,iCAAW,CAAC,IAAI,CAClB,2DAA2D,CAC5D,CACF,CAAC;oBACF,MAAM,cAAc,GAAG,UAAU,EAAE,OAAO,IAAI,SAAS,CAAC;oBAExD,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CACxB,6CAA6C,EAC7C;wBACE,cAAc;wBACd,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC;wBAClC,iBAAiB,EAAE,UAAU,EAAE,OAAO;wBACtC,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE;qBAC7B,CACF,CAAC;oBAEF,qCAAqC;oBACrC,MAAM,iBAAiB,GAAG;wBACxB,EAAE,EAAE,mBAAmB;wBACvB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,8BAA8B;wBAC5D,KAAK,EAAE,WAAW;wBAClB,cAAc,EAAE,2CAA2C;wBAC3D,OAAO,EAAE,KAAK,EAAE,6CAA6C;wBAC7D,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,SAA8B;wBACtC,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,aAAa,EAAE,SAAS,EAAE,6CAA6C;qBACxE,CAAC;oBAEF,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;gBACtD,CAAC,CAAC,CAAC;YACL,CAAC;YAED,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,wCAAwC,EAAE;gBACnE,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,QAAQ;gBACzC,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC;aACjC,CAAC,CAAC;YAEH,qBAAqB;YACrB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAE/C,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,mCAAmC,EAAE;gBAC9D,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;YAEH,+BAA+B;YAC/B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;oBACzB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;wBACpC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;wBACvB,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBAEvC,MAAM,sBAAsB,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAC/D,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,mBAAmB,CACxC,CAAC;wBAEF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;4BAClB,6DAA6D;4BAC7D,sDAAsD;4BACtD,yDAAyD;4BACzD,+DAA+D;4BAC/D,8DAA8D;4BAC9D,yDAAyD;4BACzD,6DAA6D;4BAC7D,IAAI,sBAAsB,KAAK,CAAC,CAAC,EAAE,CAAC;gCAClC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;4BAC7D,CAAC;4BAED,KAAK,CAAC,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;4BAE1D,MAAM,eAAe,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CACnD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAC/D,CAAC;4BACF,KAAK,CAAC,kBAAkB,GAAG,eAAe,CAAC;wBAC7C,CAAC;6BAAM,IAAI,sBAAsB,KAAK,CAAC,CAAC,EAAE,CAAC;4BACzC,MAAM,eAAe,GACnB,KAAK,CAAC,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;4BACnD,yCAAyC;4BACzC,eAAe,CAAC,MAAM,GAAG,UAA+B,CAAC;4BACzD,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC;4BAC/B,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gCACxB,eAAe,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;4BACrD,CAAC;wBACH,CAAC;wBAED,0EAA0E;wBAC1E,2EAA2E;wBAC3E,KAAK,CAAC,kBAAkB,GAAG;4BACzB,OAAO,EAAE,IAAI;4BACb,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;4BAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,KAAK,EAAE,WAAW;4BAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;4BACrB,KAAK,EAAE,EAAE;yBACV,CAAC;oBACJ,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,uCAAuC,EAAE;oBAClE,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;iBAClC,CAAC,CAAC;gBAEH,wCAAwC;gBACxC,MAAM,kBAAkB,GAAG,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBACpE,uBAAA,IAAI,4BAAM,CAAC,OAAO,CAAC,eAAe,CAChC,mBAAmB,CAAC,qBAAqB,EACzC;oBACE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,QAAQ;oBAChE,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;oBACnE,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,EAAE,kBAAkB;iBAC/D,CACF,CAAC;gBAEF,iDAAiD;gBACjD,mBAAmB,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,EAAE;oBAC3C,uBAAA,IAAI,4BAAM,CAAC,MAAM,CAAC,KAAK,CACrB,WAAW,CAAC,YAAY,EAAE,yBAAyB,CAAC,EACpD;wBACE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,WAAW,EAAE;wBAC9C,OAAO,EAAE;4BACP,IAAI,EAAE,yBAAyB;4BAC/B,IAAI,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE;yBAC3C;qBACF,CACF,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,0FAA0F;gBAC1F,uBAAA,IAAI,4BAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;gBAEtE,SAAS,GAAG;oBACV,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;oBAC3B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;iBACxC,CAAC;gBAEF,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,iBAAiB;YACjB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,iBAAiB,CAAC,eAAe,CAAC;oBACpE,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvC,KAAK,CAAC,kBAAkB,GAAG;wBACzB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,iBAAiB,CAAC,eAAe;wBACxD,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,KAAK,EAAE,WAAW;wBAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,MAAM,EAAE,EAAE;qBACX,CAAC;oBAEF,MAAM,sBAAsB,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAC/D,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,mBAAmB,CACxC,CAAC;oBACF,IAAI,sBAAsB,KAAK,CAAC,CAAC,EAAE,CAAC;wBAClC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;oBAC7D,CAAC;oBACD,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAC/D,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAED,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,mCAAmC,EAAE;gBAC9D,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM;aACP,CAAC,CAAC;YAEH,sCAAsC;YACtC,MAAM,kBAAkB,GAAG,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACpE,uBAAA,IAAI,4BAAM,CAAC,OAAO,CAAC,eAAe,CAChC,mBAAmB,CAAC,qBAAqB,EACzC;gBACE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM;gBAC9D,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnE,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,EAAE,kBAAkB;gBAC9D,CAAC,oBAAoB,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,eAAe;aACtE,CACF,CAAC;YAEF,SAAS,GAAG;gBACV,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,eAAe;aACvC,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK;gBACpB,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC;YAExC,uBAAA,IAAI,4BAAM,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,yBAAyB,CAAC,EAAE;gBACrE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,WAAW,EAAE;gBAC9C,OAAO,EAAE;oBACP,IAAI,EAAE,yBAAyB;oBAC/B,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;iBACzD;aACF,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpC,KAAK,CAAC,SAAS,GAAG,YAAY,CAAC;oBAC/B,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvC,KAAK,CAAC,kBAAkB,GAAG;wBACzB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,YAAY;wBACnB,MAAM,EAAE,GAAG;wBACX,KAAK,EAAE,WAAW;wBAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,MAAM,EAAE,EAAE;qBACX,CAAC;oBAEF,MAAM,sBAAsB,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAC/D,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,mBAAmB,CACxC,CAAC;oBACF,IAAI,sBAAsB,KAAK,CAAC,CAAC,EAAE,CAAC;wBAClC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;oBAC7D,CAAC;oBACD,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAC/D,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAED,oDAAoD;YACpD,MAAM,kBAAkB,GAAG,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACpE,uBAAA,IAAI,4BAAM,CAAC,OAAO,CAAC,eAAe,CAChC,mBAAmB,CAAC,qBAAqB,EACzC;gBACE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM;gBAC9D,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM;gBACvD,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,EAAE,kBAAkB;gBAC9D,CAAC,oBAAoB,CAAC,aAAa,CAAC,EAAE,YAAY;aACnD,CACF,CAAC;YAEF,SAAS,GAAG;gBACV,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,YAAY;aACpB,CAAC;YAEF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QACjD,CAAC;gBAAS,CAAC;YACT,uBAAA,IAAI,4BAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;gBACzB,IAAI,EAAE,eAAe,CAAC,QAAQ;gBAC9B,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,SAAS;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,kBAAkB,CAAC,OAGxB;QACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAErC,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uBAAA,IAAI,4BAAM,CAAC,MAAM,CAAC,KAAK,CACrB,WAAW,CAAC,KAAK,EAAE,mCAAmC,CAAC,EACvD;gBACE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,WAAW,EAAE;gBAC9C,OAAO,EAAE;oBACP,IAAI,EAAE,mCAAmC;oBACzC,IAAI,EAAE,EAAE,MAAM,EAAE;iBACjB;aACF,CACF,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF","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
- // Build a Map for O(1) lookup instead of O(n) find per fill
1754
- const orderMap = new Map();
1755
- if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOrders, "f")) {
1756
- for (const order of __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOrders, "f")) {
1757
- if (order.detailedOrderType) {
1758
- orderMap.set(order.orderId, order.detailedOrderType);
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) {