@drift-labs/sdk 2.152.0-beta.1 → 2.153.0-beta.0

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 (46) hide show
  1. package/VERSION +1 -1
  2. package/build-browser.js +58 -0
  3. package/bun.lock +182 -1
  4. package/esbuild-shims.js +12 -0
  5. package/lib/browser/constants/perpMarkets.js +12 -0
  6. package/lib/browser/constants/txConstants.d.ts +1 -0
  7. package/lib/browser/constants/txConstants.js +2 -1
  8. package/lib/browser/driftClient.d.ts +13 -6
  9. package/lib/browser/driftClient.js +280 -36
  10. package/lib/browser/idl/drift.json +207 -18
  11. package/lib/browser/markets.d.ts +5 -0
  12. package/lib/browser/markets.js +16 -0
  13. package/lib/browser/swap/UnifiedSwapClient.d.ts +2 -1
  14. package/lib/browser/swap/UnifiedSwapClient.js +5 -5
  15. package/lib/browser/titan/titanClient.d.ts +6 -1
  16. package/lib/browser/titan/titanClient.js +80 -53
  17. package/lib/browser/user.d.ts +1 -1
  18. package/lib/node/constants/perpMarkets.d.ts.map +1 -1
  19. package/lib/node/constants/perpMarkets.js +12 -0
  20. package/lib/node/constants/txConstants.d.ts +1 -0
  21. package/lib/node/constants/txConstants.d.ts.map +1 -1
  22. package/lib/node/constants/txConstants.js +2 -1
  23. package/lib/node/driftClient.d.ts +13 -6
  24. package/lib/node/driftClient.d.ts.map +1 -1
  25. package/lib/node/driftClient.js +280 -36
  26. package/lib/node/idl/drift.json +207 -18
  27. package/lib/node/markets.d.ts +6 -0
  28. package/lib/node/markets.d.ts.map +1 -0
  29. package/lib/node/markets.js +16 -0
  30. package/lib/node/swap/UnifiedSwapClient.d.ts +2 -1
  31. package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
  32. package/lib/node/swap/UnifiedSwapClient.js +5 -5
  33. package/lib/node/titan/titanClient.d.ts +6 -1
  34. package/lib/node/titan/titanClient.d.ts.map +1 -1
  35. package/lib/node/titan/titanClient.js +80 -53
  36. package/lib/node/user.d.ts +1 -1
  37. package/lib/node/user.d.ts.map +1 -1
  38. package/package.json +10 -2
  39. package/src/constants/perpMarkets.ts +13 -0
  40. package/src/constants/txConstants.ts +2 -0
  41. package/src/driftClient.ts +477 -52
  42. package/src/idl/drift.json +207 -18
  43. package/src/markets.ts +24 -0
  44. package/src/swap/UnifiedSwapClient.ts +7 -5
  45. package/src/titan/titanClient.ts +114 -66
  46. package/src/user.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.150.0",
2
+ "version": "2.152.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -23,7 +23,7 @@
23
23
  {
24
24
  "name": "authority",
25
25
  "isMut": false,
26
- "isSigner": true
26
+ "isSigner": false
27
27
  },
28
28
  {
29
29
  "name": "payer",
@@ -73,7 +73,7 @@
73
73
  {
74
74
  "name": "authority",
75
75
  "isMut": false,
76
- "isSigner": true
76
+ "isSigner": false
77
77
  },
78
78
  {
79
79
  "name": "payer",
@@ -652,6 +652,163 @@
652
652
  }
653
653
  ]
654
654
  },
