@metamask-previews/perps-controller 1.3.0-preview-a0caca0c0 → 1.3.0-preview-17c76be24

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 (158) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/PerpsController-method-action-types.cjs +3 -0
  3. package/dist/PerpsController-method-action-types.cjs.map +1 -0
  4. package/dist/PerpsController-method-action-types.d.cts +147 -0
  5. package/dist/PerpsController-method-action-types.d.cts.map +1 -0
  6. package/dist/PerpsController-method-action-types.d.mts +147 -0
  7. package/dist/PerpsController-method-action-types.d.mts.map +1 -0
  8. package/dist/PerpsController-method-action-types.mjs +2 -0
  9. package/dist/PerpsController-method-action-types.mjs.map +1 -0
  10. package/dist/PerpsController.cjs +488 -183
  11. package/dist/PerpsController.cjs.map +1 -1
  12. package/dist/PerpsController.d.cts +91 -131
  13. package/dist/PerpsController.d.cts.map +1 -1
  14. package/dist/PerpsController.d.mts +91 -131
  15. package/dist/PerpsController.d.mts.map +1 -1
  16. package/dist/PerpsController.mjs +485 -182
  17. package/dist/PerpsController.mjs.map +1 -1
  18. package/dist/constants/eventNames.cjs +26 -0
  19. package/dist/constants/eventNames.cjs.map +1 -1
  20. package/dist/constants/eventNames.d.cts +19 -0
  21. package/dist/constants/eventNames.d.cts.map +1 -1
  22. package/dist/constants/eventNames.d.mts +19 -0
  23. package/dist/constants/eventNames.d.mts.map +1 -1
  24. package/dist/constants/eventNames.mjs +26 -0
  25. package/dist/constants/eventNames.mjs.map +1 -1
  26. package/dist/constants/hyperLiquidConfig.cjs +24 -4
  27. package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
  28. package/dist/constants/hyperLiquidConfig.d.cts +8 -3
  29. package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
  30. package/dist/constants/hyperLiquidConfig.d.mts +8 -3
  31. package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
  32. package/dist/constants/hyperLiquidConfig.mjs +23 -3
  33. package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
  34. package/dist/constants/myxConfig.cjs +75 -51
  35. package/dist/constants/myxConfig.cjs.map +1 -1
  36. package/dist/constants/myxConfig.d.cts +58 -19
  37. package/dist/constants/myxConfig.d.cts.map +1 -1
  38. package/dist/constants/myxConfig.d.mts +58 -19
  39. package/dist/constants/myxConfig.d.mts.map +1 -1
  40. package/dist/constants/myxConfig.mjs +74 -50
  41. package/dist/constants/myxConfig.mjs.map +1 -1
  42. package/dist/constants/perpsConfig.cjs +6 -2
  43. package/dist/constants/perpsConfig.cjs.map +1 -1
  44. package/dist/constants/perpsConfig.d.cts +5 -1
  45. package/dist/constants/perpsConfig.d.cts.map +1 -1
  46. package/dist/constants/perpsConfig.d.mts +5 -1
  47. package/dist/constants/perpsConfig.d.mts.map +1 -1
  48. package/dist/constants/perpsConfig.mjs +5 -1
  49. package/dist/constants/perpsConfig.mjs.map +1 -1
  50. package/dist/index.cjs +243 -25
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +48 -5
  53. package/dist/index.d.cts.map +1 -1
  54. package/dist/index.d.mts +48 -5
  55. package/dist/index.d.mts.map +1 -1
  56. package/dist/index.mjs +36 -10
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/providers/AggregatedPerpsProvider.cjs +24 -0
  59. package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
  60. package/dist/providers/AggregatedPerpsProvider.d.cts +4 -0
  61. package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
  62. package/dist/providers/AggregatedPerpsProvider.d.mts +4 -0
  63. package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
  64. package/dist/providers/AggregatedPerpsProvider.mjs +24 -0
  65. package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
  66. package/dist/providers/HyperLiquidProvider.cjs +470 -154
  67. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  68. package/dist/providers/HyperLiquidProvider.d.cts +11 -2
  69. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  70. package/dist/providers/HyperLiquidProvider.d.mts +11 -2
  71. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  72. package/dist/providers/HyperLiquidProvider.mjs +471 -155
  73. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  74. package/dist/selectors.cjs +1 -1
  75. package/dist/selectors.cjs.map +1 -1
  76. package/dist/selectors.mjs +1 -1
  77. package/dist/selectors.mjs.map +1 -1
  78. package/dist/services/AccountService.cjs +1 -1
  79. package/dist/services/AccountService.cjs.map +1 -1
  80. package/dist/services/AccountService.d.cts.map +1 -1
  81. package/dist/services/AccountService.d.mts.map +1 -1
  82. package/dist/services/AccountService.mjs +2 -2
  83. package/dist/services/AccountService.mjs.map +1 -1
  84. package/dist/services/DepositService.cjs +2 -1
  85. package/dist/services/DepositService.cjs.map +1 -1
  86. package/dist/services/DepositService.d.cts.map +1 -1
  87. package/dist/services/DepositService.d.mts.map +1 -1
  88. package/dist/services/DepositService.mjs +2 -1
  89. package/dist/services/DepositService.mjs.map +1 -1
  90. package/dist/services/EligibilityService.cjs +8 -103
  91. package/dist/services/EligibilityService.cjs.map +1 -1
  92. package/dist/services/EligibilityService.d.cts +4 -15
  93. package/dist/services/EligibilityService.d.cts.map +1 -1
  94. package/dist/services/EligibilityService.d.mts +4 -15
  95. package/dist/services/EligibilityService.d.mts.map +1 -1
  96. package/dist/services/EligibilityService.mjs +8 -103
  97. package/dist/services/EligibilityService.mjs.map +1 -1
  98. package/dist/services/HyperLiquidSubscriptionService.cjs +252 -46
  99. package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
  100. package/dist/services/HyperLiquidSubscriptionService.d.cts +1 -0
  101. package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
  102. package/dist/services/HyperLiquidSubscriptionService.d.mts +1 -0
  103. package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
  104. package/dist/services/HyperLiquidSubscriptionService.mjs +252 -46
  105. package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
  106. package/dist/services/MarketDataService.cjs +2 -4
  107. package/dist/services/MarketDataService.cjs.map +1 -1
  108. package/dist/services/MarketDataService.d.cts.map +1 -1
  109. package/dist/services/MarketDataService.d.mts.map +1 -1
  110. package/dist/services/MarketDataService.mjs +2 -4
  111. package/dist/services/MarketDataService.mjs.map +1 -1
  112. package/dist/services/TradingService.cjs +72 -6
  113. package/dist/services/TradingService.cjs.map +1 -1
  114. package/dist/services/TradingService.d.cts.map +1 -1
  115. package/dist/services/TradingService.d.mts.map +1 -1
  116. package/dist/services/TradingService.mjs +72 -6
  117. package/dist/services/TradingService.mjs.map +1 -1
  118. package/dist/types/index.cjs.map +1 -1
  119. package/dist/types/index.d.cts +51 -3
  120. package/dist/types/index.d.cts.map +1 -1
  121. package/dist/types/index.d.mts +51 -3
  122. package/dist/types/index.d.mts.map +1 -1
  123. package/dist/types/index.mjs.map +1 -1
  124. package/dist/types/messenger.cjs.map +1 -1
  125. package/dist/types/messenger.d.cts +2 -1
  126. package/dist/types/messenger.d.cts.map +1 -1
  127. package/dist/types/messenger.d.mts +2 -1
  128. package/dist/types/messenger.d.mts.map +1 -1
  129. package/dist/types/messenger.mjs.map +1 -1
  130. package/dist/types/myx-types.cjs +19 -3
  131. package/dist/types/myx-types.cjs.map +1 -1
  132. package/dist/types/myx-types.d.cts +33 -2
  133. package/dist/types/myx-types.d.cts.map +1 -1
  134. package/dist/types/myx-types.d.mts +33 -2
  135. package/dist/types/myx-types.d.mts.map +1 -1
  136. package/dist/types/myx-types.mjs +6 -2
  137. package/dist/types/myx-types.mjs.map +1 -1
  138. package/dist/types/perps-types.cjs +3 -0
  139. package/dist/types/perps-types.cjs.map +1 -1
  140. package/dist/types/perps-types.d.cts +3 -3
  141. package/dist/types/perps-types.d.cts.map +1 -1
  142. package/dist/types/perps-types.d.mts +3 -3
  143. package/dist/types/perps-types.d.mts.map +1 -1
  144. package/dist/types/perps-types.mjs +3 -0
  145. package/dist/types/perps-types.mjs.map +1 -1
  146. package/dist/utils/accountUtils.cjs.map +1 -1
  147. package/dist/utils/accountUtils.d.cts.map +1 -1
  148. package/dist/utils/accountUtils.d.mts.map +1 -1
  149. package/dist/utils/accountUtils.mjs.map +1 -1
  150. package/dist/utils/myxAdapter.cjs +360 -15
  151. package/dist/utils/myxAdapter.cjs.map +1 -1
  152. package/dist/utils/myxAdapter.d.cts +94 -7
  153. package/dist/utils/myxAdapter.d.cts.map +1 -1
  154. package/dist/utils/myxAdapter.d.mts +94 -7
  155. package/dist/utils/myxAdapter.d.mts.map +1 -1
  156. package/dist/utils/myxAdapter.mjs +351 -16
  157. package/dist/utils/myxAdapter.mjs.map +1 -1
  158. package/package.json +5 -3
