@drift-labs/common 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/lib/clients/DlobWebsocketClient.d.ts +81 -0
  2. package/lib/clients/DlobWebsocketClient.js +226 -0
  3. package/lib/clients/DlobWebsocketClient.js.map +1 -0
  4. package/lib/clients/swiftClient.js +1 -0
  5. package/lib/clients/swiftClient.js.map +1 -1
  6. package/lib/common-ui-utils/commonUiUtils.d.ts +1 -1
  7. package/lib/common-ui-utils/trading.d.ts +1 -1
  8. package/lib/common-ui-utils/trading.js +2 -1
  9. package/lib/common-ui-utils/trading.js.map +1 -1
  10. package/lib/common-ui-utils/user.js +4 -3
  11. package/lib/common-ui-utils/user.js.map +1 -1
  12. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.d.ts +20 -2
  13. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js +32 -0
  14. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js.map +1 -1
  15. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.d.ts +31 -1
  16. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.js.map +1 -1
  17. package/lib/drift/Drift/clients/AuthorityDrift/index.d.ts +10 -2
  18. package/lib/drift/Drift/clients/AuthorityDrift/index.js +12 -0
  19. package/lib/drift/Drift/clients/AuthorityDrift/index.js.map +1 -1
  20. package/lib/drift/base/actions/builder/createRevenueShareAccount.d.ts +62 -0
  21. package/lib/drift/base/actions/builder/createRevenueShareAccount.js +59 -0
  22. package/lib/drift/base/actions/builder/createRevenueShareAccount.js.map +1 -0
  23. package/lib/drift/base/actions/builder/createRevenueShareEscrow.d.ts +126 -0
  24. package/lib/drift/base/actions/builder/createRevenueShareEscrow.js +114 -0
  25. package/lib/drift/base/actions/builder/createRevenueShareEscrow.js.map +1 -0
  26. package/lib/drift/base/actions/builder/index.d.ts +3 -0
  27. package/lib/drift/base/actions/builder/index.js +20 -0
  28. package/lib/drift/base/actions/builder/index.js.map +1 -0
  29. package/lib/drift/base/actions/builder/manageBuilder.d.ts +157 -0
  30. package/lib/drift/base/actions/builder/manageBuilder.js +139 -0
  31. package/lib/drift/base/actions/builder/manageBuilder.js.map +1 -0
  32. package/lib/drift/base/actions/index.d.ts +1 -0
  33. package/lib/drift/base/actions/index.js +1 -0
  34. package/lib/drift/base/actions/index.js.map +1 -1
  35. package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.d.ts +0 -5
  36. package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.js.map +1 -1
  37. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.d.ts +29 -1
  38. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js +2 -1
  39. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js.map +1 -1
  40. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.d.ts +8 -0
  41. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js +1 -0
  42. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js.map +1 -1
  43. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.d.ts +56 -2
  44. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js +9 -3
  45. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js.map +1 -1
  46. package/lib/drift/base/constants/index.d.ts +2 -0
  47. package/lib/drift/base/constants/index.js +19 -0
  48. package/lib/drift/base/constants/index.js.map +1 -0
  49. package/lib/drift/index.d.ts +1 -0
  50. package/lib/drift/index.js +1 -0
  51. package/lib/drift/index.js.map +1 -1
  52. package/lib/index.d.ts +1 -0
  53. package/lib/index.js +1 -0
  54. package/lib/index.js.map +1 -1
  55. package/lib/utils/MultiplexWebSocket.d.ts +4 -2
  56. package/lib/utils/MultiplexWebSocket.js +18 -9
  57. package/lib/utils/MultiplexWebSocket.js.map +1 -1
  58. package/lib/utils/ResultSlotIncrementer.d.ts +31 -0
  59. package/lib/utils/ResultSlotIncrementer.js +83 -0
  60. package/lib/utils/ResultSlotIncrementer.js.map +1 -0
  61. package/lib/utils/index.d.ts +3 -1
  62. package/lib/utils/index.js +7 -1
  63. package/lib/utils/index.js.map +1 -1
  64. package/lib/utils/math.js +1 -1
  65. package/lib/utils/math.js.map +1 -1
  66. package/lib/utils/signedMsgs.d.ts +1 -0
  67. package/lib/utils/signedMsgs.js +10 -0
  68. package/lib/utils/signedMsgs.js.map +1 -0
  69. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ import { MarketId, RawL2Output, deserializeL2Response, OrderbookGrouping, DlobServerChannel } from '../index';
