@drift-labs/sdk 2.40.0-beta.9 → 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 (40) hide show
  1. package/VERSION +1 -1
  2. package/bun.lockb +0 -0
  3. package/lib/addresses/pda.d.ts +1 -0
  4. package/lib/addresses/pda.js +5 -1
  5. package/lib/adminClient.d.ts +2 -0
  6. package/lib/adminClient.js +20 -0
  7. package/lib/constants/spotMarkets.js +1 -1
  8. package/lib/dlob/DLOB.d.ts +2 -6
  9. package/lib/dlob/DLOB.js +9 -11
  10. package/lib/dlob/DLOBSubscriber.js +4 -7
  11. package/lib/dlob/orderBookLevels.d.ts +4 -2
  12. package/lib/dlob/orderBookLevels.js +79 -16
  13. package/lib/factory/bigNum.js +4 -2
  14. package/lib/idl/drift.json +171 -2
  15. package/lib/jupiter/jupiterClient.d.ts +3 -2
  16. package/lib/jupiter/jupiterClient.js +3 -2
  17. package/lib/math/auction.d.ts +12 -1
  18. package/lib/math/auction.js +22 -1
  19. package/lib/math/market.js +2 -4
  20. package/lib/math/superStake.js +1 -1
  21. package/lib/math/trade.js +2 -4
  22. package/lib/orderSubscriber/WebsocketSubscription.js +2 -0
  23. package/package.json +2 -1
  24. package/src/addresses/pda.ts +9 -0
  25. package/src/adminClient.ts +32 -0
  26. package/src/constants/spotMarkets.ts +1 -1
  27. package/src/dlob/DLOB.ts +9 -32
  28. package/src/dlob/DLOBSubscriber.ts +8 -7
  29. package/src/dlob/orderBookLevels.ts +133 -32
  30. package/src/factory/bigNum.ts +2 -0
  31. package/src/idl/drift.json +171 -2
  32. package/src/jupiter/jupiterClient.ts +4 -1
  33. package/src/math/auction.ts +36 -2
  34. package/src/math/market.ts +4 -9
  35. package/src/math/superStake.ts +2 -2
  36. package/src/math/trade.ts +3 -11
  37. package/src/orderSubscriber/WebsocketSubscription.ts +1 -0
  38. package/tests/amm/test.ts +402 -0
  39. package/tests/auctions/test.ts +66 -0
  40. package/tests/dlob/test.ts +1 -73
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.40.0-beta.9
1
+ 2.41.0-beta.1
package/bun.lockb ADDED
Binary file
@@ -17,3 +17,4 @@ export declare function getSerumSignerPublicKey(programId: PublicKey, market: Pu
17
17
  export declare function getSerumFulfillmentConfigPublicKey(programId: PublicKey, market: PublicKey): PublicKey;
18
18
  export declare function getPhoenixFulfillmentConfigPublicKey(programId: PublicKey, market: PublicKey): PublicKey;
19
19
  export declare function getReferrerNamePublicKeySync(programId: PublicKey, nameBuffer: number[]): PublicKey;
20
+ export declare function getProtocolIfSharesTransferConfigPublicKey(programId: PublicKey): PublicKey;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getReferrerNamePublicKeySync = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
26
+ exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
27
27
  const web3_js_1 = require("@solana/web3.js");
28
28
  const anchor = __importStar(require("@coral-xyz/anchor"));
29
29
  async function getDriftStateAccountPublicKeyAndNonce(programId) {
@@ -133,3 +133,7 @@ function getReferrerNamePublicKeySync(programId, nameBuffer) {
133
133
  ], programId)[0];
134
134
  }
135
135
  exports.getReferrerNamePublicKeySync = getReferrerNamePublicKeySync;
