@drift-labs/common 1.0.54 → 1.0.56
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/lib/clients/DlobWebsocketClient.d.ts +3 -1
- package/lib/clients/DlobWebsocketClient.js +6 -5
- package/lib/clients/DlobWebsocketClient.js.map +1 -1
- package/lib/common-ui-utils/commonUiUtils.d.ts +3 -0
- package/lib/common-ui-utils/commonUiUtils.js +4 -3
- package/lib/common-ui-utils/commonUiUtils.js.map +1 -1
- package/lib/common-ui-utils/trading.d.ts +15 -0
- package/lib/common-ui-utils/trading.js +31 -2
- package/lib/common-ui-utils/trading.js.map +1 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/types/MarketId.js +7 -7
- package/lib/types/MarketId.js.map +1 -1
- package/lib/types/UIMarket.js +2 -2
- package/lib/types/UIMarket.js.map +1 -1
- package/lib/utils/enum.d.ts +11 -0
- package/lib/utils/enum.js +24 -0
- package/lib/utils/enum.js.map +1 -0
- package/lib/utils/index.d.ts +2 -10
- package/lib/utils/index.js +11 -28
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/math.d.ts +22 -1
- package/lib/utils/math.js +93 -1
- package/lib/utils/math.js.map +1 -1
- package/lib/utils/millify.d.ts +12 -0
- package/lib/utils/millify.js +38 -0
- package/lib/utils/millify.js.map +1 -0
- package/lib/utils/strings.d.ts +34 -0
- package/lib/utils/strings.js +121 -0
- package/lib/utils/strings.js.map +1 -0
- package/lib/utils/validation.d.ts +17 -0
- package/lib/utils/validation.js +89 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { MarketId
|
|
1
|
+
import { MarketId } from '../types/MarketId';
|
|
2
|
+
import { deserializeL2Response } from '../utils/orderbook';
|
|
3
|
+
import { OrderbookGrouping, DlobServerChannel } from '../utils/dlob-server/DlobServerWebsocketUtils';
|
|
2
4
|
import { Observable } from 'rxjs';
|
|
3
5
|
import { ResultSlotIncrementer } from '../utils/ResultSlotIncrementer';
|
|
4
6
|
import { RawL2Output } from '../utils/orderbook/types';
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.DlobWebsocketClient = void 0;
|
|
5
|
-
const
|
|
5
|
+
const orderbook_1 = require("../utils/orderbook");
|
|
6
|
+
const DlobServerWebsocketUtils_1 = require("../utils/dlob-server/DlobServerWebsocketUtils");
|
|
6
7
|
const rxjs_1 = require("rxjs");
|
|
7
8
|
const operators_1 = require("rxjs/operators");
|
|
8
9
|
const ResultSlotIncrementer_1 = require("../utils/ResultSlotIncrementer");
|
|
@@ -152,12 +153,12 @@ class DlobWebsocketClient {
|
|
|
152
153
|
wsUrl: this.config.websocketUrl,
|
|
153
154
|
enableHeartbeatMonitoring: true,
|
|
154
155
|
subscriptionId: this.getCachedString(`${this.config.websocketUrl}_dlob_liquidity_${marketId.key}`, 'subscription'),
|
|
155
|
-
subscribeMessage: JSON.stringify(
|
|
156
|
+
subscribeMessage: JSON.stringify(DlobServerWebsocketUtils_1.DLOB_SERVER_WEBSOCKET_UTILS.getSubscriptionProps({
|
|
156
157
|
type: channel,
|
|
157
158
|
market: marketId,
|
|
158
159
|
grouping,
|
|
159
160
|
})),
|
|
160
|
-
unsubscribeMessage: JSON.stringify(
|
|
161
|
+
unsubscribeMessage: JSON.stringify(DlobServerWebsocketUtils_1.DLOB_SERVER_WEBSOCKET_UTILS.getUnsubscriptionProps({
|
|
161
162
|
type: channel,
|
|
162
163
|
market: marketId,
|
|
163
164
|
grouping,
|
|
@@ -170,7 +171,7 @@ class DlobWebsocketClient {
|
|
|
170
171
|
});
|
|
171
172
|
},
|
|
172
173
|
messageFilter: (message) => {
|
|
173
|
-
return
|
|
174
|
+
return DlobServerWebsocketUtils_1.DLOB_SERVER_WEBSOCKET_UTILS.getMessageFilter({
|
|
174
175
|
type: channel,
|
|
175
176
|
market: marketId,
|
|
176
177
|
grouping,
|
|
@@ -205,7 +206,7 @@ class DlobWebsocketClient {
|
|
|
205
206
|
if (!validResult) {
|
|
206
207
|
return null; // Skip results which aren't slot-increasing or are filtered due to tab return
|
|
207
208
|
}
|
|
208
|
-
const deserializedData = (0,
|
|
209
|
+
const deserializedData = (0, orderbook_1.deserializeL2Response)(parsed);
|
|
209
210
|
return {
|
|
210
211
|
marketId,
|
|
211
212
|
rawData: parsed,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DlobWebsocketClient.js","sourceRoot":"","sources":["../../src/clients/DlobWebsocketClient.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n\tMarketId,\n\tdeserializeL2Response,\n\tOrderbookGrouping,\n\tDLOB_SERVER_WEBSOCKET_UTILS,\n\tDlobServerChannel,\n} from '..';\nimport { Observable, Subject, BehaviorSubject, EMPTY } from 'rxjs';\nimport {\n\tmap,\n\tfilter,\n\tcatchError,\n\ttakeUntil,\n\tshare,\n\tdistinctUntilChanged,\n\tswitchMap,\n} from 'rxjs/operators';\nimport { ResultSlotIncrementer } from '../utils/ResultSlotIncrementer';\nimport { MultiplexWebSocket } from '../utils/MultiplexWebSocket';\nimport { RawL2Output } from '../utils/orderbook/types';\n\nexport type OrderbookChannelTypes = Extract<\n\tDlobServerChannel,\n\t'orderbook' | 'orderbook_indicative'\n>;\n\nexport interface DlobWebsocketClientConfig {\n\twebsocketUrl: string;\n\tenableIndicativeOrderbook?: boolean;\n\tresultSlotIncrementer?: ResultSlotIncrementer;\n\tonFallback?: (marketId: MarketId) => void;\n}\n\nexport interface MarketSubscription {\n\tmarketId: MarketId;\n\tchannel: OrderbookChannelTypes;\n\tgrouping?: OrderbookGrouping;\n}\n\nexport interface ProcessedMarketData {\n\tmarketId: MarketId;\n\trawData: RawL2Output;\n\tdeserializedData: ReturnType<typeof deserializeL2Response>;\n\tslot: number;\n}\n\nexport class DlobWebsocketClient {\n\tprivate config: DlobWebsocketClientConfig;\n\tprivate subscriptions = new Map<string, { unsubscribe: () => void }>();\n\tprivate resultIncrementer: ResultSlotIncrementer;\n\tprivate destroy$ = new Subject<void>();\n\n\t// String caches to prevent repeated string concatenation\n\tprivate static readonly stringCache = new Map<string, string>();\n\tprivate static readonly maxCacheSize = 1000;\n\n\t// Subjects for reactive streams\n\tprivate marketSubscriptions$ = new BehaviorSubject<MarketSubscription[]>([]);\n\tprivate rawMessages$ = new Subject<{\n\t\tmarketId: MarketId;\n\t\tchannel: string;\n\t\tdata: string;\n\t}>();\n\n\tconstructor(config: DlobWebsocketClientConfig) {\n\t\tthis.config = config;\n\t\tthis.resultIncrementer =\n\t\t\tconfig.resultSlotIncrementer || new ResultSlotIncrementer();\n\n\t\tthis.setupSubscriptionManagement();\n\t}\n\n\t/**\n\t * Get an observable stream of processed market data for specific markets\n\t */\n\tgetMarketDataStream(marketIds: MarketId[]): Observable<ProcessedMarketData> {\n\t\treturn this.rawMessages$.pipe(\n\t\t\tfilter(({ marketId }) => marketIds.some((id) => id.key === marketId.key)),\n\t\t\tmap(({ marketId, channel, data }) =>\n\t\t\t\tthis.processRawMessage(marketId, channel, data)\n\t\t\t),\n\t\t\tfilter((result): result is ProcessedMarketData => result !== null),\n\t\t\tcatchError((error) => {\n\t\t\t\tconsole.error('Caught error in getMarketDataStream', error);\n\t\t\t\treturn EMPTY;\n\t\t\t}),\n\t\t\ttakeUntil(this.destroy$),\n\t\t\tshare()\n\t\t);\n\t}\n\n\t/**\n\t * Subscribe to market data for given markets\n\t */\n\tsubscribeToMarkets(\n\t\tmarkets: {\n\t\t\tmarketId: MarketId;\n\t\t\tgrouping?: OrderbookGrouping;\n\t\t}[]\n\t): void {\n\t\tconst subscriptions: MarketSubscription[] = markets.map(\n\t\t\t({ marketId, grouping }) => ({\n\t\t\t\tmarketId,\n\t\t\t\tchannel: this.config.enableIndicativeOrderbook\n\t\t\t\t\t? 'orderbook_indicative'\n\t\t\t\t\t: 'orderbook',\n\t\t\t\tgrouping,\n\t\t\t})\n\t\t);\n\n\t\tthis.marketSubscriptions$.next(subscriptions);\n\t}\n\n\t/**\n\t * Unsubscribe from all markets\n\t */\n\tunsubscribeAll(): void {\n\t\tthis.marketSubscriptions$.next([]);\n\t}\n\n\t/**\n\t * Handle tab return to prevent \"speed run\" through queued messages\n\t */\n\thandleTabReturn(): void {\n\t\tthis.resultIncrementer.handleTabReturn();\n\t}\n\n\t/**\n\t * Reset slot tracking for clean state on reconnection\n\t */\n\tresetSlotTracking(): void {\n\t\t// Get all current subscription keys and reset their slot tracking\n\t\tfor (const subscriptionKey of this.subscriptions.keys()) {\n\t\t\t// Extract marketId and channel from subscription key\n\t\t\tconst [marketKey, channel] = subscriptionKey.split('_');\n\t\t\tconst resultKey = this.getCachedString(\n\t\t\t\t`${channel}_${marketKey}`,\n\t\t\t\t'result'\n\t\t\t);\n\t\t\tthis.resultIncrementer.resetKey(resultKey);\n\t\t}\n\t}\n\n\t/**\n\t * Cache frequently used strings to reduce memory allocation\n\t */\n\tprivate getCachedString(baseString: string, type: string): string {\n\t\tconst cacheKey = `${type}:${baseString}`;\n\n\t\tif (DlobWebsocketClient.stringCache.has(cacheKey)) {\n\t\t\treturn DlobWebsocketClient.stringCache.get(cacheKey)!;\n\t\t}\n\n\t\t// If cache is getting too large, clear oldest entries\n\t\tif (\n\t\t\tDlobWebsocketClient.stringCache.size >= DlobWebsocketClient.maxCacheSize\n\t\t) {\n\t\t\tconst firstKey = DlobWebsocketClient.stringCache.keys().next().value;\n\t\t\tDlobWebsocketClient.stringCache.delete(firstKey);\n\t\t}\n\n\t\tDlobWebsocketClient.stringCache.set(cacheKey, baseString);\n\t\treturn baseString;\n\t}\n\n\t/**\n\t * Destroy the client and clean up all subscriptions\n\t */\n\tdestroy(): void {\n\t\tthis.destroy$.next();\n\t\tthis.destroy$.complete();\n\t\tthis.subscriptions.forEach(({ unsubscribe }) => unsubscribe());\n\t\tthis.subscriptions.clear();\n\t}\n\n\t/**\n\t * Sets up the subscription management pipeline that handles market data subscriptions.\n\t * This pipeline:\n\t * 1. Watches for changes in market subscriptions\n\t * 2. Only processes changes when the subscription list actually changes\n\t * 3. Manages the lifecycle of websocket subscriptions\n\t * 4. Cleans up when the client is destroyed\n\t */\n\tprivate setupSubscriptionManagement(): void {\n\t\tthis.marketSubscriptions$\n\t\t\t.pipe(\n\t\t\t\t// Only emit when the subscription list actually changes\n\t\t\t\t// Uses JSON.stringify for deep comparison of subscription arrays\n\t\t\t\tdistinctUntilChanged(\n\t\t\t\t\t(prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)\n\t\t\t\t),\n\t\t\t\t// Switch to managing the new set of subscriptions\n\t\t\t\t// This will cancel any previous subscription management\n\t\t\t\tswitchMap((subscriptions) =>\n\t\t\t\t\tthis.manageNewSubscriptions(subscriptions)\n\t\t\t\t),\n\t\t\t\t// Clean up when the client is destroyed\n\t\t\t\ttakeUntil(this.destroy$)\n\t\t\t)\n\t\t\t.subscribe();\n\t}\n\n\t/**\n\t * Manages the lifecycle of websocket subscriptions by:\n\t * 1. Comparing current subscriptions with new subscriptions\n\t * 2. Unsubscribing from any subscriptions that are no longer needed\n\t * 3. Creating new subscriptions for markets that weren't previously subscribed\n\t *\n\t * @param newSubscriptions - The new set of market subscriptions to maintain\n\t * @returns An empty observable since this is a side-effect operation\n\t */\n\tprivate manageNewSubscriptions(\n\t\tnewSubscriptions: MarketSubscription[]\n\t): Observable<never> {\n\t\t// Get sets of subscription keys for efficient comparison\n\t\tconst currentKeys = new Set(this.subscriptions.keys());\n\t\tconst newKeys = new Set(\n\t\t\tnewSubscriptions.map((sub) => this.getSubscriptionKey(sub))\n\t\t);\n\n\t\t// Unsubscribe from removed subscriptions\n\t\tfor (const key of currentKeys) {\n\t\t\tif (!newKeys.has(key)) {\n\t\t\t\tconst subscription = this.subscriptions.get(key);\n\t\t\t\tif (subscription) {\n\t\t\t\t\tsubscription.unsubscribe();\n\t\t\t\t\tthis.subscriptions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Subscribe to new subscriptions\n\t\tfor (const subscription of newSubscriptions) {\n\t\t\tconst key = this.getSubscriptionKey(subscription);\n\t\t\tif (!currentKeys.has(key)) {\n\t\t\t\tthis.createSubscription(subscription);\n\t\t\t}\n\t\t}\n\n\t\treturn EMPTY;\n\t}\n\n\tprivate createSubscription(subscription: MarketSubscription): void {\n\t\tconst { marketId, channel, grouping } = subscription;\n\t\tconst subscriptionKey = this.getSubscriptionKey(subscription);\n\n\t\ttry {\n\t\t\tconst { unsubscribe } = MultiplexWebSocket.createWebSocketSubscription<{\n\t\t\t\tchannel: string;\n\t\t\t\tdata: string;\n\t\t\t}>({\n\t\t\t\twsUrl: this.config.websocketUrl,\n\t\t\t\tenableHeartbeatMonitoring: true,\n\t\t\t\tsubscriptionId: this.getCachedString(\n\t\t\t\t\t`${this.config.websocketUrl}_dlob_liquidity_${marketId.key}`,\n\t\t\t\t\t'subscription'\n\t\t\t\t),\n\t\t\t\tsubscribeMessage: JSON.stringify(\n\t\t\t\t\tDLOB_SERVER_WEBSOCKET_UTILS.getSubscriptionProps({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tunsubscribeMessage: JSON.stringify(\n\t\t\t\t\tDLOB_SERVER_WEBSOCKET_UTILS.getUnsubscriptionProps({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tonMessage: (message: { channel: string; data: string }) => {\n\t\t\t\t\tthis.rawMessages$.next({\n\t\t\t\t\t\tmarketId,\n\t\t\t\t\t\tchannel: message.channel,\n\t\t\t\t\t\tdata: message.data,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tmessageFilter: (message: { channel: string; data: string }) => {\n\t\t\t\t\treturn DLOB_SERVER_WEBSOCKET_UTILS.getMessageFilter({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})(message);\n\t\t\t\t},\n\t\t\t\tonError: (error?: any) => {\n\t\t\t\t\tconsole.error('Caught error in createSubscription', error);\n\t\t\t\t\tthis.config.onFallback?.(marketId);\n\t\t\t\t},\n\t\t\t\terrorMessageFilter: (message?: any) => {\n\t\t\t\t\tif (message?.error) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.subscriptions.set(subscriptionKey, { unsubscribe });\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to create subscription:', error);\n\t\t\tthis.config.onFallback?.(marketId);\n\t\t}\n\t}\n\n\tprivate processRawMessage(\n\t\tmarketId: MarketId,\n\t\tchannel: string,\n\t\tdata: string\n\t): ProcessedMarketData | null {\n\t\ttry {\n\t\t\tconst parsed = this.tryParse(data) as RawL2Output;\n\t\t\tconst resultKey = this.getCachedString(\n\t\t\t\t`${channel}_${marketId.key}`,\n\t\t\t\t'result'\n\t\t\t);\n\t\t\tconst messageTimestamp = Date.now(); // Capture when we received this message\n\n\t\t\tconst validResult = this.resultIncrementer.handleResult(\n\t\t\t\tresultKey,\n\t\t\t\tparsed.slot ?? 0,\n\t\t\t\tmessageTimestamp\n\t\t\t);\n\n\t\t\tif (!validResult) {\n\t\t\t\treturn null; // Skip results which aren't slot-increasing or are filtered due to tab return\n\t\t\t}\n\n\t\t\tconst deserializedData = deserializeL2Response(parsed);\n\n\t\t\treturn {\n\t\t\t\tmarketId,\n\t\t\t\trawData: parsed,\n\t\t\t\tdeserializedData,\n\t\t\t\tslot: parsed.slot ?? 0,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate tryParse(data: unknown): unknown {\n\t\ttry {\n\t\t\treturn JSON.parse(data as string, (key, value) => {\n\t\t\t\t// If the value is a number and it's too large to be safely represented as a JavaScript number,\n\t\t\t\t// convert it to a string to prevent precision loss\n\t\t\t\tif (typeof value === 'number' && !Number.isSafeInteger(value)) {\n\t\t\t\t\treturn value.toString();\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t} catch (e) {\n\t\t\treturn data;\n\t\t}\n\t}\n\n\tprivate getSubscriptionKey(subscription: MarketSubscription): string {\n\t\tconst { marketId, channel, grouping } = subscription;\n\t\tconst baseKey = `${marketId.key}_${channel}${\n\t\t\tgrouping ? `_${grouping}` : ''\n\t\t}`;\n\t\treturn this.getCachedString(baseKey, 'subscription_key');\n\t}\n}\n\nexport default DlobWebsocketClient;\n"]}
|
|
1
|
+
{"version":3,"file":"DlobWebsocketClient.js","sourceRoot":"","sources":["../../src/clients/DlobWebsocketClient.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { MarketId } from '../types/MarketId';\nimport { deserializeL2Response } from '../utils/orderbook';\nimport {\n\tOrderbookGrouping,\n\tDLOB_SERVER_WEBSOCKET_UTILS,\n\tDlobServerChannel,\n} from '../utils/dlob-server/DlobServerWebsocketUtils';\nimport { Observable, Subject, BehaviorSubject, EMPTY } from 'rxjs';\nimport {\n\tmap,\n\tfilter,\n\tcatchError,\n\ttakeUntil,\n\tshare,\n\tdistinctUntilChanged,\n\tswitchMap,\n} from 'rxjs/operators';\nimport { ResultSlotIncrementer } from '../utils/ResultSlotIncrementer';\nimport { MultiplexWebSocket } from '../utils/MultiplexWebSocket';\nimport { RawL2Output } from '../utils/orderbook/types';\n\nexport type OrderbookChannelTypes = Extract<\n\tDlobServerChannel,\n\t'orderbook' | 'orderbook_indicative'\n>;\n\nexport interface DlobWebsocketClientConfig {\n\twebsocketUrl: string;\n\tenableIndicativeOrderbook?: boolean;\n\tresultSlotIncrementer?: ResultSlotIncrementer;\n\tonFallback?: (marketId: MarketId) => void;\n}\n\nexport interface MarketSubscription {\n\tmarketId: MarketId;\n\tchannel: OrderbookChannelTypes;\n\tgrouping?: OrderbookGrouping;\n}\n\nexport interface ProcessedMarketData {\n\tmarketId: MarketId;\n\trawData: RawL2Output;\n\tdeserializedData: ReturnType<typeof deserializeL2Response>;\n\tslot: number;\n}\n\nexport class DlobWebsocketClient {\n\tprivate config: DlobWebsocketClientConfig;\n\tprivate subscriptions = new Map<string, { unsubscribe: () => void }>();\n\tprivate resultIncrementer: ResultSlotIncrementer;\n\tprivate destroy$ = new Subject<void>();\n\n\t// String caches to prevent repeated string concatenation\n\tprivate static readonly stringCache = new Map<string, string>();\n\tprivate static readonly maxCacheSize = 1000;\n\n\t// Subjects for reactive streams\n\tprivate marketSubscriptions$ = new BehaviorSubject<MarketSubscription[]>([]);\n\tprivate rawMessages$ = new Subject<{\n\t\tmarketId: MarketId;\n\t\tchannel: string;\n\t\tdata: string;\n\t}>();\n\n\tconstructor(config: DlobWebsocketClientConfig) {\n\t\tthis.config = config;\n\t\tthis.resultIncrementer =\n\t\t\tconfig.resultSlotIncrementer || new ResultSlotIncrementer();\n\n\t\tthis.setupSubscriptionManagement();\n\t}\n\n\t/**\n\t * Get an observable stream of processed market data for specific markets\n\t */\n\tgetMarketDataStream(marketIds: MarketId[]): Observable<ProcessedMarketData> {\n\t\treturn this.rawMessages$.pipe(\n\t\t\tfilter(({ marketId }) => marketIds.some((id) => id.key === marketId.key)),\n\t\t\tmap(({ marketId, channel, data }) =>\n\t\t\t\tthis.processRawMessage(marketId, channel, data)\n\t\t\t),\n\t\t\tfilter((result): result is ProcessedMarketData => result !== null),\n\t\t\tcatchError((error) => {\n\t\t\t\tconsole.error('Caught error in getMarketDataStream', error);\n\t\t\t\treturn EMPTY;\n\t\t\t}),\n\t\t\ttakeUntil(this.destroy$),\n\t\t\tshare()\n\t\t);\n\t}\n\n\t/**\n\t * Subscribe to market data for given markets\n\t */\n\tsubscribeToMarkets(\n\t\tmarkets: {\n\t\t\tmarketId: MarketId;\n\t\t\tgrouping?: OrderbookGrouping;\n\t\t}[]\n\t): void {\n\t\tconst subscriptions: MarketSubscription[] = markets.map(\n\t\t\t({ marketId, grouping }) => ({\n\t\t\t\tmarketId,\n\t\t\t\tchannel: this.config.enableIndicativeOrderbook\n\t\t\t\t\t? 'orderbook_indicative'\n\t\t\t\t\t: 'orderbook',\n\t\t\t\tgrouping,\n\t\t\t})\n\t\t);\n\n\t\tthis.marketSubscriptions$.next(subscriptions);\n\t}\n\n\t/**\n\t * Unsubscribe from all markets\n\t */\n\tunsubscribeAll(): void {\n\t\tthis.marketSubscriptions$.next([]);\n\t}\n\n\t/**\n\t * Handle tab return to prevent \"speed run\" through queued messages\n\t */\n\thandleTabReturn(): void {\n\t\tthis.resultIncrementer.handleTabReturn();\n\t}\n\n\t/**\n\t * Reset slot tracking for clean state on reconnection\n\t */\n\tresetSlotTracking(): void {\n\t\t// Get all current subscription keys and reset their slot tracking\n\t\tfor (const subscriptionKey of this.subscriptions.keys()) {\n\t\t\t// Extract marketId and channel from subscription key\n\t\t\tconst [marketKey, channel] = subscriptionKey.split('_');\n\t\t\tconst resultKey = this.getCachedString(\n\t\t\t\t`${channel}_${marketKey}`,\n\t\t\t\t'result'\n\t\t\t);\n\t\t\tthis.resultIncrementer.resetKey(resultKey);\n\t\t}\n\t}\n\n\t/**\n\t * Cache frequently used strings to reduce memory allocation\n\t */\n\tprivate getCachedString(baseString: string, type: string): string {\n\t\tconst cacheKey = `${type}:${baseString}`;\n\n\t\tif (DlobWebsocketClient.stringCache.has(cacheKey)) {\n\t\t\treturn DlobWebsocketClient.stringCache.get(cacheKey)!;\n\t\t}\n\n\t\t// If cache is getting too large, clear oldest entries\n\t\tif (\n\t\t\tDlobWebsocketClient.stringCache.size >= DlobWebsocketClient.maxCacheSize\n\t\t) {\n\t\t\tconst firstKey = DlobWebsocketClient.stringCache.keys().next().value;\n\t\t\tDlobWebsocketClient.stringCache.delete(firstKey);\n\t\t}\n\n\t\tDlobWebsocketClient.stringCache.set(cacheKey, baseString);\n\t\treturn baseString;\n\t}\n\n\t/**\n\t * Destroy the client and clean up all subscriptions\n\t */\n\tdestroy(): void {\n\t\tthis.destroy$.next();\n\t\tthis.destroy$.complete();\n\t\tthis.subscriptions.forEach(({ unsubscribe }) => unsubscribe());\n\t\tthis.subscriptions.clear();\n\t}\n\n\t/**\n\t * Sets up the subscription management pipeline that handles market data subscriptions.\n\t * This pipeline:\n\t * 1. Watches for changes in market subscriptions\n\t * 2. Only processes changes when the subscription list actually changes\n\t * 3. Manages the lifecycle of websocket subscriptions\n\t * 4. Cleans up when the client is destroyed\n\t */\n\tprivate setupSubscriptionManagement(): void {\n\t\tthis.marketSubscriptions$\n\t\t\t.pipe(\n\t\t\t\t// Only emit when the subscription list actually changes\n\t\t\t\t// Uses JSON.stringify for deep comparison of subscription arrays\n\t\t\t\tdistinctUntilChanged(\n\t\t\t\t\t(prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)\n\t\t\t\t),\n\t\t\t\t// Switch to managing the new set of subscriptions\n\t\t\t\t// This will cancel any previous subscription management\n\t\t\t\tswitchMap((subscriptions) =>\n\t\t\t\t\tthis.manageNewSubscriptions(subscriptions)\n\t\t\t\t),\n\t\t\t\t// Clean up when the client is destroyed\n\t\t\t\ttakeUntil(this.destroy$)\n\t\t\t)\n\t\t\t.subscribe();\n\t}\n\n\t/**\n\t * Manages the lifecycle of websocket subscriptions by:\n\t * 1. Comparing current subscriptions with new subscriptions\n\t * 2. Unsubscribing from any subscriptions that are no longer needed\n\t * 3. Creating new subscriptions for markets that weren't previously subscribed\n\t *\n\t * @param newSubscriptions - The new set of market subscriptions to maintain\n\t * @returns An empty observable since this is a side-effect operation\n\t */\n\tprivate manageNewSubscriptions(\n\t\tnewSubscriptions: MarketSubscription[]\n\t): Observable<never> {\n\t\t// Get sets of subscription keys for efficient comparison\n\t\tconst currentKeys = new Set(this.subscriptions.keys());\n\t\tconst newKeys = new Set(\n\t\t\tnewSubscriptions.map((sub) => this.getSubscriptionKey(sub))\n\t\t);\n\n\t\t// Unsubscribe from removed subscriptions\n\t\tfor (const key of currentKeys) {\n\t\t\tif (!newKeys.has(key)) {\n\t\t\t\tconst subscription = this.subscriptions.get(key);\n\t\t\t\tif (subscription) {\n\t\t\t\t\tsubscription.unsubscribe();\n\t\t\t\t\tthis.subscriptions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Subscribe to new subscriptions\n\t\tfor (const subscription of newSubscriptions) {\n\t\t\tconst key = this.getSubscriptionKey(subscription);\n\t\t\tif (!currentKeys.has(key)) {\n\t\t\t\tthis.createSubscription(subscription);\n\t\t\t}\n\t\t}\n\n\t\treturn EMPTY;\n\t}\n\n\tprivate createSubscription(subscription: MarketSubscription): void {\n\t\tconst { marketId, channel, grouping } = subscription;\n\t\tconst subscriptionKey = this.getSubscriptionKey(subscription);\n\n\t\ttry {\n\t\t\tconst { unsubscribe } = MultiplexWebSocket.createWebSocketSubscription<{\n\t\t\t\tchannel: string;\n\t\t\t\tdata: string;\n\t\t\t}>({\n\t\t\t\twsUrl: this.config.websocketUrl,\n\t\t\t\tenableHeartbeatMonitoring: true,\n\t\t\t\tsubscriptionId: this.getCachedString(\n\t\t\t\t\t`${this.config.websocketUrl}_dlob_liquidity_${marketId.key}`,\n\t\t\t\t\t'subscription'\n\t\t\t\t),\n\t\t\t\tsubscribeMessage: JSON.stringify(\n\t\t\t\t\tDLOB_SERVER_WEBSOCKET_UTILS.getSubscriptionProps({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tunsubscribeMessage: JSON.stringify(\n\t\t\t\t\tDLOB_SERVER_WEBSOCKET_UTILS.getUnsubscriptionProps({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tonMessage: (message: { channel: string; data: string }) => {\n\t\t\t\t\tthis.rawMessages$.next({\n\t\t\t\t\t\tmarketId,\n\t\t\t\t\t\tchannel: message.channel,\n\t\t\t\t\t\tdata: message.data,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tmessageFilter: (message: { channel: string; data: string }) => {\n\t\t\t\t\treturn DLOB_SERVER_WEBSOCKET_UTILS.getMessageFilter({\n\t\t\t\t\t\ttype: channel,\n\t\t\t\t\t\tmarket: marketId,\n\t\t\t\t\t\tgrouping,\n\t\t\t\t\t})(message);\n\t\t\t\t},\n\t\t\t\tonError: (error?: any) => {\n\t\t\t\t\tconsole.error('Caught error in createSubscription', error);\n\t\t\t\t\tthis.config.onFallback?.(marketId);\n\t\t\t\t},\n\t\t\t\terrorMessageFilter: (message?: any) => {\n\t\t\t\t\tif (message?.error) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.subscriptions.set(subscriptionKey, { unsubscribe });\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to create subscription:', error);\n\t\t\tthis.config.onFallback?.(marketId);\n\t\t}\n\t}\n\n\tprivate processRawMessage(\n\t\tmarketId: MarketId,\n\t\tchannel: string,\n\t\tdata: string\n\t): ProcessedMarketData | null {\n\t\ttry {\n\t\t\tconst parsed = this.tryParse(data) as RawL2Output;\n\t\t\tconst resultKey = this.getCachedString(\n\t\t\t\t`${channel}_${marketId.key}`,\n\t\t\t\t'result'\n\t\t\t);\n\t\t\tconst messageTimestamp = Date.now(); // Capture when we received this message\n\n\t\t\tconst validResult = this.resultIncrementer.handleResult(\n\t\t\t\tresultKey,\n\t\t\t\tparsed.slot ?? 0,\n\t\t\t\tmessageTimestamp\n\t\t\t);\n\n\t\t\tif (!validResult) {\n\t\t\t\treturn null; // Skip results which aren't slot-increasing or are filtered due to tab return\n\t\t\t}\n\n\t\t\tconst deserializedData = deserializeL2Response(parsed);\n\n\t\t\treturn {\n\t\t\t\tmarketId,\n\t\t\t\trawData: parsed,\n\t\t\t\tdeserializedData,\n\t\t\t\tslot: parsed.slot ?? 0,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate tryParse(data: unknown): unknown {\n\t\ttry {\n\t\t\treturn JSON.parse(data as string, (key, value) => {\n\t\t\t\t// If the value is a number and it's too large to be safely represented as a JavaScript number,\n\t\t\t\t// convert it to a string to prevent precision loss\n\t\t\t\tif (typeof value === 'number' && !Number.isSafeInteger(value)) {\n\t\t\t\t\treturn value.toString();\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t} catch (e) {\n\t\t\treturn data;\n\t\t}\n\t}\n\n\tprivate getSubscriptionKey(subscription: MarketSubscription): string {\n\t\tconst { marketId, channel, grouping } = subscription;\n\t\tconst baseKey = `${marketId.key}_${channel}${\n\t\t\tgrouping ? `_${grouping}` : ''\n\t\t}`;\n\t\treturn this.getCachedString(baseKey, 'subscription_key');\n\t}\n}\n\nexport default DlobWebsocketClient;\n"]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { BN, BigNum, DriftClient, IWalletV2, MarketType, OptionalOrderParams, OrderType, PositionDirection, PublicKey, SpotMarketConfig, User, UserAccount } from '@drift-labs/sdk';
|
|
4
4
|
import { AccountInfo, Connection, ParsedAccountData } from '@solana/web3.js';
|
|
5
5
|
import { AuctionParams, TradeOffsetPrice } from 'src/types';
|
|
6
|
+
export declare const abbreviateAddress: (address: string | PublicKey, length?: number) => string;
|
|
6
7
|
declare function chunks<T>(array: T[], size: number): T[][];
|
|
7
8
|
export declare const COMMON_UI_UTILS: {
|
|
8
9
|
getOrderLabelFromOrderDetails: (orderDetails: Pick<import("..").UISerializableOrder, "orderType" | "direction" | "triggerCondition" | "oraclePriceOffset" | "existingPositionDirection">) => string;
|
|
@@ -93,6 +94,8 @@ export declare const COMMON_UI_UTILS: {
|
|
|
93
94
|
getMarketStepSize: (driftClient: DriftClient, marketId: import("src/types").MarketId) => BN;
|
|
94
95
|
getMarketStepSizeDecimals: (driftClient: DriftClient, marketId: import("src/types").MarketId) => number;
|
|
95
96
|
isEntirePositionOrder: (orderAmount: BigNum) => boolean;
|
|
97
|
+
getMaxLeverageOrderSize: (orderAmount: BigNum) => BigNum;
|
|
98
|
+
formatOrderSize: (orderAmount: BigNum, formatFn?: (amount: BigNum) => string) => string;
|
|
96
99
|
getMarginUsedForPosition: (user: User, marketIndex: number, includeOpenOrders?: boolean) => any;
|
|
97
100
|
validateLeverageChange: ({ user, marketIndex, newLeverage, }: {
|
|
98
101
|
user: User;
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.COMMON_UI_UTILS = void 0;
|
|
29
|
+
exports.COMMON_UI_UTILS = exports.abbreviateAddress = void 0;
|
|
30
30
|
const sdk_1 = require("@drift-labs/sdk");
|
|
31
31
|
const utils_1 = require("../utils");
|
|
32
32
|
const web3_js_1 = require("@solana/web3.js");
|
|
@@ -51,7 +51,7 @@ function getCachedUiString(pattern, ...values) {
|
|
|
51
51
|
switch (pattern) {
|
|
52
52
|
case 'abbreviate': {
|
|
53
53
|
const [authString, length] = values;
|
|
54
|
-
result = `${authString.slice(0, length)}
|
|
54
|
+
result = `${authString.slice(0, length)}\u2026${authString.slice(-length)}`;
|
|
55
55
|
break;
|
|
56
56
|
}
|
|
57
57
|
case 'userKey': {
|
|
@@ -82,6 +82,7 @@ const abbreviateAddress = (address, length = 4) => {
|
|
|
82
82
|
const authString = address.toString();
|
|
83
83
|
return getCachedUiString('abbreviate', authString, length);
|
|
84
84
|
};
|
|
85
|
+
exports.abbreviateAddress = abbreviateAddress;
|
|
85
86
|
/**
|
|
86
87
|
* Get a unique key for an authority's subaccount
|
|
87
88
|
* @param userId
|
|
@@ -609,7 +610,7 @@ const formatTokenInputCurried = (setAmount, spotMarketConfig) => (newAmount) =>
|
|
|
609
610
|
};
|
|
610
611
|
// --- Export The Utils
|
|
611
612
|
exports.COMMON_UI_UTILS = {
|
|
612
|
-
abbreviateAddress,
|
|
613
|
+
abbreviateAddress: exports.abbreviateAddress,
|
|
613
614
|
calculateAverageEntryPrice,
|
|
614
615
|
chunks,
|
|
615
616
|
compareSignatures,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commonUiUtils.js","sourceRoot":"","sources":["../../src/common-ui-utils/commonUiUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION_EXP,\n\tAMM_TO_QUOTE_PRECISION_RATIO,\n\tBASE_PRECISION_EXP,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tIWalletV2,\n\tMarketType,\n\tOptionalOrderParams,\n\tOrderType,\n\tPRICE_PRECISION,\n\tPRICE_PRECISION_EXP,\n\tPositionDirection,\n\tPublicKey,\n\tQUOTE_PRECISION_EXP,\n\tSpotMarketConfig,\n\tUser,\n\tUserAccount,\n\tZERO,\n\tderiveOracleAuctionParams,\n\tgetMarketOrderParams,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { ENUM_UTILS, sleep } from '../utils';\nimport {\n\tAccountInfo,\n\tConnection,\n\tKeypair,\n\tParsedAccountData,\n} from '@solana/web3.js';\nimport bcrypt from 'bcryptjs-react';\nimport nacl, { sign } from 'tweetnacl';\nimport { getAssociatedTokenAddress } from '@solana/spl-token';\nimport { AuctionParams, TradeOffsetPrice } from 'src/types';\nimport { USER_UTILS } from './user';\nimport { TRADING_UTILS } from './trading';\nimport { MARKET_UTILS } from './market';\nimport { ORDER_COMMON_UTILS } from './order';\nimport { EMPTY_AUCTION_PARAMS } from '../constants/trade';\n\n// Cache for common UI string patterns to reduce memory allocation\nconst uiStringCache = new Map<string, string>();\nconst MAX_UI_STRING_CACHE_SIZE = 2000;\n\n// Helper function to cache common string patterns\nfunction getCachedUiString(\n\tpattern: string,\n\t...values: (string | number)[]\n): string {\n\tconst cacheKey = `${pattern}:${values.join(':')}`;\n\n\tif (uiStringCache.has(cacheKey)) {\n\t\treturn uiStringCache.get(cacheKey)!;\n\t}\n\n\tlet result: string;\n\tswitch (pattern) {\n\t\tcase 'abbreviate': {\n\t\t\tconst [authString, length] = values as [string, number];\n\t\t\tresult = `${authString.slice(0, length)}...${authString.slice(-length)}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'userKey': {\n\t\t\tconst [userId, authority] = values as [number, string];\n\t\t\tresult = `${userId}_${authority}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'marketKey': {\n\t\t\tconst [marketType, marketIndex] = values as [string, number];\n\t\t\tresult = `${marketType}_${marketIndex}`;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tresult = values.join('_');\n\t}\n\n\t// Cache if not too large\n\tif (uiStringCache.size < MAX_UI_STRING_CACHE_SIZE) {\n\t\tuiStringCache.set(cacheKey, result);\n\t}\n\n\treturn result;\n}\n\n// When creating an account, try 5 times over 5 seconds to wait for the new account to hit the blockchain.\nconst ACCOUNT_INITIALIZATION_RETRY_DELAY_MS = 1000;\nconst ACCOUNT_INITIALIZATION_RETRY_ATTEMPTS = 5;\n\nconst abbreviateAddress = (address: string | PublicKey, length = 4) => {\n\tif (!address) return '';\n\tconst authString = address.toString();\n\treturn getCachedUiString('abbreviate', authString, length);\n};\n\n/**\n * Get a unique key for an authority's subaccount\n * @param userId\n * @param authority\n * @returns\n */\nconst getUserKey = (userId: number, authority: PublicKey) => {\n\tif (userId == undefined || !authority) return '';\n\treturn getCachedUiString('userKey', userId, authority.toString());\n};\n\n/**\n * Get the authority and subAccountId from a user's account key\n * @param key\n * @returns\n */\nconst getIdAndAuthorityFromKey = (\n\tkey: string\n):\n\t| { userId: number; userAuthority: PublicKey }\n\t| { userId: undefined; userAuthority: undefined } => {\n\tconst splitKey = key?.split('_');\n\n\tif (!splitKey || splitKey.length !== 2)\n\t\treturn { userId: undefined, userAuthority: undefined };\n\n\treturn {\n\t\tuserId: Number(splitKey[0]),\n\t\tuserAuthority: new PublicKey(splitKey[1]),\n\t};\n};\n\nconst fetchCurrentSubaccounts = (driftClient: DriftClient): UserAccount[] => {\n\treturn driftClient.getUsers().map((user) => user.getUserAccount());\n};\n\nconst fetchUserClientsAndAccounts = (\n\tdriftClient: DriftClient\n): { user: User; userAccount: UserAccount }[] => {\n\tconst accounts = fetchCurrentSubaccounts(driftClient);\n\tconst allUsersAndUserAccounts = accounts.map((acct) => {\n\t\treturn {\n\t\t\tuser: driftClient.getUser(acct.subAccountId, acct.authority),\n\t\t\tuserAccount: acct,\n\t\t};\n\t});\n\n\treturn allUsersAndUserAccounts;\n};\n\nconst awaitAccountInitializationChainState = async (\n\tdriftClient: DriftClient,\n\tuserId: number,\n\tauthority: PublicKey\n) => {\n\tconst user = driftClient.getUser(userId, authority);\n\n\tif (!user.isSubscribed) {\n\t\tawait user.subscribe();\n\t}\n\n\tlet retryCount = 0;\n\n\tdo {\n\t\ttry {\n\t\t\tawait updateUserAccount(user);\n\t\t\tif (user?.getUserAccountAndSlot()?.data !== undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tretryCount++;\n\t\t\tawait sleep(ACCOUNT_INITIALIZATION_RETRY_DELAY_MS);\n\t\t}\n\t} while (retryCount < ACCOUNT_INITIALIZATION_RETRY_ATTEMPTS);\n\n\tthrow new Error('awaitAccountInitializationFailed');\n};\n\n/**\n * Using your own callback to do the account initialization, this method will run the initialization step, switch to the drift user, await for the account to be available on chain, subscribe to the user account, and switch to the user account using the drift client.\n *\n * It provides extra callbacks to handle steps directly after the initialiation tx, and after fully initializing+subscribing to the account.\n *\n * Callbacks available:\n * - initializationStep: This callback should send the transaction to initialize the user account\n * - postInitializationStep: This callback will run after the successful initialization transaction, but before trying to load/subscribe to the new account\n * - handleSuccessStep: This callback will run after everything has initialized+subscribed successfully\n *\n * // TODO : Need to do the subscription step\n */\nconst initializeAndSubscribeToNewUserAccount = async (\n\tdriftClient: DriftClient,\n\tuserIdToInit: number,\n\tauthority: PublicKey,\n\tcallbacks: {\n\t\tinitializationStep: () => Promise<boolean>;\n\t\tpostInitializationStep?: () => Promise<boolean>;\n\t\thandleSuccessStep?: (accountAlreadyExisted: boolean) => Promise<boolean>;\n\t}\n): Promise<\n\t| 'ok'\n\t| 'failed_initializationStep'\n\t| 'failed_postInitializationStep'\n\t| 'failed_awaitAccountInitializationChainState'\n\t| 'failed_handleSuccessStep'\n> => {\n\tawait driftClient.addUser(userIdToInit, authority);\n\n\tconst accountAlreadyExisted = await driftClient\n\t\t.getUser(userIdToInit)\n\t\t?.exists();\n\n\t// Do the account initialization step\n\tlet result = await callbacks.initializationStep();\n\n\t// Fetch account to make sure it's loaded\n\tawait updateUserAccount(driftClient.getUser(userIdToInit));\n\n\tif (!result) {\n\t\treturn 'failed_initializationStep';\n\t}\n\n\t// Do the post-initialization step\n\tresult = callbacks.postInitializationStep\n\t\t? await callbacks.postInitializationStep()\n\t\t: result;\n\n\tif (!result) {\n\t\treturn 'failed_postInitializationStep';\n\t}\n\n\t// Await the account initialization step to update the blockchain\n\tresult = await awaitAccountInitializationChainState(\n\t\tdriftClient,\n\t\tuserIdToInit,\n\t\tauthority\n\t);\n\n\tif (!result) {\n\t\treturn 'failed_awaitAccountInitializationChainState';\n\t}\n\n\tawait driftClient.switchActiveUser(userIdToInit, authority);\n\n\t// Do the subscription step\n\n\t// Run the success handler\n\tresult = callbacks.handleSuccessStep\n\t\t? await callbacks.handleSuccessStep(accountAlreadyExisted)\n\t\t: result;\n\n\tif (!result) {\n\t\treturn 'failed_handleSuccessStep';\n\t}\n\n\treturn 'ok';\n};\n\nasync function updateUserAccount(user: User): Promise<void> {\n\tconst publicKey = user.userAccountPublicKey;\n\ttry {\n\t\tconst dataAndContext =\n\t\t\tawait user.driftClient.program.account.user.fetchAndContext(\n\t\t\t\tpublicKey,\n\t\t\t\t'processed'\n\t\t\t);\n\t\tuser.accountSubscriber.updateData(\n\t\t\tdataAndContext.data as UserAccount,\n\t\t\tdataAndContext.context.slot\n\t\t);\n\t} catch (e) {\n\t\t// noop\n\t}\n}\n\nconst getMarketKey = (marketIndex: number, marketType: MarketType) =>\n\tgetCachedUiString('marketKey', ENUM_UTILS.toStr(marketType), marketIndex);\n\n/**\n * Creates an IWallet wrapper, with redundant methods. If a `walletPubKey` is passed in,\n * the `publicKey` will be based on that.\n */\nconst createPlaceholderIWallet = (walletPubKey?: PublicKey) => {\n\tconst newKeypair = walletPubKey\n\t\t? new Keypair({\n\t\t\t\tpublicKey: walletPubKey.toBytes(),\n\t\t\t\tsecretKey: new Keypair().publicKey.toBytes(),\n\t\t })\n\t\t: new Keypair();\n\n\tconst newWallet: IWalletV2 = {\n\t\tpublicKey: newKeypair.publicKey,\n\t\t//@ts-ignore\n\t\tsignTransaction: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t\t//@ts-ignore\n\t\tsignAllTransactions: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t\t//@ts-ignore\n\t\tsignMessage: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t};\n\n\treturn newWallet;\n};\n\nconst getSignatureVerificationMessageForSettings = (\n\tauthority: PublicKey,\n\tsignTs: number\n): Uint8Array => {\n\treturn new TextEncoder().encode(\n\t\t`Verify you are the owner of this wallet to update trade settings: \\n${authority.toBase58()}\\n\\nThis signature will be valid for the next 30 minutes.\\n\\nTS: ${signTs.toString()}`\n\t);\n};\n\nconst verifySignature = (\n\tsignature: Uint8Array,\n\tmessage: Uint8Array,\n\tpubKey: PublicKey\n): boolean => {\n\treturn sign.detached.verify(message, signature, pubKey.toBytes());\n};\n\nconst hashSignature = async (signature: string): Promise<string> => {\n\tbcrypt.setRandomFallback((num: number) => {\n\t\treturn Array.from(nacl.randomBytes(num));\n\t});\n\tconst hashedSignature = await bcrypt.hash(signature, bcrypt.genSaltSync(10));\n\treturn hashedSignature;\n};\n\nconst compareSignatures = async (\n\toriginal: string,\n\thashed: string\n): Promise<boolean> => {\n\tconst signaturesMatch = await bcrypt.compare(original, hashed);\n\treturn signaturesMatch;\n};\n\n/* Trading-related helper functions */\n\nconst calculateAverageEntryPrice = (\n\tquoteAssetAmount: BigNum,\n\tbaseAssetAmount: BigNum\n): BigNum => {\n\tif (baseAssetAmount.eqZero()) return BigNum.zero();\n\n\treturn BigNum.from(\n\t\tquoteAssetAmount.val\n\t\t\t.mul(PRICE_PRECISION)\n\t\t\t.mul(AMM_TO_QUOTE_PRECISION_RATIO)\n\t\t\t.div(baseAssetAmount.shiftTo(BASE_PRECISION_EXP).val)\n\t\t\t.abs(),\n\t\tPRICE_PRECISION_EXP\n\t);\n};\n\nconst getMarketOrderLimitPrice = ({\n\tdirection,\n\tbaselinePrice,\n\tslippageTolerance,\n}: {\n\tdirection: PositionDirection;\n\tbaselinePrice: BN;\n\tslippageTolerance: number;\n}): BN => {\n\tlet limitPrice;\n\n\tif (!baselinePrice) return ZERO;\n\n\tif (slippageTolerance === 0) return baselinePrice;\n\n\t// infinite slippage capped at 15% currently\n\tif (slippageTolerance == undefined) slippageTolerance = 15;\n\n\t// if manually entered, cap at 99%\n\tif (slippageTolerance > 99) slippageTolerance = 99;\n\n\tlet limitPricePctDiff;\n\tif (isVariant(direction, 'long')) {\n\t\tlimitPricePctDiff = PRICE_PRECISION.add(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t} else {\n\t\tlimitPricePctDiff = PRICE_PRECISION.sub(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t}\n\n\treturn limitPrice;\n};\n\nconst getMarketAuctionParams = ({\n\tdirection,\n\tstartPriceFromSettings,\n\tendPriceFromSettings,\n\tlimitPrice,\n\tduration,\n\tauctionStartPriceOffset,\n\tauctionEndPriceOffset,\n\tadditionalEndPriceBuffer,\n\tforceUpToSlippage,\n\tbestBidPrice,\n\tbestAskPrice,\n\tensureCrossingEndPrice,\n}: {\n\tdirection: PositionDirection;\n\tstartPriceFromSettings: BN;\n\tendPriceFromSettings: BN;\n\t/**\n\t * Limit price is the oracle limit price - market orders use the oracle order type under the hood on Drift UI\n\t * So oracle limit price is the oracle price + oracle offset\n\t */\n\tlimitPrice: BN;\n\tduration: number;\n\tauctionStartPriceOffset: number;\n\tauctionEndPriceOffset: number;\n\tadditionalEndPriceBuffer?: BN;\n\tforceUpToSlippage?: boolean;\n\tbestBidPrice?: BN;\n\tbestAskPrice?: BN;\n\tensureCrossingEndPrice?: boolean;\n}): AuctionParams => {\n\tlet auctionStartPrice: BN;\n\tlet auctionEndPrice: BN;\n\tlet constrainedBySlippage: boolean;\n\n\tconst auctionEndPriceBuffer = BigNum.from(PRICE_PRECISION).scale(\n\t\tMath.abs(auctionEndPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tconst auctionStartPriceBuffer = BigNum.from(startPriceFromSettings).scale(\n\t\tMath.abs(auctionStartPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tif (isVariant(direction, 'long')) {\n\t\tauctionStartPrice = startPriceFromSettings.sub(auctionStartPriceBuffer);\n\n\t\tconst worstPriceToUse = BN.max(\n\t\t\tendPriceFromSettings,\n\t\t\tstartPriceFromSettings\n\t\t); // Handles edge cases like if the worst price on the book was better than the oracle price, and the settings are asking to be relative to the oracle price\n\n\t\tauctionEndPrice = PRICE_PRECISION.add(auctionEndPriceBuffer)\n\t\t\t.mul(worstPriceToUse)\n\t\t\t.div(PRICE_PRECISION);\n\n\t\tconstrainedBySlippage = limitPrice.lt(auctionEndPrice);\n\n\t\t// if forceUpToSlippage is passed, use max slippage price as end price\n\t\tif (forceUpToSlippage) {\n\t\t\tauctionEndPrice = limitPrice;\n\t\t\tconstrainedBySlippage = false;\n\t\t} else {\n\t\t\t// use BEST (limit price, auction end price) as end price\n\t\t\tauctionEndPrice = BN.min(limitPrice, auctionEndPrice);\n\t\t}\n\n\t\t// apply additional buffer if provided\n\t\tif (additionalEndPriceBuffer) {\n\t\t\tauctionEndPrice = auctionEndPrice.add(additionalEndPriceBuffer);\n\t\t\tconstrainedBySlippage = limitPrice.lt(auctionEndPrice);\n\t\t}\n\n\t\t// if ensureCrossingEndPrice is passed, ensure auction end price crosses bestAskPrice\n\t\tif (ensureCrossingEndPrice && bestAskPrice) {\n\t\t\tauctionEndPrice = BN.max(\n\t\t\t\tauctionEndPrice,\n\t\t\t\tbestAskPrice.add(auctionEndPriceBuffer)\n\t\t\t);\n\t\t}\n\n\t\tauctionStartPrice = BN.min(auctionStartPrice, auctionEndPrice);\n\t} else {\n\t\tauctionStartPrice = startPriceFromSettings.add(auctionStartPriceBuffer);\n\n\t\tconst worstPriceToUse = BN.min(\n\t\t\tendPriceFromSettings,\n\t\t\tstartPriceFromSettings\n\t\t); // Handles edge cases like if the worst price on the book was better than the oracle price, and the settings are asking to be relative to the oracle price\n\n\t\tauctionEndPrice = PRICE_PRECISION.sub(auctionEndPriceBuffer)\n\t\t\t.mul(worstPriceToUse)\n\t\t\t.div(PRICE_PRECISION);\n\n\t\tconstrainedBySlippage = limitPrice.gt(auctionEndPrice);\n\n\t\t// if forceUpToSlippage is passed, use max slippage price as end price\n\t\tif (forceUpToSlippage) {\n\t\t\tauctionEndPrice = limitPrice;\n\t\t\tconstrainedBySlippage = false;\n\t\t} else {\n\t\t\t// use BEST (limit price, auction end price) as end price\n\t\t\tauctionEndPrice = BN.max(limitPrice, auctionEndPrice);\n\t\t}\n\n\t\t// apply additional buffer if provided\n\t\tif (additionalEndPriceBuffer) {\n\t\t\tauctionEndPrice = auctionEndPrice.sub(additionalEndPriceBuffer);\n\t\t\tconstrainedBySlippage = limitPrice.gt(auctionEndPrice);\n\t\t}\n\n\t\t// if ensureCrossingEndPrice is passed, ensure auction end price crosses bestBidPrice\n\t\tif (ensureCrossingEndPrice && bestBidPrice) {\n\t\t\tauctionEndPrice = BN.min(\n\t\t\t\tauctionEndPrice,\n\t\t\t\tbestBidPrice.sub(auctionEndPriceBuffer)\n\t\t\t);\n\t\t}\n\n\t\tauctionStartPrice = BN.max(auctionStartPrice, auctionEndPrice);\n\t}\n\n\treturn {\n\t\tauctionStartPrice,\n\t\tauctionEndPrice,\n\t\tauctionDuration: duration,\n\t\tconstrainedBySlippage,\n\t};\n};\n\n/**\n * Helper function which derived market order params from the CORE data that is used to create them.\n * @param param0\n * @returns\n */\nconst deriveMarketOrderParams = ({\n\tmarketType,\n\tmarketIndex,\n\tdirection,\n\tmaxLeverageSelected,\n\tmaxLeverageOrderSize,\n\tbaseAmount,\n\treduceOnly,\n\tallowInfSlippage,\n\toraclePrice,\n\tbestPrice,\n\tentryPrice,\n\tworstPrice,\n\tmarkPrice,\n\tauctionDuration,\n\tauctionStartPriceOffset,\n\tauctionEndPriceOffset,\n\tauctionStartPriceOffsetFrom,\n\tauctionEndPriceOffsetFrom,\n\tauctionPriceCaps,\n\tslippageTolerance,\n\tisOracleOrder,\n\tadditionalEndPriceBuffer,\n\tforceUpToSlippage,\n\tbestBidPrice,\n\tbestAskPrice,\n\tensureCrossingEndPrice,\n}: {\n\tmarketType: MarketType;\n\tmarketIndex: number;\n\tdirection: PositionDirection;\n\tmaxLeverageSelected: boolean;\n\tmaxLeverageOrderSize: BN;\n\tbaseAmount: BN;\n\treduceOnly: boolean;\n\tallowInfSlippage: boolean;\n\toraclePrice: BN;\n\tbestPrice: BN;\n\tentryPrice: BN;\n\tworstPrice: BN;\n\tmarkPrice: BN;\n\tauctionDuration: number;\n\tauctionStartPriceOffset: number;\n\tauctionEndPriceOffset: number;\n\tauctionPriceCaps?: {\n\t\tmin: BN;\n\t\tmax: BN;\n\t};\n\tauctionStartPriceOffsetFrom: TradeOffsetPrice;\n\tauctionEndPriceOffsetFrom: TradeOffsetPrice;\n\tslippageTolerance: number;\n\tisOracleOrder?: boolean;\n\tadditionalEndPriceBuffer?: BN;\n\tforceUpToSlippage?: boolean;\n\tbestBidPrice?: BN;\n\tbestAskPrice?: BN;\n\tensureCrossingEndPrice?: boolean;\n}): OptionalOrderParams & { constrainedBySlippage?: boolean } => {\n\tconst priceObject = getPriceObject({\n\t\toraclePrice,\n\t\tmarkPrice,\n\t\tbestOffer: bestPrice,\n\t\tentryPrice,\n\t\tworstPrice,\n\t\tdirection,\n\t});\n\n\t// max slippage price\n\tlet limitPrice = getMarketOrderLimitPrice({\n\t\tdirection,\n\t\tbaselinePrice: priceObject[auctionStartPriceOffsetFrom],\n\t\tslippageTolerance: allowInfSlippage ? undefined : slippageTolerance,\n\t});\n\n\tif (additionalEndPriceBuffer) {\n\t\tlimitPrice = isVariant(direction, 'long')\n\t\t\t? limitPrice.add(additionalEndPriceBuffer)\n\t\t\t: limitPrice.sub(additionalEndPriceBuffer);\n\t}\n\n\tconst auctionParams = getMarketAuctionParams({\n\t\tdirection,\n\t\tstartPriceFromSettings: priceObject[auctionStartPriceOffsetFrom],\n\t\tendPriceFromSettings: priceObject[auctionEndPriceOffsetFrom],\n\t\tlimitPrice,\n\t\tduration: auctionDuration,\n\t\tauctionStartPriceOffset: auctionStartPriceOffset,\n\t\tauctionEndPriceOffset: auctionEndPriceOffset,\n\t\tadditionalEndPriceBuffer,\n\t\tforceUpToSlippage,\n\t\tbestBidPrice,\n\t\tbestAskPrice,\n\t\tensureCrossingEndPrice,\n\t});\n\n\tlet orderParams = getMarketOrderParams({\n\t\tmarketType,\n\t\tmarketIndex,\n\t\tdirection,\n\t\tbaseAssetAmount: maxLeverageSelected ? maxLeverageOrderSize : baseAmount,\n\t\treduceOnly,\n\t\tprice: allowInfSlippage ? undefined : limitPrice,\n\t\t...auctionParams,\n\t});\n\n\tif (isOracleOrder) {\n\t\t// wont work if oracle is zero\n\t\tif (!oraclePrice.eq(ZERO)) {\n\t\t\tconst oracleAuctionParams = deriveOracleAuctionParams({\n\t\t\t\tdirection: direction,\n\t\t\t\toraclePrice,\n\t\t\t\tauctionStartPrice: auctionParams.auctionStartPrice,\n\t\t\t\tauctionEndPrice: auctionParams.auctionEndPrice,\n\t\t\t\tlimitPrice: auctionParams.auctionEndPrice,\n\t\t\t\tauctionPriceCaps: auctionPriceCaps,\n\t\t\t});\n\n\t\t\torderParams = {\n\t\t\t\t...orderParams,\n\t\t\t\t...oracleAuctionParams,\n\t\t\t\tprice: undefined,\n\t\t\t\torderType: OrderType.ORACLE,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn orderParams;\n};\n\nconst getLimitAuctionParams = ({\n\tdirection,\n\tinputPrice,\n\tstartPriceFromSettings,\n\tduration,\n\tauctionStartPriceOffset,\n\toraclePriceBands,\n}: {\n\tdirection: PositionDirection;\n\tinputPrice: BigNum;\n\tstartPriceFromSettings: BN;\n\tduration: number;\n\tauctionStartPriceOffset: number;\n\toraclePriceBands?: [BN, BN];\n}): AuctionParams => {\n\tlet limitAuctionParams = EMPTY_AUCTION_PARAMS;\n\n\tconst auctionStartPriceBuffer = inputPrice.scale(\n\t\tMath.abs(auctionStartPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tif (\n\t\tisVariant(direction, 'long') &&\n\t\tstartPriceFromSettings &&\n\t\tstartPriceFromSettings.lt(inputPrice.val) &&\n\t\tstartPriceFromSettings.gt(ZERO)\n\t) {\n\t\tlimitAuctionParams = {\n\t\t\tauctionStartPrice: startPriceFromSettings.sub(auctionStartPriceBuffer),\n\t\t\tauctionEndPrice: inputPrice.val,\n\t\t\tauctionDuration: duration,\n\t\t};\n\t} else if (\n\t\tisVariant(direction, 'short') &&\n\t\tstartPriceFromSettings &&\n\t\tstartPriceFromSettings.gt(ZERO) &&\n\t\tstartPriceFromSettings.gt(inputPrice.val)\n\t) {\n\t\tlimitAuctionParams = {\n\t\t\tauctionStartPrice: startPriceFromSettings.add(auctionStartPriceBuffer),\n\t\t\tauctionEndPrice: inputPrice.val,\n\t\t\tauctionDuration: duration,\n\t\t};\n\t}\n\n\tif (oraclePriceBands && limitAuctionParams.auctionDuration) {\n\t\tconst [minPrice, maxPrice] = oraclePriceBands;\n\n\t\t// start and end price cant be outside of the oracle price bands\n\t\tlimitAuctionParams.auctionStartPrice = BN.max(\n\t\t\tBN.min(limitAuctionParams.auctionStartPrice, maxPrice),\n\t\t\tminPrice\n\t\t);\n\n\t\tlimitAuctionParams.auctionEndPrice = BN.max(\n\t\t\tBN.min(limitAuctionParams.auctionEndPrice, maxPrice),\n\t\t\tminPrice\n\t\t);\n\t}\n\n\treturn limitAuctionParams;\n};\n\nconst getPriceObject = ({\n\toraclePrice,\n\tbestOffer,\n\tentryPrice,\n\tworstPrice,\n\tmarkPrice,\n\tdirection,\n}: {\n\toraclePrice: BN;\n\tbestOffer: BN;\n\tentryPrice: BN;\n\tworstPrice: BN;\n\tmarkPrice: BN;\n\tdirection: PositionDirection;\n}) => {\n\tlet best: BN;\n\n\tconst nonZeroOptions = [oraclePrice, bestOffer, markPrice].filter(\n\t\t(price) => price !== undefined && price?.gt(ZERO)\n\t);\n\n\tif (nonZeroOptions.length === 0) {\n\t\t// console.error('Unable to create valid auction params');\n\t\treturn {\n\t\t\toracle: ZERO,\n\t\t\tbestOffer: ZERO,\n\t\t\tentry: ZERO,\n\t\t\tbest: ZERO,\n\t\t\tworst: ZERO,\n\t\t\tmark: ZERO,\n\t\t};\n\t}\n\n\tif (isVariant(direction, 'long')) {\n\t\tbest = nonZeroOptions.reduce((a, b) => (a.lt(b) ? a : b)); // lowest price\n\t} else {\n\t\tbest = nonZeroOptions.reduce((a, b) => (a.gt(b) ? a : b)); // highest price\n\t}\n\n\t// if zero values come through, fallback to nonzero value\n\treturn {\n\t\toracle: oraclePrice?.gt(ZERO) ? oraclePrice : best,\n\t\tbestOffer: bestOffer?.gt(ZERO) ? bestOffer : best,\n\t\tentry: entryPrice,\n\t\tbest,\n\t\tworst: worstPrice,\n\t\tmark: markPrice?.gt(ZERO) ? markPrice : best,\n\t};\n};\n\n/* LP Utils */\nconst getLpSharesAmountForQuote = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tquoteAmount: BN\n): BigNum => {\n\tconst tenMillionBigNum = BigNum.fromPrint('10000000', QUOTE_PRECISION_EXP);\n\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t);\n\n\treturn BigNum.from(quoteAmount, QUOTE_PRECISION_EXP)\n\t\t.scale(\n\t\t\ttenMillionBigNum.toNum(),\n\t\t\tpricePerLpShare.mul(tenMillionBigNum).toNum()\n\t\t)\n\t\t.shiftTo(AMM_RESERVE_PRECISION_EXP);\n};\n\nconst getQuoteValueForLpShares = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tsharesAmount: BN\n): BigNum => {\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t).shiftTo(AMM_RESERVE_PRECISION_EXP);\n\tconst lpSharesBigNum = BigNum.from(sharesAmount, AMM_RESERVE_PRECISION_EXP);\n\treturn lpSharesBigNum.mul(pricePerLpShare).shiftTo(QUOTE_PRECISION_EXP);\n};\n\nconst getTokenAddress = (\n\tmintAddress: PublicKey,\n\tuserPubKey: PublicKey\n): Promise<PublicKey> => {\n\treturn getAssociatedTokenAddress(mintAddress, userPubKey, true);\n};\n\nconst getBalanceFromTokenAccountResult = (account: {\n\tpubkey: PublicKey;\n\taccount: AccountInfo<ParsedAccountData>;\n}) => {\n\treturn account?.account.data?.parsed?.info?.tokenAmount?.uiAmount;\n};\n\nconst getTokenAccount = async (\n\tconnection: Connection,\n\tmintAddress: PublicKey,\n\tuserPubKey: PublicKey\n): Promise<{\n\ttokenAccount: {\n\t\tpubkey: PublicKey;\n\t\taccount: import('@solana/web3.js').AccountInfo<\n\t\t\timport('@solana/web3.js').ParsedAccountData\n\t\t>;\n\t};\n\ttokenAccountWarning: boolean;\n}> => {\n\tconst tokenAccounts = await connection.getParsedTokenAccountsByOwner(\n\t\tuserPubKey,\n\t\t{ mint: mintAddress }\n\t);\n\n\tconst associatedAddress = await getAssociatedTokenAddress(\n\t\tmintAddress,\n\t\tuserPubKey,\n\t\ttrue\n\t);\n\n\tconst targetAccount =\n\t\ttokenAccounts.value.filter((account) =>\n\t\t\taccount.pubkey.equals(associatedAddress)\n\t\t)[0] || tokenAccounts.value[0];\n\n\tconst anotherBalanceExists = tokenAccounts.value.find((account) => {\n\t\treturn (\n\t\t\t!!getBalanceFromTokenAccountResult(account) &&\n\t\t\t!account.pubkey.equals(targetAccount.pubkey)\n\t\t);\n\t});\n\n\tlet tokenAccountWarning = false;\n\n\tif (anotherBalanceExists) {\n\t\ttokenAccountWarning = true;\n\t}\n\n\treturn {\n\t\ttokenAccount: targetAccount,\n\t\ttokenAccountWarning,\n\t};\n};\n\nconst getMultipleAccounts = async (\n\tconnection: any,\n\tkeys: string[],\n\tcommitment: string\n) => {\n\tconst result = await Promise.all(\n\t\tchunks(keys, 99).map((chunk) =>\n\t\t\tgetMultipleAccountsCore(connection, chunk, commitment)\n\t\t)\n\t);\n\n\tconst array = result\n\t\t.map(\n\t\t\t(a) =>\n\t\t\t\ta.array\n\t\t\t\t\t.map((acc) => {\n\t\t\t\t\t\tif (!acc) {\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { data, ...rest } = acc;\n\t\t\t\t\t\tconst obj = {\n\t\t\t\t\t\t\t...rest,\n\t\t\t\t\t\t\tdata: Buffer.from(data[0], 'base64'),\n\t\t\t\t\t\t} as AccountInfo<Buffer>;\n\t\t\t\t\t\treturn obj;\n\t\t\t\t\t})\n\t\t\t\t\t.filter((_) => _) as AccountInfo<Buffer>[]\n\t\t)\n\t\t.flat();\n\treturn { keys, array };\n};\n\nconst getMultipleAccountsCore = async (\n\tconnection: any,\n\tkeys: string[],\n\tcommitment: string\n) => {\n\tconst args = connection._buildArgs([keys], commitment, 'base64');\n\n\tconst unsafeRes = await connection._rpcRequest('getMultipleAccounts', args);\n\tif (unsafeRes.error) {\n\t\tthrow new Error(\n\t\t\t'failed to get info about account ' + unsafeRes.error.message\n\t\t);\n\t}\n\n\tif (unsafeRes.result.value) {\n\t\tconst array = unsafeRes.result.value as AccountInfo<string[]>[];\n\t\treturn { keys, array };\n\t}\n\n\t// TODO: fix\n\tthrow new Error();\n};\n\nconst userExists = async (\n\tdriftClient: DriftClient,\n\tuserId: number,\n\tauthority: PublicKey\n) => {\n\tlet userAccountExists = false;\n\n\ttry {\n\t\tconst user = driftClient.getUser(userId, authority);\n\t\tuserAccountExists = await user.exists();\n\t} catch (e) {\n\t\t// user account does not exist so we leave userAccountExists false\n\t}\n\n\treturn userAccountExists;\n};\n\nfunction chunks<T>(array: T[], size: number): T[][] {\n\treturn Array.apply(0, new Array(Math.ceil(array.length / size))).map(\n\t\t(_, index) => array.slice(index * size, (index + 1) * size)\n\t);\n}\n\n/**\n * Trim trailing zeros from a numerical string\n * @param str - numerical string to format\n * @param zerosToShow - max number of zeros to show after the decimal. Similar to number.toFixed() but won't trim non-zero values. Optional, default value is 1\n */\nconst trimTrailingZeros = (str: string, zerosToShow = 1) => {\n\t// Ignore strings with no decimal point\n\tif (!str.includes('.')) return str;\n\n\tconst sides = str.split('.');\n\n\tsides[1] = sides[1].replace(/0+$/, '');\n\n\tif (sides[1].length < zerosToShow) {\n\t\tconst zerosToAdd = zerosToShow - sides[1].length;\n\t\tsides[1] = `${sides[1]}${Array(zerosToAdd).fill('0').join('')}`;\n\t}\n\n\tif (sides[1].length === 0) {\n\t\treturn sides[0];\n\t} else {\n\t\treturn sides.join('.');\n\t}\n};\n\nconst formatTokenInputCurried =\n\t(setAmount: (amount: string) => void, spotMarketConfig: SpotMarketConfig) =>\n\t(newAmount: string) => {\n\t\tif (isNaN(+newAmount)) return;\n\n\t\tif (newAmount === '') {\n\t\t\tsetAmount('');\n\t\t\treturn;\n\t\t}\n\n\t\tconst lastChar = newAmount[newAmount.length - 1];\n\n\t\t// if last char of string is a decimal point, don't format\n\t\tif (lastChar === '.') {\n\t\t\tsetAmount(newAmount);\n\t\t\treturn;\n\t\t}\n\n\t\tif (lastChar === '0') {\n\t\t\t// if last char of string is a zero in the decimal places, cut it off if it exceeds precision\n\t\t\tconst numOfDigitsAfterDecimal = newAmount.split('.')[1]?.length ?? 0;\n\t\t\tif (numOfDigitsAfterDecimal > spotMarketConfig.precisionExp.toNumber()) {\n\t\t\t\tsetAmount(newAmount.slice(0, -1));\n\t\t\t} else {\n\t\t\t\tsetAmount(newAmount);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst formattedAmount = Number(\n\t\t\t(+newAmount).toFixed(spotMarketConfig.precisionExp.toNumber())\n\t\t);\n\t\tsetAmount(formattedAmount.toString());\n\t};\n\n// --- Export The Utils\n\nexport const COMMON_UI_UTILS = {\n\tabbreviateAddress,\n\tcalculateAverageEntryPrice,\n\tchunks,\n\tcompareSignatures,\n\tcreatePlaceholderIWallet,\n\tderiveMarketOrderParams,\n\tfetchCurrentSubaccounts,\n\tfetchUserClientsAndAccounts,\n\tformatTokenInputCurried,\n\tgetBalanceFromTokenAccountResult,\n\tgetIdAndAuthorityFromKey,\n\tgetLimitAuctionParams,\n\tgetLpSharesAmountForQuote,\n\tgetMarketAuctionParams,\n\tgetMarketKey,\n\tgetMarketOrderLimitPrice,\n\tgetMultipleAccounts,\n\tgetMultipleAccountsCore,\n\tgetPriceObject,\n\tgetQuoteValueForLpShares,\n\tgetSignatureVerificationMessageForSettings,\n\tgetTokenAccount,\n\tgetTokenAddress,\n\tgetUserKey,\n\thashSignature,\n\tinitializeAndSubscribeToNewUserAccount,\n\tuserExists,\n\tverifySignature,\n\ttrimTrailingZeros,\n\t...USER_UTILS,\n\t...TRADING_UTILS,\n\t...MARKET_UTILS,\n\t...ORDER_COMMON_UTILS,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"commonUiUtils.js","sourceRoot":"","sources":["../../src/common-ui-utils/commonUiUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION_EXP,\n\tAMM_TO_QUOTE_PRECISION_RATIO,\n\tBASE_PRECISION_EXP,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tIWalletV2,\n\tMarketType,\n\tOptionalOrderParams,\n\tOrderType,\n\tPRICE_PRECISION,\n\tPRICE_PRECISION_EXP,\n\tPositionDirection,\n\tPublicKey,\n\tQUOTE_PRECISION_EXP,\n\tSpotMarketConfig,\n\tUser,\n\tUserAccount,\n\tZERO,\n\tderiveOracleAuctionParams,\n\tgetMarketOrderParams,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { ENUM_UTILS, sleep } from '../utils';\nimport {\n\tAccountInfo,\n\tConnection,\n\tKeypair,\n\tParsedAccountData,\n} from '@solana/web3.js';\nimport bcrypt from 'bcryptjs-react';\nimport nacl, { sign } from 'tweetnacl';\nimport { getAssociatedTokenAddress } from '@solana/spl-token';\nimport { AuctionParams, TradeOffsetPrice } from 'src/types';\nimport { USER_UTILS } from './user';\nimport { TRADING_UTILS } from './trading';\nimport { MARKET_UTILS } from './market';\nimport { ORDER_COMMON_UTILS } from './order';\nimport { EMPTY_AUCTION_PARAMS } from '../constants/trade';\n\n// Cache for common UI string patterns to reduce memory allocation\nconst uiStringCache = new Map<string, string>();\nconst MAX_UI_STRING_CACHE_SIZE = 2000;\n\n// Helper function to cache common string patterns\nfunction getCachedUiString(\n\tpattern: string,\n\t...values: (string | number)[]\n): string {\n\tconst cacheKey = `${pattern}:${values.join(':')}`;\n\n\tif (uiStringCache.has(cacheKey)) {\n\t\treturn uiStringCache.get(cacheKey)!;\n\t}\n\n\tlet result: string;\n\tswitch (pattern) {\n\t\tcase 'abbreviate': {\n\t\t\tconst [authString, length] = values as [string, number];\n\t\t\tresult = `${authString.slice(0, length)}\\u2026${authString.slice(\n\t\t\t\t-length\n\t\t\t)}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'userKey': {\n\t\t\tconst [userId, authority] = values as [number, string];\n\t\t\tresult = `${userId}_${authority}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'marketKey': {\n\t\t\tconst [marketType, marketIndex] = values as [string, number];\n\t\t\tresult = `${marketType}_${marketIndex}`;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tresult = values.join('_');\n\t}\n\n\t// Cache if not too large\n\tif (uiStringCache.size < MAX_UI_STRING_CACHE_SIZE) {\n\t\tuiStringCache.set(cacheKey, result);\n\t}\n\n\treturn result;\n}\n\n// When creating an account, try 5 times over 5 seconds to wait for the new account to hit the blockchain.\nconst ACCOUNT_INITIALIZATION_RETRY_DELAY_MS = 1000;\nconst ACCOUNT_INITIALIZATION_RETRY_ATTEMPTS = 5;\n\nexport const abbreviateAddress = (address: string | PublicKey, length = 4) => {\n\tif (!address) return '';\n\tconst authString = address.toString();\n\treturn getCachedUiString('abbreviate', authString, length);\n};\n\n/**\n * Get a unique key for an authority's subaccount\n * @param userId\n * @param authority\n * @returns\n */\nconst getUserKey = (userId: number, authority: PublicKey) => {\n\tif (userId == undefined || !authority) return '';\n\treturn getCachedUiString('userKey', userId, authority.toString());\n};\n\n/**\n * Get the authority and subAccountId from a user's account key\n * @param key\n * @returns\n */\nconst getIdAndAuthorityFromKey = (\n\tkey: string\n):\n\t| { userId: number; userAuthority: PublicKey }\n\t| { userId: undefined; userAuthority: undefined } => {\n\tconst splitKey = key?.split('_');\n\n\tif (!splitKey || splitKey.length !== 2)\n\t\treturn { userId: undefined, userAuthority: undefined };\n\n\treturn {\n\t\tuserId: Number(splitKey[0]),\n\t\tuserAuthority: new PublicKey(splitKey[1]),\n\t};\n};\n\nconst fetchCurrentSubaccounts = (driftClient: DriftClient): UserAccount[] => {\n\treturn driftClient.getUsers().map((user) => user.getUserAccount());\n};\n\nconst fetchUserClientsAndAccounts = (\n\tdriftClient: DriftClient\n): { user: User; userAccount: UserAccount }[] => {\n\tconst accounts = fetchCurrentSubaccounts(driftClient);\n\tconst allUsersAndUserAccounts = accounts.map((acct) => {\n\t\treturn {\n\t\t\tuser: driftClient.getUser(acct.subAccountId, acct.authority),\n\t\t\tuserAccount: acct,\n\t\t};\n\t});\n\n\treturn allUsersAndUserAccounts;\n};\n\nconst awaitAccountInitializationChainState = async (\n\tdriftClient: DriftClient,\n\tuserId: number,\n\tauthority: PublicKey\n) => {\n\tconst user = driftClient.getUser(userId, authority);\n\n\tif (!user.isSubscribed) {\n\t\tawait user.subscribe();\n\t}\n\n\tlet retryCount = 0;\n\n\tdo {\n\t\ttry {\n\t\t\tawait updateUserAccount(user);\n\t\t\tif (user?.getUserAccountAndSlot()?.data !== undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tretryCount++;\n\t\t\tawait sleep(ACCOUNT_INITIALIZATION_RETRY_DELAY_MS);\n\t\t}\n\t} while (retryCount < ACCOUNT_INITIALIZATION_RETRY_ATTEMPTS);\n\n\tthrow new Error('awaitAccountInitializationFailed');\n};\n\n/**\n * Using your own callback to do the account initialization, this method will run the initialization step, switch to the drift user, await for the account to be available on chain, subscribe to the user account, and switch to the user account using the drift client.\n *\n * It provides extra callbacks to handle steps directly after the initialiation tx, and after fully initializing+subscribing to the account.\n *\n * Callbacks available:\n * - initializationStep: This callback should send the transaction to initialize the user account\n * - postInitializationStep: This callback will run after the successful initialization transaction, but before trying to load/subscribe to the new account\n * - handleSuccessStep: This callback will run after everything has initialized+subscribed successfully\n *\n * // TODO : Need to do the subscription step\n */\nconst initializeAndSubscribeToNewUserAccount = async (\n\tdriftClient: DriftClient,\n\tuserIdToInit: number,\n\tauthority: PublicKey,\n\tcallbacks: {\n\t\tinitializationStep: () => Promise<boolean>;\n\t\tpostInitializationStep?: () => Promise<boolean>;\n\t\thandleSuccessStep?: (accountAlreadyExisted: boolean) => Promise<boolean>;\n\t}\n): Promise<\n\t| 'ok'\n\t| 'failed_initializationStep'\n\t| 'failed_postInitializationStep'\n\t| 'failed_awaitAccountInitializationChainState'\n\t| 'failed_handleSuccessStep'\n> => {\n\tawait driftClient.addUser(userIdToInit, authority);\n\n\tconst accountAlreadyExisted = await driftClient\n\t\t.getUser(userIdToInit)\n\t\t?.exists();\n\n\t// Do the account initialization step\n\tlet result = await callbacks.initializationStep();\n\n\t// Fetch account to make sure it's loaded\n\tawait updateUserAccount(driftClient.getUser(userIdToInit));\n\n\tif (!result) {\n\t\treturn 'failed_initializationStep';\n\t}\n\n\t// Do the post-initialization step\n\tresult = callbacks.postInitializationStep\n\t\t? await callbacks.postInitializationStep()\n\t\t: result;\n\n\tif (!result) {\n\t\treturn 'failed_postInitializationStep';\n\t}\n\n\t// Await the account initialization step to update the blockchain\n\tresult = await awaitAccountInitializationChainState(\n\t\tdriftClient,\n\t\tuserIdToInit,\n\t\tauthority\n\t);\n\n\tif (!result) {\n\t\treturn 'failed_awaitAccountInitializationChainState';\n\t}\n\n\tawait driftClient.switchActiveUser(userIdToInit, authority);\n\n\t// Do the subscription step\n\n\t// Run the success handler\n\tresult = callbacks.handleSuccessStep\n\t\t? await callbacks.handleSuccessStep(accountAlreadyExisted)\n\t\t: result;\n\n\tif (!result) {\n\t\treturn 'failed_handleSuccessStep';\n\t}\n\n\treturn 'ok';\n};\n\nasync function updateUserAccount(user: User): Promise<void> {\n\tconst publicKey = user.userAccountPublicKey;\n\ttry {\n\t\tconst dataAndContext =\n\t\t\tawait user.driftClient.program.account.user.fetchAndContext(\n\t\t\t\tpublicKey,\n\t\t\t\t'processed'\n\t\t\t);\n\t\tuser.accountSubscriber.updateData(\n\t\t\tdataAndContext.data as UserAccount,\n\t\t\tdataAndContext.context.slot\n\t\t);\n\t} catch (e) {\n\t\t// noop\n\t}\n}\n\nconst getMarketKey = (marketIndex: number, marketType: MarketType) =>\n\tgetCachedUiString('marketKey', ENUM_UTILS.toStr(marketType), marketIndex);\n\n/**\n * Creates an IWallet wrapper, with redundant methods. If a `walletPubKey` is passed in,\n * the `publicKey` will be based on that.\n */\nconst createPlaceholderIWallet = (walletPubKey?: PublicKey) => {\n\tconst newKeypair = walletPubKey\n\t\t? new Keypair({\n\t\t\t\tpublicKey: walletPubKey.toBytes(),\n\t\t\t\tsecretKey: new Keypair().publicKey.toBytes(),\n\t\t })\n\t\t: new Keypair();\n\n\tconst newWallet: IWalletV2 = {\n\t\tpublicKey: newKeypair.publicKey,\n\t\t//@ts-ignore\n\t\tsignTransaction: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t\t//@ts-ignore\n\t\tsignAllTransactions: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t\t//@ts-ignore\n\t\tsignMessage: () => {\n\t\t\treturn Promise.resolve();\n\t\t},\n\t};\n\n\treturn newWallet;\n};\n\nconst getSignatureVerificationMessageForSettings = (\n\tauthority: PublicKey,\n\tsignTs: number\n): Uint8Array => {\n\treturn new TextEncoder().encode(\n\t\t`Verify you are the owner of this wallet to update trade settings: \\n${authority.toBase58()}\\n\\nThis signature will be valid for the next 30 minutes.\\n\\nTS: ${signTs.toString()}`\n\t);\n};\n\nconst verifySignature = (\n\tsignature: Uint8Array,\n\tmessage: Uint8Array,\n\tpubKey: PublicKey\n): boolean => {\n\treturn sign.detached.verify(message, signature, pubKey.toBytes());\n};\n\nconst hashSignature = async (signature: string): Promise<string> => {\n\tbcrypt.setRandomFallback((num: number) => {\n\t\treturn Array.from(nacl.randomBytes(num));\n\t});\n\tconst hashedSignature = await bcrypt.hash(signature, bcrypt.genSaltSync(10));\n\treturn hashedSignature;\n};\n\nconst compareSignatures = async (\n\toriginal: string,\n\thashed: string\n): Promise<boolean> => {\n\tconst signaturesMatch = await bcrypt.compare(original, hashed);\n\treturn signaturesMatch;\n};\n\n/* Trading-related helper functions */\n\nconst calculateAverageEntryPrice = (\n\tquoteAssetAmount: BigNum,\n\tbaseAssetAmount: BigNum\n): BigNum => {\n\tif (baseAssetAmount.eqZero()) return BigNum.zero();\n\n\treturn BigNum.from(\n\t\tquoteAssetAmount.val\n\t\t\t.mul(PRICE_PRECISION)\n\t\t\t.mul(AMM_TO_QUOTE_PRECISION_RATIO)\n\t\t\t.div(baseAssetAmount.shiftTo(BASE_PRECISION_EXP).val)\n\t\t\t.abs(),\n\t\tPRICE_PRECISION_EXP\n\t);\n};\n\nconst getMarketOrderLimitPrice = ({\n\tdirection,\n\tbaselinePrice,\n\tslippageTolerance,\n}: {\n\tdirection: PositionDirection;\n\tbaselinePrice: BN;\n\tslippageTolerance: number;\n}): BN => {\n\tlet limitPrice;\n\n\tif (!baselinePrice) return ZERO;\n\n\tif (slippageTolerance === 0) return baselinePrice;\n\n\t// infinite slippage capped at 15% currently\n\tif (slippageTolerance == undefined) slippageTolerance = 15;\n\n\t// if manually entered, cap at 99%\n\tif (slippageTolerance > 99) slippageTolerance = 99;\n\n\tlet limitPricePctDiff;\n\tif (isVariant(direction, 'long')) {\n\t\tlimitPricePctDiff = PRICE_PRECISION.add(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t} else {\n\t\tlimitPricePctDiff = PRICE_PRECISION.sub(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t}\n\n\treturn limitPrice;\n};\n\nconst getMarketAuctionParams = ({\n\tdirection,\n\tstartPriceFromSettings,\n\tendPriceFromSettings,\n\tlimitPrice,\n\tduration,\n\tauctionStartPriceOffset,\n\tauctionEndPriceOffset,\n\tadditionalEndPriceBuffer,\n\tforceUpToSlippage,\n\tbestBidPrice,\n\tbestAskPrice,\n\tensureCrossingEndPrice,\n}: {\n\tdirection: PositionDirection;\n\tstartPriceFromSettings: BN;\n\tendPriceFromSettings: BN;\n\t/**\n\t * Limit price is the oracle limit price - market orders use the oracle order type under the hood on Drift UI\n\t * So oracle limit price is the oracle price + oracle offset\n\t */\n\tlimitPrice: BN;\n\tduration: number;\n\tauctionStartPriceOffset: number;\n\tauctionEndPriceOffset: number;\n\tadditionalEndPriceBuffer?: BN;\n\tforceUpToSlippage?: boolean;\n\tbestBidPrice?: BN;\n\tbestAskPrice?: BN;\n\tensureCrossingEndPrice?: boolean;\n}): AuctionParams => {\n\tlet auctionStartPrice: BN;\n\tlet auctionEndPrice: BN;\n\tlet constrainedBySlippage: boolean;\n\n\tconst auctionEndPriceBuffer = BigNum.from(PRICE_PRECISION).scale(\n\t\tMath.abs(auctionEndPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tconst auctionStartPriceBuffer = BigNum.from(startPriceFromSettings).scale(\n\t\tMath.abs(auctionStartPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tif (isVariant(direction, 'long')) {\n\t\tauctionStartPrice = startPriceFromSettings.sub(auctionStartPriceBuffer);\n\n\t\tconst worstPriceToUse = BN.max(\n\t\t\tendPriceFromSettings,\n\t\t\tstartPriceFromSettings\n\t\t); // Handles edge cases like if the worst price on the book was better than the oracle price, and the settings are asking to be relative to the oracle price\n\n\t\tauctionEndPrice = PRICE_PRECISION.add(auctionEndPriceBuffer)\n\t\t\t.mul(worstPriceToUse)\n\t\t\t.div(PRICE_PRECISION);\n\n\t\tconstrainedBySlippage = limitPrice.lt(auctionEndPrice);\n\n\t\t// if forceUpToSlippage is passed, use max slippage price as end price\n\t\tif (forceUpToSlippage) {\n\t\t\tauctionEndPrice = limitPrice;\n\t\t\tconstrainedBySlippage = false;\n\t\t} else {\n\t\t\t// use BEST (limit price, auction end price) as end price\n\t\t\tauctionEndPrice = BN.min(limitPrice, auctionEndPrice);\n\t\t}\n\n\t\t// apply additional buffer if provided\n\t\tif (additionalEndPriceBuffer) {\n\t\t\tauctionEndPrice = auctionEndPrice.add(additionalEndPriceBuffer);\n\t\t\tconstrainedBySlippage = limitPrice.lt(auctionEndPrice);\n\t\t}\n\n\t\t// if ensureCrossingEndPrice is passed, ensure auction end price crosses bestAskPrice\n\t\tif (ensureCrossingEndPrice && bestAskPrice) {\n\t\t\tauctionEndPrice = BN.max(\n\t\t\t\tauctionEndPrice,\n\t\t\t\tbestAskPrice.add(auctionEndPriceBuffer)\n\t\t\t);\n\t\t}\n\n\t\tauctionStartPrice = BN.min(auctionStartPrice, auctionEndPrice);\n\t} else {\n\t\tauctionStartPrice = startPriceFromSettings.add(auctionStartPriceBuffer);\n\n\t\tconst worstPriceToUse = BN.min(\n\t\t\tendPriceFromSettings,\n\t\t\tstartPriceFromSettings\n\t\t); // Handles edge cases like if the worst price on the book was better than the oracle price, and the settings are asking to be relative to the oracle price\n\n\t\tauctionEndPrice = PRICE_PRECISION.sub(auctionEndPriceBuffer)\n\t\t\t.mul(worstPriceToUse)\n\t\t\t.div(PRICE_PRECISION);\n\n\t\tconstrainedBySlippage = limitPrice.gt(auctionEndPrice);\n\n\t\t// if forceUpToSlippage is passed, use max slippage price as end price\n\t\tif (forceUpToSlippage) {\n\t\t\tauctionEndPrice = limitPrice;\n\t\t\tconstrainedBySlippage = false;\n\t\t} else {\n\t\t\t// use BEST (limit price, auction end price) as end price\n\t\t\tauctionEndPrice = BN.max(limitPrice, auctionEndPrice);\n\t\t}\n\n\t\t// apply additional buffer if provided\n\t\tif (additionalEndPriceBuffer) {\n\t\t\tauctionEndPrice = auctionEndPrice.sub(additionalEndPriceBuffer);\n\t\t\tconstrainedBySlippage = limitPrice.gt(auctionEndPrice);\n\t\t}\n\n\t\t// if ensureCrossingEndPrice is passed, ensure auction end price crosses bestBidPrice\n\t\tif (ensureCrossingEndPrice && bestBidPrice) {\n\t\t\tauctionEndPrice = BN.min(\n\t\t\t\tauctionEndPrice,\n\t\t\t\tbestBidPrice.sub(auctionEndPriceBuffer)\n\t\t\t);\n\t\t}\n\n\t\tauctionStartPrice = BN.max(auctionStartPrice, auctionEndPrice);\n\t}\n\n\treturn {\n\t\tauctionStartPrice,\n\t\tauctionEndPrice,\n\t\tauctionDuration: duration,\n\t\tconstrainedBySlippage,\n\t};\n};\n\n/**\n * Helper function which derived market order params from the CORE data that is used to create them.\n * @param param0\n * @returns\n */\nconst deriveMarketOrderParams = ({\n\tmarketType,\n\tmarketIndex,\n\tdirection,\n\tmaxLeverageSelected,\n\tmaxLeverageOrderSize,\n\tbaseAmount,\n\treduceOnly,\n\tallowInfSlippage,\n\toraclePrice,\n\tbestPrice,\n\tentryPrice,\n\tworstPrice,\n\tmarkPrice,\n\tauctionDuration,\n\tauctionStartPriceOffset,\n\tauctionEndPriceOffset,\n\tauctionStartPriceOffsetFrom,\n\tauctionEndPriceOffsetFrom,\n\tauctionPriceCaps,\n\tslippageTolerance,\n\tisOracleOrder,\n\tadditionalEndPriceBuffer,\n\tforceUpToSlippage,\n\tbestBidPrice,\n\tbestAskPrice,\n\tensureCrossingEndPrice,\n}: {\n\tmarketType: MarketType;\n\tmarketIndex: number;\n\tdirection: PositionDirection;\n\tmaxLeverageSelected: boolean;\n\tmaxLeverageOrderSize: BN;\n\tbaseAmount: BN;\n\treduceOnly: boolean;\n\tallowInfSlippage: boolean;\n\toraclePrice: BN;\n\tbestPrice: BN;\n\tentryPrice: BN;\n\tworstPrice: BN;\n\tmarkPrice: BN;\n\tauctionDuration: number;\n\tauctionStartPriceOffset: number;\n\tauctionEndPriceOffset: number;\n\tauctionPriceCaps?: {\n\t\tmin: BN;\n\t\tmax: BN;\n\t};\n\tauctionStartPriceOffsetFrom: TradeOffsetPrice;\n\tauctionEndPriceOffsetFrom: TradeOffsetPrice;\n\tslippageTolerance: number;\n\tisOracleOrder?: boolean;\n\tadditionalEndPriceBuffer?: BN;\n\tforceUpToSlippage?: boolean;\n\tbestBidPrice?: BN;\n\tbestAskPrice?: BN;\n\tensureCrossingEndPrice?: boolean;\n}): OptionalOrderParams & { constrainedBySlippage?: boolean } => {\n\tconst priceObject = getPriceObject({\n\t\toraclePrice,\n\t\tmarkPrice,\n\t\tbestOffer: bestPrice,\n\t\tentryPrice,\n\t\tworstPrice,\n\t\tdirection,\n\t});\n\n\t// max slippage price\n\tlet limitPrice = getMarketOrderLimitPrice({\n\t\tdirection,\n\t\tbaselinePrice: priceObject[auctionStartPriceOffsetFrom],\n\t\tslippageTolerance: allowInfSlippage ? undefined : slippageTolerance,\n\t});\n\n\tif (additionalEndPriceBuffer) {\n\t\tlimitPrice = isVariant(direction, 'long')\n\t\t\t? limitPrice.add(additionalEndPriceBuffer)\n\t\t\t: limitPrice.sub(additionalEndPriceBuffer);\n\t}\n\n\tconst auctionParams = getMarketAuctionParams({\n\t\tdirection,\n\t\tstartPriceFromSettings: priceObject[auctionStartPriceOffsetFrom],\n\t\tendPriceFromSettings: priceObject[auctionEndPriceOffsetFrom],\n\t\tlimitPrice,\n\t\tduration: auctionDuration,\n\t\tauctionStartPriceOffset: auctionStartPriceOffset,\n\t\tauctionEndPriceOffset: auctionEndPriceOffset,\n\t\tadditionalEndPriceBuffer,\n\t\tforceUpToSlippage,\n\t\tbestBidPrice,\n\t\tbestAskPrice,\n\t\tensureCrossingEndPrice,\n\t});\n\n\tlet orderParams = getMarketOrderParams({\n\t\tmarketType,\n\t\tmarketIndex,\n\t\tdirection,\n\t\tbaseAssetAmount: maxLeverageSelected ? maxLeverageOrderSize : baseAmount,\n\t\treduceOnly,\n\t\tprice: allowInfSlippage ? undefined : limitPrice,\n\t\t...auctionParams,\n\t});\n\n\tif (isOracleOrder) {\n\t\t// wont work if oracle is zero\n\t\tif (!oraclePrice.eq(ZERO)) {\n\t\t\tconst oracleAuctionParams = deriveOracleAuctionParams({\n\t\t\t\tdirection: direction,\n\t\t\t\toraclePrice,\n\t\t\t\tauctionStartPrice: auctionParams.auctionStartPrice,\n\t\t\t\tauctionEndPrice: auctionParams.auctionEndPrice,\n\t\t\t\tlimitPrice: auctionParams.auctionEndPrice,\n\t\t\t\tauctionPriceCaps: auctionPriceCaps,\n\t\t\t});\n\n\t\t\torderParams = {\n\t\t\t\t...orderParams,\n\t\t\t\t...oracleAuctionParams,\n\t\t\t\tprice: undefined,\n\t\t\t\torderType: OrderType.ORACLE,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn orderParams;\n};\n\nconst getLimitAuctionParams = ({\n\tdirection,\n\tinputPrice,\n\tstartPriceFromSettings,\n\tduration,\n\tauctionStartPriceOffset,\n\toraclePriceBands,\n}: {\n\tdirection: PositionDirection;\n\tinputPrice: BigNum;\n\tstartPriceFromSettings: BN;\n\tduration: number;\n\tauctionStartPriceOffset: number;\n\toraclePriceBands?: [BN, BN];\n}): AuctionParams => {\n\tlet limitAuctionParams = EMPTY_AUCTION_PARAMS;\n\n\tconst auctionStartPriceBuffer = inputPrice.scale(\n\t\tMath.abs(auctionStartPriceOffset * 100),\n\t\t10000\n\t).val;\n\n\tif (\n\t\tisVariant(direction, 'long') &&\n\t\tstartPriceFromSettings &&\n\t\tstartPriceFromSettings.lt(inputPrice.val) &&\n\t\tstartPriceFromSettings.gt(ZERO)\n\t) {\n\t\tlimitAuctionParams = {\n\t\t\tauctionStartPrice: startPriceFromSettings.sub(auctionStartPriceBuffer),\n\t\t\tauctionEndPrice: inputPrice.val,\n\t\t\tauctionDuration: duration,\n\t\t};\n\t} else if (\n\t\tisVariant(direction, 'short') &&\n\t\tstartPriceFromSettings &&\n\t\tstartPriceFromSettings.gt(ZERO) &&\n\t\tstartPriceFromSettings.gt(inputPrice.val)\n\t) {\n\t\tlimitAuctionParams = {\n\t\t\tauctionStartPrice: startPriceFromSettings.add(auctionStartPriceBuffer),\n\t\t\tauctionEndPrice: inputPrice.val,\n\t\t\tauctionDuration: duration,\n\t\t};\n\t}\n\n\tif (oraclePriceBands && limitAuctionParams.auctionDuration) {\n\t\tconst [minPrice, maxPrice] = oraclePriceBands;\n\n\t\t// start and end price cant be outside of the oracle price bands\n\t\tlimitAuctionParams.auctionStartPrice = BN.max(\n\t\t\tBN.min(limitAuctionParams.auctionStartPrice, maxPrice),\n\t\t\tminPrice\n\t\t);\n\n\t\tlimitAuctionParams.auctionEndPrice = BN.max(\n\t\t\tBN.min(limitAuctionParams.auctionEndPrice, maxPrice),\n\t\t\tminPrice\n\t\t);\n\t}\n\n\treturn limitAuctionParams;\n};\n\nconst getPriceObject = ({\n\toraclePrice,\n\tbestOffer,\n\tentryPrice,\n\tworstPrice,\n\tmarkPrice,\n\tdirection,\n}: {\n\toraclePrice: BN;\n\tbestOffer: BN;\n\tentryPrice: BN;\n\tworstPrice: BN;\n\tmarkPrice: BN;\n\tdirection: PositionDirection;\n}) => {\n\tlet best: BN;\n\n\tconst nonZeroOptions = [oraclePrice, bestOffer, markPrice].filter(\n\t\t(price) => price !== undefined && price?.gt(ZERO)\n\t);\n\n\tif (nonZeroOptions.length === 0) {\n\t\t// console.error('Unable to create valid auction params');\n\t\treturn {\n\t\t\toracle: ZERO,\n\t\t\tbestOffer: ZERO,\n\t\t\tentry: ZERO,\n\t\t\tbest: ZERO,\n\t\t\tworst: ZERO,\n\t\t\tmark: ZERO,\n\t\t};\n\t}\n\n\tif (isVariant(direction, 'long')) {\n\t\tbest = nonZeroOptions.reduce((a, b) => (a.lt(b) ? a : b)); // lowest price\n\t} else {\n\t\tbest = nonZeroOptions.reduce((a, b) => (a.gt(b) ? a : b)); // highest price\n\t}\n\n\t// if zero values come through, fallback to nonzero value\n\treturn {\n\t\toracle: oraclePrice?.gt(ZERO) ? oraclePrice : best,\n\t\tbestOffer: bestOffer?.gt(ZERO) ? bestOffer : best,\n\t\tentry: entryPrice,\n\t\tbest,\n\t\tworst: worstPrice,\n\t\tmark: markPrice?.gt(ZERO) ? markPrice : best,\n\t};\n};\n\n/* LP Utils */\nconst getLpSharesAmountForQuote = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tquoteAmount: BN\n): BigNum => {\n\tconst tenMillionBigNum = BigNum.fromPrint('10000000', QUOTE_PRECISION_EXP);\n\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t);\n\n\treturn BigNum.from(quoteAmount, QUOTE_PRECISION_EXP)\n\t\t.scale(\n\t\t\ttenMillionBigNum.toNum(),\n\t\t\tpricePerLpShare.mul(tenMillionBigNum).toNum()\n\t\t)\n\t\t.shiftTo(AMM_RESERVE_PRECISION_EXP);\n};\n\nconst getQuoteValueForLpShares = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tsharesAmount: BN\n): BigNum => {\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t).shiftTo(AMM_RESERVE_PRECISION_EXP);\n\tconst lpSharesBigNum = BigNum.from(sharesAmount, AMM_RESERVE_PRECISION_EXP);\n\treturn lpSharesBigNum.mul(pricePerLpShare).shiftTo(QUOTE_PRECISION_EXP);\n};\n\nconst getTokenAddress = (\n\tmintAddress: PublicKey,\n\tuserPubKey: PublicKey\n): Promise<PublicKey> => {\n\treturn getAssociatedTokenAddress(mintAddress, userPubKey, true);\n};\n\nconst getBalanceFromTokenAccountResult = (account: {\n\tpubkey: PublicKey;\n\taccount: AccountInfo<ParsedAccountData>;\n}) => {\n\treturn account?.account.data?.parsed?.info?.tokenAmount?.uiAmount;\n};\n\nconst getTokenAccount = async (\n\tconnection: Connection,\n\tmintAddress: PublicKey,\n\tuserPubKey: PublicKey\n): Promise<{\n\ttokenAccount: {\n\t\tpubkey: PublicKey;\n\t\taccount: import('@solana/web3.js').AccountInfo<\n\t\t\timport('@solana/web3.js').ParsedAccountData\n\t\t>;\n\t};\n\ttokenAccountWarning: boolean;\n}> => {\n\tconst tokenAccounts = await connection.getParsedTokenAccountsByOwner(\n\t\tuserPubKey,\n\t\t{ mint: mintAddress }\n\t);\n\n\tconst associatedAddress = await getAssociatedTokenAddress(\n\t\tmintAddress,\n\t\tuserPubKey,\n\t\ttrue\n\t);\n\n\tconst targetAccount =\n\t\ttokenAccounts.value.filter((account) =>\n\t\t\taccount.pubkey.equals(associatedAddress)\n\t\t)[0] || tokenAccounts.value[0];\n\n\tconst anotherBalanceExists = tokenAccounts.value.find((account) => {\n\t\treturn (\n\t\t\t!!getBalanceFromTokenAccountResult(account) &&\n\t\t\t!account.pubkey.equals(targetAccount.pubkey)\n\t\t);\n\t});\n\n\tlet tokenAccountWarning = false;\n\n\tif (anotherBalanceExists) {\n\t\ttokenAccountWarning = true;\n\t}\n\n\treturn {\n\t\ttokenAccount: targetAccount,\n\t\ttokenAccountWarning,\n\t};\n};\n\nconst getMultipleAccounts = async (\n\tconnection: any,\n\tkeys: string[],\n\tcommitment: string\n) => {\n\tconst result = await Promise.all(\n\t\tchunks(keys, 99).map((chunk) =>\n\t\t\tgetMultipleAccountsCore(connection, chunk, commitment)\n\t\t)\n\t);\n\n\tconst array = result\n\t\t.map(\n\t\t\t(a) =>\n\t\t\t\ta.array\n\t\t\t\t\t.map((acc) => {\n\t\t\t\t\t\tif (!acc) {\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { data, ...rest } = acc;\n\t\t\t\t\t\tconst obj = {\n\t\t\t\t\t\t\t...rest,\n\t\t\t\t\t\t\tdata: Buffer.from(data[0], 'base64'),\n\t\t\t\t\t\t} as AccountInfo<Buffer>;\n\t\t\t\t\t\treturn obj;\n\t\t\t\t\t})\n\t\t\t\t\t.filter((_) => _) as AccountInfo<Buffer>[]\n\t\t)\n\t\t.flat();\n\treturn { keys, array };\n};\n\nconst getMultipleAccountsCore = async (\n\tconnection: any,\n\tkeys: string[],\n\tcommitment: string\n) => {\n\tconst args = connection._buildArgs([keys], commitment, 'base64');\n\n\tconst unsafeRes = await connection._rpcRequest('getMultipleAccounts', args);\n\tif (unsafeRes.error) {\n\t\tthrow new Error(\n\t\t\t'failed to get info about account ' + unsafeRes.error.message\n\t\t);\n\t}\n\n\tif (unsafeRes.result.value) {\n\t\tconst array = unsafeRes.result.value as AccountInfo<string[]>[];\n\t\treturn { keys, array };\n\t}\n\n\t// TODO: fix\n\tthrow new Error();\n};\n\nconst userExists = async (\n\tdriftClient: DriftClient,\n\tuserId: number,\n\tauthority: PublicKey\n) => {\n\tlet userAccountExists = false;\n\n\ttry {\n\t\tconst user = driftClient.getUser(userId, authority);\n\t\tuserAccountExists = await user.exists();\n\t} catch (e) {\n\t\t// user account does not exist so we leave userAccountExists false\n\t}\n\n\treturn userAccountExists;\n};\n\nfunction chunks<T>(array: T[], size: number): T[][] {\n\treturn Array.apply(0, new Array(Math.ceil(array.length / size))).map(\n\t\t(_, index) => array.slice(index * size, (index + 1) * size)\n\t);\n}\n\n/**\n * Trim trailing zeros from a numerical string\n * @param str - numerical string to format\n * @param zerosToShow - max number of zeros to show after the decimal. Similar to number.toFixed() but won't trim non-zero values. Optional, default value is 1\n */\nconst trimTrailingZeros = (str: string, zerosToShow = 1) => {\n\t// Ignore strings with no decimal point\n\tif (!str.includes('.')) return str;\n\n\tconst sides = str.split('.');\n\n\tsides[1] = sides[1].replace(/0+$/, '');\n\n\tif (sides[1].length < zerosToShow) {\n\t\tconst zerosToAdd = zerosToShow - sides[1].length;\n\t\tsides[1] = `${sides[1]}${Array(zerosToAdd).fill('0').join('')}`;\n\t}\n\n\tif (sides[1].length === 0) {\n\t\treturn sides[0];\n\t} else {\n\t\treturn sides.join('.');\n\t}\n};\n\nconst formatTokenInputCurried =\n\t(setAmount: (amount: string) => void, spotMarketConfig: SpotMarketConfig) =>\n\t(newAmount: string) => {\n\t\tif (isNaN(+newAmount)) return;\n\n\t\tif (newAmount === '') {\n\t\t\tsetAmount('');\n\t\t\treturn;\n\t\t}\n\n\t\tconst lastChar = newAmount[newAmount.length - 1];\n\n\t\t// if last char of string is a decimal point, don't format\n\t\tif (lastChar === '.') {\n\t\t\tsetAmount(newAmount);\n\t\t\treturn;\n\t\t}\n\n\t\tif (lastChar === '0') {\n\t\t\t// if last char of string is a zero in the decimal places, cut it off if it exceeds precision\n\t\t\tconst numOfDigitsAfterDecimal = newAmount.split('.')[1]?.length ?? 0;\n\t\t\tif (numOfDigitsAfterDecimal > spotMarketConfig.precisionExp.toNumber()) {\n\t\t\t\tsetAmount(newAmount.slice(0, -1));\n\t\t\t} else {\n\t\t\t\tsetAmount(newAmount);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst formattedAmount = Number(\n\t\t\t(+newAmount).toFixed(spotMarketConfig.precisionExp.toNumber())\n\t\t);\n\t\tsetAmount(formattedAmount.toString());\n\t};\n\n// --- Export The Utils\n\nexport const COMMON_UI_UTILS = {\n\tabbreviateAddress,\n\tcalculateAverageEntryPrice,\n\tchunks,\n\tcompareSignatures,\n\tcreatePlaceholderIWallet,\n\tderiveMarketOrderParams,\n\tfetchCurrentSubaccounts,\n\tfetchUserClientsAndAccounts,\n\tformatTokenInputCurried,\n\tgetBalanceFromTokenAccountResult,\n\tgetIdAndAuthorityFromKey,\n\tgetLimitAuctionParams,\n\tgetLpSharesAmountForQuote,\n\tgetMarketAuctionParams,\n\tgetMarketKey,\n\tgetMarketOrderLimitPrice,\n\tgetMultipleAccounts,\n\tgetMultipleAccountsCore,\n\tgetPriceObject,\n\tgetQuoteValueForLpShares,\n\tgetSignatureVerificationMessageForSettings,\n\tgetTokenAccount,\n\tgetTokenAddress,\n\tgetUserKey,\n\thashSignature,\n\tinitializeAndSubscribeToNewUserAccount,\n\tuserExists,\n\tverifySignature,\n\ttrimTrailingZeros,\n\t...USER_UTILS,\n\t...TRADING_UTILS,\n\t...MARKET_UTILS,\n\t...ORDER_COMMON_UTILS,\n};\n"]}
|
|
@@ -7,6 +7,19 @@ import { MarketId, OpenPosition, UIOrderType } from 'src/types';
|
|
|
7
7
|
* @returns true if the order is for the entire position, false otherwise
|
|
8
8
|
*/
|
|
9
9
|
export declare const isEntirePositionOrder: (orderAmount: BigNum) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Gets the MAX_LEVERAGE_ORDER_SIZE as a BigNum with the same precision as the given amount
|
|
12
|
+
* @param orderAmount - The BigNum order amount to match precision with
|
|
13
|
+
* @returns BigNum representation of MAX_LEVERAGE_ORDER_SIZE
|
|
14
|
+
*/
|
|
15
|
+
export declare const getMaxLeverageOrderSize: (orderAmount: BigNum) => BigNum;
|
|
16
|
+
/**
|
|
17
|
+
* Formats an order size for display, showing "Entire Position" if it's a max leverage order
|
|
18
|
+
* @param orderAmount - The BigNum order amount to format
|
|
19
|
+
* @param formatFn - Optional custom format function, defaults to prettyPrint()
|
|
20
|
+
* @returns Formatted string showing either "Entire Position" or the formatted amount
|
|
21
|
+
*/
|
|
22
|
+
export declare const formatOrderSize: (orderAmount: BigNum, formatFn?: (amount: BigNum) => string) => string;
|
|
10
23
|
export declare const TRADING_UTILS: {
|
|
11
24
|
calculatePnlPctFromPosition: (pnl: BN, position: OpenPosition, marginUsed?: BN) => number;
|
|
12
25
|
calculatePotentialProfit: (props: {
|
|
@@ -55,6 +68,8 @@ export declare const TRADING_UTILS: {
|
|
|
55
68
|
getMarketStepSize: (driftClient: DriftClient, marketId: MarketId) => BN;
|
|
56
69
|
getMarketStepSizeDecimals: (driftClient: DriftClient, marketId: MarketId) => number;
|
|
57
70
|
isEntirePositionOrder: (orderAmount: BigNum) => boolean;
|
|
71
|
+
getMaxLeverageOrderSize: (orderAmount: BigNum) => BigNum;
|
|
72
|
+
formatOrderSize: (orderAmount: BigNum, formatFn?: (amount: BigNum) => string) => string;
|
|
58
73
|
getMarginUsedForPosition: (user: User, marketIndex: number, includeOpenOrders?: boolean) => BN | undefined;
|
|
59
74
|
validateLeverageChange: ({ user, marketIndex, newLeverage, }: {
|
|
60
75
|
user: User;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TRADING_UTILS = exports.isEntirePositionOrder = void 0;
|
|
3
|
+
exports.TRADING_UTILS = exports.formatOrderSize = exports.getMaxLeverageOrderSize = exports.isEntirePositionOrder = void 0;
|
|
4
4
|
const sdk_1 = require("@drift-labs/sdk");
|
|
5
5
|
const calculatePnlPctFromPosition = (pnl, position, marginUsed) => {
|
|
6
6
|
var _a;
|
|
@@ -206,9 +206,36 @@ const getMarketStepSizeDecimals = (driftClient, marketId) => {
|
|
|
206
206
|
*/
|
|
207
207
|
const isEntirePositionOrder = (orderAmount) => {
|
|
208
208
|
const maxLeverageSize = new sdk_1.BigNum(sdk_1.MAX_LEVERAGE_ORDER_SIZE, orderAmount.precision);
|
|
209
|
-
|
|
209
|
+
const isMaxLeverage = Math.abs(maxLeverageSize.sub(orderAmount).toNum()) < 1;
|
|
210
|
+
// Some order paths produce a truncated u64::MAX instead of MAX_LEVERAGE_ORDER_SIZE
|
|
211
|
+
const ALTERNATIVE_MAX_ORDER_SIZE = '18446744072000000000';
|
|
212
|
+
const alternativeMaxSize = new sdk_1.BigNum(ALTERNATIVE_MAX_ORDER_SIZE, orderAmount.precision);
|
|
213
|
+
const isAlternativeMax = Math.abs(alternativeMaxSize.sub(orderAmount).toNum()) < 1;
|
|
214
|
+
return isMaxLeverage || isAlternativeMax;
|
|
210
215
|
};
|
|
211
216
|
exports.isEntirePositionOrder = isEntirePositionOrder;
|
|
217
|
+
/**
|
|
218
|
+
* Gets the MAX_LEVERAGE_ORDER_SIZE as a BigNum with the same precision as the given amount
|
|
219
|
+
* @param orderAmount - The BigNum order amount to match precision with
|
|
220
|
+
* @returns BigNum representation of MAX_LEVERAGE_ORDER_SIZE
|
|
221
|
+
*/
|
|
222
|
+
const getMaxLeverageOrderSize = (orderAmount) => {
|
|
223
|
+
return new sdk_1.BigNum(sdk_1.MAX_LEVERAGE_ORDER_SIZE, orderAmount.precision);
|
|
224
|
+
};
|
|
225
|
+
exports.getMaxLeverageOrderSize = getMaxLeverageOrderSize;
|
|
226
|
+
/**
|
|
227
|
+
* Formats an order size for display, showing "Entire Position" if it's a max leverage order
|
|
228
|
+
* @param orderAmount - The BigNum order amount to format
|
|
229
|
+
* @param formatFn - Optional custom format function, defaults to prettyPrint()
|
|
230
|
+
* @returns Formatted string showing either "Entire Position" or the formatted amount
|
|
231
|
+
*/
|
|
232
|
+
const formatOrderSize = (orderAmount, formatFn) => {
|
|
233
|
+
if ((0, exports.isEntirePositionOrder)(orderAmount)) {
|
|
234
|
+
return 'Entire Position';
|
|
235
|
+
}
|
|
236
|
+
return formatFn ? formatFn(orderAmount) : orderAmount.prettyPrint();
|
|
237
|
+
};
|
|
238
|
+
exports.formatOrderSize = formatOrderSize;
|
|
212
239
|
/**
|
|
213
240
|
* Calculate the margin used for a specific perp position
|
|
214
241
|
* Returns the minimum of user's total collateral or the position's weighted value
|
|
@@ -278,6 +305,8 @@ exports.TRADING_UTILS = {
|
|
|
278
305
|
getMarketStepSize,
|
|
279
306
|
getMarketStepSizeDecimals,
|
|
280
307
|
isEntirePositionOrder: exports.isEntirePositionOrder,
|
|
308
|
+
getMaxLeverageOrderSize: exports.getMaxLeverageOrderSize,
|
|
309
|
+
formatOrderSize: exports.formatOrderSize,
|
|
281
310
|
getMarginUsedForPosition,
|
|
282
311
|
validateLeverageChange,
|
|
283
312
|
};
|