@drift-labs/sdk 2.41.0-beta.0 → 2.41.0-beta.1

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 (81) hide show
  1. package/README.md +0 -1
  2. package/VERSION +1 -1
  3. package/bun.lockb +0 -0
  4. package/lib/accounts/types.d.ts +5 -1
  5. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -1
  6. package/lib/accounts/webSocketAccountSubscriber.js +28 -2
  7. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +2 -1
  8. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +6 -5
  9. package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +32 -0
  10. package/lib/accounts/webSocketProgramAccountSubscriber.js +99 -0
  11. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +2 -1
  12. package/lib/accounts/webSocketUserAccountSubscriber.js +3 -2
  13. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +2 -1
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +3 -2
  15. package/lib/addresses/pda.d.ts +1 -0
  16. package/lib/addresses/pda.js +5 -1
  17. package/lib/adminClient.d.ts +2 -0
  18. package/lib/adminClient.js +20 -0
  19. package/lib/auctionSubscriber/auctionSubscriber.d.ts +3 -2
  20. package/lib/auctionSubscriber/auctionSubscriber.js +15 -7
  21. package/lib/auctionSubscriber/types.d.ts +1 -0
  22. package/lib/dlob/DLOB.d.ts +2 -6
  23. package/lib/dlob/DLOB.js +9 -11
  24. package/lib/dlob/DLOBSubscriber.js +4 -7
  25. package/lib/dlob/orderBookLevels.d.ts +4 -2
  26. package/lib/dlob/orderBookLevels.js +79 -16
  27. package/lib/driftClient.d.ts +2 -1
  28. package/lib/driftClient.js +5 -4
  29. package/lib/driftClientConfig.d.ts +1 -0
  30. package/lib/factory/bigNum.js +4 -2
  31. package/lib/idl/drift.json +222 -2
  32. package/lib/jupiter/jupiterClient.d.ts +4 -1
  33. package/lib/jupiter/jupiterClient.js +4 -1
  34. package/lib/math/amm.js +7 -2
  35. package/lib/math/auction.d.ts +12 -1
  36. package/lib/math/auction.js +22 -1
  37. package/lib/math/market.js +2 -4
  38. package/lib/math/superStake.d.ts +51 -4
  39. package/lib/math/superStake.js +173 -21
  40. package/lib/math/trade.js +2 -4
  41. package/lib/math/utils.d.ts +1 -0
  42. package/lib/math/utils.js +10 -1
  43. package/lib/orderSubscriber/OrderSubscriber.d.ts +1 -3
  44. package/lib/orderSubscriber/OrderSubscriber.js +4 -3
  45. package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -2
  46. package/lib/orderSubscriber/WebsocketSubscription.js +15 -12
  47. package/lib/orderSubscriber/types.d.ts +1 -0
  48. package/lib/user.d.ts +2 -2
  49. package/lib/user.js +5 -5
  50. package/package.json +2 -1
  51. package/src/accounts/types.ts +8 -1
  52. package/src/accounts/webSocketAccountSubscriber.ts +36 -2
  53. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +15 -5
  54. package/src/accounts/webSocketProgramAccountSubscriber.ts +152 -0
  55. package/src/accounts/webSocketUserAccountSubscriber.ts +10 -2
  56. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +10 -2
  57. package/src/addresses/pda.ts +9 -0
  58. package/src/adminClient.ts +32 -0
  59. package/src/auctionSubscriber/auctionSubscriber.ts +30 -21
  60. package/src/auctionSubscriber/types.ts +1 -0
  61. package/src/dlob/DLOB.ts +9 -32
  62. package/src/dlob/DLOBSubscriber.ts +8 -7
  63. package/src/dlob/orderBookLevels.ts +133 -32
  64. package/src/driftClient.ts +5 -1
  65. package/src/driftClientConfig.ts +1 -0
  66. package/src/factory/bigNum.ts +2 -0
  67. package/src/idl/drift.json +222 -2
  68. package/src/jupiter/jupiterClient.ts +6 -0
  69. package/src/math/amm.ts +9 -2
  70. package/src/math/auction.ts +36 -2
  71. package/src/math/market.ts +4 -9
  72. package/src/math/superStake.ts +247 -23
  73. package/src/math/trade.ts +3 -11
  74. package/src/math/utils.ts +12 -0
  75. package/src/orderSubscriber/OrderSubscriber.ts +12 -7
  76. package/src/orderSubscriber/WebsocketSubscription.ts +34 -23
  77. package/src/orderSubscriber/types.ts +1 -0
  78. package/src/user.ts +7 -5
  79. package/tests/amm/test.ts +402 -0
  80. package/tests/auctions/test.ts +66 -0
  81. package/tests/dlob/test.ts +1 -73