136
+ function getProtocolIfSharesTransferConfigPublicKey(programId) {
137
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from(anchor.utils.bytes.utf8.encode('if_shares_transfer_config'))], programId)[0];
138
+ }
139
+ exports.getProtocolIfSharesTransferConfigPublicKey = getProtocolIfSharesTransferConfigPublicKey;
@@ -70,4 +70,6 @@ export declare class AdminClient extends DriftClient {
70
70
  updateSerumVault(srmVault: PublicKey): Promise<TransactionSignature>;
71
71
  updatePerpMarketLiquidationFee(perpMarketIndex: number, liquidatorFee: number, ifLiquidationFee: number): Promise<TransactionSignature>;
72
72
  updateSpotMarketLiquidationFee(spotMarketIndex: number, liquidatorFee: number, ifLiquidationFee: number): Promise<TransactionSignature>;
73
+ initializeProtocolIfSharesTransferConfig(): Promise<TransactionSignature>;
74
+ updateProtocolIfSharesTransferConfig(whitelistedSigners?: PublicKey[], maxTransferPerEpoch?: BN): Promise<TransactionSignature>;
73
75
  }
@@ -791,5 +791,25 @@ class AdminClient extends driftClient_1.DriftClient {
791
791
  },
792
792
  });
793
793
  }
794
+ async initializeProtocolIfSharesTransferConfig() {
795
+ return await this.program.rpc.initializeProtocolIfSharesTransferConfig({
796
+ accounts: {
797
+ admin: this.wallet.publicKey,
798
+ state: await this.getStatePublicKey(),
799
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
800
+ systemProgram: anchor.web3.SystemProgram.programId,
801
+ protocolIfSharesTransferConfig: (0, pda_1.getProtocolIfSharesTransferConfigPublicKey)(this.program.programId),
802
+ },
803
+ });
804
+ }
805
+ async updateProtocolIfSharesTransferConfig(whitelistedSigners, maxTransferPerEpoch) {
806
+ return await this.program.rpc.updateProtocolIfSharesTransferConfig(whitelistedSigners || null, maxTransferPerEpoch, {
807
+ accounts: {
808
+ admin: this.wallet.publicKey,
809
+ state: await this.getStatePublicKey(),
810
+ protocolIfSharesTransferConfig: (0, pda_1.getProtocolIfSharesTransferConfigPublicKey)(this.program.programId),
811
+ },
812
+ });
813
+ }
794
814
  }
795
815
  exports.AdminClient = AdminClient;
@@ -100,7 +100,7 @@ exports.MainnetSpotMarkets = [
100
100
  serumMarket: new web3_js_1.PublicKey('B2na8Awyd7cpC59iEU43FagJAPLigr3AP3s38KM982bu'),
101
101
  },
102
102
  {
103
- symbol: 'JitoSOL',
103
+ symbol: 'jitoSOL',
104
104
  marketIndex: 6,
105
105
  oracle: new web3_js_1.PublicKey('7yyaeuJ1GGtVBLT2z2xub5ZWYKaNhF28mj1RdV4VDFVk'),
106
106
  oracleSource: __1.OracleSource.PYTH,
@@ -63,7 +63,7 @@ export declare class DLOB {
63
63
  mergeNodesToFill(restingLimitOrderNodesToFill: NodeToFill[], takingOrderNodesToFill: NodeToFill[]): NodeToFill[];
64
64
  findRestingLimitOrderNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
65
65
  findTakingNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid?: BN | undefined): NodeToFill[];
66
- findTakingNodesCrossingMakerNodes(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, takerNodeGenerator: Generator<DLOBNode>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, fallbackPrice?: BN) => Generator<DLOBNode>, doesCross: (takerPrice: BN | undefined, makerPrice: BN) => boolean, fallbackPrice?: BN): NodeToFill[];
66
+ findTakingNodesCrossingMakerNodes(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, takerNodeGenerator: Generator<DLOBNode>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData) => Generator<DLOBNode>, doesCross: (takerPrice: BN | undefined, makerPrice: BN) => boolean): NodeToFill[];
67
67
  findNodesCrossingFallbackLiquidity(marketType: MarketType, slot: number, oraclePriceData: OraclePriceData, nodeGenerator: Generator<DLOBNode>, fallbackPrice: BN, doesCross: (nodePrice: BN | undefined, fallbackPrice: BN) => boolean, minAuctionDuration: number): NodeToFill[];
68
68
  findExpiredNodesToFill(marketIndex: number, ts: number, marketType: MarketType): NodeToFill[];
69
69
  findJitAuctionNodesToFill(marketIndex: number, slot: number, oraclePriceData: OraclePriceData, marketType: MarketType): NodeToFill[];