655
+ {
656
+ "name": "depositIntoIsolatedPerpPosition",
657
+ "accounts": [
658
+ {
659
+ "name": "state",
660
+ "isMut": false,
661
+ "isSigner": false
662
+ },
663
+ {
664
+ "name": "user",
665
+ "isMut": true,
666
+ "isSigner": false
667
+ },
668
+ {
669
+ "name": "userStats",
670
+ "isMut": true,
671
+ "isSigner": false
672
+ },
673
+ {
674
+ "name": "authority",
675
+ "isMut": false,
676
+ "isSigner": true
677
+ },
678
+ {
679
+ "name": "spotMarketVault",
680
+ "isMut": true,
681
+ "isSigner": false
682
+ },
683
+ {
684
+ "name": "userTokenAccount",
685
+ "isMut": true,
686
+ "isSigner": false
687
+ },
688
+ {
689
+ "name": "tokenProgram",
690
+ "isMut": false,
691
+ "isSigner": false
692
+ }
693
+ ],
694
+ "args": [
695
+ {
696
+ "name": "spotMarketIndex",
697
+ "type": "u16"
698
+ },
699
+ {
700
+ "name": "perpMarketIndex",
701
+ "type": "u16"
702
+ },
703
+ {
704
+ "name": "amount",
705
+ "type": "u64"
706
+ }
707
+ ]
708
+ },
709
+ {
710
+ "name": "transferIsolatedPerpPositionDeposit",
711
+ "accounts": [
712
+ {
713
+ "name": "user",
714
+ "isMut": true,
715
+ "isSigner": false
716
+ },
717
+ {
718
+ "name": "userStats",
719
+ "isMut": true,
720
+ "isSigner": false
721
+ },
722
+ {
723
+ "name": "authority",
724
+ "isMut": false,
725
+ "isSigner": true
726
+ },
727
+ {
728
+ "name": "state",
729
+ "isMut": false,
730
+ "isSigner": false
731
+ },
732
+ {
733
+ "name": "spotMarketVault",
734
+ "isMut": false,
735
+ "isSigner": false
736
+ }
737
+ ],
738
+ "args": [
739
+ {
740
+ "name": "spotMarketIndex",
741
+ "type": "u16"
742
+ },
743
+ {
744
+ "name": "perpMarketIndex",
745
+ "type": "u16"
746
+ },
747
+ {
748
+ "name": "amount",
749
+ "type": "i64"
750
+ }
751
+ ]
752
+ },
753
+ {
754
+ "name": "withdrawFromIsolatedPerpPosition",
755
+ "accounts": [
756
+ {
757
+ "name": "state",
758
+ "isMut": false,
759
+ "isSigner": false
760
+ },
761
+ {
762
+ "name": "user",
763
+ "isMut": true,
764
+ "isSigner": false
765
+ },
766
+ {
767
+ "name": "userStats",
768
+ "isMut": true,
769
+ "isSigner": false
770
+ },
771
+ {
772
+ "name": "authority",
773
+ "isMut": false,
774
+ "isSigner": true
775
+ },
776
+ {
777
+ "name": "spotMarketVault",
778
+ "isMut": true,
779
+ "isSigner": false
780
+ },
781
+ {
782
+ "name": "driftSigner",
783
+ "isMut": false,
784
+ "isSigner": false
785
+ },
786
+ {
787
+ "name": "userTokenAccount",
788
+ "isMut": true,
789
+ "isSigner": false
790
+ },
791
+ {
792
+ "name": "tokenProgram",
793
+ "isMut": false,
794
+ "isSigner": false
795
+ }
796
+ ],
797
+ "args": [
798
+ {
799
+ "name": "spotMarketIndex",
800
+ "type": "u16"
801
+ },
802
+ {
803
+ "name": "perpMarketIndex",
804
+ "type": "u16"
805
+ },
806
+ {
807
+ "name": "amount",
808
+ "type": "u64"
809
+ }
810
+ ]
811
+ },
655
812
  {
656
813
  "name": "placePerpOrder",
657
814
  "accounts": [
@@ -11584,7 +11741,7 @@
11584
11741
  },
11585
11742
  {
11586
11743
  "name": "disableUpdatePerpBidAskTwap",
11587
- "type": "bool"
11744
+ "type": "u8"
11588
11745
  },
11589
11746
  {
11590
11747
  "name": "pausedOperations",
@@ -14407,13 +14564,13 @@
14407
14564
  "type": "u64"
14408
14565
  },
14409
14566
  {
14410
- "name": "lastBaseAssetAmountPerLp",
14567
+ "name": "isolatedPositionScaledBalance",
14411
14568
  "docs": [
14412
14569
  "The last base asset amount per lp the amm had",
14413
14570
  "Used to settle the users lp position",
14414
- "precision: BASE_PRECISION"
14571
+ "precision: SPOT_BALANCE_PRECISION"
14415
14572
  ],
14416
- "type": "i64"
14573
+ "type": "u64"
14417
14574
  },
14418
14575
  {
14419
14576
  "name": "lastQuoteAssetAmountPerLp",
@@ -14452,8 +14609,8 @@
14452
14609
  "type": "u8"
14453
14610
  },
14454
14611
  {
14455
- "name": "perLpBase",
14456
- "type": "i8"
14612
+ "name": "positionFlag",
14613
+ "type": "u8"
14457
14614
  }
14458
14615
  ]