@@ -10,11 +10,13 @@ import {
10
10
  OraclePriceData,
11
11
  PerpMarketAccount,
12
12
  PositionDirection,
13
+ QUOTE_PRECISION,
13
14
  standardizePrice,
14
15
  SwapDirection,
15
16
  ZERO,
16
17
  } from '..';
17
18
  import { PublicKey } from '@solana/web3.js';
19
+ import { assert } from '../assert/assert';
18
20
 
19
21
  type liquiditySource = 'serum' | 'vamm' | 'dlob' | 'phoenix';
20
22
 
@@ -46,9 +48,16 @@ export type L3OrderBook = {
46
48
  bids: L3Level[];
47
49
  };
48
50
 
51
+ export const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
52
+ new BN(500).mul(QUOTE_PRECISION),
53
+ new BN(1000).mul(QUOTE_PRECISION),
54
+ new BN(2000).mul(QUOTE_PRECISION),
55
+ new BN(5000).mul(QUOTE_PRECISION),
56
+ ];
57
+
49
58
  /**
50
59
  * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
51
- * @param dlobNodes e.g. {@link DLOB#getMakerLimitAsks} or {@link DLOB#getMakerLimitBids}
60
+ * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
52
61
  * @param oraclePriceData
53
62
  * @param slot
54
63
  */
