@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.
- package/CHANGELOG.md +9 -0
- package/dist/PerpsController-method-action-types.cjs +3 -0
- package/dist/PerpsController-method-action-types.cjs.map +1 -0
- package/dist/PerpsController-method-action-types.d.cts +147 -0
- package/dist/PerpsController-method-action-types.d.cts.map +1 -0
- package/dist/PerpsController-method-action-types.d.mts +147 -0
- package/dist/PerpsController-method-action-types.d.mts.map +1 -0
- package/dist/PerpsController-method-action-types.mjs +2 -0
- package/dist/PerpsController-method-action-types.mjs.map +1 -0
- package/dist/PerpsController.cjs +488 -183
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +91 -131
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +91 -131
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +485 -182
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/constants/eventNames.cjs +26 -0
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +19 -0
- package/dist/constants/eventNames.d.cts.map +1 -1
- package/dist/constants/eventNames.d.mts +19 -0
- package/dist/constants/eventNames.d.mts.map +1 -1
- package/dist/constants/eventNames.mjs +26 -0
- package/dist/constants/eventNames.mjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.cjs +24 -4
- package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.cts +8 -3
- package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.mts +8 -3
- package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
- package/dist/constants/hyperLiquidConfig.mjs +23 -3
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
- package/dist/constants/myxConfig.cjs +75 -51
- package/dist/constants/myxConfig.cjs.map +1 -1
- package/dist/constants/myxConfig.d.cts +58 -19
- package/dist/constants/myxConfig.d.cts.map +1 -1
- package/dist/constants/myxConfig.d.mts +58 -19
- package/dist/constants/myxConfig.d.mts.map +1 -1
- package/dist/constants/myxConfig.mjs +74 -50
- package/dist/constants/myxConfig.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +6 -2
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +5 -1
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +5 -1
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +5 -1
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/index.cjs +243 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +48 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +36 -10
- package/dist/index.mjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.cjs +24 -0
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts +4 -0
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts +4 -0
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.mjs +24 -0
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +470 -154
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +11 -2
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +11 -2
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +471 -155
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/selectors.cjs +1 -1
- package/dist/selectors.cjs.map +1 -1
- package/dist/selectors.mjs +1 -1
- package/dist/selectors.mjs.map +1 -1
- package/dist/services/AccountService.cjs +1 -1
- package/dist/services/AccountService.cjs.map +1 -1
- package/dist/services/AccountService.d.cts.map +1 -1
- package/dist/services/AccountService.d.mts.map +1 -1
- package/dist/services/AccountService.mjs +2 -2
- package/dist/services/AccountService.mjs.map +1 -1
- package/dist/services/DepositService.cjs +2 -1
- package/dist/services/DepositService.cjs.map +1 -1
- package/dist/services/DepositService.d.cts.map +1 -1
- package/dist/services/DepositService.d.mts.map +1 -1
- package/dist/services/DepositService.mjs +2 -1
- package/dist/services/DepositService.mjs.map +1 -1
- package/dist/services/EligibilityService.cjs +8 -103
- package/dist/services/EligibilityService.cjs.map +1 -1
- package/dist/services/EligibilityService.d.cts +4 -15
- package/dist/services/EligibilityService.d.cts.map +1 -1
- package/dist/services/EligibilityService.d.mts +4 -15
- package/dist/services/EligibilityService.d.mts.map +1 -1
- package/dist/services/EligibilityService.mjs +8 -103
- package/dist/services/EligibilityService.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +252 -46
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts +1 -0
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts +1 -0
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +252 -46
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/MarketDataService.cjs +2 -4
- package/dist/services/MarketDataService.cjs.map +1 -1
- package/dist/services/MarketDataService.d.cts.map +1 -1
- package/dist/services/MarketDataService.d.mts.map +1 -1
- package/dist/services/MarketDataService.mjs +2 -4
- package/dist/services/MarketDataService.mjs.map +1 -1
- package/dist/services/TradingService.cjs +72 -6
- package/dist/services/TradingService.cjs.map +1 -1
- package/dist/services/TradingService.d.cts.map +1 -1
- package/dist/services/TradingService.d.mts.map +1 -1
- package/dist/services/TradingService.mjs +72 -6
- package/dist/services/TradingService.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +51 -3
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +51 -3
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/types/messenger.cjs.map +1 -1
- package/dist/types/messenger.d.cts +2 -1
- package/dist/types/messenger.d.cts.map +1 -1
- package/dist/types/messenger.d.mts +2 -1
- package/dist/types/messenger.d.mts.map +1 -1
- package/dist/types/messenger.mjs.map +1 -1
- package/dist/types/myx-types.cjs +19 -3
- package/dist/types/myx-types.cjs.map +1 -1
- package/dist/types/myx-types.d.cts +33 -2
- package/dist/types/myx-types.d.cts.map +1 -1
- package/dist/types/myx-types.d.mts +33 -2
- package/dist/types/myx-types.d.mts.map +1 -1
- package/dist/types/myx-types.mjs +6 -2
- package/dist/types/myx-types.mjs.map +1 -1
- package/dist/types/perps-types.cjs +3 -0
- package/dist/types/perps-types.cjs.map +1 -1
- package/dist/types/perps-types.d.cts +3 -3
- package/dist/types/perps-types.d.cts.map +1 -1
- package/dist/types/perps-types.d.mts +3 -3
- package/dist/types/perps-types.d.mts.map +1 -1
- package/dist/types/perps-types.mjs +3 -0
- package/dist/types/perps-types.mjs.map +1 -1
- package/dist/utils/accountUtils.cjs.map +1 -1
- package/dist/utils/accountUtils.d.cts.map +1 -1
- package/dist/utils/accountUtils.d.mts.map +1 -1
- package/dist/utils/accountUtils.mjs.map +1 -1
- package/dist/utils/myxAdapter.cjs +360 -15
- package/dist/utils/myxAdapter.cjs.map +1 -1
- package/dist/utils/myxAdapter.d.cts +94 -7
- package/dist/utils/myxAdapter.d.cts.map +1 -1
- package/dist/utils/myxAdapter.d.mts +94 -7
- package/dist/utils/myxAdapter.d.mts.map +1 -1
- package/dist/utils/myxAdapter.mjs +351 -16
- package/dist/utils/myxAdapter.mjs.map +1 -1
- package/package.json +5 -3
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* MYX SDK Adapter Utilities
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
-
* -
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
195
|
+
// Pool IDs in MYX are hex addresses ("0x...")
|
|
198
196
|
// The actual symbol comes from the pool's baseSymbol field
|
|
199
|
-
//
|
|
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"]}
|