@@ -107,18 +107,14 @@ export declare class DLOB {
107
107
  * @param slot
108
108
  * @param oraclePriceData
109
109
  * @param depth how many levels of the order book to return
110
- * @param fallbackAsk best ask for fallback liquidity, only relevant for perps
111
- * @param fallbackBid best bid for fallback liquidity, only relevant for perps
112
110
  * @param fallbackL2Generators L2 generators for fallback liquidity e.g. vAMM {@link getVammL2Generator}, openbook {@link SerumSubscriber}
113
111
  */
114
- getL2({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackAsk, fallbackBid, fallbackL2Generators, }: {
112
+ getL2({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackL2Generators, }: {
115
113
  marketIndex: number;
116
114
  marketType: MarketType;
117
115
  slot: number;
118
116
  oraclePriceData: OraclePriceData;
119
117
  depth: number;
120
- fallbackAsk?: BN;
121
- fallbackBid?: BN;
122
118
  fallbackL2Generators?: L2OrderBookGenerator[];
123
119
  }): L2OrderBook;
124
120
  /**
package/lib/dlob/DLOB.js CHANGED
@@ -365,7 +365,7 @@ class DLOB {
365
365
  findTakingNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid) {
366
366
  const nodesToFill = new Array();
367
367
  let takingOrderGenerator = this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData);
368
- const takingAsksCrossingBids = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getMakerLimitBids.bind(this), (takerPrice, makerPrice) => {
368
+ const takingAsksCrossingBids = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getRestingLimitBids.bind(this), (takerPrice, makerPrice) => {
369
369
  if ((0, __1.isVariant)(marketType, 'spot')) {
370
370
  if (takerPrice === undefined) {
371
371
  return false;
@@ -375,7 +375,7 @@ class DLOB {
375
375
  }
376
376
  }
377
377
  return takerPrice === undefined || takerPrice.lte(makerPrice);
378
- }, fallbackAsk);
378
+ });
379
379
  for (const takingAskCrossingBid of takingAsksCrossingBids) {
380
380
  nodesToFill.push(takingAskCrossingBid);
381
381
  }
@@ -389,7 +389,7 @@ class DLOB {
389
389
  }
390
390
  }
391
391
  takingOrderGenerator = this.getTakingBids(marketIndex, marketType, slot, oraclePriceData);
392
- const takingBidsToFill = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getMakerLimitAsks.bind(this), (takerPrice, makerPrice) => {
392
+ const takingBidsToFill = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getRestingLimitAsks.bind(this), (takerPrice, makerPrice) => {
393
393
  if ((0, __1.isVariant)(marketType, 'spot')) {
394
394
  if (takerPrice === undefined) {
395
395
  return false;
@@ -399,7 +399,7 @@ class DLOB {
399
399
  }
400
400
  }
401
401
  return takerPrice === undefined || takerPrice.gte(makerPrice);
402
- }, fallbackBid);
402
+ });
403
403
  for (const takingBidToFill of takingBidsToFill) {
404
404
  nodesToFill.push(takingBidToFill);
405
405
  }
@@ -414,10 +414,10 @@ class DLOB {
414
414
  }
415
415
  return nodesToFill;
416
416
  }
417
- findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takerNodeGenerator, makerNodeGeneratorFn, doesCross, fallbackPrice) {
417
+ findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takerNodeGenerator, makerNodeGeneratorFn, doesCross) {
418
418
  const nodesToFill = new Array();
419
419
  for (const takerNode of takerNodeGenerator) {
420
- const makerNodeGenerator = makerNodeGeneratorFn(marketIndex, slot, marketType, oraclePriceData, fallbackPrice);
420
+ const makerNodeGenerator = makerNodeGeneratorFn(marketIndex, slot, marketType, oraclePriceData);
421
421
  for (const makerNode of makerNodeGenerator) {
422
422
  // Can't match orders from the same user
423
423
  const sameUser = takerNode.userAccount.equals(makerNode.userAccount);
@@ -964,12 +964,10 @@ class DLOB {
964
964
  * @param slot
965
965
  * @param oraclePriceData
966
966
  * @param depth how many levels of the order book to return
967
- * @param fallbackAsk best ask for fallback liquidity, only relevant for perps
968
- * @param fallbackBid best bid for fallback liquidity, only relevant for perps
969
967
  * @param fallbackL2Generators L2 generators for fallback liquidity e.g. vAMM {@link getVammL2Generator}, openbook {@link SerumSubscriber}
970
968
  */
971
- getL2({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackAsk, fallbackBid, fallbackL2Generators = [], }) {
972
- const makerAskL2LevelGenerator = (0, orderBookLevels_1.getL2GeneratorFromDLOBNodes)(this.getMakerLimitAsks(marketIndex, slot, marketType, oraclePriceData, fallbackBid), oraclePriceData, slot);
969
+ getL2({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackL2Generators = [], }) {
970
+ const makerAskL2LevelGenerator = (0, orderBookLevels_1.getL2GeneratorFromDLOBNodes)(this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData), oraclePriceData, slot);
973
971
  const fallbackAskGenerators = fallbackL2Generators.map((fallbackL2Generator) => {
974
972
  return fallbackL2Generator.getL2Asks();
975
973
  });
@@ -977,7 +975,7 @@ class DLOB {
977
975
  return a.price.lt(b.price);
978
976
  });
979
977
  const asks = (0, orderBookLevels_1.createL2Levels)(askL2LevelGenerator, depth);
980
- const makerBidGenerator = (0, orderBookLevels_1.getL2GeneratorFromDLOBNodes)(this.getMakerLimitBids(marketIndex, slot, marketType, oraclePriceData, fallbackAsk), oraclePriceData, slot);
978
+ const makerBidGenerator = (0, orderBookLevels_1.getL2GeneratorFromDLOBNodes)(this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData), oraclePriceData, slot);
981
979
  const fallbackBidGenerators = fallbackL2Generators.map((fallbackOrders) => {
982
980
  return fallbackOrders.getL2Bids();
983
981
  });
@@ -5,7 +5,6 @@ const DLOB_1 = require("./DLOB");
5
5
  const events_1 = require("events");
6
6
  const types_1 = require("../types");
7
7
  const orderBookLevels_1 = require("./orderBookLevels");
8
- const market_1 = require("../math/market");
9
8
  class DLOBSubscriber {
10
9
  constructor(config) {
11
10
  this.dlob = new DLOB_1.DLOB();
@@ -61,25 +60,25 @@ class DLOBSubscriber {
61
60
  }
62
61
  }
63
62
  let oraclePriceData;
64
- let fallbackBid;
65
- let fallbackAsk;
66
63
  const isPerp = (0, types_1.isVariant)(marketType, 'perp');
67
64
  if (isPerp) {
68
65
  const perpMarketAccount = this.driftClient.getPerpMarketAccount(marketIndex);
69
66
  oraclePriceData = this.driftClient.getOracleDataForPerpMarket(perpMarketAccount.marketIndex);
70
- fallbackBid = (0, market_1.calculateBidPrice)(perpMarketAccount, oraclePriceData);
71
- fallbackAsk = (0, market_1.calculateAskPrice)(perpMarketAccount, oraclePriceData);
72
67
  }
73
68
  else {
74
69
  oraclePriceData =
75
70
  this.driftClient.getOracleDataForSpotMarket(marketIndex);
76
71
  }
77
72
  if (isPerp && includeVamm) {
73
+ if (fallbackL2Generators.length > 0) {
74
+ throw new Error('includeVamm can only be used if fallbackL2Generators is empty');
75
+ }
78
76
  fallbackL2Generators = [
79
77
  (0, orderBookLevels_1.getVammL2Generator)({
80
78
  marketAccount: this.driftClient.getPerpMarketAccount(marketIndex),
81
79
  oraclePriceData,
82
80
  numOrders: numVammOrders !== null && numVammOrders !== void 0 ? numVammOrders : depth,
81
+ topOfBookQuoteAmounts: orderBookLevels_1.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
83
82
  }),
84
83
  ];
85
84
  }
@@ -89,8 +88,6 @@ class DLOBSubscriber {
89
88
  depth,
90
89
  oraclePriceData,
91
90
  slot: this.slotSource.getSlot(),
92
- fallbackBid,
93
- fallbackAsk,
94
91
  fallbackL2Generators: fallbackL2Generators,
95
92
  });
96
93
  }
@@ -26,20 +26,22 @@ export type L3OrderBook = {
26
26
  asks: L3Level[];
27
27
  bids: L3Level[];
28
28
  };
29
+ export declare const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS: any[];
29
30
  /**
30
31
  * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
31
- * @param dlobNodes e.g. {@link DLOB#getMakerLimitAsks} or {@link DLOB#getMakerLimitBids}
32
+ * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
32
33
  * @param oraclePriceData
33
34
  * @param slot
34
35
  */
35
36
  export declare function getL2GeneratorFromDLOBNodes(dlobNodes: Generator<DLOBNode>, oraclePriceData: OraclePriceData, slot: number): Generator<L2Level>;
36
37
  export declare function mergeL2LevelGenerators(l2LevelGenerators: Generator<L2Level>[], compare: (a: L2Level, b: L2Level) => boolean): Generator<L2Level>;
37
38
  export declare function createL2Levels(generator: Generator<L2Level>, depth: number): L2Level[];
38
- export declare function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, }: {
39
+ export declare function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, topOfBookQuoteAmounts, }: {
39
40
  marketAccount: PerpMarketAccount;
40
41
  oraclePriceData: OraclePriceData;
41
42
  numOrders: number;
42
43
  now?: BN;
44
+ topOfBookQuoteAmounts?: BN[];
43
45
  }): L2OrderBookGenerator;