14459
14616
  }
@@ -15133,6 +15290,17 @@
15133
15290
  ]
15134
15291
  }
15135
15292
  },
15293
+ {
15294
+ "name": "LiquidationBitFlag",
15295
+ "type": {
15296
+ "kind": "enum",
15297
+ "variants": [
15298
+ {
15299
+ "name": "IsolatedPosition"
15300
+ }
15301
+ ]
15302
+ }
15303
+ },
15136
15304
  {
15137
15305
  "name": "SettlePnlExplanation",
15138
15306
  "type": {
@@ -15262,13 +15430,7 @@
15262
15430
  "kind": "enum",
15263
15431
  "variants": [
15264
15432
  {
15265
- "name": "Standard",
15266
- "fields": [
15267
- {
15268
- "name": "trackOpenOrdersFraction",
15269
- "type": "bool"
15270
- }
15271
- ]
15433
+ "name": "Standard"
15272
15434
  },
15273
15435
  {
15274
15436
  "name": "Liquidation",
@@ -15910,6 +16072,23 @@
15910
16072
  ]
15911
16073
  }
15912
16074
  },
16075
+ {
16076
+ "name": "PositionFlag",
16077
+ "type": {
16078
+ "kind": "enum",
16079
+ "variants": [
16080
+ {
16081
+ "name": "IsolatedPosition"
16082
+ },
16083
+ {
16084
+ "name": "BeingLiquidated"
16085
+ },
16086
+ {
16087
+ "name": "Bankrupt"
16088
+ }
16089
+ ]
16090
+ }
16091
+ },
15913
16092
  {
15914
16093
  "name": "ReferrerStatus",
15915
16094
  "type": {
@@ -16903,6 +17082,11 @@
16903
17082
  "defined": "SpotBankruptcyRecord"
16904
17083
  },
16905
17084
  "index": false
17085
+ },
17086
+ {
17087
+ "name": "bitFlags",
17088
+ "type": "u8",
17089
+ "index": false
16906
17090
  }
16907
17091
  ]
16908
17092
  },
@@ -18339,8 +18523,8 @@
18339
18523
  },
18340
18524
  {
18341
18525
  "code": 6094,
18342
- "name": "CantUpdatePoolBalanceType",
18343
- "msg": "CantUpdatePoolBalanceType"
18526
+ "name": "CantUpdateSpotBalanceType",
18527
+ "msg": "CantUpdateSpotBalanceType"
18344
18528
  },
18345
18529
  {
18346
18530
  "code": 6095,
@@ -19591,6 +19775,11 @@
19591
19775
  "code": 6344,
19592
19776
  "name": "MarketIndexNotFoundAmmCache",
19593
19777
  "msg": "MarketIndexNotFoundAmmCache"
19778
+ },
19779
+ {
19780
+ "code": 6345,
19781
+ "name": "InvalidIsolatedPerpMarket",
19782
+ "msg": "Invalid Isolated Perp Market"
19594
19783
  }
19595
19784
  ],
19596
19785
  "metadata": {
package/src/markets.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { DriftEnv } from './config';
2
+ import { SpotMarketConfig, SpotMarkets } from './constants';
3
+ import { PerpMarketConfig, PerpMarkets } from './constants/perpMarkets';
4
+ import { isOneOfVariant } from './types';
5
+
6
+ export const getActivePerpMarkets = (
7
+ driftEnv: DriftEnv
8
+ ): PerpMarketConfig[] => {
9
+ return PerpMarkets[driftEnv ?? 'mainnet-beta'].filter(
10
+ (market) =>
11
+ !market.marketStatus ||
12
+ !isOneOfVariant(market.marketStatus, ['delisted', 'settlement'])
13
+ );
14
+ };
15
+
16
+ export const getActiveSpotMarkets = (
17
+ driftEnv: DriftEnv
18
+ ): SpotMarketConfig[] => {
19
+ return SpotMarkets[driftEnv ?? 'mainnet-beta'].filter(
20
+ (market) =>
21
+ !market.marketStatus ||
22
+ !isOneOfVariant(market.marketStatus, ['delisted', 'settlement'])
23
+ );
24
+ };
@@ -82,11 +82,13 @@ export class UnifiedSwapClient {
82
82
  connection,
83
83
  authToken,
84
84
  url,
85
+ proxyUrl,
85
86
  }: {
86
87
  clientType: SwapClientType;
87
88
  connection: Connection;
88
- authToken?: string; // Required for Titan, optional for Jupiter
89
+ authToken?: string; // Required for Titan when not using proxy, optional for Jupiter
89
90
  url?: string; // Optional custom URL
91
+ proxyUrl?: string; // Optional proxy URL for Titan
90
92
  }) {
91
93
  this.clientType = clientType;
92
94
 
@@ -96,13 +98,11 @@ export class UnifiedSwapClient {
96
98
  url,
97
99
  });