@@ -2,20 +2,20 @@
2
2
  /**
3
3
  * MYX SDK Adapter Utilities
4
4
  *
5
- * Stage 1 adapters for transforming between MetaMask Perps API types and MYX SDK types.
6
- * Only includes adapters needed for market display and price fetching.
5
+ * Adapters for transforming between MetaMask Perps API types and MYX SDK types.
6
+ * Includes adapters for market display, positions, orders, account state, and fills.
7
7
  *
8
8
  * Portable: no mobile-specific imports.
9
9
  * Formatters are injected via MarketDataFormatters interface (same pattern as marketDataTransform.ts).
10
10
  *
11
11
  * Key differences from HyperLiquid:
12
- * - Prices use 30 decimals
12
+ * - API prices are normal floats (SDK contract layer uses 30 decimals internally)
13
13
  * - Sizes use 18 decimals (vs HyperLiquid's szDecimals per asset)
14
14
  * - Multiple pools can exist per symbol (MPM model)
15
15
  * - USDT collateral (vs USDC)
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.extractSymbolFromPoolId = exports.buildSymbolPoolsMap = exports.buildPoolSymbolMap = exports.isOverlappingMarket = exports.filterMYXExclusiveMarkets = exports.adaptMarketDataFromMYX = exports.adaptPriceFromMYX = exports.adaptMarketFromMYX = void 0;
18
+ exports.assertMYXSuccess = exports.toMYXKlineResolution = exports.adaptCandleFromMYXWebSocket = exports.adaptCandleFromMYX = exports.adaptUserHistoryFromMYX = exports.adaptFundingFromMYX = exports.adaptOrderFillFromMYX = exports.adaptAccountStateFromMYX = exports.adaptOrderFromMYX = exports.adaptPositionFromMYX = exports.extractSymbolFromPoolId = exports.buildSymbolPoolsMap = exports.buildPoolSymbolMap = exports.isOverlappingMarket = exports.filterMYXExclusiveMarkets = exports.adaptMarketDataFromMYX = exports.adaptPriceFromMYX = exports.adaptMarketFromMYX = void 0;
19
19
  const myxConfig_1 = require("../constants/myxConfig.cjs");
20
20
  const myx_types_1 = require("../types/myx-types.cjs");
21
21
  /**
@@ -53,15 +53,12 @@ function adaptMarketFromMYX(pool) {
53
53
  const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);
54
54
  // MYX uses fixed 18 decimals for sizes
55
55
  const szDecimals = 18;
56
- // Default max leverage - MYX supports up to 100x on most markets
57
- // Will be refined when pool level config is fetched
58
- const maxLeverage = 100;
59
56
  return {
60
57
  name: symbol,
61
58
  szDecimals,
62
- maxLeverage,
59
+ maxLeverage: myxConfig_1.MYX_MAX_LEVERAGE,
63
60
  marginTableId: 0, // MYX doesn't use margin tables like HyperLiquid
64
- minimumOrderSize: 10, // MYX minimum order size is $10
61
+ minimumOrderSize: myxConfig_1.MYX_MINIMUM_ORDER_SIZE_USD,
65
62
  providerId: 'myx',
66
63
  };
67
64
  }
@@ -73,7 +70,7 @@ exports.adaptMarketFromMYX = adaptMarketFromMYX;
73
70
  * @returns Object with price string and 24h change percentage
74
71
  */