44
46
  export declare function groupL2(l2: L2OrderBook, grouping: BN, depth: number): L2OrderBook;
45
47
  export {};
@@ -1,10 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = void 0;
3
+ exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = void 0;
4
4
  const __1 = require("..");
5
+ const assert_1 = require("../assert/assert");
6
+ exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
7
+ new __1.BN(500).mul(__1.QUOTE_PRECISION),
8
+ new __1.BN(1000).mul(__1.QUOTE_PRECISION),
9
+ new __1.BN(2000).mul(__1.QUOTE_PRECISION),
10
+ new __1.BN(5000).mul(__1.QUOTE_PRECISION),
11
+ ];
5
12
  /**
6
13
  * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
7
- * @param dlobNodes e.g. {@link DLOB#getMakerLimitAsks} or {@link DLOB#getMakerLimitBids}
14
+ * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
8
15
  * @param oraclePriceData
9
16
  * @param slot
10
17
  */
@@ -78,13 +85,19 @@ function createL2Levels(generator, depth) {
78
85
  return levels;
79
86
  }
80
87
  exports.createL2Levels = createL2Levels;
81
- function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, }) {
88
+ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, topOfBookQuoteAmounts, }) {
89
+ let numBaseOrders = numOrders;
90
+ if (topOfBookQuoteAmounts) {
91
+ numBaseOrders = numOrders - topOfBookQuoteAmounts.length;
92
+ (0, assert_1.assert)(topOfBookQuoteAmounts.length < numOrders);
93
+ }
82
94
  const updatedAmm = (0, __1.calculateUpdatedAMM)(marketAccount.amm, oraclePriceData);
83
95
  const [openBids, openAsks] = (0, __1.calculateMarketOpenBidAsk)(updatedAmm.baseAssetReserve, updatedAmm.minBaseAssetReserve, updatedAmm.maxBaseAssetReserve, updatedAmm.orderStepSize);
84
96
  now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
85
97
  const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now);