98
100
  } else if (clientType === 'titan') {
99
- if (!authToken) {
100
- throw new Error('authToken is required for Titan client');
101
- }
102
101
  this.client = new TitanClient({
103
102
  connection,
104
- authToken,
103
+ authToken: authToken || '', // Not needed when using proxy
105
104
  url,
105
+ proxyUrl,
106
106
  });
107
107
  } else {
108
108
  throw new Error(`Unsupported client type: ${clientType}`);
@@ -143,6 +143,7 @@ export class UnifiedSwapClient {
143
143
  ...titanParams,
144
144
  userPublicKey: titanParams.userPublicKey,
145
145
  swapMode: titanParams.swapMode as string, // Titan expects string
146
+ sizeConstraint: titanParams.sizeConstraint || 1280 - 375, // Use same default as getSwapInstructions
146
147
  };
147
148
 
148
149
  return await titanClient.getQuote(titanParamsWithUser);
@@ -177,6 +178,7 @@ export class UnifiedSwapClient {
177
178
  userPublicKey,
178
179
  slippageBps: slippageBps || titanQuote.slippageBps,
179
180
  swapMode: titanQuote.swapMode,
181
+ sizeConstraint: 1280 - 375, // MAX_TX_BYTE_SIZE - buffer for drift instructions
180
182
  });
181
183
 