@@ -139,12 +148,20 @@ export function getVammL2Generator({
139
148
  oraclePriceData,
140
149
  numOrders,
141
150
  now,
151
+ topOfBookQuoteAmounts,
142
152
  }: {
143
153
  marketAccount: PerpMarketAccount;
144
154
  oraclePriceData: OraclePriceData;
145
155
  numOrders: number;
146
156
  now?: BN;
157
+ topOfBookQuoteAmounts?: BN[];
147
158
  }): L2OrderBookGenerator {
159
+ let numBaseOrders = numOrders;
160
+ if (topOfBookQuoteAmounts) {
161
+ numBaseOrders = numOrders - topOfBookQuoteAmounts.length;
162
+ assert(topOfBookQuoteAmounts.length < numOrders);
163
+ }
164
+
148
165
  const updatedAmm = calculateUpdatedAMM(marketAccount.amm, oraclePriceData);
149
166
 
150
167
  const [openBids, openAsks] = calculateMarketOpenBidAsk(
@@ -162,38 +179,78 @@ export function getVammL2Generator({
162
179
  );
163
180
 
164
181
  let numBids = 0;
165
- const baseSize = openBids.div(new BN(numOrders));
182
+
183
+ let topOfBookBidSize = ZERO;
184
+ let bidSize = openBids.div(new BN(numBaseOrders));
166
185
  const bidAmm = {
167
186
  baseAssetReserve: bidReserves.baseAssetReserve,
168
187
  quoteAssetReserve: bidReserves.quoteAssetReserve,
169
188
  sqrtK: updatedAmm.sqrtK,
170
189
  pegMultiplier: updatedAmm.pegMultiplier,
171
190
  };
191
+
172
192
  const getL2Bids = function* () {
173
- while (numBids < numOrders && baseSize.gt(ZERO)) {
174
- const [afterSwapQuoteReserves, afterSwapBaseReserves] =
175
- calculateAmmReservesAfterSwap(
176
- bidAmm,
177
- 'base',
178
- baseSize,
193
+ while (numBids < numOrders && bidSize.gt(ZERO)) {
194
+ let quoteSwapped = ZERO;
195
+ let baseSwapped = ZERO;
196
+ let [afterSwapQuoteReserves, afterSwapBaseReserves] = [ZERO, ZERO];
197
+
198
+ if (topOfBookQuoteAmounts && numBids < topOfBookQuoteAmounts?.length) {
199
+ const remainingBaseLiquidity = openBids.sub(topOfBookBidSize);
200
+ quoteSwapped = topOfBookQuoteAmounts[numBids];
201
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
202
+ calculateAmmReservesAfterSwap(
203
+ bidAmm,
204
+ 'quote',
205
+ quoteSwapped,
206
+ SwapDirection.REMOVE
207
+ );
208
+
209
+ baseSwapped = bidAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
210
+ if (remainingBaseLiquidity.lt(baseSwapped)) {
211
+ baseSwapped = remainingBaseLiquidity;
212
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
213
+ calculateAmmReservesAfterSwap(
214
+ bidAmm,
215
+ 'base',
216
+ baseSwapped,
217
+ SwapDirection.ADD
218
+ );
219
+
220
+ quoteSwapped = calculateQuoteAssetAmountSwapped(
221
+ bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
222
+ bidAmm.pegMultiplier,
223
+ SwapDirection.ADD
224
+ );
225
+ }
226
+ topOfBookBidSize = topOfBookBidSize.add(baseSwapped);
227
+ bidSize = openBids.sub(topOfBookBidSize).div(new BN(numBaseOrders));
228
+ } else {
229
+ baseSwapped = bidSize;
230
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
231
+ calculateAmmReservesAfterSwap(
232
+ bidAmm,
233
+ 'base',
234
+ baseSwapped,
235
+ SwapDirection.ADD
236
+ );
237
+
238
+ quoteSwapped = calculateQuoteAssetAmountSwapped(
239
+ bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
240
+ bidAmm.pegMultiplier,
179
241
  SwapDirection.ADD
180
242
  );
243
+ }
181
244
 
182
- const quoteSwapped = calculateQuoteAssetAmountSwapped(
183
- bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
184
- bidAmm.pegMultiplier,
185
- SwapDirection.ADD
186
- );
187
-
188
- const price = quoteSwapped.mul(BASE_PRECISION).div(baseSize);
245
+ const price = quoteSwapped.mul(BASE_PRECISION).div(baseSwapped);
189
246
 
190
247
  bidAmm.baseAssetReserve = afterSwapBaseReserves;
191
248
  bidAmm.quoteAssetReserve = afterSwapQuoteReserves;
192
249
 
193
250
  yield {
194
251
  price,
195
- size: baseSize,
196
- sources: { vamm: baseSize },
252
+ size: baseSwapped,
253
+ sources: { vamm: baseSwapped },
197
254
  };
198
255
 
199
256
  numBids++;
@@ -201,38 +258,82 @@ export function getVammL2Generator({
201
258
  };
202
259
 
203
260
  let numAsks = 0;
204
- const askSize = openAsks.abs().div(new BN(numOrders));
261
+ let topOfBookAskSize = ZERO;
262
+ let askSize = openAsks.abs().div(new BN(numBaseOrders));
205
263
  const askAmm = {
206
264
  baseAssetReserve: askReserves.baseAssetReserve,
207
265
  quoteAssetReserve: askReserves.quoteAssetReserve,
208
266
  sqrtK: updatedAmm.sqrtK,
209
267
  pegMultiplier: updatedAmm.pegMultiplier,
210
268
  };
269
+
211
270
  const getL2Asks = function* () {
212
271
  while (numAsks < numOrders && askSize.gt(ZERO)) {
213
- const [afterSwapQuoteReserves, afterSwapBaseReserves] =
214
- calculateAmmReservesAfterSwap(
215
- askAmm,
216
- 'base',
217
- askSize,
272
+ let quoteSwapped: BN = ZERO;
273
+ let baseSwapped: BN = ZERO;
274
+ let [afterSwapQuoteReserves, afterSwapBaseReserves] = [ZERO, ZERO];
275
+
276
+ if (topOfBookQuoteAmounts && numAsks < topOfBookQuoteAmounts?.length) {
277
+ const remainingBaseLiquidity = openAsks
278
+ .mul(new BN(-1))
279
+ .sub(topOfBookAskSize);
280
+ quoteSwapped = topOfBookQuoteAmounts[numAsks];
281
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
282
+ calculateAmmReservesAfterSwap(
283
+ askAmm,
284
+ 'quote',
285
+ quoteSwapped,
286
+ SwapDirection.ADD
287
+ );
288
+
289
+ baseSwapped = askAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
290
+ if (remainingBaseLiquidity.lt(baseSwapped)) {
291
+ baseSwapped = remainingBaseLiquidity;
292
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
293
+ calculateAmmReservesAfterSwap(
294
+ bidAmm,
295
+ 'base',
296
+ baseSwapped,
297
+ SwapDirection.REMOVE
298
+ );
299
+
300
+ quoteSwapped = calculateQuoteAssetAmountSwapped(
301
+ bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
302
+ bidAmm.pegMultiplier,
303
+ SwapDirection.REMOVE
304
+ );
305
+ }
306
+ topOfBookAskSize = topOfBookAskSize.add(baseSwapped);
307
+ askSize = openAsks
308
+ .abs()
309
+ .sub(topOfBookAskSize)
310
+ .div(new BN(numBaseOrders));
311
+ } else {
312
+ baseSwapped = askSize;
313
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
314
+ calculateAmmReservesAfterSwap(
315
+ askAmm,
316
+ 'base',
317
+ askSize,
318
+ SwapDirection.REMOVE
319
+ );
320
+
321
+ quoteSwapped = calculateQuoteAssetAmountSwapped(
322
+ askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
323
+ askAmm.pegMultiplier,
218
324
  SwapDirection.REMOVE
219
325
  );
326
+ }
220
327
 
221
- const quoteSwapped = calculateQuoteAssetAmountSwapped(
222
- askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
223
- askAmm.pegMultiplier,
224
- SwapDirection.REMOVE
225
- );
226
-
227
- const price = quoteSwapped.mul(BASE_PRECISION).div(askSize);
328
+ const price = quoteSwapped.mul(BASE_PRECISION).div(baseSwapped);
228
329
 
229
330
  askAmm.baseAssetReserve = afterSwapBaseReserves;
230
331
  askAmm.quoteAssetReserve = afterSwapQuoteReserves;
231
332
 
232
333
  yield {
233
334
  price,
234
- size: askSize,
235
- sources: { vamm: baseSize },
335
+ size: baseSwapped,
336
+ sources: { vamm: baseSwapped },
236
337
  };
237
338
 
238
339
  numAsks++;
@@ -278,7 +278,8 @@ export class DriftClient {
278
278
  config.perpMarketIndexes ?? [],
279
279
  config.spotMarketIndexes ?? [],
280
280
  config.oracleInfos ?? [],
281
- noMarketsAndOraclesSpecified
281
+ noMarketsAndOraclesSpecified,
282
+ config.accountSubscription?.resubTimeoutMs
282
283
  );
283
284
  }
284
285
  this.eventEmitter = this.accountSubscriber.eventEmitter;
@@ -3424,6 +3425,7 @@ export class DriftClient {
3424
3425
  reduceOnly,
3425
3426
  txParams,
3426
3427
  v6,
3428
+ onlyDirectRoutes = false,
3427
3429
  }: {
3428
3430
  jupiterClient: JupiterClient;
3429
3431
  outMarketIndex: number;
@@ -3436,6 +3438,7 @@ export class DriftClient {
3436
3438
  route?: Route;
3437
3439
  reduceOnly?: SwapReduceOnly;
3438
3440
  txParams?: TxParams;
3441
+ onlyDirectRoutes?: boolean;
3439
3442
  v6?: {
3440
3443
  quote?: QuoteResponse;
3441
3444
  };
@@ -3455,6 +3458,7 @@ export class DriftClient {
3455
3458
  swapMode,
3456
3459
  quote: v6.quote,
3457
3460
  reduceOnly,
3461
+ onlyDirectRoutes,
3458
3462
  });
3459
3463
  ixs = res.ixs;
3460
3464
  lookupTables = res.lookupTables;
@@ -36,6 +36,7 @@ export type DriftClientConfig = {
36
36
  export type DriftClientSubscriptionConfig =
37
37
  | {
38
38
  type: 'websocket';
39
+ resubTimeoutMs?: number;
39
40
  }
40
41
  | {
41
42
  type: 'polling';
@@ -618,6 +618,8 @@ export class BigNum {
618
618
  if (!val.replace(BigNum.delim, '')) {
619
619
  return BigNum.from(ZERO, precisionShift);
620
620
  }
621
+ if (val.includes('e'))
622
+ val = (+val).toFixed(precisionShift?.toNumber() ?? 9); // prevent small numbers e.g. 3.1e-8, use assume max precision 9 as default
621
623
 
622
624
  const sides = val.split(BigNum.delim);
623
625
  const rightSide = sides[1];
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.39.0",
2
+ "version": "2.40.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -2376,6 +2376,61 @@
2376
2376
  }
2377
2377
  ]
2378
2378
  },
2379
+ {
2380
+ "name": "transferProtocolIfShares",
2381
+ "accounts": [
2382
+ {
2383
+ "name": "signer",
2384
+ "isMut": false,
2385
+ "isSigner": true
2386
+ },
2387
+ {
2388
+ "name": "transferConfig",
2389
+ "isMut": true,
2390
+ "isSigner": false
2391
+ },
2392
+ {
2393
+ "name": "state",
2394
+ "isMut": false,
2395
+ "isSigner": false
2396
+ },
2397
+ {
2398
+ "name": "spotMarket",
2399
+ "isMut": false,
2400
+ "isSigner": false
2401
+ },
2402
+ {
2403
+ "name": "insuranceFundStake",
2404
+ "isMut": true,
2405
+ "isSigner": false
2406
+ },
2407
+ {
2408
+ "name": "userStats",
2409
+ "isMut": true,
2410
+ "isSigner": false
2411
+ },
2412
+ {
2413
+ "name": "authority",
2414
+ "isMut": false,
2415
+ "isSigner": true
2416
+ },
2417
+ {
2418
+ "name": "insuranceFundVault",
2419
+ "isMut": false,
2420
+ "isSigner": false
2421
+ }
2422
+ ],
2423
+ "args": [
2424
+ {
2425
+ "name": "marketIndex",
2426
+ "type": "u16"
2427
+ },
2428
+ {
2429
+ "name": "shares",
2430
+ "type": "u128"
2431
+ }
2432
+ ]
2433
+ },
2379
2434
  {
2380
2435
  "name": "initialize",
2381
2436
  "accounts": [
@@ -4542,6 +4597,76 @@
4542
4597
  "type": "u64"
4543
4598
  }
4544
4599
  ]
4600
+ },
4601
+ {
4602
+ "name": "initializeProtocolIfSharesTransferConfig",
4603
+ "accounts": [
4604
+ {
4605
+ "name": "admin",
4606
+ "isMut": true,
4607
+ "isSigner": true
4608
+ },
4609
+ {
4610
+ "name": "protocolIfSharesTransferConfig",
4611
+ "isMut": true,
4612
+ "isSigner": false
4613
+ },
4614
+ {
4615
+ "name": "state",
4616
+ "isMut": false,
4617
+ "isSigner": false
4618
+ },
4619
+ {
4620
+ "name": "rent",
4621
+ "isMut": false,
4622
+ "isSigner": false
4623
+ },
4624
+ {
4625
+ "name": "systemProgram",
4626
+ "isMut": false,
4627
+ "isSigner": false
4628
+ }
4629
+ ],
4630
+ "args": []
4631
+ },
4632
+ {
4633
+ "name": "updateProtocolIfSharesTransferConfig",
4634
+ "accounts": [
4635
+ {
4636
+ "name": "admin",
4637
+ "isMut": true,
4638
+ "isSigner": true
4639
+ },
4640
+ {
4641
+ "name": "protocolIfSharesTransferConfig",
4642
+ "isMut": true,
4643
+ "isSigner": false
4644
+ },
4645
+ {
4646
+ "name": "state",
4647
+ "isMut": false,
4648
+ "isSigner": false
4649
+ }
4650
+ ],
4651
+ "args": [
4652
+ {
4653
+ "name": "whitelistedSigners",
4654
+ "type": {
4655
+ "option": {
4656
+ "array": [
4657
+ "publicKey",
4658
+ 4
4659
+ ]
4660
+ }
4661
+ }
4662
+ },
4663
+ {
4664
+ "name": "maxTransferPerEpoch",
4665
+ "type": {
4666
+ "option": "u128"
4667
+ }
4668
+ }
4669
+ ]
4545
4670
  }
4546
4671
  ],
4547
4672
  "accounts": [
@@ -4732,6 +4857,44 @@
4732
4857
  ]
4733
4858
  }
4734
4859
  },
4860
+ {
4861
+ "name": "ProtocolIfSharesTransferConfig",
4862
+ "type": {
4863
+ "kind": "struct",
4864
+ "fields": [
4865
+ {
4866
+ "name": "whitelistedSigners",
4867
+ "type": {
4868
+ "array": [
4869
+ "publicKey",
4870
+ 4
4871
+ ]
4872
+ }
4873
+ },
4874
+ {
4875
+ "name": "maxTransferPerEpoch",
4876
+ "type": "u128"
4877
+ },
4878
+ {
4879
+ "name": "currentEpochTransfer",
4880
+ "type": "u128"
4881
+ },
4882
+ {
4883
+ "name": "nextEpochTs",
4884
+ "type": "i64"
4885
+ },
4886
+ {
4887
+ "name": "padding",
4888
+ "type": {
4889
+ "array": [
4890
+ "u128",
4891
+ 8
4892
+ ]
4893
+ }
4894
+ }
4895
+ ]
4896
+ }
4897
+ },
4735
4898
  {
4736
4899
  "name": "PerpMarket",
4737
4900
  "type": {
@@ -5004,7 +5167,7 @@
5004
5167
  {
5005
5168
  "name": "name",
5006
5169
  "docs": [
5007
- "The encoded display name fo the market e.g. SOL"
5170
+ "The encoded display name for the market e.g. SOL"
5008
5171
  ],
5009
5172
  "type": {
5010
5173
  "array": [
@@ -6314,6 +6477,24 @@
6314
6477
  ]
6315
6478
  }
6316
6479
  },
6480
+ {
6481
+ "name": "MarketIdentifier",
6482
+ "type": {
6483
+ "kind": "struct",
6484
+ "fields": [
6485
+ {
6486
+ "name": "marketType",
6487
+ "type": {
6488
+ "defined": "MarketType"
6489
+ }
6490
+ },
6491
+ {
6492
+ "name": "marketIndex",
6493
+ "type": "u16"
6494
+ }
6495
+ ]
6496
+ }
6497
+ },
6317
6498
  {
6318
6499
  "name": "HistoricalOracleData",
6319
6500
  "type": {
@@ -8157,6 +8338,12 @@
8157
8338
  },
8158
8339
  {
8159
8340
  "name": "Unstake"
8341
+ },
8342
+ {
8343
+ "name": "UnstakeTransfer"
8344
+ },
8345
+ {
8346
+ "name": "StakeTransfer"
8160
8347
  }
8161
8348
  ]
8162
8349
  }
@@ -8198,6 +8385,34 @@
8198
8385
  ]
8199
8386
  }
8200
8387
  },
8388
+ {
8389
+ "name": "MarginCalculationMode",
8390
+ "type": {
8391
+ "kind": "enum",
8392
+ "variants": [
8393
+ {
8394
+ "name": "Standard"
8395
+ },
8396
+ {
8397
+ "name": "Liquidation",
8398
+ "fields": [
8399
+ {
8400
+ "name": "margin_buffer",
8401
+ "type": "u128"
8402
+ },
8403
+ {
8404
+ "name": "market_to_track_margin_requirement",
8405
+ "type": {
8406
+ "option": {
8407
+ "defined": "MarketIdentifier"
8408
+ }
8409
+ }
8410
+ }
8411
+ ]
8412
+ }
8413
+ ]
8414
+ }
8415
+ },
8201
8416
  {
8202
8417
  "name": "OracleSource",
8203
8418
  "type": {
@@ -10781,6 +10996,11 @@
10781
10996
  "code": 6254,
10782
10997
  "name": "UserReduceOnly",
10783
10998
  "msg": "UserReduceOnly"
10999
+ },
11000
+ {
11001
+ "code": 6255,
11002
+ "name": "InvalidMarginCalculation",
11003
+ "msg": "InvalidMarginCalculation"
10784
11004
  }
10785
11005
  ]
10786
11006
  }
@@ -275,16 +275,20 @@ export class JupiterClient {
275
275
  inputMint,
276
276
  outputMint,
277
277
  amount,
278
+ maxAccounts = 50, // 50 is an estimated amount with buffer
278
279
  slippageBps = 50,
279
280
  swapMode = 'ExactIn',
280
281
  onlyDirectRoutes = false,
282
+ excludeDexes = [],
281
283
  }: {
282
284
  inputMint: PublicKey;
283
285
  outputMint: PublicKey;
284
286
  amount: BN;
287
+ maxAccounts?: number;
285
288
  slippageBps?: number;
286
289
  swapMode?: SwapMode;
287
290
  onlyDirectRoutes?: boolean;
291
+ excludeDexes?: string[];
288
292
  }): Promise<QuoteResponse> {
289
293
  const params = new URLSearchParams({
290
294
  inputMint: inputMint.toString(),
@@ -293,6 +297,8 @@ export class JupiterClient {
293
297
  slippageBps: slippageBps.toString(),
294
298
  swapMode,
295
299
  onlyDirectRoutes: onlyDirectRoutes.toString(),
300
+ maxAccounts: maxAccounts.toString(),
301
+ excludeDexes: excludeDexes.join(','),
296
302
  }).toString();
297
303
  const quote = await (await fetch(`${this.url}/v6/quote?${params}`)).json();
298
304
  return quote;
package/src/math/amm.ts CHANGED
@@ -471,12 +471,19 @@ export function calculateVolSpreadBN(
471
471
  clampMax
472
472
  );
473
473
 
474
+ // only consider confidence interval at full value when above 25 bps
475
+ let confComponent = lastOracleConfPct;
476
+
477
+ if (lastOracleConfPct.lte(PRICE_PRECISION.div(new BN(400)))) {
478
+ confComponent = lastOracleConfPct.div(new BN(10));
479
+ }
480
+
474
481
  const longVolSpread = BN.max(
475
- lastOracleConfPct,
482
+ confComponent,
476
483
  volSpread.mul(longVolSpreadFactor).div(PERCENTAGE_PRECISION)
477
484
  );
478
485
  const shortVolSpread = BN.max(
479
- lastOracleConfPct,
486
+ confComponent,
480
487
  volSpread.mul(shortVolSpreadFactor).div(PERCENTAGE_PRECISION)
481
488
  );
482
489
 
@@ -1,5 +1,5 @@
1
- import { isOneOfVariant, isVariant, Order } from '../types';
2
- import { BN, ZERO } from '../.';
1
+ import { isOneOfVariant, isVariant, Order, PositionDirection } from '../types';
2
+ import { BN, ONE, ZERO } from '../.';
3
3
 
4
4
  export function isAuctionComplete(order: Order, slot: number): boolean {
5
5
  if (order.auctionDuration === 0) {
@@ -104,3 +104,37 @@ export function getAuctionPriceForOracleOffsetAuction(
104
104
 
105
105
  return oraclePrice.add(priceOffset);
106
106
  }
107
+
108
+ export function deriveOracleAuctionParams({
109
+ direction,
110
+ oraclePrice,
111
+ auctionStartPrice,
112
+ auctionEndPrice,
113
+ limitPrice,
114
+ }: {
115
+ direction: PositionDirection;
116
+ oraclePrice: BN;
117
+ auctionStartPrice: BN;
118
+ auctionEndPrice: BN;
119
+ limitPrice: BN;
120
+ }): { auctionStartPrice: BN; auctionEndPrice: BN; oraclePriceOffset: number } {
121
+ let oraclePriceOffset = limitPrice.sub(oraclePrice);
122
+ if (oraclePriceOffset.eq(ZERO)) {
123
+ oraclePriceOffset = isVariant(direction, 'long')
124
+ ? auctionEndPrice.sub(oraclePrice).add(ONE)
125
+ : auctionEndPrice.sub(oraclePrice).sub(ONE);
126
+ }
127
+
128
+ let oraclePriceOffsetNum;
129
+ try {
130
+ oraclePriceOffsetNum = oraclePriceOffset.toNumber();
131
+ } catch (e) {
132
+ oraclePriceOffsetNum = 0;
133
+ }
134
+
135
+ return {
136
+ auctionStartPrice: auctionStartPrice.sub(oraclePrice),
137
+ auctionEndPrice: auctionEndPrice.sub(oraclePrice),
138
+ oraclePriceOffset: oraclePriceOffsetNum,
139
+ };
140
+ }
@@ -279,27 +279,22 @@ export function calculateAvailablePerpLiquidity(
279
279
 
280
280
  asks = asks.abs();
281
281
 
282
- const bidPrice = calculateBidPrice(market, oraclePriceData);
283
- const askPrice = calculateAskPrice(market, oraclePriceData);
284
-
285
- for (const bid of dlob.getMakerLimitBids(
282
+ for (const bid of dlob.getRestingLimitBids(
286
283
  market.marketIndex,
287
284
  slot,
288
285
  MarketType.PERP,
289
- oraclePriceData,
290
- askPrice
286
+ oraclePriceData
291
287
  )) {
292
288
  bids = bids.add(
293
289
  bid.order.baseAssetAmount.sub(bid.order.baseAssetAmountFilled)
294
290
  );
295
291
  }
296
292
 
297
- for (const ask of dlob.getMakerLimitAsks(
293
+ for (const ask of dlob.getRestingLimitAsks(
298
294
  market.marketIndex,
299
295
  slot,
300
296
  MarketType.PERP,
301
- oraclePriceData,
302
- bidPrice
297
+ oraclePriceData
303
298
  )) {
304
299
  asks = asks.add(
305
300
  ask.order.baseAssetAmount.sub(ask.order.baseAssetAmountFilled)