86
98
  let numBids = 0;
87
- const baseSize = openBids.div(new __1.BN(numOrders));
99
+ let topOfBookBidSize = __1.ZERO;
100
+ let bidSize = openBids.div(new __1.BN(numBaseOrders));
88
101
  const bidAmm = {
89
102
  baseAssetReserve: bidReserves.baseAssetReserve,
90
103
  quoteAssetReserve: bidReserves.quoteAssetReserve,
@@ -92,22 +105,45 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, })
92
105
  pegMultiplier: updatedAmm.pegMultiplier,
93
106
  };
94
107
  const getL2Bids = function* () {
95
- while (numBids < numOrders && baseSize.gt(__1.ZERO)) {
96
- const [afterSwapQuoteReserves, afterSwapBaseReserves] = (0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSize, __1.SwapDirection.ADD);
97
- const quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
98
- const price = quoteSwapped.mul(__1.BASE_PRECISION).div(baseSize);
108
+ while (numBids < numOrders && bidSize.gt(__1.ZERO)) {
109
+ let quoteSwapped = __1.ZERO;
110
+ let baseSwapped = __1.ZERO;
111
+ let [afterSwapQuoteReserves, afterSwapBaseReserves] = [__1.ZERO, __1.ZERO];
112
+ if (topOfBookQuoteAmounts && numBids < (topOfBookQuoteAmounts === null || topOfBookQuoteAmounts === void 0 ? void 0 : topOfBookQuoteAmounts.length)) {
113
+ const remainingBaseLiquidity = openBids.sub(topOfBookBidSize);
114
+ quoteSwapped = topOfBookQuoteAmounts[numBids];
115
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
116
+ (0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'quote', quoteSwapped, __1.SwapDirection.REMOVE);
117
+ baseSwapped = bidAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
118
+ if (remainingBaseLiquidity.lt(baseSwapped)) {
119
+ baseSwapped = remainingBaseLiquidity;
120
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
121
+ (0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
122
+ quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
123
+ }
124
+ topOfBookBidSize = topOfBookBidSize.add(baseSwapped);
125
+ bidSize = openBids.sub(topOfBookBidSize).div(new __1.BN(numBaseOrders));
126
+ }
127
+ else {
128
+ baseSwapped = bidSize;
129
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
130
+ (0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
131
+ quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
132
+ }
133
+ const price = quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwapped);
99
134
  bidAmm.baseAssetReserve = afterSwapBaseReserves;
100
135
  bidAmm.quoteAssetReserve = afterSwapQuoteReserves;
101
136
  yield {
102
137
  price,
103
- size: baseSize,
104
- sources: { vamm: baseSize },
138
+ size: baseSwapped,
139
+ sources: { vamm: baseSwapped },
105
140
  };
106
141
  numBids++;
107
142
  }
108
143
  };
109
144
  let numAsks = 0;
110
- const askSize = openAsks.abs().div(new __1.BN(numOrders));
145
+ let topOfBookAskSize = __1.ZERO;
146
+ let askSize = openAsks.abs().div(new __1.BN(numBaseOrders));
111
147
  const askAmm = {
112
148
  baseAssetReserve: askReserves.baseAssetReserve,
113
149
  quoteAssetReserve: askReserves.quoteAssetReserve,
@@ -116,15 +152,42 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, })
116
152
  };