182
184
  return {
@@ -93,30 +93,33 @@ export class TitanClient {
93
93
  authToken: string;
94
94
  url: string;
95
95
  connection: Connection;
96
+ proxyUrl?: string;
97
+ private lastQuoteData?: SwapQuotes;
98
+ private lastQuoteParams?: string;
96
99
 
97
100
  constructor({
98
101
  connection,
99
102
  authToken,
100
103
  url,
104
+ proxyUrl,
101
105
  }: {
102
106
  connection: Connection;
103
107
  authToken: string;
104
108
  url?: string;
109
+ proxyUrl?: string;
105
110
  }) {
106
111
  this.connection = connection;
107
112
  this.authToken = authToken;
108
113
  this.url = url ?? TITAN_API_URL;
114
+ this.proxyUrl = proxyUrl;
109
115
  }
110
116
 
111
- /**
112
- * Get routes for a swap
113
- */
114
- public async getQuote({
117
+ private buildParams({
115
118
  inputMint,
116
119
  outputMint,
117
120
  amount,
118
121
  userPublicKey,
119
- maxAccounts = 50, // 50 is an estimated amount with buffer
122
+ maxAccounts,
120
123
  slippageBps,
121
124
  swapMode,
122
125
  onlyDirectRoutes,
@@ -130,43 +133,103 @@ export class TitanClient {
130
133
  userPublicKey: PublicKey;
131
134
  maxAccounts?: number;
132
135
  slippageBps?: number;
133
- swapMode?: string;
136
+ swapMode?: string | SwapMode;
134
137
  onlyDirectRoutes?: boolean;
135
138
  excludeDexes?: string[];
136
139
  sizeConstraint?: number;
137
140
  accountsLimitWritable?: number;
138
- }): Promise<QuoteResponse> {
139
- const params = new URLSearchParams({
141
+ }): URLSearchParams {
142
+ // Normalize swapMode to enum value
143
+ const normalizedSwapMode =
144
+ swapMode === 'ExactOut' || swapMode === SwapMode.ExactOut
145
+ ? SwapMode.ExactOut
146
+ : SwapMode.ExactIn;
147
+
148
+ return new URLSearchParams({
140
149
  inputMint: inputMint.toString(),
141
150
  outputMint: outputMint.toString(),
142
151
  amount: amount.toString(),
143
152
  userPublicKey: userPublicKey.toString(),
144
153
  ...(slippageBps && { slippageBps: slippageBps.toString() }),
145
- ...(swapMode && {
146
- swapMode:
147
- swapMode === 'ExactOut' ? SwapMode.ExactOut : SwapMode.ExactIn,
148
- }),
154
+ ...(swapMode && { swapMode: normalizedSwapMode.toString() }),
155
+ ...(maxAccounts && { accountsLimitTotal: maxAccounts.toString() }),
156
+ ...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
149
157
  ...(onlyDirectRoutes && {
150
158
  onlyDirectRoutes: onlyDirectRoutes.toString(),
151
159
  }),
152
- ...(maxAccounts && { accountsLimitTotal: maxAccounts.toString() }),
153
- ...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
154
160
  ...(sizeConstraint && { sizeConstraint: sizeConstraint.toString() }),
155
161
  ...(accountsLimitWritable && {
156
162
  accountsLimitWritable: accountsLimitWritable.toString(),
157
163
  }),
158
164
  });
165
+ }
159
166
 
160
- const response = await fetch(
161
- `${this.url}/api/v1/quote/swap?${params.toString()}`,
162
- {
167
+ /**
168
+ * Get routes for a swap
169
+ */
170
+ public async getQuote({
171
+ inputMint,
172
+ outputMint,
173
+ amount,
174
+ userPublicKey,
175
+ maxAccounts = 50, // 50 is an estimated amount with buffer
176
+ slippageBps,
177
+ swapMode,
178
+ onlyDirectRoutes,
179
+ excludeDexes,
180
+ sizeConstraint,
181
+ accountsLimitWritable,
182
+ }: {
183
+ inputMint: PublicKey;
184
+ outputMint: PublicKey;
185
+ amount: BN;
186
+ userPublicKey: PublicKey;
187
+ maxAccounts?: number;
188
+ slippageBps?: number;
189
+ swapMode?: string;
190
+ onlyDirectRoutes?: boolean;
191
+ excludeDexes?: string[];
192
+ sizeConstraint?: number;
193
+ accountsLimitWritable?: number;
194
+ }): Promise<QuoteResponse> {
195
+ const params = this.buildParams({
196
+ inputMint,
197
+ outputMint,
198
+ amount,
199
+ userPublicKey,
200
+ maxAccounts,
201
+ slippageBps,
202
+ swapMode,
203
+ onlyDirectRoutes,
204
+ excludeDexes,
205
+ sizeConstraint,
206
+ accountsLimitWritable,
207
+ });
208
+
209
+ let response: Response;
210
+
211
+ if (this.proxyUrl) {
212
+ // Use proxy route - send parameters in request body
213
+ response = await fetch(this.proxyUrl, {
214
+ method: 'POST',
163
215
  headers: {
164
- Accept: 'application/vnd.msgpack',
165
- 'Accept-Encoding': 'gzip, deflate, br',
166
- Authorization: `Bearer ${this.authToken}`,
216
+ 'Content-Type': 'application/json',
167
217
  },
168
- }
169
- );
218
+ body: JSON.stringify(Object.fromEntries(params.entries())),
219
+ });
220
+ } else {
221
+ // Direct request to Titan API
222
+ response = await fetch(
223
+ `${this.url}/api/v1/quote/swap?${params.toString()}`,
224
+ {
225
+ headers: {
226
+ Accept: 'application/vnd.msgpack',
227
+ 'Accept-Encoding': 'gzip, deflate, br',
228
+ Authorization: `Bearer ${this.authToken}`,
229
+ },
230
+ }
231
+ );
232
+ }
170
233
 
171
234
  if (!response.ok) {
172
235
  throw new Error(
@@ -177,11 +240,12 @@ export class TitanClient {
177
240
  const buffer = await response.arrayBuffer();
178
241
  const data = decode(buffer) as SwapQuotes;
179
242
 
180
- const route =
181
- data.quotes[
182
- Object.keys(data.quotes).find((key) => key.toLowerCase() === 'titan') ||
183
- ''
184
- ];
243
+ // Cache the quote data and parameters for later use in getSwap
244
+ this.lastQuoteData = data;
245
+ this.lastQuoteParams = params.toString();
246
+
247
+ // We are only querying for the best avaiable route so use that
248
+ const route = data.quotes[Object.keys(data.quotes)[0]];
185
249
 
186
250
  if (!route) {
187
251
  throw new Error('No routes available');
@@ -250,52 +314,32 @@ export class TitanClient {
250
314
  transactionMessage: TransactionMessage;
251
315
  lookupTables: AddressLookupTableAccount[];
252
316
  }> {
253
- const params = new URLSearchParams({
254
- inputMint: inputMint.toString(),
255
- outputMint: outputMint.toString(),
256
- amount: amount.toString(),
257
- userPublicKey: userPublicKey.toString(),
258
- ...(slippageBps && { slippageBps: slippageBps.toString() }),
259
- ...(swapMode && { swapMode: swapMode }),
260
- ...(maxAccounts && { accountsLimitTotal: maxAccounts.toString() }),
261
- ...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
262
- ...(onlyDirectRoutes && {
263
- onlyDirectRoutes: onlyDirectRoutes.toString(),
264
- }),
265
- ...(sizeConstraint && { sizeConstraint: sizeConstraint.toString() }),
266
- ...(accountsLimitWritable && {
267
- accountsLimitWritable: accountsLimitWritable.toString(),
268
- }),
317
+ const params = this.buildParams({
318
+ inputMint,
319
+ outputMint,
320
+ amount,
321
+ userPublicKey,
322
+ maxAccounts,
323
+ slippageBps,
324
+ swapMode,
325
+ onlyDirectRoutes,
326
+ excludeDexes,
327
+ sizeConstraint,
328
+ accountsLimitWritable,
269
329
  });
270
330
 
271
- const response = await fetch(
272
- `${this.url}/api/v1/quote/swap?${params.toString()}`,
273
- {
274
- headers: {
275
- Accept: 'application/vnd.msgpack',
276
- 'Accept-Encoding': 'gzip, deflate, br',
277
- Authorization: `Bearer ${this.authToken}`,
278
- },
279
- }
280
- );
281
-
282
- if (!response.ok) {
283
- if (response.status === 404) {
284
- throw new Error('No routes available');
285
- }
331
+ // Check if we have cached quote data that matches the current parameters
332
+ if (!this.lastQuoteData || this.lastQuoteParams !== params.toString()) {
286
333
  throw new Error(
287
- `Titan API error: ${response.status} ${response.statusText}`
334
+ 'No matching quote data found. Please get a fresh quote before attempting to swap.'
288
335
  );
289
336
  }
290
337
 
291
- const buffer = await response.arrayBuffer();
292
- const data = decode(buffer) as SwapQuotes;
338
+ // Reuse the cached quote data
339
+ const data = this.lastQuoteData;
293
340
 
294
- const route =
295
- data.quotes[
296
- Object.keys(data.quotes).find((key) => key.toLowerCase() === 'titan') ||
297
- ''
298
- ];
341
+ // We are only querying for the best avaiable route so use that
342
+ const route = data.quotes[Object.keys(data.quotes)[0]];
299
343
 
300
344
  if (!route) {
301
345
  throw new Error('No routes available');
@@ -310,6 +354,10 @@ export class TitanClient {
310
354
  throw new Error(
311
355
  'Something went wrong with creating the Titan swap transaction. Please try again.'
312
356
  );
357
+ } finally {
358
+ // Clear cached quote data after use
359
+ this.lastQuoteData = undefined;
360
+ this.lastQuoteParams = undefined;
313
361
  }
314
362
  }
315
363
  throw new Error('No instructions provided in the route');
package/src/user.ts CHANGED
@@ -4587,7 +4587,7 @@ export class User {
4587
4587
  return calc;
4588
4588
  }
4589
4589
 
4590
- private isPerpPositionIsolated(perpPosition: PerpPosition): boolean {
4590
+ public isPerpPositionIsolated(perpPosition: PerpPosition): boolean {
4591
4591
  return (perpPosition.positionFlag & PositionFlag.IsolatedPosition) !== 0;
4592
4592
  }
4593
4593
  }