75
72
  function adaptPriceFromMYX(ticker) {
76
- // MYX ticker prices are in 30-decimal format
73
+ // MYX API returns normal float strings (e.g. "64854.76")
77
74
  const priceNum = (0, myxConfig_1.fromMYXPrice)(ticker.price);
78
75
  // Change is provided as a percentage string (e.g., "2.5" means 2.5%)
79
76
  const change24h = ticker.change ? parseFloat(ticker.change) : 0;
@@ -114,7 +111,7 @@ function adaptMarketDataFromMYX(pool, ticker, formatters) {
114
111
  return {
115
112
  symbol,
116
113
  name: getTokenName(symbol),
117
- maxLeverage: '100x', // MYX default
114
+ maxLeverage: `${myxConfig_1.MYX_MAX_LEVERAGE}x`,
118
115
  price: formattedPrice,
119
116
  change24h: formattedChange,
120
117
  change24hPercent: formattedChangePercent,
@@ -188,15 +185,19 @@ function buildSymbolPoolsMap(pools) {
188
185
  exports.buildSymbolPoolsMap = buildSymbolPoolsMap;
189
186
  /**
190
187
  * Extract symbol from pool ID
191
- * Pool IDs typically contain the symbol as a suffix or can be parsed
188
+ * Pool IDs typically contain the symbol as a suffix or can be parsed.
189
+ * When baseSymbol is unavailable, returns a truncated address for UI display.
192
190
  *
193
191
  * @param poolId - MYX pool ID string
194
- * @returns Extracted symbol or poolId as fallback
192
+ * @returns Extracted symbol or truncated poolId as fallback
195
193
  */
196
194
  function extractSymbolFromPoolId(poolId) {
197
- // Pool IDs in MYX typically look like "0x..." hex addresses
195
+ // Pool IDs in MYX are hex addresses ("0x...")
198
196
  // The actual symbol comes from the pool's baseSymbol field
199
- // This is a fallback when baseSymbol is not available
197
+ // Truncate hex addresses so they're UI-friendly
198
+ if (poolId.startsWith('0x') && poolId.length > 10) {
199
+ return `${poolId.slice(0, 6)}...${poolId.slice(-4)}`;
200
+ }
200
201
  return poolId;
201
202
  }
202
203
  exports.extractSymbolFromPoolId = extractSymbolFromPoolId;
@@ -221,4 +222,348 @@ function getTokenName(symbol) {
221
222
  };
222
223
  return tokenNames[symbol] || symbol;
223
224
  }
225
+ // ============================================================================
226
+ // Position Adapter
227
+ // ============================================================================
228
+ /**
229
+ * Adapt MYX SDK PositionType to MetaMask Position
230
+ *
231
+ * @param pos - MYX position from SDK
232
+ * @param poolSymbolMap - Map of poolId to symbol
233
+ * @returns MetaMask Position object
234
+ */
235
+ function adaptPositionFromMYX(pos, poolSymbolMap) {
236
+ const symbol = poolSymbolMap.get(pos.poolId) ?? pos.poolId;
237
+ const sizeNum = (0, myxConfig_1.fromMYXSize)(pos.size);
238
+ const entryPriceNum = (0, myxConfig_1.fromMYXPrice)(pos.entryPrice);
239
+ const collateralNum = (0, myxConfig_1.fromMYXCollateral)(pos.collateralAmount);
240
+ // Direction: 0 = LONG (positive size), 1 = SHORT (negative size)
241
+ const isLong = pos.direction === myx_types_1.MYXDirection.LONG;
242
+ const signedSize = isLong ? sizeNum : -sizeNum;
243
+ // Position value = size * entry price
244
+ const positionValue = Math.abs(sizeNum * entryPriceNum);
245
+ // Leverage = position value / collateral (approximate)
246
+ const leverage = collateralNum > 0 ? positionValue / collateralNum : 1;
247
+ return {
248
+ symbol,
249
+ size: signedSize.toString(),
250
+ entryPrice: entryPriceNum.toString(),
251
+ positionValue: positionValue.toString(),
252
+ unrealizedPnl: '0', // Requires mark price - will be enriched by WS or separate call
253
+ marginUsed: collateralNum.toString(),
254
+ leverage: {
255
+ type: 'isolated',
256
+ value: Math.round(leverage),
257
+ rawUsd: collateralNum.toString(),
258
+ },
259
+ liquidationPrice: null, // Requires separate calculation
260
+ maxLeverage: myxConfig_1.MYX_MAX_LEVERAGE,
261
+ returnOnEquity: '0',
262
+ cumulativeFunding: {
263
+ allTime: '0',
264
+ sinceOpen: '0',
265
+ sinceChange: '0',
266
+ },
267
+ takeProfitPrice: undefined,
268
+ stopLossPrice: undefined,
269
+ takeProfitCount: 0,
270
+ stopLossCount: 0,
271
+ providerId: 'myx',
272
+ };
273
+ }
274
+ exports.adaptPositionFromMYX = adaptPositionFromMYX;
275
+ // ============================================================================
276
+ // Order Adapter
277
+ // ============================================================================
278
+ /**
279
+ * Adapt MYX SDK open order (PositionType-shaped from getOrders) to MetaMask Order.
280
+ * Note: getOrders returns PositionType[] per the SDK types.
281
+ * For richer order data, use getOrderHistory.
282
+ *
283
+ * @param historyOrder - MYX history order item
284
+ * @param poolSymbolMap - Map of poolId to symbol
285
+ * @returns MetaMask Order object
286
+ */
287
+ function adaptOrderFromMYX(historyOrder, poolSymbolMap) {
288
+ const symbol = historyOrder.baseSymbol ??
289
+ poolSymbolMap.get(historyOrder.poolId) ??
290
+ historyOrder.poolId;
291
+ const priceNum = (0, myxConfig_1.fromMYXPrice)(historyOrder.price);
292
+ const sizeNum = (0, myxConfig_1.fromMYXSize)(historyOrder.size);
293
+ const filledSizeNum = (0, myxConfig_1.fromMYXSize)(historyOrder.filledSize);
294
+ const remainingSize = Math.max(0, sizeNum - filledSizeNum);
295
+ // Map direction
296
+ const side = historyOrder.direction === myx_types_1.MYXDirectionEnum.Long ? 'buy' : 'sell';
297
+ // Map order type
298
+ let orderType = 'market';
299
+ if (historyOrder.orderType === myx_types_1.MYXOrderTypeEnum.Limit) {
300
+ orderType = 'limit';
301
+ }
302
+ // Map status
303
+ let status = 'open';
304
+ switch (historyOrder.orderStatus) {
305
+ case myx_types_1.MYXOrderStatusEnum.Successful:
306
+ status = 'filled';
307
+ break;
308
+ case myx_types_1.MYXOrderStatusEnum.Cancelled:
309
+ status = 'canceled';
310
+ break;
311
+ case myx_types_1.MYXOrderStatusEnum.Expired:
312
+ status = 'canceled';
313
+ break;
314
+ default:
315
+ status = 'open';
316
+ }
317
+ // Detect trigger orders
318
+ const isTrigger = historyOrder.execType === myx_types_1.MYXExecTypeEnum.TP ||
319
+ historyOrder.execType === myx_types_1.MYXExecTypeEnum.SL;
320
+ let detailedOrderType;
321
+ if (historyOrder.execType === myx_types_1.MYXExecTypeEnum.TP) {
322
+ detailedOrderType = 'Take Profit';
323
+ }
324
+ else if (historyOrder.execType === myx_types_1.MYXExecTypeEnum.SL) {
325
+ detailedOrderType = 'Stop Loss';
326
+ }
327
+ else if (historyOrder.execType === myx_types_1.MYXExecTypeEnum.Liquidation) {
328
+ detailedOrderType = 'Liquidation';
329
+ }
330
+ return {
331
+ orderId: String(historyOrder.orderId),
332
+ symbol,
333
+ side,
334
+ orderType,
335
+ size: sizeNum.toString(),
336
+ originalSize: sizeNum.toString(),
337
+ price: priceNum.toString(),
338
+ filledSize: filledSizeNum.toString(),
339
+ remainingSize: remainingSize.toString(),
340
+ status,
341
+ timestamp: historyOrder.txTime,
342
+ isTrigger,
343
+ detailedOrderType,
344
+ reduceOnly: historyOrder.operation === myx_types_1.MYXOperationEnum.Decrease ? true : undefined,
345
+ providerId: 'myx',
346
+ };
347
+ }
348
+ exports.adaptOrderFromMYX = adaptOrderFromMYX;
349
+ // ============================================================================
350
+ // Account State Adapter
351
+ // ============================================================================
352
+ /**
353
+ * Adapt MYX account info response to MetaMask AccountState.
354
+ *
355
+ * @param accountInfo - Raw account info from MYX SDK
356
+ * @param walletBalance - Wallet USDT balance (from getWalletQuoteTokenBalance)
357
+ * @returns MetaMask AccountState
358
+ */
359
+ function adaptAccountStateFromMYX(accountInfo, walletBalance) {
360
+ // accountInfo structure varies; extract what we can
361
+ // TODO: Verify SDK semantics — if totalCollateral already includes unrealizedPnl,
362
+ // the totalBalance formula below double-counts. Needs SDK documentation check.
363
+ const rawCollateral = accountInfo?.totalCollateral ?? '0';
364
+ const rawPnl = accountInfo?.unrealizedPnl ?? '0';
365
+ const marginUsed = accountInfo ? (0, myxConfig_1.fromMYXCollateral)(String(rawCollateral)) : 0;
366
+ const unrealizedPnl = accountInfo ? (0, myxConfig_1.fromMYXCollateral)(String(rawPnl)) : 0;
367
+ const balance = walletBalance ? (0, myxConfig_1.fromMYXCollateral)(walletBalance) : 0;
368
+ const totalBalance = balance + marginUsed + unrealizedPnl;
369
+ const availableBalance = balance;
370
+ return {
371
+ availableBalance: availableBalance.toString(),
372
+ totalBalance: totalBalance.toString(),
373
+ marginUsed: marginUsed.toString(),
374
+ unrealizedPnl: unrealizedPnl.toString(),
375
+ returnOnEquity: '0',
376
+ };
377
+ }
378
+ exports.adaptAccountStateFromMYX = adaptAccountStateFromMYX;
379
+ // ============================================================================
380
+ // Order Fill Adapter
381
+ // ============================================================================
382
+ /**
383
+ * Adapt MYX history order item (filled) to MetaMask OrderFill
384
+ *
385
+ * @param order - MYX history order item
386
+ * @param poolSymbolMap - Map of poolId to symbol
387
+ * @returns MetaMask OrderFill
388
+ */
389
+ function adaptOrderFillFromMYX(order, poolSymbolMap) {
390
+ const symbol = order.baseSymbol ?? poolSymbolMap.get(order.poolId) ?? order.poolId;
391
+ const sizeNum = (0, myxConfig_1.fromMYXSize)(order.filledSize || order.size);
392
+ const priceNum = (0, myxConfig_1.fromMYXPrice)(order.lastPrice || order.price);
393
+ const side = order.direction === myx_types_1.MYXDirectionEnum.Long ? 'buy' : 'sell';
394
+ const feeNum = (0, myxConfig_1.fromMYXCollateral)(order.tradingFee || '0');
395
+ const pnlNum = (0, myxConfig_1.fromMYXCollateral)(order.realizedPnl || '0');
396
+ let orderType = 'regular';
397
+ if (order.execType === myx_types_1.MYXExecTypeEnum.TP) {
398
+ orderType = 'take_profit';
399
+ }
400
+ else if (order.execType === myx_types_1.MYXExecTypeEnum.SL) {
401
+ orderType = 'stop_loss';
402
+ }
403
+ else if (order.execType === myx_types_1.MYXExecTypeEnum.Liquidation) {
404
+ orderType = 'liquidation';
405
+ }
406
+ return {
407
+ orderId: String(order.orderId),
408
+ symbol,
409
+ side,
410
+ size: sizeNum.toString(),
411
+ price: priceNum.toString(),
412
+ pnl: pnlNum.toString(),
413
+ direction: side,
414
+ fee: feeNum.toString(),
415
+ feeToken: 'USDT',
416
+ timestamp: order.txTime,
417
+ success: order.orderStatus === myx_types_1.MYXOrderStatusEnum.Successful,
418
+ orderType,
419
+ providerId: 'myx',
420
+ };
421
+ }
422
+ exports.adaptOrderFillFromMYX = adaptOrderFillFromMYX;
423
+ // ============================================================================
424
+ // Funding Adapter
425
+ // ============================================================================
426
+ /**
427
+ * Adapt MYX trade flow items (funding type) to MetaMask Funding
428
+ *
429
+ * @param flows - MYX trade flow items filtered to funding type
430
+ * @param poolSymbolMap - Map of poolId to symbol
431
+ * @returns Array of MetaMask Funding objects
432
+ */
433
+ function adaptFundingFromMYX(flows, poolSymbolMap) {
434
+ return flows
435
+ .filter((flow) => flow.fundingFee && flow.fundingFee !== '0' && flow.fundingFee !== '')
436
+ .map((flow) => {
437
+ const symbol = poolSymbolMap.get(flow.poolId) ?? flow.poolId;
438
+ const amountUsd = (0, myxConfig_1.fromMYXCollateral)(flow.fundingFee);
439
+ return {
440
+ symbol,
441
+ amountUsd: amountUsd.toString(),
442
+ rate: undefined, // Funding rate not available in MYX trade flow data
443
+ timestamp: flow.txTime,
444
+ transactionHash: flow.txHash,
445
+ };
446
+ });
447
+ }
448
+ exports.adaptFundingFromMYX = adaptFundingFromMYX;
449
+ // ============================================================================
450
+ // User History Adapter
451
+ // ============================================================================
452
+ /**
453
+ * Adapt MYX trade flow items to MetaMask UserHistoryItem
454
+ *
455
+ * @param flows - MYX trade flow items
456
+ * @returns Array of UserHistoryItem
457
+ */
458
+ function adaptUserHistoryFromMYX(flows) {
459
+ return flows
460
+ .filter((flow) => flow.type === myx_types_1.MYXTradeFlowTypeEnum.MarginAccountDeposit ||
461
+ flow.type === myx_types_1.MYXTradeFlowTypeEnum.TransferToWallet)
462
+ .map((flow) => {
463
+ const isDeposit = flow.type === myx_types_1.MYXTradeFlowTypeEnum.MarginAccountDeposit;
464
+ const amount = (0, myxConfig_1.fromMYXCollateral)(flow.collateralAmount || '0');
465
+ return {
466
+ id: String(flow.orderId),
467
+ timestamp: flow.txTime,
468
+ type: isDeposit ? 'deposit' : 'withdrawal',
469
+ amount: Math.abs(amount).toString(),
470
+ asset: 'USDT',
471
+ txHash: flow.txHash,
472
+ status: 'completed',
473
+ details: {
474
+ source: 'myx',
475
+ },
476
+ };
477
+ });
478
+ }
479
+ exports.adaptUserHistoryFromMYX = adaptUserHistoryFromMYX;
480
+ // ============================================================================
481
+ // Candle (Kline) Adapter
482
+ // ============================================================================
483
+ /**
484
+ * Adapt MYX KlineDataItemType to MetaMask CandleStick.
485
+ * KlineDataItemType fields (time, open, close, high, low) are already
486
+ * human-readable strings — no 30-decimal conversion needed.
487
+ *
488
+ * @param item - MYX kline data item from SDK
489
+ * @returns MetaMask CandleStick object
490
+ */
491
+ function adaptCandleFromMYX(item) {
492
+ return {
493
+ time: item.time,
494
+ open: item.open,
495
+ high: item.high,
496
+ low: item.low,
497
+ close: item.close,
498
+ volume: '0', // KlineDataItemType has no volume field
499
+ };
500
+ }
501
+ exports.adaptCandleFromMYX = adaptCandleFromMYX;
502
+ /**
503
+ * Adapt MYX WebSocket KlineData to MetaMask CandleStick.
504
+ * WS KlineData uses single-letter fields: {t, o, h, l, c, v}.
505
+ *
506
+ * @param data - MYX WebSocket kline data
507
+ * @returns MetaMask CandleStick object
508
+ */
509
+ function adaptCandleFromMYXWebSocket(data) {
510
+ return {
511
+ time: data.t,
512
+ open: data.o,
513
+ high: data.h,
514
+ low: data.l,
515
+ close: data.c,
516
+ volume: data.v,
517
+ };
518
+ }
519
+ exports.adaptCandleFromMYXWebSocket = adaptCandleFromMYXWebSocket;
520
+ /**
521
+ * Map CandlePeriod values to MYX KlineResolution.
522
+ * MYX SDK supports: '1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w', '1M'.
523
+ * Unsupported CandlePeriod values are mapped to the nearest supported resolution.
524
+ */
525
+ const CANDLE_PERIOD_TO_MYX_RESOLUTION = {
526
+ '1m': '1m',
527
+ '3m': '5m', // No 3m → use 5m
528
+ '5m': '5m',
529
+ '15m': '15m',
530
+ '30m': '30m',
531
+ '1h': '1h',
532
+ '2h': '4h', // No 2h → use 4h
533
+ '4h': '4h',
534
+ '8h': '4h', // No 8h → use 4h
535
+ '12h': '1d', // No 12h → use 1d
536
+ '1d': '1d',
537
+ '3d': '1w', // No 3d → use 1w
538
+ '1w': '1w',
539
+ '1M': '1M',
540
+ };
541
+ /**
542
+ * Convert a CandlePeriod string to MYX KlineResolution.
543
+ *
544
+ * @param period - CandlePeriod value (e.g., '1m', '3m', '1h')
545
+ * @returns MYX KlineResolution string
546
+ */
547
+ function toMYXKlineResolution(period) {
548
+ return CANDLE_PERIOD_TO_MYX_RESOLUTION[period] ?? '1h';
549
+ }
550
+ exports.toMYXKlineResolution = toMYXKlineResolution;
551
+ // ============================================================================
552
+ // Response Validation
553
+ // ============================================================================
554
+ /**
555
+ * Assert MYX API response is successful.
556
+ * MYX uses code 9200 or 0 for success.
557
+ *
558
+ * @param response - MYX API response with code field
559
+ * @param response.code - Response code (9200 or 0 = success)
560
+ * @param response.message - Optional error message
561
+ * @param context - Context string for error messages
562
+ */
563
+ function assertMYXSuccess(response, context) {
564
+ if (response.code !== 9200 && response.code !== 0) {
565
+ throw new Error(`MYX ${context} failed: code=${response.code} message=${response.message ?? 'unknown'}`);
566
+ }
567
+ }
568
+ exports.assertMYXSuccess = assertMYXSuccess;
224
569
  //# sourceMappingURL=myxAdapter.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"myxAdapter.cjs","sourceRoot":"","sources":["../../src/utils/myxAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MYX SDK Adapter Utilities\n *\n * Stage 1 adapters for transforming between MetaMask Perps API types and MYX SDK types.\n * Only includes adapters needed for market display and price fetching.\n *\n * Portable: no mobile-specific imports.\n * Formatters are injected via MarketDataFormatters interface (same pattern as marketDataTransform.ts).\n *\n * Key differences from HyperLiquid:\n * - Prices use 30 decimals\n * - Sizes use 18 decimals (vs HyperLiquid's szDecimals per asset)\n * - Multiple pools can exist per symbol (MPM model)\n * - USDT collateral (vs USDC)\n */\n\nimport { fromMYXPrice } from '../constants/myxConfig';\nimport type {\n MarketInfo,\n PerpsMarketData,\n MarketDataFormatters,\n} from '../types';\nimport { MYX_HL_OVERLAPPING_MARKETS } from '../types/myx-types';\nimport type { MYXPoolSymbol, MYXTicker } from '../types/myx-types';\n\n/**\n * Format a price change value with sign prefix.\n * Uses injected formatters (same pattern as marketDataTransform.ts formatChange).\n *\n * @param change - The price change value to format.\n * @param formatters - Injectable formatters for platform-agnostic formatting.\n * @returns The formatted change string with sign and dollar symbol.\n */\nfunction formatChange(\n change: number,\n formatters: MarketDataFormatters,\n): string {\n if (isNaN(change) || !isFinite(change)) {\n return '$0.00';\n }\n if (change === 0) {\n return '$0.00';\n }\n\n const formatted = formatters.formatPerpsFiat(Math.abs(change), {\n ranges: formatters.priceRangesUniversal,\n });\n\n const valueWithoutDollar = formatted.replace('$', '');\n return change > 0 ? `+$${valueWithoutDollar}` : `-$${valueWithoutDollar}`;\n}\n\n// ============================================================================\n// Market Transformation\n// ============================================================================\n\n/**\n * Transform MYX Pool/Market info to MetaMask Perps API MarketInfo format\n *\n * @param pool - Pool symbol data from MYX SDK (PoolSymbolAllResponse)\n * @returns MetaMask Perps API market info object\n */\nexport function adaptMarketFromMYX(pool: MYXPoolSymbol): MarketInfo {\n // Extract base symbol from pool data\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n\n // MYX uses fixed 18 decimals for sizes\n const szDecimals = 18;\n\n // Default max leverage - MYX supports up to 100x on most markets\n // Will be refined when pool level config is fetched\n const maxLeverage = 100;\n\n return {\n name: symbol,\n szDecimals,\n maxLeverage,\n marginTableId: 0, // MYX doesn't use margin tables like HyperLiquid\n minimumOrderSize: 10, // MYX minimum order size is $10\n providerId: 'myx',\n };\n}\n\n/**\n * Convert MYX ticker data to price and change values\n *\n * @param ticker - Ticker data from MYX SDK\n * @returns Object with price string and 24h change percentage\n */\nexport function adaptPriceFromMYX(ticker: MYXTicker): {\n price: string;\n change24h: number;\n} {\n // MYX ticker prices are in 30-decimal format\n const priceNum = fromMYXPrice(ticker.price);\n\n // Change is provided as a percentage string (e.g., \"2.5\" means 2.5%)\n const change24h = ticker.change ? parseFloat(ticker.change) : 0;\n\n return {\n price: priceNum.toString(),\n change24h,\n };\n}\n\n/**\n * Transform MYX pool and ticker to PerpsMarketData for UI display\n *\n * @param pool - Pool symbol data from MYX SDK\n * @param ticker - Optional ticker data for price info\n * @param formatters - Injectable formatters for platform-agnostic formatting\n * @returns Formatted market data for UI display\n */\nexport function adaptMarketDataFromMYX(\n pool: MYXPoolSymbol,\n ticker: MYXTicker | undefined,\n formatters: MarketDataFormatters,\n): PerpsMarketData {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n\n // Get price data from ticker if available\n let price = '0';\n let change24h = 0;\n let volume = '0';\n\n if (ticker) {\n const priceData = adaptPriceFromMYX(ticker);\n price = priceData.price;\n change24h = priceData.change24h;\n // Volume is already in USD (not 30-decimal format)\n volume = ticker.volume || '0';\n }\n\n // Format using injected formatters (consistent with HyperLiquid via marketDataTransform.ts)\n const priceNum = parseFloat(price);\n const formattedPrice = formatters.formatPerpsFiat(priceNum);\n const priceChange = priceNum * (change24h / 100);\n const formattedChange = formatChange(priceChange, formatters);\n const formattedChangePercent = formatters.formatPercentage(change24h);\n const formattedVolume = formatters.formatVolume(parseFloat(volume));\n\n return {\n symbol,\n name: getTokenName(symbol),\n maxLeverage: '100x', // MYX default\n price: formattedPrice,\n change24h: formattedChange,\n change24hPercent: formattedChangePercent,\n volume: formattedVolume,\n providerId: 'myx',\n };\n}\n\n// ============================================================================\n// Market Filtering\n// ============================================================================\n\n/**\n * Filter MYX markets to only include MYX-exclusive markets\n * Removes markets that overlap with HyperLiquid\n *\n * @param pools - Array of MYX pool symbols\n * @returns Filtered array with only MYX-exclusive markets\n */\nexport function filterMYXExclusiveMarkets(\n pools: MYXPoolSymbol[],\n): MYXPoolSymbol[] {\n return pools.filter((pool) => {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n // Exclude markets that overlap with HyperLiquid\n return !MYX_HL_OVERLAPPING_MARKETS.includes(\n symbol as (typeof MYX_HL_OVERLAPPING_MARKETS)[number],\n );\n });\n}\n\n/**\n * Check if a symbol overlaps with HyperLiquid markets\n *\n * @param symbol - Market symbol to check\n * @returns true if the symbol is available on both MYX and HyperLiquid\n */\nexport function isOverlappingMarket(symbol: string): boolean {\n return MYX_HL_OVERLAPPING_MARKETS.includes(\n symbol as (typeof MYX_HL_OVERLAPPING_MARKETS)[number],\n );\n}\n\n// ============================================================================\n// Pool ID Utilities\n// ============================================================================\n\n/**\n * Build a map of poolId to symbol for quick lookup\n *\n * @param pools - Array of MYX pool symbols\n * @returns Map of poolId to symbol\n */\nexport function buildPoolSymbolMap(\n pools: MYXPoolSymbol[],\n): Map<string, string> {\n const map = new Map<string, string>();\n for (const pool of pools) {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n map.set(pool.poolId, symbol);\n }\n return map;\n}\n\n/**\n * Build a map of symbol to poolIds (for multi-pool support)\n *\n * @param pools - Array of MYX pool symbols\n * @returns Map of symbol to array of poolIds\n */\nexport function buildSymbolPoolsMap(\n pools: MYXPoolSymbol[],\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n for (const pool of pools) {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n const existing = map.get(symbol) ?? [];\n existing.push(pool.poolId);\n map.set(symbol, existing);\n }\n return map;\n}\n\n/**\n * Extract symbol from pool ID\n * Pool IDs typically contain the symbol as a suffix or can be parsed\n *\n * @param poolId - MYX pool ID string\n * @returns Extracted symbol or poolId as fallback\n */\nexport function extractSymbolFromPoolId(poolId: string): string {\n // Pool IDs in MYX typically look like \"0x...\" hex addresses\n // The actual symbol comes from the pool's baseSymbol field\n // This is a fallback when baseSymbol is not available\n return poolId;\n}\n\n/**\n * Get full token name from symbol\n * Returns the symbol as name if not found (MYX-specific tokens)\n *\n * @param symbol - The market symbol to look up.\n * @returns The human-readable token name, or the symbol itself if not found.\n */\nfunction getTokenName(symbol: string): string {\n const tokenNames: Record<string, string> = {\n BTC: 'Bitcoin',\n ETH: 'Ethereum',\n BNB: 'BNB',\n MYX: 'MYX Protocol',\n RHEA: 'Rhea Finance',\n PARTI: 'Particle Network',\n SKYAI: 'SkyAI',\n PUMP: 'PumpFun',\n WLFI: 'World Liberty Financial',\n };\n\n return tokenNames[symbol] || symbol;\n}\n"]}
1
+ {"version":3,"file":"myxAdapter.cjs","sourceRoot":"","sources":["../../src/utils/myxAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MYX SDK Adapter Utilities\n *\n * Adapters for transforming between MetaMask Perps API types and MYX SDK types.\n * Includes adapters for market display, positions, orders, account state, and fills.\n *\n * Portable: no mobile-specific imports.\n * Formatters are injected via MarketDataFormatters interface (same pattern as marketDataTransform.ts).\n *\n * Key differences from HyperLiquid:\n * - API prices are normal floats (SDK contract layer uses 30 decimals internally)\n * - Sizes use 18 decimals (vs HyperLiquid's szDecimals per asset)\n * - Multiple pools can exist per symbol (MPM model)\n * - USDT collateral (vs USDC)\n */\n\nimport {\n fromMYXPrice,\n fromMYXSize,\n fromMYXCollateral,\n MYX_MAX_LEVERAGE,\n MYX_MINIMUM_ORDER_SIZE_USD,\n} from '../constants/myxConfig';\nimport type {\n AccountState,\n CandleStick,\n Funding,\n MarketInfo,\n Order,\n OrderFill,\n PerpsMarketData,\n Position,\n MarketDataFormatters,\n UserHistoryItem,\n} from '../types';\nimport {\n MYX_HL_OVERLAPPING_MARKETS,\n MYXDirection,\n MYXDirectionEnum,\n MYXOperationEnum,\n MYXOrderStatusEnum,\n MYXOrderTypeEnum,\n MYXExecTypeEnum,\n MYXTradeFlowTypeEnum,\n} from '../types/myx-types';\nimport type {\n MYXPoolSymbol,\n MYXTicker,\n MYXPositionType,\n MYXHistoryOrderItem,\n MYXTradeFlowItem,\n MYXKlineData,\n MYXKlineWsData,\n} from '../types/myx-types';\n\n/**\n * Format a price change value with sign prefix.\n * Uses injected formatters (same pattern as marketDataTransform.ts formatChange).\n *\n * @param change - The price change value to format.\n * @param formatters - Injectable formatters for platform-agnostic formatting.\n * @returns The formatted change string with sign and dollar symbol.\n */\nfunction formatChange(\n change: number,\n formatters: MarketDataFormatters,\n): string {\n if (isNaN(change) || !isFinite(change)) {\n return '$0.00';\n }\n if (change === 0) {\n return '$0.00';\n }\n\n const formatted = formatters.formatPerpsFiat(Math.abs(change), {\n ranges: formatters.priceRangesUniversal,\n });\n\n const valueWithoutDollar = formatted.replace('$', '');\n return change > 0 ? `+$${valueWithoutDollar}` : `-$${valueWithoutDollar}`;\n}\n\n// ============================================================================\n// Market Transformation\n// ============================================================================\n\n/**\n * Transform MYX Pool/Market info to MetaMask Perps API MarketInfo format\n *\n * @param pool - Pool symbol data from MYX SDK (PoolSymbolAllResponse)\n * @returns MetaMask Perps API market info object\n */\nexport function adaptMarketFromMYX(pool: MYXPoolSymbol): MarketInfo {\n // Extract base symbol from pool data\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n\n // MYX uses fixed 18 decimals for sizes\n const szDecimals = 18;\n\n return {\n name: symbol,\n szDecimals,\n maxLeverage: MYX_MAX_LEVERAGE,\n marginTableId: 0, // MYX doesn't use margin tables like HyperLiquid\n minimumOrderSize: MYX_MINIMUM_ORDER_SIZE_USD,\n providerId: 'myx',\n };\n}\n\n/**\n * Convert MYX ticker data to price and change values\n *\n * @param ticker - Ticker data from MYX SDK\n * @returns Object with price string and 24h change percentage\n */\nexport function adaptPriceFromMYX(ticker: MYXTicker): {\n price: string;\n change24h: number;\n} {\n // MYX API returns normal float strings (e.g. \"64854.76\")\n const priceNum = fromMYXPrice(ticker.price);\n\n // Change is provided as a percentage string (e.g., \"2.5\" means 2.5%)\n const change24h = ticker.change ? parseFloat(ticker.change) : 0;\n\n return {\n price: priceNum.toString(),\n change24h,\n };\n}\n\n/**\n * Transform MYX pool and ticker to PerpsMarketData for UI display\n *\n * @param pool - Pool symbol data from MYX SDK\n * @param ticker - Optional ticker data for price info\n * @param formatters - Injectable formatters for platform-agnostic formatting\n * @returns Formatted market data for UI display\n */\nexport function adaptMarketDataFromMYX(\n pool: MYXPoolSymbol,\n ticker: MYXTicker | undefined,\n formatters: MarketDataFormatters,\n): PerpsMarketData {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n\n // Get price data from ticker if available\n let price = '0';\n let change24h = 0;\n let volume = '0';\n\n if (ticker) {\n const priceData = adaptPriceFromMYX(ticker);\n price = priceData.price;\n change24h = priceData.change24h;\n // Volume is already in USD (not 30-decimal format)\n volume = ticker.volume || '0';\n }\n\n // Format using injected formatters (consistent with HyperLiquid via marketDataTransform.ts)\n const priceNum = parseFloat(price);\n const formattedPrice = formatters.formatPerpsFiat(priceNum);\n const priceChange = priceNum * (change24h / 100);\n const formattedChange = formatChange(priceChange, formatters);\n const formattedChangePercent = formatters.formatPercentage(change24h);\n const formattedVolume = formatters.formatVolume(parseFloat(volume));\n\n return {\n symbol,\n name: getTokenName(symbol),\n maxLeverage: `${MYX_MAX_LEVERAGE}x`,\n price: formattedPrice,\n change24h: formattedChange,\n change24hPercent: formattedChangePercent,\n volume: formattedVolume,\n providerId: 'myx',\n };\n}\n\n// ============================================================================\n// Market Filtering\n// ============================================================================\n\n/**\n * Filter MYX markets to only include MYX-exclusive markets\n * Removes markets that overlap with HyperLiquid\n *\n * @param pools - Array of MYX pool symbols\n * @returns Filtered array with only MYX-exclusive markets\n */\nexport function filterMYXExclusiveMarkets(\n pools: MYXPoolSymbol[],\n): MYXPoolSymbol[] {\n return pools.filter((pool) => {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n // Exclude markets that overlap with HyperLiquid\n return !MYX_HL_OVERLAPPING_MARKETS.includes(\n symbol as (typeof MYX_HL_OVERLAPPING_MARKETS)[number],\n );\n });\n}\n\n/**\n * Check if a symbol overlaps with HyperLiquid markets\n *\n * @param symbol - Market symbol to check\n * @returns true if the symbol is available on both MYX and HyperLiquid\n */\nexport function isOverlappingMarket(symbol: string): boolean {\n return MYX_HL_OVERLAPPING_MARKETS.includes(\n symbol as (typeof MYX_HL_OVERLAPPING_MARKETS)[number],\n );\n}\n\n// ============================================================================\n// Pool ID Utilities\n// ============================================================================\n\n/**\n * Build a map of poolId to symbol for quick lookup\n *\n * @param pools - Array of MYX pool symbols\n * @returns Map of poolId to symbol\n */\nexport function buildPoolSymbolMap(\n pools: MYXPoolSymbol[],\n): Map<string, string> {\n const map = new Map<string, string>();\n for (const pool of pools) {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n map.set(pool.poolId, symbol);\n }\n return map;\n}\n\n/**\n * Build a map of symbol to poolIds (for multi-pool support)\n *\n * @param pools - Array of MYX pool symbols\n * @returns Map of symbol to array of poolIds\n */\nexport function buildSymbolPoolsMap(\n pools: MYXPoolSymbol[],\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n for (const pool of pools) {\n const symbol = pool.baseSymbol || extractSymbolFromPoolId(pool.poolId);\n const existing = map.get(symbol) ?? [];\n existing.push(pool.poolId);\n map.set(symbol, existing);\n }\n return map;\n}\n\n/**\n * Extract symbol from pool ID\n * Pool IDs typically contain the symbol as a suffix or can be parsed.\n * When baseSymbol is unavailable, returns a truncated address for UI display.\n *\n * @param poolId - MYX pool ID string\n * @returns Extracted symbol or truncated poolId as fallback\n */\nexport function extractSymbolFromPoolId(poolId: string): string {\n // Pool IDs in MYX are hex addresses (\"0x...\")\n // The actual symbol comes from the pool's baseSymbol field\n // Truncate hex addresses so they're UI-friendly\n if (poolId.startsWith('0x') && poolId.length > 10) {\n return `${poolId.slice(0, 6)}...${poolId.slice(-4)}`;\n }\n return poolId;\n}\n\n/**\n * Get full token name from symbol\n * Returns the symbol as name if not found (MYX-specific tokens)\n *\n * @param symbol - The market symbol to look up.\n * @returns The human-readable token name, or the symbol itself if not found.\n */\nfunction getTokenName(symbol: string): string {\n const tokenNames: Record<string, string> = {\n BTC: 'Bitcoin',\n ETH: 'Ethereum',\n BNB: 'BNB',\n MYX: 'MYX Protocol',\n RHEA: 'Rhea Finance',\n PARTI: 'Particle Network',\n SKYAI: 'SkyAI',\n PUMP: 'PumpFun',\n WLFI: 'World Liberty Financial',\n };\n\n return tokenNames[symbol] || symbol;\n}\n\n// ============================================================================\n// Position Adapter\n// ============================================================================\n\n/**\n * Adapt MYX SDK PositionType to MetaMask Position\n *\n * @param pos - MYX position from SDK\n * @param poolSymbolMap - Map of poolId to symbol\n * @returns MetaMask Position object\n */\nexport function adaptPositionFromMYX(\n pos: MYXPositionType,\n poolSymbolMap: Map<string, string>,\n): Position {\n const symbol = poolSymbolMap.get(pos.poolId) ?? pos.poolId;\n const sizeNum = fromMYXSize(pos.size);\n const entryPriceNum = fromMYXPrice(pos.entryPrice);\n const collateralNum = fromMYXCollateral(pos.collateralAmount);\n\n // Direction: 0 = LONG (positive size), 1 = SHORT (negative size)\n const isLong = pos.direction === MYXDirection.LONG;\n const signedSize = isLong ? sizeNum : -sizeNum;\n\n // Position value = size * entry price\n const positionValue = Math.abs(sizeNum * entryPriceNum);\n\n // Leverage = position value / collateral (approximate)\n const leverage = collateralNum > 0 ? positionValue / collateralNum : 1;\n\n return {\n symbol,\n size: signedSize.toString(),\n entryPrice: entryPriceNum.toString(),\n positionValue: positionValue.toString(),\n unrealizedPnl: '0', // Requires mark price - will be enriched by WS or separate call\n marginUsed: collateralNum.toString(),\n leverage: {\n type: 'isolated',\n value: Math.round(leverage),\n rawUsd: collateralNum.toString(),\n },\n liquidationPrice: null, // Requires separate calculation\n maxLeverage: MYX_MAX_LEVERAGE,\n returnOnEquity: '0',\n cumulativeFunding: {\n allTime: '0',\n sinceOpen: '0',\n sinceChange: '0',\n },\n takeProfitPrice: undefined,\n stopLossPrice: undefined,\n takeProfitCount: 0,\n stopLossCount: 0,\n providerId: 'myx',\n };\n}\n\n// ============================================================================\n// Order Adapter\n// ============================================================================\n\n/**\n * Adapt MYX SDK open order (PositionType-shaped from getOrders) to MetaMask Order.\n * Note: getOrders returns PositionType[] per the SDK types.\n * For richer order data, use getOrderHistory.\n *\n * @param historyOrder - MYX history order item\n * @param poolSymbolMap - Map of poolId to symbol\n * @returns MetaMask Order object\n */\nexport function adaptOrderFromMYX(\n historyOrder: MYXHistoryOrderItem,\n poolSymbolMap: Map<string, string>,\n): Order {\n const symbol =\n historyOrder.baseSymbol ??\n poolSymbolMap.get(historyOrder.poolId) ??\n historyOrder.poolId;\n\n const priceNum = fromMYXPrice(historyOrder.price);\n const sizeNum = fromMYXSize(historyOrder.size);\n const filledSizeNum = fromMYXSize(historyOrder.filledSize);\n const remainingSize = Math.max(0, sizeNum - filledSizeNum);\n\n // Map direction\n const side: 'buy' | 'sell' =\n historyOrder.direction === MYXDirectionEnum.Long ? 'buy' : 'sell';\n\n // Map order type\n let orderType: 'market' | 'limit' = 'market';\n if (historyOrder.orderType === MYXOrderTypeEnum.Limit) {\n orderType = 'limit';\n }\n\n // Map status\n let status: Order['status'] = 'open';\n switch (historyOrder.orderStatus) {\n case MYXOrderStatusEnum.Successful:\n status = 'filled';\n break;\n case MYXOrderStatusEnum.Cancelled:\n status = 'canceled';\n break;\n case MYXOrderStatusEnum.Expired:\n status = 'canceled';\n break;\n default:\n status = 'open';\n }\n\n // Detect trigger orders\n const isTrigger =\n historyOrder.execType === MYXExecTypeEnum.TP ||\n historyOrder.execType === MYXExecTypeEnum.SL;\n let detailedOrderType: string | undefined;\n if (historyOrder.execType === MYXExecTypeEnum.TP) {\n detailedOrderType = 'Take Profit';\n } else if (historyOrder.execType === MYXExecTypeEnum.SL) {\n detailedOrderType = 'Stop Loss';\n } else if (historyOrder.execType === MYXExecTypeEnum.Liquidation) {\n detailedOrderType = 'Liquidation';\n }\n\n return {\n orderId: String(historyOrder.orderId),\n symbol,\n side,\n orderType,\n size: sizeNum.toString(),\n originalSize: sizeNum.toString(),\n price: priceNum.toString(),\n filledSize: filledSizeNum.toString(),\n remainingSize: remainingSize.toString(),\n status,\n timestamp: historyOrder.txTime,\n isTrigger,\n detailedOrderType,\n reduceOnly:\n historyOrder.operation === MYXOperationEnum.Decrease ? true : undefined,\n providerId: 'myx',\n };\n}\n\n// ============================================================================\n// Account State Adapter\n// ============================================================================\n\n/**\n * Adapt MYX account info response to MetaMask AccountState.\n *\n * @param accountInfo - Raw account info from MYX SDK\n * @param walletBalance - Wallet USDT balance (from getWalletQuoteTokenBalance)\n * @returns MetaMask AccountState\n */\nexport function adaptAccountStateFromMYX(\n accountInfo: Record<string, unknown> | undefined,\n walletBalance?: string,\n): AccountState {\n // accountInfo structure varies; extract what we can\n // TODO: Verify SDK semantics — if totalCollateral already includes unrealizedPnl,\n // the totalBalance formula below double-counts. Needs SDK documentation check.\n const rawCollateral = accountInfo?.totalCollateral ?? '0';\n const rawPnl = accountInfo?.unrealizedPnl ?? '0';\n const marginUsed = accountInfo ? fromMYXCollateral(String(rawCollateral)) : 0;\n const unrealizedPnl = accountInfo ? fromMYXCollateral(String(rawPnl)) : 0;\n const balance = walletBalance ? fromMYXCollateral(walletBalance) : 0;\n\n const totalBalance = balance + marginUsed + unrealizedPnl;\n const availableBalance = balance;\n\n return {\n availableBalance: availableBalance.toString(),\n totalBalance: totalBalance.toString(),\n marginUsed: marginUsed.toString(),\n unrealizedPnl: unrealizedPnl.toString(),\n returnOnEquity: '0',\n };\n}\n\n// ============================================================================\n// Order Fill Adapter\n// ============================================================================\n\n/**\n * Adapt MYX history order item (filled) to MetaMask OrderFill\n *\n * @param order - MYX history order item\n * @param poolSymbolMap - Map of poolId to symbol\n * @returns MetaMask OrderFill\n */\nexport function adaptOrderFillFromMYX(\n order: MYXHistoryOrderItem,\n poolSymbolMap: Map<string, string>,\n): OrderFill {\n const symbol =\n order.baseSymbol ?? poolSymbolMap.get(order.poolId) ?? order.poolId;\n const sizeNum = fromMYXSize(order.filledSize || order.size);\n const priceNum = fromMYXPrice(order.lastPrice || order.price);\n const side = order.direction === MYXDirectionEnum.Long ? 'buy' : 'sell';\n const feeNum = fromMYXCollateral(order.tradingFee || '0');\n const pnlNum = fromMYXCollateral(order.realizedPnl || '0');\n\n let orderType: OrderFill['orderType'] = 'regular';\n if (order.execType === MYXExecTypeEnum.TP) {\n orderType = 'take_profit';\n } else if (order.execType === MYXExecTypeEnum.SL) {\n orderType = 'stop_loss';\n } else if (order.execType === MYXExecTypeEnum.Liquidation) {\n orderType = 'liquidation';\n }\n\n return {\n orderId: String(order.orderId),\n symbol,\n side,\n size: sizeNum.toString(),\n price: priceNum.toString(),\n pnl: pnlNum.toString(),\n direction: side,\n fee: feeNum.toString(),\n feeToken: 'USDT',\n timestamp: order.txTime,\n success: order.orderStatus === MYXOrderStatusEnum.Successful,\n orderType,\n providerId: 'myx',\n };\n}\n\n// ============================================================================\n// Funding Adapter\n// ============================================================================\n\n/**\n * Adapt MYX trade flow items (funding type) to MetaMask Funding\n *\n * @param flows - MYX trade flow items filtered to funding type\n * @param poolSymbolMap - Map of poolId to symbol\n * @returns Array of MetaMask Funding objects\n */\nexport function adaptFundingFromMYX(\n flows: MYXTradeFlowItem[],\n poolSymbolMap: Map<string, string>,\n): Funding[] {\n return flows\n .filter(\n (flow) =>\n flow.fundingFee && flow.fundingFee !== '0' && flow.fundingFee !== '',\n )\n .map((flow) => {\n const symbol = poolSymbolMap.get(flow.poolId) ?? flow.poolId;\n const amountUsd = fromMYXCollateral(flow.fundingFee);\n return {\n symbol,\n amountUsd: amountUsd.toString(),\n rate: undefined, // Funding rate not available in MYX trade flow data\n timestamp: flow.txTime,\n transactionHash: flow.txHash,\n };\n });\n}\n\n// ============================================================================\n// User History Adapter\n// ============================================================================\n\n/**\n * Adapt MYX trade flow items to MetaMask UserHistoryItem\n *\n * @param flows - MYX trade flow items\n * @returns Array of UserHistoryItem\n */\nexport function adaptUserHistoryFromMYX(\n flows: MYXTradeFlowItem[],\n): UserHistoryItem[] {\n return flows\n .filter(\n (flow) =>\n flow.type === MYXTradeFlowTypeEnum.MarginAccountDeposit ||\n flow.type === MYXTradeFlowTypeEnum.TransferToWallet,\n )\n .map((flow) => {\n const isDeposit = flow.type === MYXTradeFlowTypeEnum.MarginAccountDeposit;\n const amount = fromMYXCollateral(flow.collateralAmount || '0');\n return {\n id: String(flow.orderId),\n timestamp: flow.txTime,\n type: isDeposit ? 'deposit' : 'withdrawal',\n amount: Math.abs(amount).toString(),\n asset: 'USDT',\n txHash: flow.txHash,\n status: 'completed' as const,\n details: {\n source: 'myx',\n },\n };\n });\n}\n\n// ============================================================================\n// Candle (Kline) Adapter\n// ============================================================================\n\n/**\n * Adapt MYX KlineDataItemType to MetaMask CandleStick.\n * KlineDataItemType fields (time, open, close, high, low) are already\n * human-readable strings — no 30-decimal conversion needed.\n *\n * @param item - MYX kline data item from SDK\n * @returns MetaMask CandleStick object\n */\nexport function adaptCandleFromMYX(item: MYXKlineData): CandleStick {\n return {\n time: item.time,\n open: item.open,\n high: item.high,\n low: item.low,\n close: item.close,\n volume: '0', // KlineDataItemType has no volume field\n };\n}\n\n/**\n * Adapt MYX WebSocket KlineData to MetaMask CandleStick.\n * WS KlineData uses single-letter fields: {t, o, h, l, c, v}.\n *\n * @param data - MYX WebSocket kline data\n * @returns MetaMask CandleStick object\n */\nexport function adaptCandleFromMYXWebSocket(data: MYXKlineWsData): CandleStick {\n return {\n time: data.t,\n open: data.o,\n high: data.h,\n low: data.l,\n close: data.c,\n volume: data.v,\n };\n}\n\n/**\n * Map CandlePeriod values to MYX KlineResolution.\n * MYX SDK supports: '1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w', '1M'.\n * Unsupported CandlePeriod values are mapped to the nearest supported resolution.\n */\nconst CANDLE_PERIOD_TO_MYX_RESOLUTION: Record<string, string> = {\n '1m': '1m',\n '3m': '5m', // No 3m → use 5m\n '5m': '5m',\n '15m': '15m',\n '30m': '30m',\n '1h': '1h',\n '2h': '4h', // No 2h → use 4h\n '4h': '4h',\n '8h': '4h', // No 8h → use 4h\n '12h': '1d', // No 12h → use 1d\n '1d': '1d',\n '3d': '1w', // No 3d → use 1w\n '1w': '1w',\n '1M': '1M',\n};\n\n/**\n * Convert a CandlePeriod string to MYX KlineResolution.\n *\n * @param period - CandlePeriod value (e.g., '1m', '3m', '1h')\n * @returns MYX KlineResolution string\n */\nexport function toMYXKlineResolution(period: string): string {\n return CANDLE_PERIOD_TO_MYX_RESOLUTION[period] ?? '1h';\n}\n\n// ============================================================================\n// Response Validation\n// ============================================================================\n\n/**\n * Assert MYX API response is successful.\n * MYX uses code 9200 or 0 for success.\n *\n * @param response - MYX API response with code field\n * @param response.code - Response code (9200 or 0 = success)\n * @param response.message - Optional error message\n * @param context - Context string for error messages\n */\nexport function assertMYXSuccess(\n response: { code: number; message?: string | null },\n context: string,\n): void {\n if (response.code !== 9200 && response.code !== 0) {\n throw new Error(\n `MYX ${context} failed: code=${response.code} message=${response.message ?? 'unknown'}`,\n );\n }\n}\n"]}