117
153
  const getL2Asks = function* () {
118
154
  while (numAsks < numOrders && askSize.gt(__1.ZERO)) {
119
- const [afterSwapQuoteReserves, afterSwapBaseReserves] = (0, __1.calculateAmmReservesAfterSwap)(askAmm, 'base', askSize, __1.SwapDirection.REMOVE);
120
- const quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), askAmm.pegMultiplier, __1.SwapDirection.REMOVE);
121
- const price = quoteSwapped.mul(__1.BASE_PRECISION).div(askSize);
155
+ let quoteSwapped = __1.ZERO;
156
+ let baseSwapped = __1.ZERO;
157
+ let [afterSwapQuoteReserves, afterSwapBaseReserves] = [__1.ZERO, __1.ZERO];
158
+ if (topOfBookQuoteAmounts && numAsks < (topOfBookQuoteAmounts === null || topOfBookQuoteAmounts === void 0 ? void 0 : topOfBookQuoteAmounts.length)) {
159
+ const remainingBaseLiquidity = openAsks
160
+ .mul(new __1.BN(-1))
161
+ .sub(topOfBookAskSize);
162
+ quoteSwapped = topOfBookQuoteAmounts[numAsks];
163
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
164
+ (0, __1.calculateAmmReservesAfterSwap)(askAmm, 'quote', quoteSwapped, __1.SwapDirection.ADD);
165
+ baseSwapped = askAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
166
+ if (remainingBaseLiquidity.lt(baseSwapped)) {
167
+ baseSwapped = remainingBaseLiquidity;
168
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
169
+ (0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.REMOVE);
170
+ quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.REMOVE);
171
+ }
172
+ topOfBookAskSize = topOfBookAskSize.add(baseSwapped);
173
+ askSize = openAsks
174
+ .abs()
175
+ .sub(topOfBookAskSize)
176
+ .div(new __1.BN(numBaseOrders));
177
+ }
178
+ else {
179
+ baseSwapped = askSize;
180
+ [afterSwapQuoteReserves, afterSwapBaseReserves] =
181
+ (0, __1.calculateAmmReservesAfterSwap)(askAmm, 'base', askSize, __1.SwapDirection.REMOVE);
182
+ quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), askAmm.pegMultiplier, __1.SwapDirection.REMOVE);
183
+ }
184
+ const price = quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwapped);
122
185
  askAmm.baseAssetReserve = afterSwapBaseReserves;
