@metamask-previews/perps-controller 15.1.0-preview-00a181c → 15.1.0-preview-a302de5c3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -14
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +1 -20
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +1 -20
- package/dist/PerpsController-method-action-types.d.mts.map +1 -1
- package/dist/PerpsController-method-action-types.mjs.map +1 -1
- package/dist/PerpsController.cjs +154 -65
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +43 -37
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +43 -37
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +151 -64
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.cjs +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.cjs.map +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.d.cts +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.d.mts +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.mjs +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.mjs.map +1 -1
- package/dist/constants/index.cjs +1 -0
- package/dist/constants/index.cjs.map +1 -1
- package/dist/constants/index.d.cts +1 -0
- package/dist/constants/index.d.cts.map +1 -1
- package/dist/constants/index.d.mts +1 -0
- package/dist/constants/index.d.mts.map +1 -1
- package/dist/constants/index.mjs +1 -0
- package/dist/constants/index.mjs.map +1 -1
- package/dist/constants/myxConfig.cjs +253 -0
- package/dist/constants/myxConfig.cjs.map +1 -0
- package/dist/constants/myxConfig.d.cts +145 -0
- package/dist/constants/myxConfig.d.cts.map +1 -0
- package/dist/constants/myxConfig.d.mts +145 -0
- package/dist/constants/myxConfig.d.mts.map +1 -0
- package/dist/constants/myxConfig.mjs +243 -0
- package/dist/constants/myxConfig.mjs.map +1 -0
- package/dist/constants/perpsConfig.cjs +9 -4
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +5 -3
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +5 -3
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +9 -4
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/index.cjs +175 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.cjs +2 -8
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts +2 -3
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts +2 -3
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.mjs +2 -8
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +22 -118
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +0 -31
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +0 -31
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +22 -118
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/providers/LighterProvider.cjs +1 -1
- package/dist/providers/LighterProvider.cjs.map +1 -1
- package/dist/providers/LighterProvider.mjs +1 -1
- package/dist/providers/LighterProvider.mjs.map +1 -1
- package/dist/routing/ProviderRouter.cjs +1 -1
- package/dist/routing/ProviderRouter.cjs.map +1 -1
- package/dist/routing/ProviderRouter.d.cts +1 -1
- package/dist/routing/ProviderRouter.d.mts +1 -1
- package/dist/routing/ProviderRouter.mjs +1 -1
- package/dist/routing/ProviderRouter.mjs.map +1 -1
- package/dist/services/HyperLiquidClientService.cjs.map +1 -1
- package/dist/services/HyperLiquidClientService.d.cts +16 -26
- package/dist/services/HyperLiquidClientService.d.cts.map +1 -1
- package/dist/services/HyperLiquidClientService.d.mts +16 -26
- package/dist/services/HyperLiquidClientService.d.mts.map +1 -1
- package/dist/services/HyperLiquidClientService.mjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.cjs +30 -80
- package/dist/services/HyperLiquidWalletService.cjs.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.cts +22 -48
- package/dist/services/HyperLiquidWalletService.d.cts.map +1 -1
- package/dist/services/HyperLiquidWalletService.d.mts +22 -48
- package/dist/services/HyperLiquidWalletService.d.mts.map +1 -1
- package/dist/services/HyperLiquidWalletService.mjs +30 -80
- package/dist/services/HyperLiquidWalletService.mjs.map +1 -1
- package/dist/services/LighterWalletService.cjs +1 -1
- package/dist/services/LighterWalletService.cjs.map +1 -1
- package/dist/services/LighterWalletService.d.cts +1 -1
- package/dist/services/LighterWalletService.d.mts +1 -1
- package/dist/services/LighterWalletService.mjs +1 -1
- package/dist/services/LighterWalletService.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +16 -10
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +16 -10
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/types/myx-types.cjs +41 -0
- package/dist/types/myx-types.cjs.map +1 -0
- package/dist/types/myx-types.d.cts +94 -0
- package/dist/types/myx-types.d.cts.map +1 -0
- package/dist/types/myx-types.d.mts +94 -0
- package/dist/types/myx-types.d.mts.map +1 -0
- package/dist/types/myx-types.mjs +26 -0
- package/dist/types/myx-types.mjs.map +1 -0
- package/dist/utils/lighterAdapter.cjs +2 -1
- package/dist/utils/lighterAdapter.cjs.map +1 -1
- package/dist/utils/lighterAdapter.d.cts +2 -1
- package/dist/utils/lighterAdapter.d.cts.map +1 -1
- package/dist/utils/lighterAdapter.d.mts +2 -1
- package/dist/utils/lighterAdapter.d.mts.map +1 -1
- package/dist/utils/lighterAdapter.mjs +2 -1
- package/dist/utils/lighterAdapter.mjs.map +1 -1
- package/dist/utils/myxAdapter.cjs +569 -0
- package/dist/utils/myxAdapter.cjs.map +1 -0
- package/dist/utils/myxAdapter.d.cts +168 -0
- package/dist/utils/myxAdapter.d.cts.map +1 -0
- package/dist/utils/myxAdapter.d.mts +168 -0
- package/dist/utils/myxAdapter.d.mts.map +1 -0
- package/dist/utils/myxAdapter.mjs +548 -0
- package/dist/utils/myxAdapter.mjs.map +1 -0
- package/package.json +8 -2
|
@@ -42,7 +42,7 @@ const errorUtils_js_1 = require("../utils/errorUtils.cjs");
|
|
|
42
42
|
* symbols: ['BTC', 'ETH'],
|
|
43
43
|
* providers: [
|
|
44
44
|
* ['hyperliquid', hlProvider],
|
|
45
|
-
* ['
|
|
45
|
+
* ['myx', myxProvider],
|
|
46
46
|
* ],
|
|
47
47
|
* callback: (prices) => {
|
|
48
48
|
* // prices have providerId injected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionMultiplexer.cjs","sourceRoot":"","sources":["../../src/aggregation/SubscriptionMultiplexer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SubscriptionMultiplexer - Manages WebSocket subscriptions across multiple providers\n *\n * Responsibilities:\n * - Manage subscriptions to multiple providers simultaneously\n * - Tag all updates with providerId so UI can differentiate sources\n * - Support aggregation modes: 'merge' (all prices) or 'best_price' (best price per symbol)\n * - Cache latest updates per provider per symbol for aggregation\n */\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig.js';\nimport type {\n PerpsProviderType,\n PerpsProvider,\n PerpsLogger,\n PriceUpdate,\n Position,\n OrderFill,\n Order,\n AccountState,\n SubscribePricesParams,\n SubscribePositionsParams,\n SubscribeOrderFillsParams,\n SubscribeOrdersParams,\n SubscribeAccountParams,\n} from '../types/index.js';\nimport { ensureError } from '../utils/errorUtils.js';\n\n/**\n * Options for constructing SubscriptionMultiplexer\n */\nexport type SubscriptionMultiplexerOptions = {\n /** Optional logger for error reporting (e.g., Sentry) */\n logger?: PerpsLogger;\n};\n\n/**\n * Aggregation mode for price subscriptions\n */\nexport type PriceAggregationMode = 'merge' | 'best_price';\n\n/**\n * Parameters for multiplexed price subscriptions\n */\nexport type MultiplexedPricesParams = {\n /** Symbols to subscribe to */\n symbols: string[];\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated price updates */\n callback: (prices: PriceUpdate[]) => void;\n /** Aggregation mode: 'merge' returns all prices, 'best_price' returns best per symbol */\n aggregationMode?: PriceAggregationMode;\n /** Optional throttle in milliseconds */\n throttleMs?: number;\n /** Include order book data */\n includeOrderBook?: boolean;\n /** Include market data (funding, OI, volume) */\n includeMarketData?: boolean;\n};\n\n/**\n * Parameters for multiplexed position subscriptions\n */\nexport type MultiplexedPositionsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated position updates */\n callback: (positions: Position[]) => void;\n};\n\n/**\n * Parameters for multiplexed order fill subscriptions\n */\nexport type MultiplexedOrderFillsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order fill updates */\n callback: (fills: OrderFill[], isSnapshot?: boolean) => void;\n};\n\n/**\n * Parameters for multiplexed order subscriptions\n */\nexport type MultiplexedOrdersParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order updates */\n callback: (orders: Order[]) => void;\n};\n\n/**\n * Parameters for multiplexed account subscriptions\n */\nexport type MultiplexedAccountParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive account updates (one per provider) */\n callback: (accounts: AccountState[]) => void;\n};\n\n/**\n * SubscriptionMultiplexer manages real-time data subscriptions across\n * multiple perps providers.\n *\n * Key features:\n * - Subscribes to all providers simultaneously\n * - Tags all updates with source providerId\n * - Caches latest values for aggregation\n * - Supports different aggregation modes for prices\n *\n * @example\n * ```typescript\n * const mux = new SubscriptionMultiplexer();\n *\n * const unsubscribe = mux.subscribeToPrices({\n * symbols: ['BTC', 'ETH'],\n * providers: [\n * ['hyperliquid', hlProvider],\n * ['lighter', lighterProvider],\n * ],\n * callback: (prices) => {\n * // prices have providerId injected\n * prices.forEach(p => console.log(`${p.providerId}: ${p.symbol} = ${p.price}`));\n * },\n * aggregationMode: 'merge',\n * });\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport class SubscriptionMultiplexer {\n /**\n * Optional logger for error reporting\n */\n readonly #logger?: PerpsLogger;\n\n /**\n * Cache of latest prices per symbol per provider\n * Map<symbol, Map<providerId, PriceUpdate>>\n */\n readonly #priceCache: Map<string, Map<PerpsProviderType, PriceUpdate>> =\n new Map();\n\n /**\n * Cache of latest positions per provider\n * Map<providerId, Position[]>\n */\n readonly #positionCache: Map<PerpsProviderType, Position[]> = new Map();\n\n /**\n * Cache of latest orders per provider\n * Map<providerId, Order[]>\n */\n readonly #orderCache: Map<PerpsProviderType, Order[]> = new Map();\n\n /**\n * Cache of latest account state per provider\n * Map<providerId, AccountState>\n */\n readonly #accountCache: Map<PerpsProviderType, AccountState> = new Map();\n\n /**\n * Create a new SubscriptionMultiplexer.\n *\n * @param options - Optional configuration including logger for error reporting\n */\n constructor(options?: SubscriptionMultiplexerOptions) {\n this.#logger = options?.logger;\n }\n\n /**\n * Subscribe to price updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPrices(params: MultiplexedPricesParams): () => void {\n const {\n symbols,\n providers,\n callback,\n aggregationMode = 'merge',\n throttleMs,\n includeOrderBook,\n includeMarketData,\n } = params;\n\n const unsubscribers: (() => void)[] = [];\n\n // Subscribe to each provider with defensive error handling\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePricesParams = {\n symbols,\n callback: (updates) => {\n // Tag and cache each update\n updates.forEach((update) => {\n const taggedUpdate: PriceUpdate = { ...update, providerId };\n\n // Initialize symbol cache if needed\n if (!this.#priceCache.has(update.symbol)) {\n this.#priceCache.set(update.symbol, new Map());\n }\n const symbolCache = this.#priceCache.get(update.symbol);\n if (symbolCache) {\n symbolCache.set(providerId, taggedUpdate);\n }\n });\n\n // Aggregate and emit based on mode\n const aggregated = this.#aggregatePrices(symbols, aggregationMode);\n callback(aggregated);\n },\n throttleMs,\n includeOrderBook,\n includeMarketData,\n };\n\n const unsub = provider.subscribeToPrices(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n // Log to Sentry before cleanup\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPrices'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPrices',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n\n // Clean up any subscriptions created before the failure\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n // Return combined unsubscribe function\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Optionally clear cache for these symbols\n symbols.forEach((symbol) => {\n this.#priceCache.delete(symbol);\n });\n };\n }\n\n /**\n * Subscribe to position updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPositions(params: MultiplexedPositionsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePositionsParams = {\n callback: (positions) => {\n // Tag positions with providerId and cache\n const taggedPositions = positions.map((pos) => ({\n ...pos,\n providerId,\n }));\n this.#positionCache.set(providerId, taggedPositions);\n\n // Emit aggregated positions from all providers\n const allPositions = this.#aggregatePositions();\n callback(allPositions);\n },\n };\n\n const unsub = provider.subscribeToPositions(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPositions'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPositions',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Clear position cache for these providers\n providers.forEach(([providerId]) => {\n this.#positionCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to order fill updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrderFills(params: MultiplexedOrderFillsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrderFillsParams = {\n callback: (fills, isSnapshot) => {\n // Tag fills with providerId\n const taggedFills = fills.map((fill) => ({\n ...fill,\n providerId,\n }));\n\n // For fills, we don't aggregate - emit immediately with tags\n callback(taggedFills, isSnapshot);\n },\n };\n\n const unsub = provider.subscribeToOrderFills(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrderFills'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrderFills',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribe to order updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrders(params: MultiplexedOrdersParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrdersParams = {\n callback: (orders) => {\n // Tag orders with providerId and cache\n const taggedOrders = orders.map((order) => ({\n ...order,\n providerId,\n }));\n this.#orderCache.set(providerId, taggedOrders);\n\n // Emit aggregated orders from all providers\n const allOrders = this.#aggregateOrders();\n callback(allOrders);\n },\n };\n\n const unsub = provider.subscribeToOrders(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrders'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrders',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#orderCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to account updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToAccount(params: MultiplexedAccountParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeAccountParams = {\n callback: (account) => {\n if (account === null) {\n this.#accountCache.delete(providerId);\n } else {\n // Tag account with providerId and cache\n const taggedAccount: AccountState = {\n ...account,\n providerId,\n };\n this.#accountCache.set(providerId, taggedAccount);\n }\n\n // Emit all cached account states\n const allAccounts = Array.from(this.#accountCache.values());\n callback(allAccounts);\n },\n };\n\n const unsub = provider.subscribeToAccount(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToAccount'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToAccount',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#accountCache.delete(providerId);\n });\n };\n }\n\n /**\n * Aggregate cached prices based on mode.\n *\n * @param symbols - Symbols to include in result\n * @param mode - Aggregation mode\n * @returns Aggregated price updates\n */\n #aggregatePrices(\n symbols: string[],\n mode: PriceAggregationMode,\n ): PriceUpdate[] {\n const result: PriceUpdate[] = [];\n\n symbols.forEach((symbol) => {\n const providerPrices = this.#priceCache.get(symbol);\n if (!providerPrices || providerPrices.size === 0) {\n return;\n }\n\n if (mode === 'merge') {\n // Return all prices (one per provider)\n providerPrices.forEach((price) => {\n result.push(price);\n });\n } else {\n // 'best_price': Return the best price across providers\n const best = this.#findBestPrice(providerPrices);\n if (best) {\n result.push(best);\n }\n }\n });\n\n return result;\n }\n\n /**\n * Find the best price from multiple provider prices.\n * \"Best\" is defined as the price with the smallest spread.\n *\n * @param providerPrices - Map of provider prices for a symbol\n * @returns Best price update or undefined\n */\n #findBestPrice(\n providerPrices: Map<PerpsProviderType, PriceUpdate>,\n ): PriceUpdate | undefined {\n let bestPrice: PriceUpdate | undefined;\n let smallestSpread = Infinity;\n\n providerPrices.forEach((price) => {\n if (price.spread === undefined) {\n // No spread info - just use the first one\n bestPrice ??= price;\n } else {\n // If spread is available, use it to determine best\n const spreadValue = parseFloat(price.spread);\n if (!isNaN(spreadValue) && spreadValue < smallestSpread) {\n smallestSpread = spreadValue;\n bestPrice = price;\n }\n }\n });\n\n return bestPrice;\n }\n\n /**\n * Aggregate positions from all providers.\n *\n * @returns All cached positions\n */\n #aggregatePositions(): Position[] {\n const allPositions: Position[] = [];\n this.#positionCache.forEach((positions) => {\n allPositions.push(...positions);\n });\n return allPositions;\n }\n\n /**\n * Aggregate orders from all providers.\n *\n * @returns All cached orders\n */\n #aggregateOrders(): Order[] {\n const allOrders: Order[] = [];\n this.#orderCache.forEach((orders) => {\n allOrders.push(...orders);\n });\n return allOrders;\n }\n\n /**\n * Clear all cached data.\n */\n clearCache(): void {\n this.#priceCache.clear();\n this.#positionCache.clear();\n this.#orderCache.clear();\n this.#accountCache.clear();\n }\n\n /**\n * Get cached price for a symbol from a specific provider.\n *\n * @param symbol - Market symbol\n * @param providerId - Provider ID\n * @returns Cached price update or undefined\n */\n getCachedPrice(\n symbol: string,\n providerId: PerpsProviderType,\n ): PriceUpdate | undefined {\n return this.#priceCache.get(symbol)?.get(providerId);\n }\n\n /**\n * Get all cached prices for a symbol.\n *\n * @param symbol - Market symbol\n * @returns Map of provider ID to price update\n */\n getAllCachedPricesForSymbol(\n symbol: string,\n ): Map<PerpsProviderType, PriceUpdate> | undefined {\n return this.#priceCache.get(symbol);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SubscriptionMultiplexer.cjs","sourceRoot":"","sources":["../../src/aggregation/SubscriptionMultiplexer.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;AAEH,iEAA8D;AAgB9D,2DAAqD;AA2ErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAa,uBAAuB;IA+BlC;;;;OAIG;IACH,YAAY,OAAwC;;QAnCpD;;WAEG;QACM,kDAAsB;QAE/B;;;WAGG;QACM,8CACP,IAAI,GAAG,EAAE,EAAC;QAEZ;;;WAGG;QACM,iDAAqD,IAAI,GAAG,EAAE,EAAC;QAExE;;;WAGG;QACM,8CAA+C,IAAI,GAAG,EAAE,EAAC;QAElE;;;WAGG;QACM,gDAAsD,IAAI,GAAG,EAAE,EAAC;QAQvE,uBAAA,IAAI,mCAAW,OAAO,EAAE,MAAM,MAAA,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,MAA+B;QAC/C,MAAM,EACJ,OAAO,EACP,SAAS,EACT,QAAQ,EACR,eAAe,GAAG,OAAO,EACzB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,GAClB,GAAG,MAAM,CAAC;QAEX,MAAM,aAAa,GAAmB,EAAE,CAAC;QAEzC,2DAA2D;QAC3D,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,eAAe,GAA0B;oBAC7C,OAAO;oBACP,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;wBACpB,4BAA4B;wBAC5B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;4BACzB,MAAM,YAAY,GAAgB,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,CAAC;4BAE5D,oCAAoC;4BACpC,IAAI,CAAC,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gCACzC,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;4BACjD,CAAC;4BACD,MAAM,WAAW,GAAG,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;4BACxD,IAAI,WAAW,EAAE,CAAC;gCAChB,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;4BAC5C,CAAC;wBACH,CAAC,CAAC,CAAC;wBAEH,mCAAmC;wBACnC,MAAM,UAAU,GAAG,uBAAA,IAAI,oFAAiB,MAArB,IAAI,EAAkB,OAAO,EAAE,eAAe,CAAC,CAAC;wBACnE,QAAQ,CAAC,UAAU,CAAC,CAAC;oBACvB,CAAC;oBACD,UAAU;oBACV,gBAAgB;oBAChB,iBAAiB;iBAClB,CAAC;gBAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;gBAC1D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,+BAA+B;gBAC/B,uBAAA,IAAI,uCAAQ,EAAE,KAAK,CACjB,IAAA,2BAAW,EAAC,KAAK,EAAE,2CAA2C,CAAC,EAC/D;oBACE,IAAI,EAAE;wBACJ,OAAO,EAAE,gCAAe,CAAC,WAAW;wBACpC,QAAQ,EAAE,UAAU;wBACpB,MAAM,EAAE,mBAAmB;qBAC5B;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,yBAAyB;wBAC/B,IAAI,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,EAAE;qBAChD;iBACF,CACF,CAAC;gBAEF,wDAAwD;gBACxD,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,2CAA2C;YAC3C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzB,uBAAA,IAAI,2CAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,MAAkC;QACrD,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,aAAa,GAAmB,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,eAAe,GAA6B;oBAChD,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE;wBACtB,0CAA0C;wBAC1C,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;4BAC9C,GAAG,GAAG;4BACN,UAAU;yBACX,CAAC,CAAC,CAAC;wBACJ,uBAAA,IAAI,8CAAe,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;wBAErD,+CAA+C;wBAC/C,MAAM,YAAY,GAAG,uBAAA,IAAI,uFAAoB,MAAxB,IAAI,CAAsB,CAAC;wBAChD,QAAQ,CAAC,YAAY,CAAC,CAAC;oBACzB,CAAC;iBACF,CAAC;gBAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;gBAC7D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uBAAA,IAAI,uCAAQ,EAAE,KAAK,CACjB,IAAA,2BAAW,EAAC,KAAK,EAAE,8CAA8C,CAAC,EAClE;oBACE,IAAI,EAAE;wBACJ,OAAO,EAAE,gCAAe,CAAC,WAAW;wBACpC,QAAQ,EAAE,UAAU;wBACpB,MAAM,EAAE,sBAAsB;qBAC/B;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,yBAAyB;wBAC/B,IAAI,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,EAAE;qBAChD;iBACF,CACF,CAAC;gBACF,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,2CAA2C;YAC3C,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE;gBACjC,uBAAA,IAAI,8CAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,qBAAqB,CAAC,MAAmC;QACvD,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,aAAa,GAAmB,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,eAAe,GAA8B;oBACjD,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;wBAC9B,4BAA4B;wBAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;4BACvC,GAAG,IAAI;4BACP,UAAU;yBACX,CAAC,CAAC,CAAC;wBAEJ,6DAA6D;wBAC7D,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;oBACpC,CAAC;iBACF,CAAC;gBAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;gBAC9D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uBAAA,IAAI,uCAAQ,EAAE,KAAK,CACjB,IAAA,2BAAW,EAAC,KAAK,EAAE,+CAA+C,CAAC,EACnE;oBACE,IAAI,EAAE;wBACJ,OAAO,EAAE,gCAAe,CAAC,WAAW;wBACpC,QAAQ,EAAE,UAAU;wBACpB,MAAM,EAAE,uBAAuB;qBAChC;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,yBAAyB;wBAC/B,IAAI,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,EAAE;qBAChD;iBACF,CACF,CAAC;gBACF,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,MAA+B;QAC/C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,aAAa,GAAmB,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,eAAe,GAA0B;oBAC7C,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;wBACnB,uCAAuC;wBACvC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;4BAC1C,GAAG,KAAK;4BACR,UAAU;yBACX,CAAC,CAAC,CAAC;wBACJ,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;wBAE/C,4CAA4C;wBAC5C,MAAM,SAAS,GAAG,uBAAA,IAAI,oFAAiB,MAArB,IAAI,CAAmB,CAAC;wBAC1C,QAAQ,CAAC,SAAS,CAAC,CAAC;oBACtB,CAAC;iBACF,CAAC;gBAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;gBAC1D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uBAAA,IAAI,uCAAQ,EAAE,KAAK,CACjB,IAAA,2BAAW,EAAC,KAAK,EAAE,2CAA2C,CAAC,EAC/D;oBACE,IAAI,EAAE;wBACJ,OAAO,EAAE,gCAAe,CAAC,WAAW;wBACpC,QAAQ,EAAE,UAAU;wBACpB,MAAM,EAAE,mBAAmB;qBAC5B;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,yBAAyB;wBAC/B,IAAI,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,EAAE;qBAChD;iBACF,CACF,CAAC;gBACF,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE;gBACjC,uBAAA,IAAI,2CAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,MAAgC;QACjD,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,aAAa,GAAmB,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,eAAe,GAA2B;oBAC9C,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;wBACpB,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;4BACrB,uBAAA,IAAI,6CAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;wBACxC,CAAC;6BAAM,CAAC;4BACN,wCAAwC;4BACxC,MAAM,aAAa,GAAiB;gCAClC,GAAG,OAAO;gCACV,UAAU;6BACX,CAAC;4BACF,uBAAA,IAAI,6CAAc,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;wBACpD,CAAC;wBAED,iCAAiC;wBACjC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,uBAAA,IAAI,6CAAc,CAAC,MAAM,EAAE,CAAC,CAAC;wBAC5D,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACxB,CAAC;iBACF,CAAC;gBAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;gBAC3D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uBAAA,IAAI,uCAAQ,EAAE,KAAK,CACjB,IAAA,2BAAW,EAAC,KAAK,EAAE,4CAA4C,CAAC,EAChE;oBACE,IAAI,EAAE;wBACJ,OAAO,EAAE,gCAAe,CAAC,WAAW;wBACpC,QAAQ,EAAE,UAAU;wBACpB,MAAM,EAAE,oBAAoB;qBAC7B;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,yBAAyB;wBAC/B,IAAI,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,EAAE;qBAChD;iBACF,CACF,CAAC;gBACF,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE;gBACjC,uBAAA,IAAI,6CAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IA8FD;;OAEG;IACH,UAAU;QACR,uBAAA,IAAI,2CAAY,CAAC,KAAK,EAAE,CAAC;QACzB,uBAAA,IAAI,8CAAe,CAAC,KAAK,EAAE,CAAC;QAC5B,uBAAA,IAAI,2CAAY,CAAC,KAAK,EAAE,CAAC;QACzB,uBAAA,IAAI,6CAAc,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CACZ,MAAc,EACd,UAA6B;QAE7B,OAAO,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACH,2BAA2B,CACzB,MAAc;QAEd,OAAO,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;CACF;AA9dD,0DA8dC;2ZAvHG,OAAiB,EACjB,IAA0B;IAE1B,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACzB,MAAM,cAAc,GAAG,uBAAA,IAAI,2CAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,uCAAuC;YACvC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,MAAM,IAAI,GAAG,uBAAA,IAAI,kFAAe,MAAnB,IAAI,EAAgB,cAAc,CAAC,CAAC;YACjD,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,2FAUC,cAAmD;IAEnD,IAAI,SAAkC,CAAC;IACvC,IAAI,cAAc,GAAG,QAAQ,CAAC;IAE9B,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,0CAA0C;YAC1C,SAAS,KAAT,SAAS,GAAK,KAAK,EAAC;QACtB,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;gBACxD,cAAc,GAAG,WAAW,CAAC;gBAC7B,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC;IAQC,MAAM,YAAY,GAAe,EAAE,CAAC;IACpC,uBAAA,IAAI,8CAAe,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QACxC,YAAY,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,OAAO,YAAY,CAAC;AACtB,CAAC;IAQC,MAAM,SAAS,GAAY,EAAE,CAAC;IAC9B,uBAAA,IAAI,2CAAY,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAClC,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * SubscriptionMultiplexer - Manages WebSocket subscriptions across multiple providers\n *\n * Responsibilities:\n * - Manage subscriptions to multiple providers simultaneously\n * - Tag all updates with providerId so UI can differentiate sources\n * - Support aggregation modes: 'merge' (all prices) or 'best_price' (best price per symbol)\n * - Cache latest updates per provider per symbol for aggregation\n */\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig.js';\nimport type {\n PerpsProviderType,\n PerpsProvider,\n PerpsLogger,\n PriceUpdate,\n Position,\n OrderFill,\n Order,\n AccountState,\n SubscribePricesParams,\n SubscribePositionsParams,\n SubscribeOrderFillsParams,\n SubscribeOrdersParams,\n SubscribeAccountParams,\n} from '../types/index.js';\nimport { ensureError } from '../utils/errorUtils.js';\n\n/**\n * Options for constructing SubscriptionMultiplexer\n */\nexport type SubscriptionMultiplexerOptions = {\n /** Optional logger for error reporting (e.g., Sentry) */\n logger?: PerpsLogger;\n};\n\n/**\n * Aggregation mode for price subscriptions\n */\nexport type PriceAggregationMode = 'merge' | 'best_price';\n\n/**\n * Parameters for multiplexed price subscriptions\n */\nexport type MultiplexedPricesParams = {\n /** Symbols to subscribe to */\n symbols: string[];\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated price updates */\n callback: (prices: PriceUpdate[]) => void;\n /** Aggregation mode: 'merge' returns all prices, 'best_price' returns best per symbol */\n aggregationMode?: PriceAggregationMode;\n /** Optional throttle in milliseconds */\n throttleMs?: number;\n /** Include order book data */\n includeOrderBook?: boolean;\n /** Include market data (funding, OI, volume) */\n includeMarketData?: boolean;\n};\n\n/**\n * Parameters for multiplexed position subscriptions\n */\nexport type MultiplexedPositionsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated position updates */\n callback: (positions: Position[]) => void;\n};\n\n/**\n * Parameters for multiplexed order fill subscriptions\n */\nexport type MultiplexedOrderFillsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order fill updates */\n callback: (fills: OrderFill[], isSnapshot?: boolean) => void;\n};\n\n/**\n * Parameters for multiplexed order subscriptions\n */\nexport type MultiplexedOrdersParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order updates */\n callback: (orders: Order[]) => void;\n};\n\n/**\n * Parameters for multiplexed account subscriptions\n */\nexport type MultiplexedAccountParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive account updates (one per provider) */\n callback: (accounts: AccountState[]) => void;\n};\n\n/**\n * SubscriptionMultiplexer manages real-time data subscriptions across\n * multiple perps providers.\n *\n * Key features:\n * - Subscribes to all providers simultaneously\n * - Tags all updates with source providerId\n * - Caches latest values for aggregation\n * - Supports different aggregation modes for prices\n *\n * @example\n * ```typescript\n * const mux = new SubscriptionMultiplexer();\n *\n * const unsubscribe = mux.subscribeToPrices({\n * symbols: ['BTC', 'ETH'],\n * providers: [\n * ['hyperliquid', hlProvider],\n * ['myx', myxProvider],\n * ],\n * callback: (prices) => {\n * // prices have providerId injected\n * prices.forEach(p => console.log(`${p.providerId}: ${p.symbol} = ${p.price}`));\n * },\n * aggregationMode: 'merge',\n * });\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport class SubscriptionMultiplexer {\n /**\n * Optional logger for error reporting\n */\n readonly #logger?: PerpsLogger;\n\n /**\n * Cache of latest prices per symbol per provider\n * Map<symbol, Map<providerId, PriceUpdate>>\n */\n readonly #priceCache: Map<string, Map<PerpsProviderType, PriceUpdate>> =\n new Map();\n\n /**\n * Cache of latest positions per provider\n * Map<providerId, Position[]>\n */\n readonly #positionCache: Map<PerpsProviderType, Position[]> = new Map();\n\n /**\n * Cache of latest orders per provider\n * Map<providerId, Order[]>\n */\n readonly #orderCache: Map<PerpsProviderType, Order[]> = new Map();\n\n /**\n * Cache of latest account state per provider\n * Map<providerId, AccountState>\n */\n readonly #accountCache: Map<PerpsProviderType, AccountState> = new Map();\n\n /**\n * Create a new SubscriptionMultiplexer.\n *\n * @param options - Optional configuration including logger for error reporting\n */\n constructor(options?: SubscriptionMultiplexerOptions) {\n this.#logger = options?.logger;\n }\n\n /**\n * Subscribe to price updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPrices(params: MultiplexedPricesParams): () => void {\n const {\n symbols,\n providers,\n callback,\n aggregationMode = 'merge',\n throttleMs,\n includeOrderBook,\n includeMarketData,\n } = params;\n\n const unsubscribers: (() => void)[] = [];\n\n // Subscribe to each provider with defensive error handling\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePricesParams = {\n symbols,\n callback: (updates) => {\n // Tag and cache each update\n updates.forEach((update) => {\n const taggedUpdate: PriceUpdate = { ...update, providerId };\n\n // Initialize symbol cache if needed\n if (!this.#priceCache.has(update.symbol)) {\n this.#priceCache.set(update.symbol, new Map());\n }\n const symbolCache = this.#priceCache.get(update.symbol);\n if (symbolCache) {\n symbolCache.set(providerId, taggedUpdate);\n }\n });\n\n // Aggregate and emit based on mode\n const aggregated = this.#aggregatePrices(symbols, aggregationMode);\n callback(aggregated);\n },\n throttleMs,\n includeOrderBook,\n includeMarketData,\n };\n\n const unsub = provider.subscribeToPrices(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n // Log to Sentry before cleanup\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPrices'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPrices',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n\n // Clean up any subscriptions created before the failure\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n // Return combined unsubscribe function\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Optionally clear cache for these symbols\n symbols.forEach((symbol) => {\n this.#priceCache.delete(symbol);\n });\n };\n }\n\n /**\n * Subscribe to position updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPositions(params: MultiplexedPositionsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePositionsParams = {\n callback: (positions) => {\n // Tag positions with providerId and cache\n const taggedPositions = positions.map((pos) => ({\n ...pos,\n providerId,\n }));\n this.#positionCache.set(providerId, taggedPositions);\n\n // Emit aggregated positions from all providers\n const allPositions = this.#aggregatePositions();\n callback(allPositions);\n },\n };\n\n const unsub = provider.subscribeToPositions(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPositions'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPositions',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Clear position cache for these providers\n providers.forEach(([providerId]) => {\n this.#positionCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to order fill updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrderFills(params: MultiplexedOrderFillsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrderFillsParams = {\n callback: (fills, isSnapshot) => {\n // Tag fills with providerId\n const taggedFills = fills.map((fill) => ({\n ...fill,\n providerId,\n }));\n\n // For fills, we don't aggregate - emit immediately with tags\n callback(taggedFills, isSnapshot);\n },\n };\n\n const unsub = provider.subscribeToOrderFills(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrderFills'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrderFills',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribe to order updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrders(params: MultiplexedOrdersParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrdersParams = {\n callback: (orders) => {\n // Tag orders with providerId and cache\n const taggedOrders = orders.map((order) => ({\n ...order,\n providerId,\n }));\n this.#orderCache.set(providerId, taggedOrders);\n\n // Emit aggregated orders from all providers\n const allOrders = this.#aggregateOrders();\n callback(allOrders);\n },\n };\n\n const unsub = provider.subscribeToOrders(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrders'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrders',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#orderCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to account updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToAccount(params: MultiplexedAccountParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeAccountParams = {\n callback: (account) => {\n if (account === null) {\n this.#accountCache.delete(providerId);\n } else {\n // Tag account with providerId and cache\n const taggedAccount: AccountState = {\n ...account,\n providerId,\n };\n this.#accountCache.set(providerId, taggedAccount);\n }\n\n // Emit all cached account states\n const allAccounts = Array.from(this.#accountCache.values());\n callback(allAccounts);\n },\n };\n\n const unsub = provider.subscribeToAccount(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToAccount'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToAccount',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#accountCache.delete(providerId);\n });\n };\n }\n\n /**\n * Aggregate cached prices based on mode.\n *\n * @param symbols - Symbols to include in result\n * @param mode - Aggregation mode\n * @returns Aggregated price updates\n */\n #aggregatePrices(\n symbols: string[],\n mode: PriceAggregationMode,\n ): PriceUpdate[] {\n const result: PriceUpdate[] = [];\n\n symbols.forEach((symbol) => {\n const providerPrices = this.#priceCache.get(symbol);\n if (!providerPrices || providerPrices.size === 0) {\n return;\n }\n\n if (mode === 'merge') {\n // Return all prices (one per provider)\n providerPrices.forEach((price) => {\n result.push(price);\n });\n } else {\n // 'best_price': Return the best price across providers\n const best = this.#findBestPrice(providerPrices);\n if (best) {\n result.push(best);\n }\n }\n });\n\n return result;\n }\n\n /**\n * Find the best price from multiple provider prices.\n * \"Best\" is defined as the price with the smallest spread.\n *\n * @param providerPrices - Map of provider prices for a symbol\n * @returns Best price update or undefined\n */\n #findBestPrice(\n providerPrices: Map<PerpsProviderType, PriceUpdate>,\n ): PriceUpdate | undefined {\n let bestPrice: PriceUpdate | undefined;\n let smallestSpread = Infinity;\n\n providerPrices.forEach((price) => {\n if (price.spread === undefined) {\n // No spread info - just use the first one\n bestPrice ??= price;\n } else {\n // If spread is available, use it to determine best\n const spreadValue = parseFloat(price.spread);\n if (!isNaN(spreadValue) && spreadValue < smallestSpread) {\n smallestSpread = spreadValue;\n bestPrice = price;\n }\n }\n });\n\n return bestPrice;\n }\n\n /**\n * Aggregate positions from all providers.\n *\n * @returns All cached positions\n */\n #aggregatePositions(): Position[] {\n const allPositions: Position[] = [];\n this.#positionCache.forEach((positions) => {\n allPositions.push(...positions);\n });\n return allPositions;\n }\n\n /**\n * Aggregate orders from all providers.\n *\n * @returns All cached orders\n */\n #aggregateOrders(): Order[] {\n const allOrders: Order[] = [];\n this.#orderCache.forEach((orders) => {\n allOrders.push(...orders);\n });\n return allOrders;\n }\n\n /**\n * Clear all cached data.\n */\n clearCache(): void {\n this.#priceCache.clear();\n this.#positionCache.clear();\n this.#orderCache.clear();\n this.#accountCache.clear();\n }\n\n /**\n * Get cached price for a symbol from a specific provider.\n *\n * @param symbol - Market symbol\n * @param providerId - Provider ID\n * @returns Cached price update or undefined\n */\n getCachedPrice(\n symbol: string,\n providerId: PerpsProviderType,\n ): PriceUpdate | undefined {\n return this.#priceCache.get(symbol)?.get(providerId);\n }\n\n /**\n * Get all cached prices for a symbol.\n *\n * @param symbol - Market symbol\n * @returns Map of provider ID to price update\n */\n getAllCachedPricesForSymbol(\n symbol: string,\n ): Map<PerpsProviderType, PriceUpdate> | undefined {\n return this.#priceCache.get(symbol);\n }\n}\n"]}
|
|
@@ -92,7 +92,7 @@ export type MultiplexedAccountParams = {
|
|
|
92
92
|
* symbols: ['BTC', 'ETH'],
|
|
93
93
|
* providers: [
|
|
94
94
|
* ['hyperliquid', hlProvider],
|
|
95
|
-
* ['
|
|
95
|
+
* ['myx', myxProvider],
|
|
96
96
|
* ],
|
|
97
97
|
* callback: (prices) => {
|
|
98
98
|
* // prices have providerId injected
|
|
@@ -92,7 +92,7 @@ export type MultiplexedAccountParams = {
|
|
|
92
92
|
* symbols: ['BTC', 'ETH'],
|
|
93
93
|
* providers: [
|
|
94
94
|
* ['hyperliquid', hlProvider],
|
|
95
|
-
* ['
|
|
95
|
+
* ['myx', myxProvider],
|
|
96
96
|
* ],
|
|
97
97
|
* callback: (prices) => {
|
|
98
98
|
* // prices have providerId injected
|
|
@@ -39,7 +39,7 @@ import { ensureError } from "../utils/errorUtils.mjs";
|
|
|
39
39
|
* symbols: ['BTC', 'ETH'],
|
|
40
40
|
* providers: [
|
|
41
41
|
* ['hyperliquid', hlProvider],
|
|
42
|
-
* ['
|
|
42
|
+
* ['myx', myxProvider],
|
|
43
43
|
* ],
|
|
44
44
|
* callback: (prices) => {
|
|
45
45
|
* // prices have providerId injected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionMultiplexer.mjs","sourceRoot":"","sources":["../../src/aggregation/SubscriptionMultiplexer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SubscriptionMultiplexer - Manages WebSocket subscriptions across multiple providers\n *\n * Responsibilities:\n * - Manage subscriptions to multiple providers simultaneously\n * - Tag all updates with providerId so UI can differentiate sources\n * - Support aggregation modes: 'merge' (all prices) or 'best_price' (best price per symbol)\n * - Cache latest updates per provider per symbol for aggregation\n */\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig.js';\nimport type {\n PerpsProviderType,\n PerpsProvider,\n PerpsLogger,\n PriceUpdate,\n Position,\n OrderFill,\n Order,\n AccountState,\n SubscribePricesParams,\n SubscribePositionsParams,\n SubscribeOrderFillsParams,\n SubscribeOrdersParams,\n SubscribeAccountParams,\n} from '../types/index.js';\nimport { ensureError } from '../utils/errorUtils.js';\n\n/**\n * Options for constructing SubscriptionMultiplexer\n */\nexport type SubscriptionMultiplexerOptions = {\n /** Optional logger for error reporting (e.g., Sentry) */\n logger?: PerpsLogger;\n};\n\n/**\n * Aggregation mode for price subscriptions\n */\nexport type PriceAggregationMode = 'merge' | 'best_price';\n\n/**\n * Parameters for multiplexed price subscriptions\n */\nexport type MultiplexedPricesParams = {\n /** Symbols to subscribe to */\n symbols: string[];\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated price updates */\n callback: (prices: PriceUpdate[]) => void;\n /** Aggregation mode: 'merge' returns all prices, 'best_price' returns best per symbol */\n aggregationMode?: PriceAggregationMode;\n /** Optional throttle in milliseconds */\n throttleMs?: number;\n /** Include order book data */\n includeOrderBook?: boolean;\n /** Include market data (funding, OI, volume) */\n includeMarketData?: boolean;\n};\n\n/**\n * Parameters for multiplexed position subscriptions\n */\nexport type MultiplexedPositionsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated position updates */\n callback: (positions: Position[]) => void;\n};\n\n/**\n * Parameters for multiplexed order fill subscriptions\n */\nexport type MultiplexedOrderFillsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order fill updates */\n callback: (fills: OrderFill[], isSnapshot?: boolean) => void;\n};\n\n/**\n * Parameters for multiplexed order subscriptions\n */\nexport type MultiplexedOrdersParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order updates */\n callback: (orders: Order[]) => void;\n};\n\n/**\n * Parameters for multiplexed account subscriptions\n */\nexport type MultiplexedAccountParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive account updates (one per provider) */\n callback: (accounts: AccountState[]) => void;\n};\n\n/**\n * SubscriptionMultiplexer manages real-time data subscriptions across\n * multiple perps providers.\n *\n * Key features:\n * - Subscribes to all providers simultaneously\n * - Tags all updates with source providerId\n * - Caches latest values for aggregation\n * - Supports different aggregation modes for prices\n *\n * @example\n * ```typescript\n * const mux = new SubscriptionMultiplexer();\n *\n * const unsubscribe = mux.subscribeToPrices({\n * symbols: ['BTC', 'ETH'],\n * providers: [\n * ['hyperliquid', hlProvider],\n * ['lighter', lighterProvider],\n * ],\n * callback: (prices) => {\n * // prices have providerId injected\n * prices.forEach(p => console.log(`${p.providerId}: ${p.symbol} = ${p.price}`));\n * },\n * aggregationMode: 'merge',\n * });\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport class SubscriptionMultiplexer {\n /**\n * Optional logger for error reporting\n */\n readonly #logger?: PerpsLogger;\n\n /**\n * Cache of latest prices per symbol per provider\n * Map<symbol, Map<providerId, PriceUpdate>>\n */\n readonly #priceCache: Map<string, Map<PerpsProviderType, PriceUpdate>> =\n new Map();\n\n /**\n * Cache of latest positions per provider\n * Map<providerId, Position[]>\n */\n readonly #positionCache: Map<PerpsProviderType, Position[]> = new Map();\n\n /**\n * Cache of latest orders per provider\n * Map<providerId, Order[]>\n */\n readonly #orderCache: Map<PerpsProviderType, Order[]> = new Map();\n\n /**\n * Cache of latest account state per provider\n * Map<providerId, AccountState>\n */\n readonly #accountCache: Map<PerpsProviderType, AccountState> = new Map();\n\n /**\n * Create a new SubscriptionMultiplexer.\n *\n * @param options - Optional configuration including logger for error reporting\n */\n constructor(options?: SubscriptionMultiplexerOptions) {\n this.#logger = options?.logger;\n }\n\n /**\n * Subscribe to price updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPrices(params: MultiplexedPricesParams): () => void {\n const {\n symbols,\n providers,\n callback,\n aggregationMode = 'merge',\n throttleMs,\n includeOrderBook,\n includeMarketData,\n } = params;\n\n const unsubscribers: (() => void)[] = [];\n\n // Subscribe to each provider with defensive error handling\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePricesParams = {\n symbols,\n callback: (updates) => {\n // Tag and cache each update\n updates.forEach((update) => {\n const taggedUpdate: PriceUpdate = { ...update, providerId };\n\n // Initialize symbol cache if needed\n if (!this.#priceCache.has(update.symbol)) {\n this.#priceCache.set(update.symbol, new Map());\n }\n const symbolCache = this.#priceCache.get(update.symbol);\n if (symbolCache) {\n symbolCache.set(providerId, taggedUpdate);\n }\n });\n\n // Aggregate and emit based on mode\n const aggregated = this.#aggregatePrices(symbols, aggregationMode);\n callback(aggregated);\n },\n throttleMs,\n includeOrderBook,\n includeMarketData,\n };\n\n const unsub = provider.subscribeToPrices(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n // Log to Sentry before cleanup\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPrices'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPrices',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n\n // Clean up any subscriptions created before the failure\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n // Return combined unsubscribe function\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Optionally clear cache for these symbols\n symbols.forEach((symbol) => {\n this.#priceCache.delete(symbol);\n });\n };\n }\n\n /**\n * Subscribe to position updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPositions(params: MultiplexedPositionsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePositionsParams = {\n callback: (positions) => {\n // Tag positions with providerId and cache\n const taggedPositions = positions.map((pos) => ({\n ...pos,\n providerId,\n }));\n this.#positionCache.set(providerId, taggedPositions);\n\n // Emit aggregated positions from all providers\n const allPositions = this.#aggregatePositions();\n callback(allPositions);\n },\n };\n\n const unsub = provider.subscribeToPositions(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPositions'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPositions',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Clear position cache for these providers\n providers.forEach(([providerId]) => {\n this.#positionCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to order fill updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrderFills(params: MultiplexedOrderFillsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrderFillsParams = {\n callback: (fills, isSnapshot) => {\n // Tag fills with providerId\n const taggedFills = fills.map((fill) => ({\n ...fill,\n providerId,\n }));\n\n // For fills, we don't aggregate - emit immediately with tags\n callback(taggedFills, isSnapshot);\n },\n };\n\n const unsub = provider.subscribeToOrderFills(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrderFills'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrderFills',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribe to order updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrders(params: MultiplexedOrdersParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrdersParams = {\n callback: (orders) => {\n // Tag orders with providerId and cache\n const taggedOrders = orders.map((order) => ({\n ...order,\n providerId,\n }));\n this.#orderCache.set(providerId, taggedOrders);\n\n // Emit aggregated orders from all providers\n const allOrders = this.#aggregateOrders();\n callback(allOrders);\n },\n };\n\n const unsub = provider.subscribeToOrders(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrders'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrders',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#orderCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to account updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToAccount(params: MultiplexedAccountParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeAccountParams = {\n callback: (account) => {\n if (account === null) {\n this.#accountCache.delete(providerId);\n } else {\n // Tag account with providerId and cache\n const taggedAccount: AccountState = {\n ...account,\n providerId,\n };\n this.#accountCache.set(providerId, taggedAccount);\n }\n\n // Emit all cached account states\n const allAccounts = Array.from(this.#accountCache.values());\n callback(allAccounts);\n },\n };\n\n const unsub = provider.subscribeToAccount(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToAccount'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToAccount',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#accountCache.delete(providerId);\n });\n };\n }\n\n /**\n * Aggregate cached prices based on mode.\n *\n * @param symbols - Symbols to include in result\n * @param mode - Aggregation mode\n * @returns Aggregated price updates\n */\n #aggregatePrices(\n symbols: string[],\n mode: PriceAggregationMode,\n ): PriceUpdate[] {\n const result: PriceUpdate[] = [];\n\n symbols.forEach((symbol) => {\n const providerPrices = this.#priceCache.get(symbol);\n if (!providerPrices || providerPrices.size === 0) {\n return;\n }\n\n if (mode === 'merge') {\n // Return all prices (one per provider)\n providerPrices.forEach((price) => {\n result.push(price);\n });\n } else {\n // 'best_price': Return the best price across providers\n const best = this.#findBestPrice(providerPrices);\n if (best) {\n result.push(best);\n }\n }\n });\n\n return result;\n }\n\n /**\n * Find the best price from multiple provider prices.\n * \"Best\" is defined as the price with the smallest spread.\n *\n * @param providerPrices - Map of provider prices for a symbol\n * @returns Best price update or undefined\n */\n #findBestPrice(\n providerPrices: Map<PerpsProviderType, PriceUpdate>,\n ): PriceUpdate | undefined {\n let bestPrice: PriceUpdate | undefined;\n let smallestSpread = Infinity;\n\n providerPrices.forEach((price) => {\n if (price.spread === undefined) {\n // No spread info - just use the first one\n bestPrice ??= price;\n } else {\n // If spread is available, use it to determine best\n const spreadValue = parseFloat(price.spread);\n if (!isNaN(spreadValue) && spreadValue < smallestSpread) {\n smallestSpread = spreadValue;\n bestPrice = price;\n }\n }\n });\n\n return bestPrice;\n }\n\n /**\n * Aggregate positions from all providers.\n *\n * @returns All cached positions\n */\n #aggregatePositions(): Position[] {\n const allPositions: Position[] = [];\n this.#positionCache.forEach((positions) => {\n allPositions.push(...positions);\n });\n return allPositions;\n }\n\n /**\n * Aggregate orders from all providers.\n *\n * @returns All cached orders\n */\n #aggregateOrders(): Order[] {\n const allOrders: Order[] = [];\n this.#orderCache.forEach((orders) => {\n allOrders.push(...orders);\n });\n return allOrders;\n }\n\n /**\n * Clear all cached data.\n */\n clearCache(): void {\n this.#priceCache.clear();\n this.#positionCache.clear();\n this.#orderCache.clear();\n this.#accountCache.clear();\n }\n\n /**\n * Get cached price for a symbol from a specific provider.\n *\n * @param symbol - Market symbol\n * @param providerId - Provider ID\n * @returns Cached price update or undefined\n */\n getCachedPrice(\n symbol: string,\n providerId: PerpsProviderType,\n ): PriceUpdate | undefined {\n return this.#priceCache.get(symbol)?.get(providerId);\n }\n\n /**\n * Get all cached prices for a symbol.\n *\n * @param symbol - Market symbol\n * @returns Map of provider ID to price update\n */\n getAllCachedPricesForSymbol(\n symbol: string,\n ): Map<PerpsProviderType, PriceUpdate> | undefined {\n return this.#priceCache.get(symbol);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SubscriptionMultiplexer.mjs","sourceRoot":"","sources":["../../src/aggregation/SubscriptionMultiplexer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SubscriptionMultiplexer - Manages WebSocket subscriptions across multiple providers\n *\n * Responsibilities:\n * - Manage subscriptions to multiple providers simultaneously\n * - Tag all updates with providerId so UI can differentiate sources\n * - Support aggregation modes: 'merge' (all prices) or 'best_price' (best price per symbol)\n * - Cache latest updates per provider per symbol for aggregation\n */\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig.js';\nimport type {\n PerpsProviderType,\n PerpsProvider,\n PerpsLogger,\n PriceUpdate,\n Position,\n OrderFill,\n Order,\n AccountState,\n SubscribePricesParams,\n SubscribePositionsParams,\n SubscribeOrderFillsParams,\n SubscribeOrdersParams,\n SubscribeAccountParams,\n} from '../types/index.js';\nimport { ensureError } from '../utils/errorUtils.js';\n\n/**\n * Options for constructing SubscriptionMultiplexer\n */\nexport type SubscriptionMultiplexerOptions = {\n /** Optional logger for error reporting (e.g., Sentry) */\n logger?: PerpsLogger;\n};\n\n/**\n * Aggregation mode for price subscriptions\n */\nexport type PriceAggregationMode = 'merge' | 'best_price';\n\n/**\n * Parameters for multiplexed price subscriptions\n */\nexport type MultiplexedPricesParams = {\n /** Symbols to subscribe to */\n symbols: string[];\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated price updates */\n callback: (prices: PriceUpdate[]) => void;\n /** Aggregation mode: 'merge' returns all prices, 'best_price' returns best per symbol */\n aggregationMode?: PriceAggregationMode;\n /** Optional throttle in milliseconds */\n throttleMs?: number;\n /** Include order book data */\n includeOrderBook?: boolean;\n /** Include market data (funding, OI, volume) */\n includeMarketData?: boolean;\n};\n\n/**\n * Parameters for multiplexed position subscriptions\n */\nexport type MultiplexedPositionsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated position updates */\n callback: (positions: Position[]) => void;\n};\n\n/**\n * Parameters for multiplexed order fill subscriptions\n */\nexport type MultiplexedOrderFillsParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order fill updates */\n callback: (fills: OrderFill[], isSnapshot?: boolean) => void;\n};\n\n/**\n * Parameters for multiplexed order subscriptions\n */\nexport type MultiplexedOrdersParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive aggregated order updates */\n callback: (orders: Order[]) => void;\n};\n\n/**\n * Parameters for multiplexed account subscriptions\n */\nexport type MultiplexedAccountParams = {\n /** Provider instances to subscribe through */\n providers: [PerpsProviderType, PerpsProvider][];\n /** Callback to receive account updates (one per provider) */\n callback: (accounts: AccountState[]) => void;\n};\n\n/**\n * SubscriptionMultiplexer manages real-time data subscriptions across\n * multiple perps providers.\n *\n * Key features:\n * - Subscribes to all providers simultaneously\n * - Tags all updates with source providerId\n * - Caches latest values for aggregation\n * - Supports different aggregation modes for prices\n *\n * @example\n * ```typescript\n * const mux = new SubscriptionMultiplexer();\n *\n * const unsubscribe = mux.subscribeToPrices({\n * symbols: ['BTC', 'ETH'],\n * providers: [\n * ['hyperliquid', hlProvider],\n * ['myx', myxProvider],\n * ],\n * callback: (prices) => {\n * // prices have providerId injected\n * prices.forEach(p => console.log(`${p.providerId}: ${p.symbol} = ${p.price}`));\n * },\n * aggregationMode: 'merge',\n * });\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport class SubscriptionMultiplexer {\n /**\n * Optional logger for error reporting\n */\n readonly #logger?: PerpsLogger;\n\n /**\n * Cache of latest prices per symbol per provider\n * Map<symbol, Map<providerId, PriceUpdate>>\n */\n readonly #priceCache: Map<string, Map<PerpsProviderType, PriceUpdate>> =\n new Map();\n\n /**\n * Cache of latest positions per provider\n * Map<providerId, Position[]>\n */\n readonly #positionCache: Map<PerpsProviderType, Position[]> = new Map();\n\n /**\n * Cache of latest orders per provider\n * Map<providerId, Order[]>\n */\n readonly #orderCache: Map<PerpsProviderType, Order[]> = new Map();\n\n /**\n * Cache of latest account state per provider\n * Map<providerId, AccountState>\n */\n readonly #accountCache: Map<PerpsProviderType, AccountState> = new Map();\n\n /**\n * Create a new SubscriptionMultiplexer.\n *\n * @param options - Optional configuration including logger for error reporting\n */\n constructor(options?: SubscriptionMultiplexerOptions) {\n this.#logger = options?.logger;\n }\n\n /**\n * Subscribe to price updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPrices(params: MultiplexedPricesParams): () => void {\n const {\n symbols,\n providers,\n callback,\n aggregationMode = 'merge',\n throttleMs,\n includeOrderBook,\n includeMarketData,\n } = params;\n\n const unsubscribers: (() => void)[] = [];\n\n // Subscribe to each provider with defensive error handling\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePricesParams = {\n symbols,\n callback: (updates) => {\n // Tag and cache each update\n updates.forEach((update) => {\n const taggedUpdate: PriceUpdate = { ...update, providerId };\n\n // Initialize symbol cache if needed\n if (!this.#priceCache.has(update.symbol)) {\n this.#priceCache.set(update.symbol, new Map());\n }\n const symbolCache = this.#priceCache.get(update.symbol);\n if (symbolCache) {\n symbolCache.set(providerId, taggedUpdate);\n }\n });\n\n // Aggregate and emit based on mode\n const aggregated = this.#aggregatePrices(symbols, aggregationMode);\n callback(aggregated);\n },\n throttleMs,\n includeOrderBook,\n includeMarketData,\n };\n\n const unsub = provider.subscribeToPrices(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n // Log to Sentry before cleanup\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPrices'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPrices',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n\n // Clean up any subscriptions created before the failure\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n // Return combined unsubscribe function\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Optionally clear cache for these symbols\n symbols.forEach((symbol) => {\n this.#priceCache.delete(symbol);\n });\n };\n }\n\n /**\n * Subscribe to position updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToPositions(params: MultiplexedPositionsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribePositionsParams = {\n callback: (positions) => {\n // Tag positions with providerId and cache\n const taggedPositions = positions.map((pos) => ({\n ...pos,\n providerId,\n }));\n this.#positionCache.set(providerId, taggedPositions);\n\n // Emit aggregated positions from all providers\n const allPositions = this.#aggregatePositions();\n callback(allPositions);\n },\n };\n\n const unsub = provider.subscribeToPositions(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToPositions'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToPositions',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n // Clear position cache for these providers\n providers.forEach(([providerId]) => {\n this.#positionCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to order fill updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrderFills(params: MultiplexedOrderFillsParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrderFillsParams = {\n callback: (fills, isSnapshot) => {\n // Tag fills with providerId\n const taggedFills = fills.map((fill) => ({\n ...fill,\n providerId,\n }));\n\n // For fills, we don't aggregate - emit immediately with tags\n callback(taggedFills, isSnapshot);\n },\n };\n\n const unsub = provider.subscribeToOrderFills(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrderFills'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrderFills',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribe to order updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToOrders(params: MultiplexedOrdersParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeOrdersParams = {\n callback: (orders) => {\n // Tag orders with providerId and cache\n const taggedOrders = orders.map((order) => ({\n ...order,\n providerId,\n }));\n this.#orderCache.set(providerId, taggedOrders);\n\n // Emit aggregated orders from all providers\n const allOrders = this.#aggregateOrders();\n callback(allOrders);\n },\n };\n\n const unsub = provider.subscribeToOrders(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToOrders'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToOrders',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#orderCache.delete(providerId);\n });\n };\n }\n\n /**\n * Subscribe to account updates from multiple providers.\n *\n * @param params - Subscription parameters\n * @returns Unsubscribe function\n */\n subscribeToAccount(params: MultiplexedAccountParams): () => void {\n const { providers, callback } = params;\n const unsubscribers: (() => void)[] = [];\n\n for (const [providerId, provider] of providers) {\n try {\n const subscribeParams: SubscribeAccountParams = {\n callback: (account) => {\n if (account === null) {\n this.#accountCache.delete(providerId);\n } else {\n // Tag account with providerId and cache\n const taggedAccount: AccountState = {\n ...account,\n providerId,\n };\n this.#accountCache.set(providerId, taggedAccount);\n }\n\n // Emit all cached account states\n const allAccounts = Array.from(this.#accountCache.values());\n callback(allAccounts);\n },\n };\n\n const unsub = provider.subscribeToAccount(subscribeParams);\n unsubscribers.push(unsub);\n } catch (error) {\n this.#logger?.error(\n ensureError(error, 'SubscriptionMultiplexer.subscribeToAccount'),\n {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n provider: providerId,\n method: 'subscribeToAccount',\n },\n context: {\n name: 'SubscriptionMultiplexer',\n data: { subscribedCount: unsubscribers.length },\n },\n },\n );\n unsubscribers.forEach((unsub) => unsub());\n throw error;\n }\n }\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n providers.forEach(([providerId]) => {\n this.#accountCache.delete(providerId);\n });\n };\n }\n\n /**\n * Aggregate cached prices based on mode.\n *\n * @param symbols - Symbols to include in result\n * @param mode - Aggregation mode\n * @returns Aggregated price updates\n */\n #aggregatePrices(\n symbols: string[],\n mode: PriceAggregationMode,\n ): PriceUpdate[] {\n const result: PriceUpdate[] = [];\n\n symbols.forEach((symbol) => {\n const providerPrices = this.#priceCache.get(symbol);\n if (!providerPrices || providerPrices.size === 0) {\n return;\n }\n\n if (mode === 'merge') {\n // Return all prices (one per provider)\n providerPrices.forEach((price) => {\n result.push(price);\n });\n } else {\n // 'best_price': Return the best price across providers\n const best = this.#findBestPrice(providerPrices);\n if (best) {\n result.push(best);\n }\n }\n });\n\n return result;\n }\n\n /**\n * Find the best price from multiple provider prices.\n * \"Best\" is defined as the price with the smallest spread.\n *\n * @param providerPrices - Map of provider prices for a symbol\n * @returns Best price update or undefined\n */\n #findBestPrice(\n providerPrices: Map<PerpsProviderType, PriceUpdate>,\n ): PriceUpdate | undefined {\n let bestPrice: PriceUpdate | undefined;\n let smallestSpread = Infinity;\n\n providerPrices.forEach((price) => {\n if (price.spread === undefined) {\n // No spread info - just use the first one\n bestPrice ??= price;\n } else {\n // If spread is available, use it to determine best\n const spreadValue = parseFloat(price.spread);\n if (!isNaN(spreadValue) && spreadValue < smallestSpread) {\n smallestSpread = spreadValue;\n bestPrice = price;\n }\n }\n });\n\n return bestPrice;\n }\n\n /**\n * Aggregate positions from all providers.\n *\n * @returns All cached positions\n */\n #aggregatePositions(): Position[] {\n const allPositions: Position[] = [];\n this.#positionCache.forEach((positions) => {\n allPositions.push(...positions);\n });\n return allPositions;\n }\n\n /**\n * Aggregate orders from all providers.\n *\n * @returns All cached orders\n */\n #aggregateOrders(): Order[] {\n const allOrders: Order[] = [];\n this.#orderCache.forEach((orders) => {\n allOrders.push(...orders);\n });\n return allOrders;\n }\n\n /**\n * Clear all cached data.\n */\n clearCache(): void {\n this.#priceCache.clear();\n this.#positionCache.clear();\n this.#orderCache.clear();\n this.#accountCache.clear();\n }\n\n /**\n * Get cached price for a symbol from a specific provider.\n *\n * @param symbol - Market symbol\n * @param providerId - Provider ID\n * @returns Cached price update or undefined\n */\n getCachedPrice(\n symbol: string,\n providerId: PerpsProviderType,\n ): PriceUpdate | undefined {\n return this.#priceCache.get(symbol)?.get(providerId);\n }\n\n /**\n * Get all cached prices for a symbol.\n *\n * @param symbol - Market symbol\n * @returns Map of provider ID to price update\n */\n getAllCachedPricesForSymbol(\n symbol: string,\n ): Map<PerpsProviderType, PriceUpdate> | undefined {\n return this.#priceCache.get(symbol);\n }\n}\n"]}
|
package/dist/constants/index.cjs
CHANGED
|
@@ -24,5 +24,6 @@ __exportStar(require("./orderTypes.cjs"), exports);
|
|
|
24
24
|
__exportStar(require("./perpsConfig.cjs"), exports);
|
|
25
25
|
__exportStar(require("./transactionsHistoryConfig.cjs"), exports);
|
|
26
26
|
__exportStar(require("./performanceMetrics.cjs"), exports);
|
|
27
|
+
__exportStar(require("./myxConfig.cjs"), exports);
|
|
27
28
|
__exportStar(require("./lighterConfig.cjs"), exports);
|
|
28
29
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,oDAAiC;AACjC,mDAAgC;AAChC,0DAAuC;AACvC,mDAAgC;AAChC,oDAAiC;AACjC,kEAA+C;AAC/C,2DAAwC;AACxC,sDAAmC","sourcesContent":["/**\n * Barrel re-export for all portable constants in controllers/\n */\nexport * from './chartConfig.js';\nexport * from './eventNames.js';\nexport * from './hyperLiquidConfig.js';\nexport * from './orderTypes.js';\nexport * from './perpsConfig.js';\nexport * from './transactionsHistoryConfig.js';\nexport * from './performanceMetrics.js';\nexport * from './lighterConfig.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,oDAAiC;AACjC,mDAAgC;AAChC,0DAAuC;AACvC,mDAAgC;AAChC,oDAAiC;AACjC,kEAA+C;AAC/C,2DAAwC;AACxC,kDAA+B;AAC/B,sDAAmC","sourcesContent":["/**\n * Barrel re-export for all portable constants in controllers/\n */\nexport * from './chartConfig.js';\nexport * from './eventNames.js';\nexport * from './hyperLiquidConfig.js';\nexport * from './orderTypes.js';\nexport * from './perpsConfig.js';\nexport * from './transactionsHistoryConfig.js';\nexport * from './performanceMetrics.js';\nexport * from './myxConfig.js';\nexport * from './lighterConfig.js';\n"]}
|
|
@@ -8,5 +8,6 @@ export * from "./orderTypes.cjs";
|
|
|
8
8
|
export * from "./perpsConfig.cjs";
|
|
9
9
|
export * from "./transactionsHistoryConfig.cjs";
|
|
10
10
|
export * from "./performanceMetrics.cjs";
|
|
11
|
+
export * from "./myxConfig.cjs";
|
|
11
12
|
export * from "./lighterConfig.cjs";
|
|
12
13
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,oCAAmC"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,gCAA+B;AAC/B,oCAAmC"}
|
|
@@ -8,5 +8,6 @@ export * from "./orderTypes.mjs";
|
|
|
8
8
|
export * from "./perpsConfig.mjs";
|
|
9
9
|
export * from "./transactionsHistoryConfig.mjs";
|
|
10
10
|
export * from "./performanceMetrics.mjs";
|
|
11
|
+
export * from "./myxConfig.mjs";
|
|
11
12
|
export * from "./lighterConfig.mjs";
|
|
12
13
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,oCAAmC"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,gCAA+B;AAC/B,oCAAmC"}
|
package/dist/constants/index.mjs
CHANGED
|
@@ -8,5 +8,6 @@ export * from "./orderTypes.mjs";
|
|
|
8
8
|
export * from "./perpsConfig.mjs";
|
|
9
9
|
export * from "./transactionsHistoryConfig.mjs";
|
|
10
10
|
export * from "./performanceMetrics.mjs";
|
|
11
|
+
export * from "./myxConfig.mjs";
|
|
11
12
|
export * from "./lighterConfig.mjs";
|
|
12
13
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,oCAAmC","sourcesContent":["/**\n * Barrel re-export for all portable constants in controllers/\n */\nexport * from './chartConfig.js';\nexport * from './eventNames.js';\nexport * from './hyperLiquidConfig.js';\nexport * from './orderTypes.js';\nexport * from './perpsConfig.js';\nexport * from './transactionsHistoryConfig.js';\nexport * from './performanceMetrics.js';\nexport * from './lighterConfig.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,kCAAiC;AACjC,iCAAgC;AAChC,wCAAuC;AACvC,iCAAgC;AAChC,kCAAiC;AACjC,gDAA+C;AAC/C,yCAAwC;AACxC,gCAA+B;AAC/B,oCAAmC","sourcesContent":["/**\n * Barrel re-export for all portable constants in controllers/\n */\nexport * from './chartConfig.js';\nexport * from './eventNames.js';\nexport * from './hyperLiquidConfig.js';\nexport * from './orderTypes.js';\nexport * from './perpsConfig.js';\nexport * from './transactionsHistoryConfig.js';\nexport * from './performanceMetrics.js';\nexport * from './myxConfig.js';\nexport * from './lighterConfig.js';\n"]}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MYX Protocol Configuration Constants
|
|
4
|
+
*
|
|
5
|
+
* Configuration for market display, price fetching, and trading.
|
|
6
|
+
* Based on MYX SDK patterns.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MYX_EXECUTION_FEE_TOKEN = exports.MYX_PROTOCOL_FEE_RATE = exports.MYX_FEE_RATE = exports.MYX_MINIMUM_ORDER_SIZE_USD = exports.MYX_MAX_LEVERAGE = exports.MYX_DEFAULT_SLIPPAGE_BPS = exports.MYX_MAX_RETRIES = exports.MYX_HTTP_TIMEOUT_MS = exports.MYX_PRICE_POLLING_INTERVAL_MS = exports.fromMYXCollateral = exports.toMYXSize = exports.fromMYXSize = exports.toMYXPrice = exports.fromMYXPrice = exports.MYX_ASSET_CONFIGS = exports.USDT_BNB_MAINNET = exports.USDT_BNB_TESTNET = exports.MYX_COLLATERAL_TOKEN_MAINNET = exports.MYX_COLLATERAL_TOKEN_TESTNET = exports.MYX_COLLATERAL_DECIMALS = exports.MYX_SIZE_DECIMALS = exports.MYX_PRICE_DECIMALS = exports.getMYXHttpEndpoint = exports.MYX_ENDPOINTS = exports.getMYXChainId = exports.MYX_TESTNET_CAIP_CHAIN_ID = exports.MYX_MAINNET_CAIP_CHAIN_ID = exports.MYX_TESTNET_CHAIN_ID = exports.MYX_MAINNET_CHAIN_ID = void 0;
|
|
10
|
+
const bignumber_js_1 = require("bignumber.js");
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Network Constants
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* MYX Chain IDs
|
|
16
|
+
* Mainnet: BNB Chain (56)
|
|
17
|
+
* Testnet: Linea Sepolia (59141) — primary testnet chain with most active pools.
|
|
18
|
+
* The testnet API also has one pool on Arbitrum Sepolia (421614) but it has no
|
|
19
|
+
* ticker data, so Linea Sepolia is the effective testnet chain.
|
|
20
|
+
*/
|
|
21
|
+
exports.MYX_MAINNET_CHAIN_ID = '56';
|
|
22
|
+
exports.MYX_TESTNET_CHAIN_ID = '59141';
|
|
23
|
+
exports.MYX_MAINNET_CAIP_CHAIN_ID = `eip155:${exports.MYX_MAINNET_CHAIN_ID}`;
|
|
24
|
+
exports.MYX_TESTNET_CAIP_CHAIN_ID = `eip155:${exports.MYX_TESTNET_CHAIN_ID}`;
|
|
25
|
+
/**
|
|
26
|
+
* Get numeric chain ID for MYX network
|
|
27
|
+
*
|
|
28
|
+
* @param network - The MYX network environment (mainnet or testnet).
|
|
29
|
+
* @returns The numeric chain ID for the specified network.
|
|
30
|
+
*/
|
|
31
|
+
function getMYXChainId(network) {
|
|
32
|
+
return network === 'testnet'
|
|
33
|
+
? parseInt(exports.MYX_TESTNET_CHAIN_ID, 10)
|
|
34
|
+
: parseInt(exports.MYX_MAINNET_CHAIN_ID, 10);
|
|
35
|
+
}
|
|
36
|
+
exports.getMYXChainId = getMYXChainId;
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// API Endpoints
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/**
|
|
41
|
+
* MYX REST and WebSocket endpoints
|
|
42
|
+
*/
|
|
43
|
+
exports.MYX_ENDPOINTS = {
|
|
44
|
+
mainnet: {
|
|
45
|
+
http: 'https://api.myx.finance',
|
|
46
|
+
ws: 'wss://oapi.myx.finance/ws',
|
|
47
|
+
},
|
|
48
|
+
testnet: {
|
|
49
|
+
http: 'https://api-test.myx.cash',
|
|
50
|
+
ws: 'wss://oapi-test.myx.cash/ws',
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Get HTTP endpoint for network
|
|
55
|
+
*
|
|
56
|
+
* @param network - The MYX network environment (mainnet or testnet).
|
|
57
|
+
* @returns The HTTP API endpoint URL for the specified network.
|
|
58
|
+
*/
|
|
59
|
+
function getMYXHttpEndpoint(network) {
|
|
60
|
+
return exports.MYX_ENDPOINTS[network].http;
|
|
61
|
+
}
|
|
62
|
+
exports.getMYXHttpEndpoint = getMYXHttpEndpoint;
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Decimal Constants
|
|
65
|
+
// ============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* MYX API returns prices as normal floating-point strings (e.g. "64854.76").
|
|
68
|
+
* No decimal scaling is needed for prices from the REST/WS API.
|
|
69
|
+
*
|
|
70
|
+
* Note: The SDK's internal contract layer uses 30 decimals, but the API
|
|
71
|
+
* endpoints (tickers, candles, order history) return human-readable values.
|
|
72
|
+
*/
|
|
73
|
+
exports.MYX_PRICE_DECIMALS = 0;
|
|
74
|
+
/**
|
|
75
|
+
* MYX uses 18 decimals for position sizes
|
|
76
|
+
*/
|
|
77
|
+
exports.MYX_SIZE_DECIMALS = 18;
|
|
78
|
+
/**
|
|
79
|
+
* MYX uses 18 decimals for collateral amounts (USDT on BNB)
|
|
80
|
+
*/
|
|
81
|
+
exports.MYX_COLLATERAL_DECIMALS = 18;
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// Token Addresses
|
|
84
|
+
// ============================================================================
|
|
85
|
+
/**
|
|
86
|
+
* Collateral token address — testnet (USDC on Linea Sepolia)
|
|
87
|
+
* From SDK: LINEA_SEPOLIA.USDC
|
|
88
|
+
*/
|
|
89
|
+
exports.MYX_COLLATERAL_TOKEN_TESTNET = '0xD984fd34f91F92DA0586e1bE82E262fF27DC431b';
|
|
90
|
+
/**
|
|
91
|
+
* Collateral token address — mainnet (BUSD on BNB, per pool quoteToken)
|
|
92
|
+
* Note: individual pools may use different quote tokens
|
|
93
|
+
*/
|
|
94
|
+
exports.MYX_COLLATERAL_TOKEN_MAINNET = '0x8bfc51e1928e91e47c6734983ac018b2fc0adf4e';
|
|
95
|
+
/** @deprecated Use MYX_COLLATERAL_TOKEN_TESTNET */
|
|
96
|
+
exports.USDT_BNB_TESTNET = exports.MYX_COLLATERAL_TOKEN_TESTNET;
|
|
97
|
+
/** @deprecated Use MYX_COLLATERAL_TOKEN_MAINNET */
|
|
98
|
+
exports.USDT_BNB_MAINNET = exports.MYX_COLLATERAL_TOKEN_MAINNET;
|
|
99
|
+
/**
|
|
100
|
+
* Collateral token configuration by network
|
|
101
|
+
*/
|
|
102
|
+
exports.MYX_ASSET_CONFIGS = {
|
|
103
|
+
USDT: {
|
|
104
|
+
mainnet: {
|
|
105
|
+
chainId: exports.MYX_MAINNET_CAIP_CHAIN_ID,
|
|
106
|
+
tokenAddress: exports.MYX_COLLATERAL_TOKEN_MAINNET,
|
|
107
|
+
},
|
|
108
|
+
testnet: {
|
|
109
|
+
chainId: exports.MYX_TESTNET_CAIP_CHAIN_ID,
|
|
110
|
+
tokenAddress: exports.MYX_COLLATERAL_TOKEN_TESTNET,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// Decimal Conversion Helpers
|
|
116
|
+
// ============================================================================
|
|
117
|
+
/**
|
|
118
|
+
* Convert MYX API price string to standard number.
|
|
119
|
+
*
|
|
120
|
+
* MYX API returns normal floating-point price strings (e.g. "64854.76"),
|
|
121
|
+
* NOT 30-decimal scaled integers. This is a simple parseFloat.
|
|
122
|
+
*
|
|
123
|
+
* @param myxPrice - Price string from MYX API (e.g. "64854.760266796727")
|
|
124
|
+
* @returns Standard decimal number
|
|
125
|
+
*/
|
|
126
|
+
function fromMYXPrice(myxPrice) {
|
|
127
|
+
if (!myxPrice || myxPrice === '0') {
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
const parsed = parseFloat(myxPrice);
|
|
131
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
132
|
+
}
|
|
133
|
+
exports.fromMYXPrice = fromMYXPrice;
|
|
134
|
+
/**
|
|
135
|
+
* Convert standard number to MYX API price string.
|
|
136
|
+
*
|
|
137
|
+
* MYX API uses normal floating-point strings, so this is a simple toString.
|
|
138
|
+
*
|
|
139
|
+
* @param price - Standard decimal number
|
|
140
|
+
* @returns Price string for MYX API
|
|
141
|
+
*/
|
|
142
|
+
function toMYXPrice(price) {
|
|
143
|
+
const parsed = typeof price === 'string' ? parseFloat(price) : price;
|
|
144
|
+
return isNaN(parsed) ? '0' : parsed.toString();
|
|
145
|
+
}
|
|
146
|
+
exports.toMYXPrice = toMYXPrice;
|
|
147
|
+
/**
|
|
148
|
+
* Convert MYX SDK size (18 decimals) to standard number
|
|
149
|
+
*
|
|
150
|
+
* @param myxSize - Size string in 18-decimal format from SDK
|
|
151
|
+
* @returns Standard decimal number
|
|
152
|
+
*/
|
|
153
|
+
function fromMYXSize(myxSize) {
|
|
154
|
+
if (!myxSize || myxSize === '0') {
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const bn = new bignumber_js_1.BigNumber(myxSize);
|
|
159
|
+
if (bn.isNaN()) {
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
const divisor = new bignumber_js_1.BigNumber(10).pow(exports.MYX_SIZE_DECIMALS);
|
|
163
|
+
return bn.dividedBy(divisor).toNumber();
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.fromMYXSize = fromMYXSize;
|
|
170
|
+
/**
|
|
171
|
+
* Convert standard number to MYX SDK size format (18 decimals)
|
|
172
|
+
*
|
|
173
|
+
* @param size - Standard decimal number
|
|
174
|
+
* @returns Size string in 18-decimal format for SDK
|
|
175
|
+
*/
|
|
176
|
+
function toMYXSize(size) {
|
|
177
|
+
try {
|
|
178
|
+
const bn = new bignumber_js_1.BigNumber(size);
|
|
179
|
+
if (bn.isNaN()) {
|
|
180
|
+
return '0';
|
|
181
|
+
}
|
|
182
|
+
const multiplier = new bignumber_js_1.BigNumber(10).pow(exports.MYX_SIZE_DECIMALS);
|
|
183
|
+
return bn.multipliedBy(multiplier).toFixed(0);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return '0';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.toMYXSize = toMYXSize;
|
|
190
|
+
/**
|
|
191
|
+
* Convert MYX SDK collateral (18 decimals) to standard number
|
|
192
|
+
*
|
|
193
|
+
* @param myxCollateral - Collateral string in 18-decimal format from SDK
|
|
194
|
+
* @returns Standard decimal number
|
|
195
|
+
*/
|
|
196
|
+
function fromMYXCollateral(myxCollateral) {
|
|
197
|
+
if (!myxCollateral || myxCollateral === '0') {
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
const bn = new bignumber_js_1.BigNumber(myxCollateral);
|
|
202
|
+
if (bn.isNaN()) {
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
const divisor = new bignumber_js_1.BigNumber(10).pow(exports.MYX_COLLATERAL_DECIMALS);
|
|
206
|
+
return bn.dividedBy(divisor).toNumber();
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
exports.fromMYXCollateral = fromMYXCollateral;
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// REST API Configuration
|
|
215
|
+
// ============================================================================
|
|
216
|
+
/**
|
|
217
|
+
* Price polling interval in milliseconds
|
|
218
|
+
* Using 5 seconds as a fallback for unreliable WebSocket
|
|
219
|
+
*/
|
|
220
|
+
exports.MYX_PRICE_POLLING_INTERVAL_MS = 5000;
|
|
221
|
+
/**
|
|
222
|
+
* HTTP request timeout in milliseconds
|
|
223
|
+
*/
|
|
224
|
+
exports.MYX_HTTP_TIMEOUT_MS = 10000;
|
|
225
|
+
/**
|
|
226
|
+
* Maximum retries for failed API requests
|
|
227
|
+
*/
|
|
228
|
+
exports.MYX_MAX_RETRIES = 3;
|
|
229
|
+
/**
|
|
230
|
+
* Default slippage in basis points for MYX orders (1% — matches SDK default)
|
|
231
|
+
*/
|
|
232
|
+
exports.MYX_DEFAULT_SLIPPAGE_BPS = 100;
|
|
233
|
+
/**
|
|
234
|
+
* Maximum leverage supported by MYX (most markets)
|
|
235
|
+
*/
|
|
236
|
+
exports.MYX_MAX_LEVERAGE = 100;
|
|
237
|
+
/**
|
|
238
|
+
* Minimum order size in USD
|
|
239
|
+
*/
|
|
240
|
+
exports.MYX_MINIMUM_ORDER_SIZE_USD = 10;
|
|
241
|
+
/**
|
|
242
|
+
* MYX fee rates (placeholder — will be replaced with per-market rates)
|
|
243
|
+
*/
|
|
244
|
+
exports.MYX_FEE_RATE = 0.0005; // 0.05% total fee rate
|
|
245
|
+
exports.MYX_PROTOCOL_FEE_RATE = 0.0005; // Protocol taker fee
|
|
246
|
+
/**
|
|
247
|
+
* USDT execution fee token address per network (used for order execution fees)
|
|
248
|
+
*/
|
|
249
|
+
exports.MYX_EXECUTION_FEE_TOKEN = {
|
|
250
|
+
testnet: exports.MYX_COLLATERAL_TOKEN_TESTNET,
|
|
251
|
+
mainnet: exports.MYX_COLLATERAL_TOKEN_MAINNET,
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=myxConfig.cjs.map
|