2
+ import { Observable } from 'rxjs';
3
+ import { ResultSlotIncrementer } from '../utils/ResultSlotIncrementer';
4
+ export type OrderbookChannelTypes = Extract<DlobServerChannel, 'orderbook' | 'orderbook_indicative'>;
5
+ export interface DlobWebsocketClientConfig {
6
+ websocketUrl: string;
7
+ enableIndicativeOrderbook?: boolean;
8
+ resultSlotIncrementer?: ResultSlotIncrementer;
9
+ onFallback?: (marketId: MarketId) => void;
10
+ }
11
+ export interface MarketSubscription {
12
+ marketId: MarketId;
13
+ channel: OrderbookChannelTypes;
14
+ grouping?: OrderbookGrouping;
15
+ }
16
+ export interface ProcessedMarketData {
17
+ marketId: MarketId;
18
+ rawData: RawL2Output;
19
+ deserializedData: ReturnType<typeof deserializeL2Response>;
20
+ slot: number;
21
+ }
22
+ export declare class DlobWebsocketClient {
23
+ private config;
24
+ private subscriptions;
25
+ private resultIncrementer;
26
+ private destroy$;
27
+ private marketSubscriptions$;
28
+ private rawMessages$;
29
+ constructor(config: DlobWebsocketClientConfig);
30
+ /**
31
+ * Get an observable stream of processed market data for specific markets
32
+ */
33
+ getMarketDataStream(marketIds: MarketId[]): Observable<ProcessedMarketData>;
34
+ /**
35
+ * Subscribe to market data for given markets
36
+ */
37
+ subscribeToMarkets(markets: {
38
+ marketId: MarketId;
39
+ grouping?: OrderbookGrouping;
40
+ }[]): void;
41
+ /**
42
+ * Unsubscribe from all markets
43
+ */
44
+ unsubscribeAll(): void;
45
+ /**
46
+ * Handle tab return to prevent "speed run" through queued messages
47
+ */
48
+ handleTabReturn(): void;
49
+ /**
50
+ * Reset slot tracking for clean state on reconnection
51
+ */
52
+ resetSlotTracking(): void;
53
+ /**
54
+ * Destroy the client and clean up all subscriptions
55
+ */
56
+ destroy(): void;
57
+ /**
58
+ * Sets up the subscription management pipeline that handles market data subscriptions.
59
+ * This pipeline:
60
+ * 1. Watches for changes in market subscriptions
61
+ * 2. Only processes changes when the subscription list actually changes
62
+ * 3. Manages the lifecycle of websocket subscriptions
63
+ * 4. Cleans up when the client is destroyed
64
+ */
65
+ private setupSubscriptionManagement;
66
+ /**
67
+ * Manages the lifecycle of websocket subscriptions by:
68
+ * 1. Comparing current subscriptions with new subscriptions
69
+ * 2. Unsubscribing from any subscriptions that are no longer needed
70
+ * 3. Creating new subscriptions for markets that weren't previously subscribed
71
+ *
72
+ * @param newSubscriptions - The new set of market subscriptions to maintain
73
+ * @returns An empty observable since this is a side-effect operation
74
+ */
75
+ private manageNewSubscriptions;
76
+ private createSubscription;
77
+ private processRawMessage;
78
+ private tryParse;
79
+ private getSubscriptionKey;
80
+ }
81
+ export default DlobWebsocketClient;
@@ -0,0 +1,226 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DlobWebsocketClient = void 0;
5
+ const index_1 = require("../index");
6
+ const rxjs_1 = require("rxjs");
7
+ const operators_1 = require("rxjs/operators");
8
+ const ResultSlotIncrementer_1 = require("../utils/ResultSlotIncrementer");
9
+ const MultiplexWebSocket_1 = require("../utils/MultiplexWebSocket");
10
+ class DlobWebsocketClient {
11
+ constructor(config) {
12
+ this.subscriptions = new Map();
13
+ this.destroy$ = new rxjs_1.Subject();
14
+ // Subjects for reactive streams
15
+ this.marketSubscriptions$ = new rxjs_1.BehaviorSubject([]);
16
+ this.rawMessages$ = new rxjs_1.Subject();
17
+ this.config = config;
18
+ this.resultIncrementer =
19
+ config.resultSlotIncrementer || new ResultSlotIncrementer_1.ResultSlotIncrementer();
20
+ this.setupSubscriptionManagement();
21
+ }
22
+ /**
23
+ * Get an observable stream of processed market data for specific markets
24
+ */
25
+ getMarketDataStream(marketIds) {
26
+ return this.rawMessages$.pipe((0, operators_1.filter)(({ marketId }) => marketIds.some((id) => id.key === marketId.key)), (0, operators_1.map)(({ marketId, channel, data }) => this.processRawMessage(marketId, channel, data)), (0, operators_1.filter)((result) => result !== null), (0, operators_1.catchError)((error) => {
27
+ console.error('Caught error in getMarketDataStream', error);
28
+ return rxjs_1.EMPTY;
29
+ }), (0, operators_1.takeUntil)(this.destroy$), (0, operators_1.share)());
30
+ }
31
+ /**
32
+ * Subscribe to market data for given markets
33
+ */
34
+ subscribeToMarkets(markets) {
35
+ const subscriptions = markets.map(({ marketId, grouping }) => ({
36
+ marketId,
37
+ channel: this.config.enableIndicativeOrderbook
38
+ ? 'orderbook_indicative'
39
+ : 'orderbook',
40
+ grouping,
41
+ }));
42
+ this.marketSubscriptions$.next(subscriptions);
43
+ }
44
+ /**
45
+ * Unsubscribe from all markets
46
+ */
47
+ unsubscribeAll() {
48
+ this.marketSubscriptions$.next([]);
49
+ }
50
+ /**
51
+ * Handle tab return to prevent "speed run" through queued messages
52
+ */
53
+ handleTabReturn() {
54
+ this.resultIncrementer.handleTabReturn();
55
+ }
56
+ /**
57
+ * Reset slot tracking for clean state on reconnection
58
+ */
59
+ resetSlotTracking() {
60
+ // Get all current subscription keys and reset their slot tracking
61
+ for (const subscriptionKey of this.subscriptions.keys()) {
62
+ // Extract marketId and channel from subscription key
63
+ const [marketKey, channel] = subscriptionKey.split('_');
64
+ const resultKey = `${channel}_${marketKey}`;
65
+ this.resultIncrementer.resetKey(resultKey);
66
+ }
67
+ }
68
+ /**
69
+ * Destroy the client and clean up all subscriptions
70
+ */
71
+ destroy() {
72
+ this.destroy$.next();
73
+ this.destroy$.complete();
74
+ this.subscriptions.forEach(({ unsubscribe }) => unsubscribe());
75
+ this.subscriptions.clear();
76
+ }
77
+ /**
78
+ * Sets up the subscription management pipeline that handles market data subscriptions.
79
+ * This pipeline:
80
+ * 1. Watches for changes in market subscriptions
81
+ * 2. Only processes changes when the subscription list actually changes
82
+ * 3. Manages the lifecycle of websocket subscriptions
83
+ * 4. Cleans up when the client is destroyed
84
+ */
85
+ setupSubscriptionManagement() {
86
+ this.marketSubscriptions$
87
+ .pipe(
88
+ // Only emit when the subscription list actually changes
89
+ // Uses JSON.stringify for deep comparison of subscription arrays
90
+ (0, operators_1.distinctUntilChanged)((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)),
91
+ // Switch to managing the new set of subscriptions
92
+ // This will cancel any previous subscription management
93
+ (0, operators_1.switchMap)((subscriptions) => this.manageNewSubscriptions(subscriptions)),
94
+ // Clean up when the client is destroyed
95
+ (0, operators_1.takeUntil)(this.destroy$))
96
+ .subscribe();
97
+ }
98
+ /**
99
+ * Manages the lifecycle of websocket subscriptions by:
100
+ * 1. Comparing current subscriptions with new subscriptions
101
+ * 2. Unsubscribing from any subscriptions that are no longer needed
102
+ * 3. Creating new subscriptions for markets that weren't previously subscribed
103
+ *
104
+ * @param newSubscriptions - The new set of market subscriptions to maintain
105
+ * @returns An empty observable since this is a side-effect operation
106
+ */
107
+ manageNewSubscriptions(newSubscriptions) {
108
+ // Get sets of subscription keys for efficient comparison
109
+ const currentKeys = new Set(this.subscriptions.keys());
110
+ const newKeys = new Set(newSubscriptions.map((sub) => this.getSubscriptionKey(sub)));
111
+ // Unsubscribe from removed subscriptions
112
+ for (const key of currentKeys) {
113
+ if (!newKeys.has(key)) {
114
+ const subscription = this.subscriptions.get(key);
115
+ if (subscription) {
116
+ subscription.unsubscribe();
117
+ this.subscriptions.delete(key);
118
+ }
119
+ }
120
+ }
121
+ // Subscribe to new subscriptions
122
+ for (const subscription of newSubscriptions) {
123
+ const key = this.getSubscriptionKey(subscription);
124
+ if (!currentKeys.has(key)) {
125
+ this.createSubscription(subscription);
126
+ }
127
+ }
128
+ return rxjs_1.EMPTY;
129
+ }
130
+ createSubscription(subscription) {
131
+ var _a, _b;
132
+ const { marketId, channel, grouping } = subscription;
133
+ const subscriptionKey = this.getSubscriptionKey(subscription);
134
+ try {
135
+ const { unsubscribe } = MultiplexWebSocket_1.MultiplexWebSocket.createWebSocketSubscription({
136
+ wsUrl: this.config.websocketUrl,
137
+ enableHeartbeatMonitoring: true,
138
+ subscriptionId: `${this.config.websocketUrl}_dlob_liquidity_${marketId.key}`,
139
+ subscribeMessage: JSON.stringify(index_1.DLOB_SERVER_WEBSOCKET_UTILS.getSubscriptionProps({
140
+ type: channel,
141
+ market: marketId,
142
+ grouping,
143
+ })),
144
+ unsubscribeMessage: JSON.stringify(index_1.DLOB_SERVER_WEBSOCKET_UTILS.getUnsubscriptionProps({
145
+ type: channel,
146
+ market: marketId,
147
+ grouping,
148
+ })),
149
+ onMessage: (message) => {
150
+ this.rawMessages$.next({
151
+ marketId,
152
+ channel: message.channel,
153
+ data: message.data,
154
+ });
155
+ },
156
+ messageFilter: (message) => {
157
+ return index_1.DLOB_SERVER_WEBSOCKET_UTILS.getMessageFilter({
158
+ type: channel,
159
+ market: marketId,
160
+ grouping,
161
+ })(message);
162
+ },
163
+ onError: (error) => {
164
+ var _a, _b;
165
+ console.error('Caught error in createSubscription', error);
166
+ (_b = (_a = this.config).onFallback) === null || _b === void 0 ? void 0 : _b.call(_a, marketId);
167
+ },
168
+ errorMessageFilter: (message) => {
169
+ if (message === null || message === void 0 ? void 0 : message.error) {
170
+ return true;
171
+ }
172
+ return false;
173
+ },
174
+ });
175
+ this.subscriptions.set(subscriptionKey, { unsubscribe });
176
+ }
177
+ catch (error) {
178
+ console.error('Failed to create subscription:', error);
179
+ (_b = (_a = this.config).onFallback) === null || _b === void 0 ? void 0 : _b.call(_a, marketId);
180
+ }
181
+ }
182
+ processRawMessage(marketId, channel, data) {
183
+ var _a, _b;
184
+ try {
185
+ const parsed = this.tryParse(data);
186
+ const resultKey = `${channel}_${marketId.key}`;
187
+ const messageTimestamp = Date.now(); // Capture when we received this message
188
+ const validResult = this.resultIncrementer.handleResult(resultKey, (_a = parsed.slot) !== null && _a !== void 0 ? _a : 0, messageTimestamp);
189
+ if (!validResult) {
190
+ return null; // Skip results which aren't slot-increasing or are filtered due to tab return
191
+ }
192
+ const deserializedData = (0, index_1.deserializeL2Response)(parsed);
193
+ return {
194
+ marketId,
195
+ rawData: parsed,
196
+ deserializedData,
197
+ slot: (_b = parsed.slot) !== null && _b !== void 0 ? _b : 0,
198
+ };
199
+ }
200
+ catch (error) {
201
+ return null;
202
+ }
203
+ }
204
+ tryParse(data) {
205
+ try {
206
+ return JSON.parse(data, (key, value) => {
207
+ // If the value is a number and it's too large to be safely represented as a JavaScript number,
208
+ // convert it to a string to prevent precision loss
209
+ if (typeof value === 'number' && !Number.isSafeInteger(value)) {
210
+ return value.toString();
211
+ }
212
+ return value;
213
+ });
214
+ }
215
+ catch (e) {
216
+ return data;
217
+ }
218
+ }
219
+ getSubscriptionKey(subscription) {
220
+ const { marketId, channel, grouping } = subscription;
221
+ return `${marketId.key}_${channel}${grouping ? `_${grouping}` : ''}`;
222
+ }
223
+ }
224
+ exports.DlobWebsocketClient = DlobWebsocketClient;
225
+ exports.default = DlobWebsocketClient;
226
+ //# sourceMappingURL=DlobWebsocketClient.js.map
@@ -0,0 +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\tRawL2Output,\n\tdeserializeL2Response,\n\tOrderbookGrouping,\n\tDLOB_SERVER_WEBSOCKET_UTILS,\n\tDlobServerChannel,\n} from '../index';\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';\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// 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 = `${channel}_${marketKey}`;\n\t\t\tthis.resultIncrementer.resetKey(resultKey);\n\t\t}\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.config.websocketUrl}_dlob_liquidity_${marketId.key}`,\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 = `${channel}_${marketId.key}`;\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\treturn `${marketId.key}_${channel}${grouping ? `_${grouping}` : ''}`;\n\t}\n}\n\nexport default DlobWebsocketClient;\n"]}
@@ -109,6 +109,7 @@ class SwiftClient {
109
109
  };
110
110
  }