123
186
  askAmm.quoteAssetReserve = afterSwapQuoteReserves;
124
187
  yield {
125
188
  price,
126
- size: askSize,
127
- sources: { vamm: baseSize },
189
+ size: baseSwapped,
190
+ sources: { vamm: baseSwapped },
128
191
  };
129
192
  numAsks++;
130
193
  }
@@ -419,19 +419,21 @@ class BigNum {
419
419
  * @returns
420
420
  */
421
421
  static fromPrint(val, precisionShift) {
422
- var _a;
422
+ var _a, _b;
423
423
  // Handle empty number edge cases
424
424
  if (!val)
425
425
  return BigNum.from(numericConstants_1.ZERO, precisionShift);
426
426
  if (!val.replace(BigNum.delim, '')) {
427
427
  return BigNum.from(numericConstants_1.ZERO, precisionShift);
428
428
  }
429
+ if (val.includes('e'))
430
+ val = (+val).toFixed((_a = precisionShift === null || precisionShift === void 0 ? void 0 : precisionShift.toNumber()) !== null && _a !== void 0 ? _a : 9); // prevent small numbers e.g. 3.1e-8, use assume max precision 9 as default
429
431
  const sides = val.split(BigNum.delim);
430
432
  const rightSide = sides[1];
431
433
  const leftSide = sides[0].replace(/\s/g, '');
432
434
  const bnInput = `${leftSide !== null && leftSide !== void 0 ? leftSide : ''}${rightSide !== null && rightSide !== void 0 ? rightSide : ''}`;
433
435
  const rawBn = new anchor_1.BN(bnInput);
434
- const rightSideLength = (_a = rightSide === null || rightSide === void 0 ? void 0 : rightSide.length) !== null && _a !== void 0 ? _a : 0;
436
+ const rightSideLength = (_b = rightSide === null || rightSide === void 0 ? void 0 : rightSide.length) !== null && _b !== void 0 ? _b : 0;
435
437
  const totalShift = precisionShift
436
438
  ? precisionShift.sub(new anchor_1.BN(rightSideLength))
437
439
  : numericConstants_1.ZERO;
@@ -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": [
@@ -8175,6 +8338,12 @@
8175
8338
  },
8176
8339
  {
8177
8340
  "name": "Unstake"
8341
+ },
8342
+ {
8343
+ "name": "UnstakeTransfer"
8344
+ },
8345
+ {
8346
+ "name": "StakeTransfer"
8178
8347
  }
8179
8348
  ]
8180
8349
  }
@@ -229,8 +229,8 @@ export declare class JupiterClient {
229
229
  * @param swapMode the swap mode (ExactIn or ExactOut)
230
230
  * @param onlyDirectRoutes whether to only return direct routes
231
231
  */
232
- getQuote({ inputMint, outputMint, amount, maxAccounts, // 52 is an estimated amount with buffer
233
- slippageBps, swapMode, onlyDirectRoutes, }: {
232
+ getQuote({ inputMint, outputMint, amount, maxAccounts, // 50 is an estimated amount with buffer
233
+ slippageBps, swapMode, onlyDirectRoutes, excludeDexes, }: {
234
234
  inputMint: PublicKey;
235
235
  outputMint: PublicKey;
236
236
  amount: BN;
@@ -238,6 +238,7 @@ export declare class JupiterClient {
238
238
  slippageBps?: number;
239
239
  swapMode?: SwapMode;
240
240
  onlyDirectRoutes?: boolean;
241
+ excludeDexes?: string[];
241
242
  }): Promise<QuoteResponse>;
242
243
  /**
243
244
  * Get a swap transaction for quote