111
111
  static async confirmSwiftOrderWS(connection, client, signedMsgUserOrdersAccount, signedMsgOrderUuid, confirmDuration) {
112
+ (0, logger_1.allEnvDlog)('swiftClient', 'confirmSwiftOrderWS - confirmation duration', confirmDuration);
112
113
  return new Promise((resolve, reject) => {
113
114
  const timeout = setTimeout(() => {
114
115
  reject(new Error('Order not found'));
@@ -1 +1 @@
1
- {"version":3,"file":"swiftClient.js","sourceRoot":"","sources":["../../src/clients/swiftClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport {\n\tDriftClient,\n\tMarketType,\n\tOrderType,\n\tSignedMsgOrderParamsDelegateMessage,\n\tSignedMsgOrderParamsMessage,\n\tSignedMsgUserOrdersAccount,\n\tdigestSignature,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { Observable, Subscriber } from 'rxjs';\nimport { allEnvDlog } from '../utils/logger';\nexport type SwiftServerOrderProcessResponse = {\n\terror?: string;\n\tmessage: string;\n};\n\ntype ClientResponse<T = void> = Promise<{\n\tsuccess: boolean;\n\tbody?: T;\n\tmessage?: string;\n\tstatus?: number;\n}>;\n\ntype BaseSwiftOrderEvent = {\n\thash: string;\n};\n\nexport interface SwiftOrderSentEvent extends BaseSwiftOrderEvent {\n\ttype: 'sent';\n}\n\nexport interface SwiftOrderErroredEvent extends BaseSwiftOrderEvent {\n\ttype: 'errored' | 'expired';\n\tmessage?: string;\n\tstatus?: number;\n}\n\nexport interface SwiftOrderConfirmedEvent extends BaseSwiftOrderEvent {\n\ttype: 'confirmed';\n\torderId: string;\n}\n\nexport type SwiftOrderEvent =\n\t| SwiftOrderErroredEvent\n\t| SwiftOrderConfirmedEvent\n\t| SwiftOrderSentEvent;\n\nexport type SwiftOrderEventWithParams<T extends SwiftOrderEvent> = T & {\n\tswiftOrderUuid: Uint8Array;\n\torderParamsMessage:\n\t\t| SignedMsgOrderParamsMessage\n\t\t| SignedMsgOrderParamsDelegateMessage;\n};\n\nexport class SwiftClient {\n\tprivate static baseUrl = '';\n\tprivate static swiftClientConsumer?: string;\n\n\tstatic supportedOrderTypes: OrderType[] = [OrderType.MARKET, OrderType.LIMIT];\n\n\tpublic static init(baseUrl: string, swiftClientConsumer?: string) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.swiftClientConsumer = swiftClientConsumer;\n\t}\n\n\tprivate static get(url: string) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\treturn new Promise<{ success: boolean; body: string; status: number }>(\n\t\t\t(res) => {\n\t\t\t\tconst headers = new Headers({\n\t\t\t\t\t...this.getSwiftHeaders(),\n\t\t\t\t});\n\n\t\t\t\tfetch(`${this.baseUrl}${url}`, {\n\t\t\t\t\theaders,\n\t\t\t\t})\n\t\t\t\t\t.then(async (response) => {\n\t\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\t\tres({\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t\t});\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate static post(url: string, bodyObject: any) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { ...this.getSwiftHeaders() },\n\t\t\tbody: JSON.stringify(bodyObject),\n\t\t};\n\n\t\treturn new Promise<{\n\t\t\tsuccess: boolean;\n\t\t\tbody: SwiftServerOrderProcessResponse;\n\t\t\tstatus: number;\n\t\t}>((res) => {\n\t\t\tconst postRequest = new Request(`${this.baseUrl}${url}`, requestOptions);\n\n\t\t\tfetch(postRequest)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tlet resBody: SwiftServerOrderProcessResponse | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresBody =\n\t\t\t\t\t\t\t(await response.json()) as SwiftServerOrderProcessResponse;\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: response.ok,\n\t\t\t\t\t\t\tbody: resBody,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tallEnvDlog('swiftClient', 'Error reading response body', err);\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tbody: err as any,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t});\n\t\t});\n\t}\n\n\tstatic async sendSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsigningAuthority?: PublicKey\n\t): ClientResponse<{\n\t\thash: string;\n\t}> {\n\t\tconst requestPayload = {\n\t\t\tmarket_index: marketIndex,\n\t\t\tmarket_type: isVariant(marketType, 'perp') ? 'perp' : 'spot',\n\t\t\tmessage,\n\t\t\tsignature: signature.toString('base64'),\n\t\t\tsigning_authority: signingAuthority?.toBase58() ?? '',\n\t\t\ttaker_authority: takerPubkey.toBase58(),\n\t\t};\n\n\t\tconst response = await this.post('/orders', requestPayload);\n\n\t\tif (response.status !== 200) {\n\t\t\tconsole.error(\n\t\t\t\t`Non-200 status code received for sent Swift order: ${response.status}`\n\t\t\t);\n\t\t\tallEnvDlog('swiftClient', 'full non-200 response body', response.body);\n\t\t\treturn {\n\t\t\t\tmessage:\n\t\t\t\t\tresponse.body?.error ||\n\t\t\t\t\tresponse.body?.message ||\n\t\t\t\t\t`HTTP ${response.status}: Error from Swift server`,\n\t\t\t\tstatus: response.status,\n\t\t\t\tsuccess: false,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmessage: `Successfully sent Swift order`,\n\t\t\tbody: {\n\t\t\t\thash: digestSignature(Uint8Array.from(signature)),\n\t\t\t},\n\t\t\tsuccess: true,\n\t\t\tstatus: 200,\n\t\t};\n\t}\n\n\tstatic async confirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number\n\t): Promise<number | undefined> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\treject(new Error('Order not found'));\n\t\t\t}, confirmDuration);\n\n\t\t\tconnection\n\t\t\t\t.getAccountInfo(signedMsgUserOrdersAccount, 'confirmed')\n\t\t\t\t.then((accountInfo) => {\n\t\t\t\t\tif (!accountInfo) {\n\t\t\t\t\t\treject(new Error('Swift message account not found'));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in initial fetch orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\tresolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tconst subId = connection.onAccountChange(\n\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t(accountInfo) => {\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in onAccountChange orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconnection.removeAccountChangeListener(subId);\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\tresolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'confirmed'\n\t\t\t);\n\t\t});\n\t}\n\n\tstatic findOrderInSignedMsgUserOrdersAccount(\n\t\tclient: DriftClient,\n\t\tordersAccount: AccountInfo<Buffer>,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t) {\n\t\tconst accountDecoder =\n\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts.decodeUnchecked.bind(\n\t\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts\n\t\t\t);\n\t\tconst decodedAccount = accountDecoder(\n\t\t\t'SignedMsgUserOrders',\n\t\t\tordersAccount.data\n\t\t) as SignedMsgUserOrdersAccount;\n\t\tallEnvDlog(\n\t\t\t'swiftClient findOrder',\n\t\t\t'decodedAccount\\n',\n\t\t\tdecodedAccount,\n\t\t\tsignedMsgOrderUuid.toString()\n\t\t);\n\t\tconst order = decodedAccount.signedMsgOrderData.find(\n\t\t\t(order) => order.uuid.toString() === signedMsgOrderUuid.toString()\n\t\t);\n\t\tallEnvDlog('swiftClient findOrder', 'order\\n', order);\n\t\treturn order;\n\t}\n\n\tstatic async confirmSwiftOrder(\n\t\thash: string,\n\t\tconfirmDuration: number\n\t): Promise<\n\t\tClientResponse<\n\t\t\t| {\n\t\t\t\t\torderId: string;\n\t\t\t\t\tstatus: 'confirmed';\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tstatus: 'expired';\n\t\t\t }\n\t\t>\n\t> {\n\t\tconst expireTime = Date.now() + confirmDuration;\n\n\t\twhile (Date.now() < expireTime) {\n\t\t\tconst confirmResponse = await this.get(\n\t\t\t\t`/confirmation/hash-status?hash=${encodeURIComponent(hash)}`\n\t\t\t);\n\n\t\t\tif (confirmResponse.status === 200) {\n\t\t\t\tconsole.log('Confirmed hash: ', hash);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\tmessage: 'Confirmed hash: ' + hash,\n\t\t\t\t\tbody: {\n\t\t\t\t\t\torderId: confirmResponse.body,\n\t\t\t\t\t\tstatus: 'confirmed',\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else if (\n\t\t\t\tconfirmResponse.status >= 500 ||\n\t\t\t\tconfirmResponse.status < 200\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t}\n\n\t\tconsole.error('Failed to confirm hash: ', hash);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tstatus: 408,\n\t\t\tmessage: 'Failed to confirm hash: ' + hash,\n\t\t\tbody: {\n\t\t\t\tstatus: 'expired',\n\t\t\t},\n\t\t};\n\t}\n\n\tstatic async handleSwiftOrderSubscriber(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst confirmResponse = await this.confirmSwiftOrder(hash, confirmDuration);\n\n\t\tif (!confirmResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: confirmResponse.body.status as 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: confirmResponse.message,\n\t\t\t\tstatus: confirmResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t}\n\t\tif (confirmResponse.body.status === 'confirmed') {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: confirmResponse.body.orderId,\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\tstatic async handleSwiftOrderSubscriberWS(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\t\tallEnvDlog('swiftClient', 'sendResponse\\n', sendResponse);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: 'Error from swift node: ' + sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst orderID = await this.confirmSwiftOrderWS(\n\t\t\tconnection,\n\t\t\tclient,\n\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\tsignedMsgOrderUuid,\n\t\t\tconfirmDuration\n\t\t).catch((err) => {\n\t\t\tallEnvDlog('swiftClient', 'confirmSwiftOrderWS error', err);\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t});\n\n\t\tif (!orderID) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: orderID.toString(),\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\n\tpublic static sendAndConfirmSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriber(\n\t\t\t\tsubscriber,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static sendAndConfirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriberWS(\n\t\t\t\tsubscriber,\n\t\t\t\tconnection,\n\t\t\t\tclient,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\t\tsignedMsgOrderUuid,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static async isSwiftServerHealthy(): Promise<boolean> {\n\t\tconst response = await this.get('/health');\n\t\treturn response.status === 200;\n\t}\n\n\tprivate static getSwiftHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'X-Swift-Client-Consumer': this.swiftClientConsumer ?? 'default',\n\t\t};\n\t}\n\n\tpublic static isSupportedOrderType(orderType: OrderType) {\n\t\treturn this.supportedOrderTypes.includes(orderType);\n\t}\n}\n"]}
1
+ {"version":3,"file":"swiftClient.js","sourceRoot":"","sources":["../../src/clients/swiftClient.ts"],"names":[],"mappings":";;;AACA,yCASyB;AACzB,+BAA8C;AAC9C,4CAA6C;AA4C7C,MAAa,WAAW;IAMhB,MAAM,CAAC,IAAI,CAAC,OAAe,EAAE,mBAA4B;QAC/D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;IAChD,CAAC;IAEO,MAAM,CAAC,GAAG,CAAC,GAAW;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,IAAI,OAAO,CACjB,CAAC,GAAG,EAAE,EAAE;YACP,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC3B,GAAG,IAAI,CAAC,eAAe,EAAE;aACzB,CAAC,CAAC;YAEH,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,EAAE;gBAC9B,OAAO;aACP,CAAC;iBACA,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;gBACxB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAClB,GAAG,CAAC;wBACH,OAAO,EAAE,KAAK;wBACd,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;wBAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;qBACvB,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBACD,GAAG,CAAC;oBACH,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;oBAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACvB,CAAC,CAAC;YACJ,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACd,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CACD,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,IAAI,CAAC,GAAW,EAAE,UAAe;QAC/C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,cAAc,GAAG;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE;YACtC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SAChC,CAAC;QAEF,OAAO,IAAI,OAAO,CAIf,CAAC,GAAG,EAAE,EAAE;YACV,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;YAEzE,KAAK,CAAC,WAAW,CAAC;iBAChB,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;gBACxB,IAAI,OAAO,GAA2C,IAAI,CAAC;gBAC3D,IAAI,CAAC;oBACJ,OAAO;wBACN,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAoC,CAAC;oBAE5D,GAAG,CAAC;wBACH,OAAO,EAAE,QAAQ,CAAC,EAAE;wBACpB,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,QAAQ,CAAC,MAAM;qBACvB,CAAC,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAA,mBAAU,EAAC,aAAa,EAAE,6BAA6B,EAAE,GAAG,CAAC,CAAC;oBAE9D,GAAG,CAAC;wBACH,OAAO,EAAE,KAAK;wBACd,IAAI,EAAE,GAAU;wBAChB,MAAM,EAAE,QAAQ,CAAC,MAAM;qBACvB,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACd,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,cAAc,CAC1B,WAAmB,EACnB,UAAsB,EACtB,OAAe,EACf,SAAiB,EACjB,WAAsB,EACtB,gBAA4B;;QAI5B,MAAM,cAAc,GAAG;YACtB,YAAY,EAAE,WAAW;YACzB,WAAW,EAAE,IAAA,eAAS,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC5D,OAAO;YACP,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvC,iBAAiB,EAAE,MAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,QAAQ,EAAE,mCAAI,EAAE;YACrD,eAAe,EAAE,WAAW,CAAC,QAAQ,EAAE;SACvC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAE5D,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CACZ,sDAAsD,QAAQ,CAAC,MAAM,EAAE,CACvE,CAAC;YACF,IAAA,mBAAU,EAAC,aAAa,EAAE,4BAA4B,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvE,OAAO;gBACN,OAAO,EACN,CAAA,MAAA,QAAQ,CAAC,IAAI,0CAAE,KAAK;qBACpB,MAAA,QAAQ,CAAC,IAAI,0CAAE,OAAO,CAAA;oBACtB,QAAQ,QAAQ,CAAC,MAAM,2BAA2B;gBACnD,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,KAAK;aACd,CAAC;QACH,CAAC;QAED,OAAO;YACN,OAAO,EAAE,+BAA+B;YACxC,IAAI,EAAE;gBACL,IAAI,EAAE,IAAA,qBAAe,EAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACjD;YACD,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,GAAG;SACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAC/B,UAAsB,EACtB,MAAmB,EACnB,0BAAqC,EACrC,kBAA8B,EAC9B,eAAuB;QAEvB,IAAA,mBAAU,EACT,aAAa,EACb,6CAA6C,EAC7C,eAAe,CACf,CAAC;QACF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACtC,CAAC,EAAE,eAAe,CAAC,CAAC;YAEpB,UAAU;iBACR,cAAc,CAAC,0BAA0B,EAAE,WAAW,CAAC;iBACvD,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;gBACrB,IAAI,CAAC,WAAW,EAAE,CAAC;oBAClB,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;oBACrD,OAAO;gBACR,CAAC;gBAED,MAAM,KAAK,GAAG,IAAI,CAAC,qCAAqC,CACvD,MAAM,EACN,WAAW,EACX,kBAAkB,CAClB,CAAC;gBAEF,IAAI,KAAK,EAAE,CAAC;oBACX,IAAA,mBAAU,EACT,aAAa,EACb,sCAAsC,EACtC,KAAK,CAAC,OAAO,CACb,CAAC;oBACF,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;YACF,CAAC,CAAC,CAAC;YAEJ,MAAM,KAAK,GAAG,UAAU,CAAC,eAAe,CACvC,0BAA0B,EAC1B,CAAC,WAAW,EAAE,EAAE;gBACf,MAAM,KAAK,GAAG,IAAI,CAAC,qCAAqC,CACvD,MAAM,EACN,WAAW,EACX,kBAAkB,CAClB,CAAC;gBACF,IAAI,KAAK,EAAE,CAAC;oBACX,IAAA,mBAAU,EACT,aAAa,EACb,wCAAwC,EACxC,KAAK,CAAC,OAAO,CACb,CAAC;oBACF,UAAU,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC;oBAC9C,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;YACF,CAAC,EACD,WAAW,CACX,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,qCAAqC,CAC3C,MAAmB,EACnB,aAAkC,EAClC,kBAA8B;QAE9B,MAAM,cAAc,GACnB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAC7E,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CACzD,CAAC;QACH,MAAM,cAAc,GAAG,cAAc,CACpC,qBAAqB,EACrB,aAAa,CAAC,IAAI,CACY,CAAC;QAChC,IAAA,mBAAU,EACT,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,CAAC,QAAQ,EAAE,CAC7B,CAAC;QACF,MAAM,KAAK,GAAG,cAAc,CAAC,kBAAkB,CAAC,IAAI,CACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAClE,CAAC;QACF,IAAA,mBAAU,EAAC,uBAAuB,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAC7B,IAAY,EACZ,eAAuB;QAYvB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC;QAEhD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC;YAChC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,GAAG,CACrC,kCAAkC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAC5D,CAAC;YAEF,IAAI,eAAe,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;gBACtC,OAAO;oBACN,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,kBAAkB,GAAG,IAAI;oBAClC,IAAI,EAAE;wBACL,OAAO,EAAE,eAAe,CAAC,IAAI;wBAC7B,MAAM,EAAE,WAAW;qBACnB;iBACD,CAAC;YACH,CAAC;iBAAM,IACN,eAAe,CAAC,MAAM,IAAI,GAAG;gBAC7B,eAAe,CAAC,MAAM,GAAG,GAAG,EAC3B,CAAC;gBACF,MAAM;YACP,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO;YACN,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,0BAA0B,GAAG,IAAI;YAC1C,IAAI,EAAE;gBACL,MAAM,EAAE,SAAS;aACjB;SACD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,0BAA0B,CACtC,UAAuC,EACvC,WAAmB,EACnB,UAAsB,EACtB,OAAe,EACf,SAAiB,EACjB,WAAsB,EACtB,eAAuB,EACvB,gBAA4B;QAE5B,uBAAuB;QACvB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAC7C,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,gBAAgB,CAChB,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,MAAM,EAAE,YAAY,CAAC,MAAM;aAC3B,CAAC,CAAC;YACH,UAAU,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI;aAC5B,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAEpC,kBAAkB;QAClB,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAE5E,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,MAAmB;gBAC9C,IAAI;gBACJ,OAAO,EAAE,eAAe,CAAC,OAAO;gBAChC,MAAM,EAAE,eAAe,CAAC,MAAM;aAC9B,CAAC,CAAC;YACH,UAAU,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACjD,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO;gBACrC,IAAI;aACJ,CAAC,CAAC;YACH,UAAU,CAAC,QAAQ,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,4BAA4B,CACxC,UAAuC,EACvC,UAAsB,EACtB,MAAmB,EACnB,WAAmB,EACnB,UAAsB,EACtB,OAAe,EACf,SAAiB,EACjB,WAAsB,EACtB,gCAA2C,EAC3C,kBAA8B,EAC9B,eAAuB,EACvB,gBAA4B;QAE5B,uBAAuB;QACvB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAC7C,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,gBAAgB,CAChB,CAAC;QACF,IAAA,mBAAU,EAAC,aAAa,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAE1D,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,OAAO;gBACzD,MAAM,EAAE,YAAY,CAAC,MAAM;aAC3B,CAAC,CAAC;YACH,UAAU,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI;aAC5B,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAEpC,kBAAkB;QAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAC7C,UAAU,EACV,MAAM,EACN,gCAAgC,EAChC,kBAAkB,EAClB,eAAe,CACf,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACf,IAAA,mBAAU,EAAC,aAAa,EAAE,2BAA2B,EAAE,GAAG,CAAC,CAAC;YAC5D,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,SAAS;gBACf,IAAI;gBACJ,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,GAAG;aACX,CAAC,CAAC;YACH,UAAU,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,SAAS;gBACf,IAAI;gBACJ,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,GAAG;aACX,CAAC,CAAC;YACH,UAAU,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;gBAC3B,IAAI;aACJ,CAAC,CAAC;YACH,UAAU,CAAC,QAAQ,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IAEM,MAAM,CAAC,wBAAwB,CACrC,WAAmB,EACnB,UAAsB,EACtB,OAAe,EACf,SAAiB,EACjB,WAAsB,EACtB,eAAuB,EACvB,gBAA2B;QAE3B,OAAO,IAAI,iBAAU,CAAkB,CAAC,UAAU,EAAE,EAAE;YACrD,IAAI,CAAC,0BAA0B,CAC9B,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,eAAe,EACf,gBAAgB,CAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,0BAA0B,CACvC,UAAsB,EACtB,MAAmB,EACnB,WAAmB,EACnB,UAAsB,EACtB,OAAe,EACf,SAAiB,EACjB,WAAsB,EACtB,gCAA2C,EAC3C,kBAA8B,EAC9B,eAAuB,EACvB,gBAA2B;QAE3B,OAAO,IAAI,iBAAU,CAAkB,CAAC,UAAU,EAAE,EAAE;YACrD,IAAI,CAAC,4BAA4B,CAChC,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,gCAAgC,EAChC,kBAAkB,EAClB,eAAe,EACf,gBAAgB,CAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,oBAAoB;QACvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,OAAO,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;IAChC,CAAC;IAEO,MAAM,CAAC,eAAe;;QAC7B,OAAO;YACN,cAAc,EAAE,kBAAkB;YAClC,yBAAyB,EAAE,MAAA,IAAI,CAAC,mBAAmB,mCAAI,SAAS;SAChE,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,oBAAoB,CAAC,SAAoB;QACtD,OAAO,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;;AAzeF,kCA0eC;AAzee,mBAAO,GAAG,EAAE,CAAC;AAGrB,+BAAmB,GAAgB,CAAC,eAAS,CAAC,MAAM,EAAE,eAAS,CAAC,KAAK,CAAC,CAAC","sourcesContent":["import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport {\n\tDriftClient,\n\tMarketType,\n\tOrderType,\n\tSignedMsgOrderParamsDelegateMessage,\n\tSignedMsgOrderParamsMessage,\n\tSignedMsgUserOrdersAccount,\n\tdigestSignature,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { Observable, Subscriber } from 'rxjs';\nimport { allEnvDlog } from '../utils/logger';\nexport type SwiftServerOrderProcessResponse = {\n\terror?: string;\n\tmessage: string;\n};\n\ntype ClientResponse<T = void> = Promise<{\n\tsuccess: boolean;\n\tbody?: T;\n\tmessage?: string;\n\tstatus?: number;\n}>;\n\ntype BaseSwiftOrderEvent = {\n\thash: string;\n};\n\nexport interface SwiftOrderSentEvent extends BaseSwiftOrderEvent {\n\ttype: 'sent';\n}\n\nexport interface SwiftOrderErroredEvent extends BaseSwiftOrderEvent {\n\ttype: 'errored' | 'expired';\n\tmessage?: string;\n\tstatus?: number;\n}\n\nexport interface SwiftOrderConfirmedEvent extends BaseSwiftOrderEvent {\n\ttype: 'confirmed';\n\torderId: string;\n}\n\nexport type SwiftOrderEvent =\n\t| SwiftOrderErroredEvent\n\t| SwiftOrderConfirmedEvent\n\t| SwiftOrderSentEvent;\n\nexport type SwiftOrderEventWithParams<T extends SwiftOrderEvent> = T & {\n\tswiftOrderUuid: Uint8Array;\n\torderParamsMessage:\n\t\t| SignedMsgOrderParamsMessage\n\t\t| SignedMsgOrderParamsDelegateMessage;\n};\n\nexport class SwiftClient {\n\tprivate static baseUrl = '';\n\tprivate static swiftClientConsumer?: string;\n\n\tstatic supportedOrderTypes: OrderType[] = [OrderType.MARKET, OrderType.LIMIT];\n\n\tpublic static init(baseUrl: string, swiftClientConsumer?: string) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.swiftClientConsumer = swiftClientConsumer;\n\t}\n\n\tprivate static get(url: string) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\treturn new Promise<{ success: boolean; body: string; status: number }>(\n\t\t\t(res) => {\n\t\t\t\tconst headers = new Headers({\n\t\t\t\t\t...this.getSwiftHeaders(),\n\t\t\t\t});\n\n\t\t\t\tfetch(`${this.baseUrl}${url}`, {\n\t\t\t\t\theaders,\n\t\t\t\t})\n\t\t\t\t\t.then(async (response) => {\n\t\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\t\tres({\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t\t});\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate static post(url: string, bodyObject: any) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { ...this.getSwiftHeaders() },\n\t\t\tbody: JSON.stringify(bodyObject),\n\t\t};\n\n\t\treturn new Promise<{\n\t\t\tsuccess: boolean;\n\t\t\tbody: SwiftServerOrderProcessResponse;\n\t\t\tstatus: number;\n\t\t}>((res) => {\n\t\t\tconst postRequest = new Request(`${this.baseUrl}${url}`, requestOptions);\n\n\t\t\tfetch(postRequest)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tlet resBody: SwiftServerOrderProcessResponse | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresBody =\n\t\t\t\t\t\t\t(await response.json()) as SwiftServerOrderProcessResponse;\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: response.ok,\n\t\t\t\t\t\t\tbody: resBody,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tallEnvDlog('swiftClient', 'Error reading response body', err);\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tbody: err as any,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t});\n\t\t});\n\t}\n\n\tstatic async sendSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsigningAuthority?: PublicKey\n\t): ClientResponse<{\n\t\thash: string;\n\t}> {\n\t\tconst requestPayload = {\n\t\t\tmarket_index: marketIndex,\n\t\t\tmarket_type: isVariant(marketType, 'perp') ? 'perp' : 'spot',\n\t\t\tmessage,\n\t\t\tsignature: signature.toString('base64'),\n\t\t\tsigning_authority: signingAuthority?.toBase58() ?? '',\n\t\t\ttaker_authority: takerPubkey.toBase58(),\n\t\t};\n\n\t\tconst response = await this.post('/orders', requestPayload);\n\n\t\tif (response.status !== 200) {\n\t\t\tconsole.error(\n\t\t\t\t`Non-200 status code received for sent Swift order: ${response.status}`\n\t\t\t);\n\t\t\tallEnvDlog('swiftClient', 'full non-200 response body', response.body);\n\t\t\treturn {\n\t\t\t\tmessage:\n\t\t\t\t\tresponse.body?.error ||\n\t\t\t\t\tresponse.body?.message ||\n\t\t\t\t\t`HTTP ${response.status}: Error from Swift server`,\n\t\t\t\tstatus: response.status,\n\t\t\t\tsuccess: false,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmessage: `Successfully sent Swift order`,\n\t\t\tbody: {\n\t\t\t\thash: digestSignature(Uint8Array.from(signature)),\n\t\t\t},\n\t\t\tsuccess: true,\n\t\t\tstatus: 200,\n\t\t};\n\t}\n\n\tstatic async confirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number\n\t): Promise<number | undefined> {\n\t\tallEnvDlog(\n\t\t\t'swiftClient',\n\t\t\t'confirmSwiftOrderWS - confirmation duration',\n\t\t\tconfirmDuration\n\t\t);\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\treject(new Error('Order not found'));\n\t\t\t}, confirmDuration);\n\n\t\t\tconnection\n\t\t\t\t.getAccountInfo(signedMsgUserOrdersAccount, 'confirmed')\n\t\t\t\t.then((accountInfo) => {\n\t\t\t\t\tif (!accountInfo) {\n\t\t\t\t\t\treject(new Error('Swift message account not found'));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in initial fetch orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\tresolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tconst subId = connection.onAccountChange(\n\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t(accountInfo) => {\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in onAccountChange orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconnection.removeAccountChangeListener(subId);\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\tresolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'confirmed'\n\t\t\t);\n\t\t});\n\t}\n\n\tstatic findOrderInSignedMsgUserOrdersAccount(\n\t\tclient: DriftClient,\n\t\tordersAccount: AccountInfo<Buffer>,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t) {\n\t\tconst accountDecoder =\n\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts.decodeUnchecked.bind(\n\t\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts\n\t\t\t);\n\t\tconst decodedAccount = accountDecoder(\n\t\t\t'SignedMsgUserOrders',\n\t\t\tordersAccount.data\n\t\t) as SignedMsgUserOrdersAccount;\n\t\tallEnvDlog(\n\t\t\t'swiftClient findOrder',\n\t\t\t'decodedAccount\\n',\n\t\t\tdecodedAccount,\n\t\t\tsignedMsgOrderUuid.toString()\n\t\t);\n\t\tconst order = decodedAccount.signedMsgOrderData.find(\n\t\t\t(order) => order.uuid.toString() === signedMsgOrderUuid.toString()\n\t\t);\n\t\tallEnvDlog('swiftClient findOrder', 'order\\n', order);\n\t\treturn order;\n\t}\n\n\tstatic async confirmSwiftOrder(\n\t\thash: string,\n\t\tconfirmDuration: number\n\t): Promise<\n\t\tClientResponse<\n\t\t\t| {\n\t\t\t\t\torderId: string;\n\t\t\t\t\tstatus: 'confirmed';\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tstatus: 'expired';\n\t\t\t }\n\t\t>\n\t> {\n\t\tconst expireTime = Date.now() + confirmDuration;\n\n\t\twhile (Date.now() < expireTime) {\n\t\t\tconst confirmResponse = await this.get(\n\t\t\t\t`/confirmation/hash-status?hash=${encodeURIComponent(hash)}`\n\t\t\t);\n\n\t\t\tif (confirmResponse.status === 200) {\n\t\t\t\tconsole.log('Confirmed hash: ', hash);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\tmessage: 'Confirmed hash: ' + hash,\n\t\t\t\t\tbody: {\n\t\t\t\t\t\torderId: confirmResponse.body,\n\t\t\t\t\t\tstatus: 'confirmed',\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else if (\n\t\t\t\tconfirmResponse.status >= 500 ||\n\t\t\t\tconfirmResponse.status < 200\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t}\n\n\t\tconsole.error('Failed to confirm hash: ', hash);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tstatus: 408,\n\t\t\tmessage: 'Failed to confirm hash: ' + hash,\n\t\t\tbody: {\n\t\t\t\tstatus: 'expired',\n\t\t\t},\n\t\t};\n\t}\n\n\tstatic async handleSwiftOrderSubscriber(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst confirmResponse = await this.confirmSwiftOrder(hash, confirmDuration);\n\n\t\tif (!confirmResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: confirmResponse.body.status as 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: confirmResponse.message,\n\t\t\t\tstatus: confirmResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t}\n\t\tif (confirmResponse.body.status === 'confirmed') {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: confirmResponse.body.orderId,\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\tstatic async handleSwiftOrderSubscriberWS(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\t\tallEnvDlog('swiftClient', 'sendResponse\\n', sendResponse);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: 'Error from swift node: ' + sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst orderID = await this.confirmSwiftOrderWS(\n\t\t\tconnection,\n\t\t\tclient,\n\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\tsignedMsgOrderUuid,\n\t\t\tconfirmDuration\n\t\t).catch((err) => {\n\t\t\tallEnvDlog('swiftClient', 'confirmSwiftOrderWS error', err);\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t});\n\n\t\tif (!orderID) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: orderID.toString(),\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\n\tpublic static sendAndConfirmSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriber(\n\t\t\t\tsubscriber,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static sendAndConfirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriberWS(\n\t\t\t\tsubscriber,\n\t\t\t\tconnection,\n\t\t\t\tclient,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\t\tsignedMsgOrderUuid,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static async isSwiftServerHealthy(): Promise<boolean> {\n\t\tconst response = await this.get('/health');\n\t\treturn response.status === 200;\n\t}\n\n\tprivate static getSwiftHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'X-Swift-Client-Consumer': this.swiftClientConsumer ?? 'default',\n\t\t};\n\t}\n\n\tpublic static isSupportedOrderType(orderType: OrderType) {\n\t\treturn this.supportedOrderTypes.includes(orderType);\n\t}\n}\n"]}
@@ -83,7 +83,7 @@ export declare const COMMON_UI_UTILS: {
83
83
  getMarketStepSize: (driftClient: DriftClient, marketId: import("src/types").MarketId) => BN;
84
84
  getMarketStepSizeDecimals: (driftClient: DriftClient, marketId: import("src/types").MarketId) => number;
85
85
  isEntirePositionOrder: (orderAmount: BigNum) => boolean;
86
- getMarginUsedForPosition: (user: User, marketIndex: number) => BN;
86
+ getMarginUsedForPosition: (user: User, marketIndex: number, includeOpenOrders?: boolean) => BN;
87
87
  validateLeverageChange: ({ user, marketIndex, newLeverage, }: {
88
88
  user: User;
89
89
  marketIndex: number;
@@ -54,7 +54,7 @@ export declare const TRADING_UTILS: {
54
54
  getMarketStepSize: (driftClient: DriftClient, marketId: MarketId) => BN;
55
55
  getMarketStepSizeDecimals: (driftClient: DriftClient, marketId: MarketId) => number;
56
56
  isEntirePositionOrder: (orderAmount: BigNum) => boolean;
57
- getMarginUsedForPosition: (user: User, marketIndex: number) => BN | undefined;
57
+ getMarginUsedForPosition: (user: User, marketIndex: number, includeOpenOrders?: boolean) => BN | undefined;
58
58
  validateLeverageChange: ({ user, marketIndex, newLeverage, }: {
59
59
  user: User;
60
60
  marketIndex: number;
@@ -213,13 +213,14 @@ exports.isEntirePositionOrder = isEntirePositionOrder;
213
213
  * Calculate the margin used for a specific perp position
214
214
  * Returns the minimum of user's total collateral or the position's weighted value
215
215
  */
216
- const getMarginUsedForPosition = (user, marketIndex) => {
216
+ const getMarginUsedForPosition = (user, marketIndex, includeOpenOrders = true) => {
217
217
  const perpPosition = user.getPerpPosition(marketIndex);
218
218
  if (!perpPosition)
219
219
  return undefined;
220
220
  const hc = user.getPerpPositionHealth({
221
221
  marginCategory: 'Initial',
222
222
  perpPosition,
223
+ includeOpenOrders,
223
224
  });
224
225
  const userCollateral = user.getTotalCollateral();
225
226
  return userCollateral.lt(hc.weightedValue)
@@ -1 +1 @@
1
- {"version":3,"file":"trading.js","sourceRoot":"","sources":["../../src/common-ui-utils/trading.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tMARGIN_PRECISION,\n\tMAX_LEVERAGE_ORDER_SIZE,\n\tONE,\n\tPRICE_PRECISION,\n\tPRICE_PRECISION_EXP,\n\tPerpMarketAccount,\n\tPositionDirection,\n\tQUOTE_PRECISION_EXP,\n\tSpotMarketAccount,\n\tUser,\n\tZERO,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { MarketId, OpenPosition, UIOrderType } from 'src/types';\n\nconst calculatePnlPctFromPosition = (\n\tpnl: BN,\n\tposition: OpenPosition,\n\tmarginUsed?: BN\n): number => {\n\tif (!position?.quoteEntryAmount || position?.quoteEntryAmount.eq(ZERO))\n\t\treturn 0;\n\n\tlet marginUsedNum: number;\n\n\tif (marginUsed) {\n\t\tmarginUsedNum = BigNum.from(marginUsed, QUOTE_PRECISION_EXP).toNum();\n\t} else {\n\t\tconst leverage = convertMarginRatioToLeverage(position.maxMarginRatio) ?? 1;\n\t\tconst quoteEntryAmountNum = BigNum.from(\n\t\t\tposition.quoteEntryAmount.abs(),\n\t\t\tQUOTE_PRECISION_EXP\n\t\t).toNum();\n\n\t\tif (leverage <= 0 || quoteEntryAmountNum <= 0) {\n\t\t\tmarginUsedNum = 0;\n\t\t} else {\n\t\t\tmarginUsedNum = quoteEntryAmountNum / leverage;\n\t\t}\n\t}\n\n\tif (marginUsedNum <= 0) {\n\t\treturn 0;\n\t}\n\n\treturn (\n\t\tBigNum.from(pnl, QUOTE_PRECISION_EXP)\n\t\t\t.shift(5)\n\t\t\t.div(BigNum.fromPrint(`${marginUsedNum}`, QUOTE_PRECISION_EXP))\n\t\t\t.toNum() * 100\n\t);\n};\n\nconst POTENTIAL_PROFIT_DEFAULT_STATE = {\n\testimatedProfit: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedProfitBeforeFees: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedTakerFee: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtEntry: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtExit: BigNum.zero(PRICE_PRECISION_EXP),\n};\n\nconst calculatePotentialProfit = (props: {\n\tcurrentPositionSize: BigNum;\n\tcurrentPositionDirection: PositionDirection;\n\tcurrentPositionEntryPrice: BigNum;\n\ttradeDirection: PositionDirection;\n\t/**\n\t * Amount of position being closed in base asset size\n\t */\n\texitBaseSize: BigNum;\n\t/**\n\t * Either the user's limit price (for limit orders) or the estimated exit price (for market orders)\n\t */\n\texitPrice: BigNum;\n\ttakerFeeBps: number;\n\tslippageTolerance?: number;\n\tisMarketOrder?: boolean;\n}): {\n\testimatedProfit: BigNum;\n\testimatedProfitBeforeFees: BigNum;\n\testimatedTakerFee: BigNum;\n\tnotionalSizeAtEntry: BigNum;\n\tnotionalSizeAtExit: BigNum;\n} => {\n\tlet estimatedProfit = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedProfitBeforeFees = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedTakerFee = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtEntry = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtExit = BigNum.zero(PRICE_PRECISION_EXP);\n\n\tconst isClosingLong =\n\t\tisVariant(props.currentPositionDirection, 'long') &&\n\t\tisVariant(props.tradeDirection, 'short');\n\tconst isClosingShort =\n\t\tisVariant(props.currentPositionDirection, 'short') &&\n\t\tisVariant(props.tradeDirection, 'long');\n\n\tif (!isClosingLong && !isClosingShort) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\tif (!props.exitBaseSize) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\n\tif (\n\t\tprops.exitBaseSize.eqZero() ||\n\t\tprops.currentPositionSize.lt(props.exitBaseSize)\n\t) {\n\t\treturn POTENTIAL_PROFIT_DEFAULT_STATE;\n\t}\n\n\tconst baseSizeBeingClosed = props.exitBaseSize.lte(props.currentPositionSize)\n\t\t? props.exitBaseSize\n\t\t: props.currentPositionSize;\n\n\t// Notional size of amount being closed at entry and exit\n\tnotionalSizeAtEntry = baseSizeBeingClosed.mul(\n\t\tprops.currentPositionEntryPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\tnotionalSizeAtExit = baseSizeBeingClosed.mul(\n\t\tprops.exitPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\n\tif (isClosingLong) {\n\t\testimatedProfitBeforeFees = notionalSizeAtExit.sub(notionalSizeAtEntry);\n\t} else if (isClosingShort) {\n\t\testimatedProfitBeforeFees = notionalSizeAtEntry.sub(notionalSizeAtExit);\n\t}\n\n\t// subtract takerFee if applicable\n\tif (props.takerFeeBps > 0) {\n\t\tconst takerFeeDenominator = Math.floor(100 / (props.takerFeeBps * 0.01));\n\t\testimatedTakerFee = notionalSizeAtExit.scale(1, takerFeeDenominator);\n\t\testimatedProfit = estimatedProfitBeforeFees.sub(\n\t\t\testimatedTakerFee.shiftTo(estimatedProfitBeforeFees.precision)\n\t\t);\n\t} else {\n\t\testimatedProfit = estimatedProfitBeforeFees;\n\t}\n\n\treturn {\n\t\testimatedProfit,\n\t\testimatedProfitBeforeFees,\n\t\testimatedTakerFee,\n\t\tnotionalSizeAtEntry,\n\t\tnotionalSizeAtExit,\n\t};\n};\n\n/**\n * Check if the order type is a market order or oracle market order\n */\nconst checkIsMarketOrderType = (orderType: UIOrderType) => {\n\treturn orderType === 'market' || orderType === 'oracle';\n};\n\n/**\n * Calculate the liquidation price of a position after a trade. Requires DriftClient to be subscribed.\n * If the order type is limit order, a limit price must be provided.\n */\nconst calculateLiquidationPriceAfterPerpTrade = ({\n\testEntryPrice,\n\torderType,\n\tperpMarketIndex,\n\ttradeBaseSize,\n\tisLong,\n\tuserClient,\n\toraclePrice,\n\tlimitPrice,\n\toffsetCollateral,\n\tprecision = 2,\n\tisEnteringHighLeverageMode,\n\tcapLiqPrice,\n}: {\n\testEntryPrice: BN;\n\torderType: UIOrderType;\n\tperpMarketIndex: number;\n\ttradeBaseSize: BN;\n\tisLong: boolean;\n\tuserClient: User;\n\toraclePrice: BN;\n\tlimitPrice?: BN;\n\toffsetCollateral?: BN;\n\tprecision?: number;\n\tisEnteringHighLeverageMode?: boolean;\n\tcapLiqPrice?: boolean;\n}) => {\n\tconst ALLOWED_ORDER_TYPES: UIOrderType[] = [\n\t\t'limit',\n\t\t'market',\n\t\t'oracle',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t];\n\n\tif (!ALLOWED_ORDER_TYPES.includes(orderType)) {\n\t\tconsole.error(\n\t\t\t'Invalid order type for perp trade liquidation price calculation',\n\t\t\torderType\n\t\t);\n\t\treturn 0;\n\t}\n\n\tif (orderType === 'limit' && !limitPrice) {\n\t\tconsole.error(\n\t\t\t'Limit order must have a limit price for perp trade liquidation price calculation'\n\t\t);\n\t\treturn 0;\n\t}\n\n\tconst signedBaseSize = isLong ? tradeBaseSize : tradeBaseSize.neg();\n\tconst priceToUse = [\n\t\t'limit',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t].includes(orderType)\n\t\t? limitPrice\n\t\t: estEntryPrice;\n\n\tconst liqPriceBn = userClient.liquidationPrice(\n\t\tperpMarketIndex,\n\t\tsignedBaseSize,\n\t\tpriceToUse,\n\t\tundefined,\n\t\tundefined, // we can exclude open orders since open orders will be cancelled first (which results in reducing account leverage) before actual liquidation\n\t\toffsetCollateral,\n\t\tisEnteringHighLeverageMode\n\t);\n\n\tif (liqPriceBn.isNeg()) {\n\t\t// means no liquidation price\n\t\treturn 0;\n\t}\n\n\t// Check if user has a spot position using the same oracle as the perp market\n\t// If so, force capLiqPrice to be false to avoid incorrect price capping\n\t// Technically in this case, liq price could be lower for a short or higher for a long\n\tconst perpMarketOracle =\n\t\tuserClient.driftClient.getPerpMarketAccount(perpMarketIndex)?.amm?.oracle;\n\n\tconst spotMarketWithSameOracle = userClient.driftClient\n\t\t.getSpotMarketAccounts()\n\t\t.find((market) => market.oracle.equals(perpMarketOracle));\n\n\tlet hasSpotPositionWithSameOracle = false;\n\tif (spotMarketWithSameOracle) {\n\t\tconst spotPosition = userClient.getSpotPosition(\n\t\t\tspotMarketWithSameOracle.marketIndex\n\t\t);\n\t\thasSpotPositionWithSameOracle = !!spotPosition;\n\t}\n\n\tconst effectiveCapLiqPrice = hasSpotPositionWithSameOracle\n\t\t? false\n\t\t: capLiqPrice;\n\n\tconst cappedLiqPriceBn = effectiveCapLiqPrice\n\t\t? isLong\n\t\t\t? BN.min(liqPriceBn, oraclePrice)\n\t\t\t: BN.max(liqPriceBn, oraclePrice)\n\t\t: liqPriceBn;\n\n\tconst liqPriceBigNum = BigNum.from(cappedLiqPriceBn, PRICE_PRECISION_EXP);\n\n\tconst liqPriceNum =\n\t\tMath.round(liqPriceBigNum.toNum() * 10 ** precision) / 10 ** precision;\n\n\treturn liqPriceNum;\n};\n\nconst convertLeverageToMarginRatio = (leverage: number): number | undefined => {\n\tif (!leverage) return undefined;\n\treturn Math.round((1 / leverage) * MARGIN_PRECISION.toNumber());\n};\n\nconst convertMarginRatioToLeverage = (\n\tmarginRatio: number,\n\tdecimals?: number\n): number | undefined => {\n\tif (!marginRatio) return undefined;\n\n\tconst leverage = 1 / (marginRatio / MARGIN_PRECISION.toNumber());\n\n\treturn decimals\n\t\t? parseFloat(leverage.toFixed(decimals))\n\t\t: Math.round(leverage);\n};\n\nconst getMarketTickSize = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n): BN => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderTickSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderTickSize;\n\t}\n};\n\nconst getMarketTickSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst tickSize = getMarketTickSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tPRICE_PRECISION.div(tickSize.eq(ZERO) ? ONE : tickSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\nconst getMarketStepSize = (driftClient: DriftClient, marketId: MarketId) => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderStepSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderStepSize;\n\t}\n};\n\nconst getMarketStepSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst stepSize = getMarketStepSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tAMM_RESERVE_PRECISION.div(stepSize.eq(ZERO) ? ONE : stepSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\n/**\n * Checks if a given order amount represents an entire position order\n * by comparing it with MAX_LEVERAGE_ORDER_SIZE\n * @param orderAmount - The BigNum order amount to check\n * @returns true if the order is for the entire position, false otherwise\n */\nexport const isEntirePositionOrder = (orderAmount: BigNum): boolean => {\n\tconst maxLeverageSize = new BigNum(\n\t\tMAX_LEVERAGE_ORDER_SIZE,\n\t\torderAmount.precision\n\t);\n\treturn Math.abs(maxLeverageSize.sub(orderAmount).toNum()) < 1;\n};\n\n/**\n * Calculate the margin used for a specific perp position\n * Returns the minimum of user's total collateral or the position's weighted value\n */\nconst getMarginUsedForPosition = (\n\tuser: User,\n\tmarketIndex: number\n): BN | undefined => {\n\tconst perpPosition = user.getPerpPosition(marketIndex);\n\tif (!perpPosition) return undefined;\n\n\tconst hc = user.getPerpPositionHealth({\n\t\tmarginCategory: 'Initial',\n\t\tperpPosition,\n\t});\n\tconst userCollateral = user.getTotalCollateral();\n\treturn userCollateral.lt(hc.weightedValue)\n\t\t? userCollateral\n\t\t: hc.weightedValue;\n};\n\n/**\n * Validate if a leverage change would exceed the user's free collateral\n * Returns true if the change is valid (doesn't exceed free collateral), false otherwise\n */\nconst validateLeverageChange = ({\n\tuser,\n\tmarketIndex,\n\tnewLeverage,\n}: {\n\tuser: User;\n\tmarketIndex: number;\n\tnewLeverage: number;\n}): boolean => {\n\ttry {\n\t\t// Convert leverage to margin ratio\n\t\tconst newMarginRatio = convertLeverageToMarginRatio(newLeverage);\n\t\tif (!newMarginRatio) return true;\n\n\t\t// Get the perp position from the user\n\t\tconst perpPosition = user.getPerpPosition(marketIndex);\n\t\tif (!perpPosition) return true;\n\n\t\t// Get current position weighted value\n\t\tconst currentPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition,\n\t\t}).weightedValue;\n\n\t\t// Create a modified version of the position with new maxMarginRatio\n\t\tconst modifiedPosition = {\n\t\t\t...perpPosition,\n\t\t\tmaxMarginRatio: newMarginRatio,\n\t\t};\n\n\t\t// Calculate new weighted value with the modified position\n\t\tconst newPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition: modifiedPosition,\n\t\t}).weightedValue;\n\n\t\tconst perpPositionWeightedValueDelta = newPositionWeightedValue.sub(\n\t\t\tcurrentPositionWeightedValue\n\t\t);\n\n\t\tconst freeCollateral = user.getFreeCollateral();\n\n\t\t// Check if weighted value delta exceeds free collateral\n\t\treturn perpPositionWeightedValueDelta.lte(freeCollateral);\n\t} catch (error) {\n\t\tconsole.warn('Error validating leverage change:', error);\n\t\treturn true; // Allow change if validation fails\n\t}\n};\n\nexport const TRADING_UTILS = {\n\tcalculatePnlPctFromPosition,\n\tcalculatePotentialProfit,\n\tcalculateLiquidationPriceAfterPerpTrade,\n\tcheckIsMarketOrderType,\n\tconvertLeverageToMarginRatio,\n\tconvertMarginRatioToLeverage,\n\tgetMarketTickSize,\n\tgetMarketTickSizeDecimals,\n\tgetMarketStepSize,\n\tgetMarketStepSizeDecimals,\n\tisEntirePositionOrder,\n\tgetMarginUsedForPosition,\n\tvalidateLeverageChange,\n};\n"]}
1
+ {"version":3,"file":"trading.js","sourceRoot":"","sources":["../../src/common-ui-utils/trading.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tMARGIN_PRECISION,\n\tMAX_LEVERAGE_ORDER_SIZE,\n\tONE,\n\tPRICE_PRECISION,\n\tPRICE_PRECISION_EXP,\n\tPerpMarketAccount,\n\tPositionDirection,\n\tQUOTE_PRECISION_EXP,\n\tSpotMarketAccount,\n\tUser,\n\tZERO,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { MarketId, OpenPosition, UIOrderType } from 'src/types';\n\nconst calculatePnlPctFromPosition = (\n\tpnl: BN,\n\tposition: OpenPosition,\n\tmarginUsed?: BN\n): number => {\n\tif (!position?.quoteEntryAmount || position?.quoteEntryAmount.eq(ZERO))\n\t\treturn 0;\n\n\tlet marginUsedNum: number;\n\n\tif (marginUsed) {\n\t\tmarginUsedNum = BigNum.from(marginUsed, QUOTE_PRECISION_EXP).toNum();\n\t} else {\n\t\tconst leverage = convertMarginRatioToLeverage(position.maxMarginRatio) ?? 1;\n\t\tconst quoteEntryAmountNum = BigNum.from(\n\t\t\tposition.quoteEntryAmount.abs(),\n\t\t\tQUOTE_PRECISION_EXP\n\t\t).toNum();\n\n\t\tif (leverage <= 0 || quoteEntryAmountNum <= 0) {\n\t\t\tmarginUsedNum = 0;\n\t\t} else {\n\t\t\tmarginUsedNum = quoteEntryAmountNum / leverage;\n\t\t}\n\t}\n\n\tif (marginUsedNum <= 0) {\n\t\treturn 0;\n\t}\n\n\treturn (\n\t\tBigNum.from(pnl, QUOTE_PRECISION_EXP)\n\t\t\t.shift(5)\n\t\t\t.div(BigNum.fromPrint(`${marginUsedNum}`, QUOTE_PRECISION_EXP))\n\t\t\t.toNum() * 100\n\t);\n};\n\nconst POTENTIAL_PROFIT_DEFAULT_STATE = {\n\testimatedProfit: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedProfitBeforeFees: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedTakerFee: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtEntry: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtExit: BigNum.zero(PRICE_PRECISION_EXP),\n};\n\nconst calculatePotentialProfit = (props: {\n\tcurrentPositionSize: BigNum;\n\tcurrentPositionDirection: PositionDirection;\n\tcurrentPositionEntryPrice: BigNum;\n\ttradeDirection: PositionDirection;\n\t/**\n\t * Amount of position being closed in base asset size\n\t */\n\texitBaseSize: BigNum;\n\t/**\n\t * Either the user's limit price (for limit orders) or the estimated exit price (for market orders)\n\t */\n\texitPrice: BigNum;\n\ttakerFeeBps: number;\n\tslippageTolerance?: number;\n\tisMarketOrder?: boolean;\n}): {\n\testimatedProfit: BigNum;\n\testimatedProfitBeforeFees: BigNum;\n\testimatedTakerFee: BigNum;\n\tnotionalSizeAtEntry: BigNum;\n\tnotionalSizeAtExit: BigNum;\n} => {\n\tlet estimatedProfit = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedProfitBeforeFees = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedTakerFee = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtEntry = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtExit = BigNum.zero(PRICE_PRECISION_EXP);\n\n\tconst isClosingLong =\n\t\tisVariant(props.currentPositionDirection, 'long') &&\n\t\tisVariant(props.tradeDirection, 'short');\n\tconst isClosingShort =\n\t\tisVariant(props.currentPositionDirection, 'short') &&\n\t\tisVariant(props.tradeDirection, 'long');\n\n\tif (!isClosingLong && !isClosingShort) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\tif (!props.exitBaseSize) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\n\tif (\n\t\tprops.exitBaseSize.eqZero() ||\n\t\tprops.currentPositionSize.lt(props.exitBaseSize)\n\t) {\n\t\treturn POTENTIAL_PROFIT_DEFAULT_STATE;\n\t}\n\n\tconst baseSizeBeingClosed = props.exitBaseSize.lte(props.currentPositionSize)\n\t\t? props.exitBaseSize\n\t\t: props.currentPositionSize;\n\n\t// Notional size of amount being closed at entry and exit\n\tnotionalSizeAtEntry = baseSizeBeingClosed.mul(\n\t\tprops.currentPositionEntryPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\tnotionalSizeAtExit = baseSizeBeingClosed.mul(\n\t\tprops.exitPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\n\tif (isClosingLong) {\n\t\testimatedProfitBeforeFees = notionalSizeAtExit.sub(notionalSizeAtEntry);\n\t} else if (isClosingShort) {\n\t\testimatedProfitBeforeFees = notionalSizeAtEntry.sub(notionalSizeAtExit);\n\t}\n\n\t// subtract takerFee if applicable\n\tif (props.takerFeeBps > 0) {\n\t\tconst takerFeeDenominator = Math.floor(100 / (props.takerFeeBps * 0.01));\n\t\testimatedTakerFee = notionalSizeAtExit.scale(1, takerFeeDenominator);\n\t\testimatedProfit = estimatedProfitBeforeFees.sub(\n\t\t\testimatedTakerFee.shiftTo(estimatedProfitBeforeFees.precision)\n\t\t);\n\t} else {\n\t\testimatedProfit = estimatedProfitBeforeFees;\n\t}\n\n\treturn {\n\t\testimatedProfit,\n\t\testimatedProfitBeforeFees,\n\t\testimatedTakerFee,\n\t\tnotionalSizeAtEntry,\n\t\tnotionalSizeAtExit,\n\t};\n};\n\n/**\n * Check if the order type is a market order or oracle market order\n */\nconst checkIsMarketOrderType = (orderType: UIOrderType) => {\n\treturn orderType === 'market' || orderType === 'oracle';\n};\n\n/**\n * Calculate the liquidation price of a position after a trade. Requires DriftClient to be subscribed.\n * If the order type is limit order, a limit price must be provided.\n */\nconst calculateLiquidationPriceAfterPerpTrade = ({\n\testEntryPrice,\n\torderType,\n\tperpMarketIndex,\n\ttradeBaseSize,\n\tisLong,\n\tuserClient,\n\toraclePrice,\n\tlimitPrice,\n\toffsetCollateral,\n\tprecision = 2,\n\tisEnteringHighLeverageMode,\n\tcapLiqPrice,\n}: {\n\testEntryPrice: BN;\n\torderType: UIOrderType;\n\tperpMarketIndex: number;\n\ttradeBaseSize: BN;\n\tisLong: boolean;\n\tuserClient: User;\n\toraclePrice: BN;\n\tlimitPrice?: BN;\n\toffsetCollateral?: BN;\n\tprecision?: number;\n\tisEnteringHighLeverageMode?: boolean;\n\tcapLiqPrice?: boolean;\n}) => {\n\tconst ALLOWED_ORDER_TYPES: UIOrderType[] = [\n\t\t'limit',\n\t\t'market',\n\t\t'oracle',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t];\n\n\tif (!ALLOWED_ORDER_TYPES.includes(orderType)) {\n\t\tconsole.error(\n\t\t\t'Invalid order type for perp trade liquidation price calculation',\n\t\t\torderType\n\t\t);\n\t\treturn 0;\n\t}\n\n\tif (orderType === 'limit' && !limitPrice) {\n\t\tconsole.error(\n\t\t\t'Limit order must have a limit price for perp trade liquidation price calculation'\n\t\t);\n\t\treturn 0;\n\t}\n\n\tconst signedBaseSize = isLong ? tradeBaseSize : tradeBaseSize.neg();\n\tconst priceToUse = [\n\t\t'limit',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t].includes(orderType)\n\t\t? limitPrice\n\t\t: estEntryPrice;\n\n\tconst liqPriceBn = userClient.liquidationPrice(\n\t\tperpMarketIndex,\n\t\tsignedBaseSize,\n\t\tpriceToUse,\n\t\tundefined,\n\t\tundefined, // we can exclude open orders since open orders will be cancelled first (which results in reducing account leverage) before actual liquidation\n\t\toffsetCollateral,\n\t\tisEnteringHighLeverageMode\n\t);\n\n\tif (liqPriceBn.isNeg()) {\n\t\t// means no liquidation price\n\t\treturn 0;\n\t}\n\n\t// Check if user has a spot position using the same oracle as the perp market\n\t// If so, force capLiqPrice to be false to avoid incorrect price capping\n\t// Technically in this case, liq price could be lower for a short or higher for a long\n\tconst perpMarketOracle =\n\t\tuserClient.driftClient.getPerpMarketAccount(perpMarketIndex)?.amm?.oracle;\n\n\tconst spotMarketWithSameOracle = userClient.driftClient\n\t\t.getSpotMarketAccounts()\n\t\t.find((market) => market.oracle.equals(perpMarketOracle));\n\n\tlet hasSpotPositionWithSameOracle = false;\n\tif (spotMarketWithSameOracle) {\n\t\tconst spotPosition = userClient.getSpotPosition(\n\t\t\tspotMarketWithSameOracle.marketIndex\n\t\t);\n\t\thasSpotPositionWithSameOracle = !!spotPosition;\n\t}\n\n\tconst effectiveCapLiqPrice = hasSpotPositionWithSameOracle\n\t\t? false\n\t\t: capLiqPrice;\n\n\tconst cappedLiqPriceBn = effectiveCapLiqPrice\n\t\t? isLong\n\t\t\t? BN.min(liqPriceBn, oraclePrice)\n\t\t\t: BN.max(liqPriceBn, oraclePrice)\n\t\t: liqPriceBn;\n\n\tconst liqPriceBigNum = BigNum.from(cappedLiqPriceBn, PRICE_PRECISION_EXP);\n\n\tconst liqPriceNum =\n\t\tMath.round(liqPriceBigNum.toNum() * 10 ** precision) / 10 ** precision;\n\n\treturn liqPriceNum;\n};\n\nconst convertLeverageToMarginRatio = (leverage: number): number | undefined => {\n\tif (!leverage) return undefined;\n\treturn Math.round((1 / leverage) * MARGIN_PRECISION.toNumber());\n};\n\nconst convertMarginRatioToLeverage = (\n\tmarginRatio: number,\n\tdecimals?: number\n): number | undefined => {\n\tif (!marginRatio) return undefined;\n\n\tconst leverage = 1 / (marginRatio / MARGIN_PRECISION.toNumber());\n\n\treturn decimals\n\t\t? parseFloat(leverage.toFixed(decimals))\n\t\t: Math.round(leverage);\n};\n\nconst getMarketTickSize = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n): BN => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderTickSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderTickSize;\n\t}\n};\n\nconst getMarketTickSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst tickSize = getMarketTickSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tPRICE_PRECISION.div(tickSize.eq(ZERO) ? ONE : tickSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\nconst getMarketStepSize = (driftClient: DriftClient, marketId: MarketId) => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderStepSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderStepSize;\n\t}\n};\n\nconst getMarketStepSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst stepSize = getMarketStepSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tAMM_RESERVE_PRECISION.div(stepSize.eq(ZERO) ? ONE : stepSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\n/**\n * Checks if a given order amount represents an entire position order\n * by comparing it with MAX_LEVERAGE_ORDER_SIZE\n * @param orderAmount - The BigNum order amount to check\n * @returns true if the order is for the entire position, false otherwise\n */\nexport const isEntirePositionOrder = (orderAmount: BigNum): boolean => {\n\tconst maxLeverageSize = new BigNum(\n\t\tMAX_LEVERAGE_ORDER_SIZE,\n\t\torderAmount.precision\n\t);\n\treturn Math.abs(maxLeverageSize.sub(orderAmount).toNum()) < 1;\n};\n\n/**\n * Calculate the margin used for a specific perp position\n * Returns the minimum of user's total collateral or the position's weighted value\n */\nconst getMarginUsedForPosition = (\n\tuser: User,\n\tmarketIndex: number,\n\tincludeOpenOrders = true\n): BN | undefined => {\n\tconst perpPosition = user.getPerpPosition(marketIndex);\n\tif (!perpPosition) return undefined;\n\n\tconst hc = user.getPerpPositionHealth({\n\t\tmarginCategory: 'Initial',\n\t\tperpPosition,\n\t\tincludeOpenOrders,\n\t});\n\tconst userCollateral = user.getTotalCollateral();\n\treturn userCollateral.lt(hc.weightedValue)\n\t\t? userCollateral\n\t\t: hc.weightedValue;\n};\n\n/**\n * Validate if a leverage change would exceed the user's free collateral\n * Returns true if the change is valid (doesn't exceed free collateral), false otherwise\n */\nconst validateLeverageChange = ({\n\tuser,\n\tmarketIndex,\n\tnewLeverage,\n}: {\n\tuser: User;\n\tmarketIndex: number;\n\tnewLeverage: number;\n}): boolean => {\n\ttry {\n\t\t// Convert leverage to margin ratio\n\t\tconst newMarginRatio = convertLeverageToMarginRatio(newLeverage);\n\t\tif (!newMarginRatio) return true;\n\n\t\t// Get the perp position from the user\n\t\tconst perpPosition = user.getPerpPosition(marketIndex);\n\t\tif (!perpPosition) return true;\n\n\t\t// Get current position weighted value\n\t\tconst currentPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition,\n\t\t}).weightedValue;\n\n\t\t// Create a modified version of the position with new maxMarginRatio\n\t\tconst modifiedPosition = {\n\t\t\t...perpPosition,\n\t\t\tmaxMarginRatio: newMarginRatio,\n\t\t};\n\n\t\t// Calculate new weighted value with the modified position\n\t\tconst newPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition: modifiedPosition,\n\t\t}).weightedValue;\n\n\t\tconst perpPositionWeightedValueDelta = newPositionWeightedValue.sub(\n\t\t\tcurrentPositionWeightedValue\n\t\t);\n\n\t\tconst freeCollateral = user.getFreeCollateral();\n\n\t\t// Check if weighted value delta exceeds free collateral\n\t\treturn perpPositionWeightedValueDelta.lte(freeCollateral);\n\t} catch (error) {\n\t\tconsole.warn('Error validating leverage change:', error);\n\t\treturn true; // Allow change if validation fails\n\t}\n};\n\nexport const TRADING_UTILS = {\n\tcalculatePnlPctFromPosition,\n\tcalculatePotentialProfit,\n\tcalculateLiquidationPriceAfterPerpTrade,\n\tcheckIsMarketOrderType,\n\tconvertLeverageToMarginRatio,\n\tconvertMarginRatioToLeverage,\n\tgetMarketTickSize,\n\tgetMarketTickSizeDecimals,\n\tgetMarketStepSize,\n\tgetMarketStepSizeDecimals,\n\tisEntirePositionOrder,\n\tgetMarginUsedForPosition,\n\tvalidateLeverageChange,\n};\n"]}