@drift-labs/sdk 0.2.0-master.32 → 0.2.0-master.33

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 (108) hide show
  1. package/lib/accounts/bulkAccountLoader.js +2 -1
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +2 -2
  3. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +8 -8
  4. package/lib/accounts/types.d.ts +1 -0
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +2 -2
  6. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +7 -7
  7. package/lib/addresses/marketAddresses.js +1 -1
  8. package/lib/addresses/pda.d.ts +4 -4
  9. package/lib/addresses/pda.js +23 -22
  10. package/lib/admin.d.ts +30 -32
  11. package/lib/admin.js +111 -119
  12. package/lib/clearingHouse.d.ts +43 -34
  13. package/lib/clearingHouse.js +353 -193
  14. package/lib/clearingHouseConfig.d.ts +2 -2
  15. package/lib/clearingHouseUser.d.ts +26 -5
  16. package/lib/clearingHouseUser.js +151 -51
  17. package/lib/config.d.ts +2 -0
  18. package/lib/config.js +5 -1
  19. package/lib/constants/numericConstants.d.ts +1 -0
  20. package/lib/constants/numericConstants.js +3 -2
  21. package/lib/dlob/DLOB.d.ts +18 -11
  22. package/lib/dlob/DLOB.js +179 -107
  23. package/lib/dlob/DLOBNode.js +2 -10
  24. package/lib/dlob/NodeList.js +1 -1
  25. package/lib/events/eventSubscriber.d.ts +1 -0
  26. package/lib/events/eventSubscriber.js +11 -4
  27. package/lib/events/fetchLogs.d.ts +3 -1
  28. package/lib/events/fetchLogs.js +13 -5
  29. package/lib/events/pollingLogProvider.js +1 -1
  30. package/lib/events/types.d.ts +1 -1
  31. package/lib/events/webSocketLogProvider.js +1 -1
  32. package/lib/factory/bigNum.d.ts +5 -4
  33. package/lib/factory/bigNum.js +36 -6
  34. package/lib/idl/clearing_house.json +1527 -1242
  35. package/lib/index.d.ts +3 -0
  36. package/lib/index.js +3 -0
  37. package/lib/math/amm.js +9 -9
  38. package/lib/math/exchangeStatus.d.ts +4 -0
  39. package/lib/math/exchangeStatus.js +18 -0
  40. package/lib/math/funding.js +10 -10
  41. package/lib/math/margin.js +6 -1
  42. package/lib/math/market.js +9 -9
  43. package/lib/math/orders.d.ts +7 -3
  44. package/lib/math/orders.js +39 -31
  45. package/lib/math/repeg.js +3 -3
  46. package/lib/math/spotBalance.js +3 -3
  47. package/lib/math/spotPosition.js +2 -2
  48. package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
  49. package/lib/serum/serumFulfillmentConfigMap.js +17 -0
  50. package/lib/serum/serumSubscriber.d.ts +4 -0
  51. package/lib/serum/serumSubscriber.js +16 -1
  52. package/lib/types.d.ts +60 -75
  53. package/lib/types.js +2 -1
  54. package/lib/userMap/userMap.d.ts +17 -1
  55. package/lib/userMap/userMap.js +12 -0
  56. package/lib/userName.d.ts +1 -0
  57. package/lib/userName.js +3 -2
  58. package/package.json +1 -1
  59. package/src/accounts/bulkAccountLoader.ts +5 -1
  60. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +9 -9
  61. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +8 -8
  62. package/src/addresses/marketAddresses.ts +2 -2
  63. package/src/addresses/pda.ts +20 -20
  64. package/src/admin.ts +246 -221
  65. package/src/assert/assert.js +9 -0
  66. package/src/clearingHouse.ts +556 -236
  67. package/src/clearingHouseConfig.ts +2 -2
  68. package/src/clearingHouseUser.ts +237 -87
  69. package/src/config.ts +8 -1
  70. package/src/constants/numericConstants.ts +5 -1
  71. package/src/dlob/DLOB.ts +257 -120
  72. package/src/dlob/DLOBNode.ts +2 -14
  73. package/src/dlob/NodeList.ts +1 -1
  74. package/src/events/eventList.js +77 -0
  75. package/src/events/eventSubscriber.ts +18 -4
  76. package/src/events/fetchLogs.ts +20 -5
  77. package/src/events/pollingLogProvider.ts +1 -1
  78. package/src/events/types.ts +2 -1
  79. package/src/events/webSocketLogProvider.ts +1 -1
  80. package/src/examples/makeTradeExample.js +157 -0
  81. package/src/factory/bigNum.ts +59 -6
  82. package/src/idl/clearing_house.json +1527 -1242
  83. package/src/idl/pyth.json +98 -2
  84. package/src/index.ts +3 -0
  85. package/src/math/amm.ts +9 -9
  86. package/src/math/exchangeStatus.ts +31 -0
  87. package/src/math/funding.ts +20 -10
  88. package/src/math/margin.ts +7 -1
  89. package/src/math/market.ts +9 -9
  90. package/src/math/orders.ts +44 -29
  91. package/src/math/repeg.ts +3 -3
  92. package/src/math/spotBalance.ts +4 -4
  93. package/src/math/spotPosition.ts +2 -2
  94. package/src/serum/serumFulfillmentConfigMap.ts +26 -0
  95. package/src/serum/serumSubscriber.ts +20 -1
  96. package/src/token/index.js +38 -0
  97. package/src/tx/types.js +2 -0
  98. package/src/tx/utils.js +17 -0
  99. package/src/types.ts +65 -51
  100. package/src/userMap/userMap.ts +25 -1
  101. package/src/userName.ts +2 -1
  102. package/src/util/computeUnits.js +27 -0
  103. package/src/util/getTokenAddress.js +9 -0
  104. package/src/util/promiseTimeout.js +14 -0
  105. package/src/util/tps.js +27 -0
  106. package/tests/bn/test.ts +22 -1
  107. package/tests/dlob/helpers.ts +252 -81
  108. package/tests/dlob/test.ts +1040 -219
@@ -10,8 +10,8 @@ export declare type ClearingHouseConfig = {
10
10
  accountSubscription?: ClearingHouseSubscriptionConfig;
11
11
  opts?: ConfirmOptions;
12
12
  txSenderConfig?: TxSenderConfig;
13
- userIds?: number[];
14
- activeUserId?: number;
13
+ subAccountIds?: number[];
14
+ activeSubAccountId?: number;
15
15
  perpMarketIndexes?: number[];
16
16
  spotMarketIndexes?: number[];
17
17
  oracleInfos?: OracleInfo[];
@@ -50,6 +50,18 @@ export declare class ClearingHouseUser {
50
50
  getOrderByUserOrderId(userOrderId: number): Order | undefined;
51
51
  getUserAccountPublicKey(): PublicKey;
52
52
  exists(): Promise<boolean>;
53
+ /**
54
+ * calculates the total open bids/asks in a perp market (including lps)
55
+ * @returns : open bids
56
+ * @returns : open asks
57
+ */
58
+ getPerpBidAsks(marketIndex: number): [BN, BN];
59
+ /**
60
+ * calculates the open bids and asks for an lp
61
+ * @returns : lp open bids
62
+ * @returns : lp open asks
63
+ */
64
+ getLPBidAsks(marketIndex: number): [BN, BN];
53
65
  /**
54
66
  * calculates the market position if the lp position was settled
55
67
  * @returns : the settled userPosition
@@ -119,10 +131,12 @@ export declare class ClearingHouseUser {
119
131
  * calculates current user leverage across all positions
120
132
  * @returns : Precision TEN_THOUSAND
121
133
  */
122
- getLeverage(marginCategory?: MarginCategory): BN;
134
+ getLeverage(): BN;
135
+ getTotalLiabilityValue(): BN;
136
+ getTotalAssetValue(): BN;
123
137
  /**
124
138
  * calculates max allowable leverage exceeding hitting requirement category
125
- * @params category {Initial, Partial, Maintenance}
139
+ * @params category {Initial, Maintenance}
126
140
  * @returns : Precision TEN_THOUSAND
127
141
  */
128
142
  getMaxLeverage(marketIndex: number, category?: MarginCategory): BN;
@@ -130,7 +144,7 @@ export declare class ClearingHouseUser {
130
144
  * calculates margin ratio: total collateral / |total position value|
131
145
  * @returns : Precision TEN_THOUSAND
132
146
  */
133
- getMarginRatio(marginCategory?: MarginCategory): BN;
147
+ getMarginRatio(): BN;
134
148
  canBeLiquidated(): boolean;
135
149
  /**
136
150
  * Checks if any user position cumulative funding differs from respective market cumulative funding
@@ -181,19 +195,26 @@ export declare class ClearingHouseUser {
181
195
  * @param tradeQuoteAmount
182
196
  * @returns leverageRatio : Precision TEN_THOUSAND
183
197
  */
184
- accountLeverageRatioAfterTrade(targetMarketIndex: number, tradeQuoteAmount: BN, tradeSide: PositionDirection): BN;
198
+ accountLeverageRatioAfterTrade(targetMarketIndex: number, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
185
199
  /**
186
200
  * Calculates how much fee will be taken for a given sized trade
187
201
  * @param quoteAmount
188
202
  * @returns feeForQuote : Precision QUOTE_PRECISION
189
203
  */
190
204
  calculateFeeForQuoteAmount(quoteAmount: BN): BN;
205
+ /**
206
+ * Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
207
+ * it will return the max withdrawal amount without opening a liability for the user
208
+ * @param marketIndex
209
+ * @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
210
+ */
211
+ getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN;
191
212
  /**
192
213
  * Get the total position value, excluding any position coming from the given target market
193
214
  * @param marketToIgnore
194
215
  * @returns positionValue : Precision QUOTE_PRECISION
195
216
  */
196
217
  private getTotalPerpPositionValueExcludingMarket;
197
- private getOracleDataForMarket;
218
+ private getOracleDataForPerpMarket;
198
219
  private getOracleDataForSpotMarket;
199
220
  }
@@ -6,6 +6,7 @@ const position_1 = require("./math/position");
6
6
  const numericConstants_1 = require("./constants/numericConstants");
7
7
  const _1 = require(".");
8
8
  const spotBalance_1 = require("./math/spotBalance");
9
+ const amm_1 = require("./math/amm");
9
10
  const margin_1 = require("./math/margin");
10
11
  const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSubscriber");
11
12
  const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
@@ -104,6 +105,38 @@ class ClearingHouseUser {
104
105
  const userAccountRPCResponse = await this.clearingHouse.connection.getParsedAccountInfo(this.userAccountPublicKey);
105
106
  return userAccountRPCResponse.value !== null;
106
107
  }
108
+ /**
109
+ * calculates the total open bids/asks in a perp market (including lps)
110
+ * @returns : open bids
111
+ * @returns : open asks
112
+ */
113
+ getPerpBidAsks(marketIndex) {
114
+ const position = this.getUserPosition(marketIndex);
115
+ const [lpOpenBids, lpOpenAsks] = this.getLPBidAsks(marketIndex);
116
+ const totalOpenBids = lpOpenBids.add(position.openBids);
117
+ const totalOpenAsks = lpOpenAsks.sub(position.openAsks);
118
+ return [totalOpenBids, totalOpenAsks];
119
+ }
120
+ /**
121
+ * calculates the open bids and asks for an lp
122
+ * @returns : lp open bids
123
+ * @returns : lp open asks
124
+ */
125
+ getLPBidAsks(marketIndex) {
126
+ const position = this.getUserPosition(marketIndex);
127
+ if (position.lpShares.eq(numericConstants_1.ZERO)) {
128
+ return [numericConstants_1.ZERO, numericConstants_1.ZERO];
129
+ }
130
+ const market = this.clearingHouse.getPerpMarketAccount(marketIndex);
131
+ const [marketOpenBids, marketOpenAsks] = (0, amm_1.calculateMarketOpenBidAsk)(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve);
132
+ const lpOpenBids = marketOpenBids
133
+ .mul(position.lpShares)
134
+ .div(market.amm.sqrtK);
135
+ const lpOpenAsks = marketOpenAsks
136
+ .mul(position.lpShares)
137
+ .div(market.amm.sqrtK);
138
+ return [lpOpenBids, lpOpenAsks];
139
+ }
107
140
  /**
108
141
  * calculates the market position if the lp position was settled
109
142
  * @returns : the settled userPosition
@@ -113,13 +146,16 @@ class ClearingHouseUser {
113
146
  getSettledLPPosition(marketIndex) {
114
147
  const _position = this.getUserPosition(marketIndex);
115
148
  const position = this.getClonedPosition(_position);
149
+ if (position.lpShares.eq(numericConstants_1.ZERO)) {
150
+ return [position, numericConstants_1.ZERO, numericConstants_1.ZERO];
151
+ }
116
152
  const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
117
153
  const nShares = position.lpShares;
118
- const deltaBaa = market.amm.marketPositionPerLp.baseAssetAmount
154
+ const deltaBaa = market.amm.baseAssetAmountPerLp
119
155
  .sub(position.lastNetBaseAssetAmountPerLp)
120
156
  .mul(nShares)
121
157
  .div(numericConstants_1.AMM_RESERVE_PRECISION);
122
- const deltaQaa = market.amm.marketPositionPerLp.quoteAssetAmount
158
+ const deltaQaa = market.amm.quoteAssetAmountPerLp
123
159
  .sub(position.lastNetQuoteAssetAmountPerLp)
124
160
  .mul(nShares)
125
161
  .div(numericConstants_1.AMM_RESERVE_PRECISION);
@@ -132,11 +168,11 @@ class ClearingHouseUser {
132
168
  const standardizedAmount = amount.sub(remainder);
133
169
  return [standardizedAmount, remainder];
134
170
  }
135
- const [standardizedBaa, remainderBaa] = standardize(deltaBaa, market.amm.baseAssetAmountStepSize);
171
+ const [standardizedBaa, remainderBaa] = standardize(deltaBaa, market.amm.orderStepSize);
136
172
  position.remainderBaseAssetAmount += remainderBaa.toNumber();
137
173
  if (Math.abs(position.remainderBaseAssetAmount) >
138
- market.amm.baseAssetAmountStepSize.toNumber()) {
139
- const [newStandardizedBaa, newRemainderBaa] = standardize(position.remainderBaseAssetAmount, market.amm.baseAssetAmountStepSize);
174
+ market.amm.orderStepSize.toNumber()) {
175
+ const [newStandardizedBaa, newRemainderBaa] = standardize(new _1.BN(position.remainderBaseAssetAmount), market.amm.orderStepSize);
140
176
  position.baseAssetAmount =
141
177
  position.baseAssetAmount.add(newStandardizedBaa);
142
178
  position.remainderBaseAssetAmount = newRemainderBaa.toNumber();
@@ -235,7 +271,7 @@ class ClearingHouseUser {
235
271
  .perpPositions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
236
272
  .reduce((unrealizedPnl, perpPosition) => {
237
273
  const market = this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex);
238
- const oraclePriceData = this.getOracleDataForMarket(market.marketIndex);
274
+ const oraclePriceData = this.getOracleDataForPerpMarket(market.marketIndex);
239
275
  let positionUnrealizedPnl = (0, _1.calculatePositionPNL)(market, perpPosition, withFunding, oraclePriceData);
240
276
  if (withWeightMarginCategory !== undefined) {
241
277
  if (positionUnrealizedPnl.gt(numericConstants_1.ZERO)) {
@@ -269,10 +305,10 @@ class ClearingHouseUser {
269
305
  const spotMarketAccount = this.clearingHouse.getSpotMarketAccount(spotPosition.marketIndex);
270
306
  if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
271
307
  if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
272
- const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
308
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
273
309
  let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
274
310
  if (marginCategory === 'Initial') {
275
- weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
311
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
276
312
  }
277
313
  const weightedTokenValue = tokenAmount
278
314
  .mul(weight)
@@ -286,7 +322,7 @@ class ClearingHouseUser {
286
322
  const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
287
323
  if (!includeOpenOrders) {
288
324
  if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
289
- const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
325
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
290
326
  const liabilityValue = this.getSpotLiabilityValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer);
291
327
  return totalLiabilityValue.add(liabilityValue);
292
328
  }
@@ -304,7 +340,7 @@ class ClearingHouseUser {
304
340
  if (worstCaseQuoteTokenAmount.lt(numericConstants_1.ZERO)) {
305
341
  let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
306
342
  if (marginCategory === 'Initial') {
307
- weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
343
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
308
344
  }
309
345
  const weightedTokenValue = worstCaseQuoteTokenAmount
310
346
  .abs()
@@ -321,7 +357,7 @@ class ClearingHouseUser {
321
357
  if (marginCategory !== undefined) {
322
358
  let weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount, spotMarketAccount, marginCategory);
323
359
  if (marginCategory === 'Initial') {
324
- weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().customMarginRatio));
360
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
325
361
  }
326
362
  if (liquidationBuffer !== undefined) {
327
363
  weight = weight.add(liquidationBuffer);
@@ -343,7 +379,7 @@ class ClearingHouseUser {
343
379
  const spotMarketAccount = this.clearingHouse.getSpotMarketAccount(spotPosition.marketIndex);
344
380
  if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
345
381
  if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
346
- const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
382
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
347
383
  return totalAssetValue.add(tokenAmount);
348
384
  }
349
385
  else {
@@ -353,7 +389,7 @@ class ClearingHouseUser {
353
389
  const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
354
390
  if (!includeOpenOrders) {
355
391
  if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
356
- const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.balance, spotMarketAccount, spotPosition.balanceType);
392
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
357
393
  const assetValue = this.getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory);
358
394
  return totalAssetValue.add(assetValue);
359
395
  }
@@ -432,9 +468,9 @@ class ClearingHouseUser {
432
468
  perpPosition.openAsks = perpPosition.openAsks.add(openAsks);
433
469
  perpPosition.openBids = perpPosition.openBids.add(openBids);
434
470
  }
435
- let valuationPrice = this.getOracleDataForMarket(market.marketIndex).price;
471
+ let valuationPrice = this.getOracleDataForPerpMarket(market.marketIndex).price;
436
472
  if ((0, types_1.isVariant)(market.status, 'settlement')) {
437
- valuationPrice = market.settlementPrice;
473
+ valuationPrice = market.expiryPrice;
438
474
  }
439
475
  const baseAssetAmount = includeOpenOrders
440
476
  ? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition)
@@ -446,11 +482,14 @@ class ClearingHouseUser {
446
482
  if (marginCategory) {
447
483
  let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory));
448
484
  if (marginCategory === 'Initial') {
449
- marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().customMarginRatio));
485
+ marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().maxMarginRatio));
450
486
  }
451
487
  if (liquidationBuffer !== undefined) {
452
488
  marginRatio = marginRatio.add(liquidationBuffer);
453
489
  }
490
+ if ((0, types_1.isVariant)(market.status, 'settlement')) {
491
+ marginRatio = numericConstants_1.ZERO;
492
+ }
454
493
  baseAssetValue = baseAssetValue
455
494
  .mul(marginRatio)
456
495
  .div(numericConstants_1.MARGIN_PRECISION);
@@ -485,7 +524,7 @@ class ClearingHouseUser {
485
524
  getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
486
525
  const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
487
526
  const entryPrice = (0, position_1.calculateEntryPrice)(position);
488
- const oraclePriceData = this.getOracleDataForMarket(position.marketIndex);
527
+ const oraclePriceData = this.getOracleDataForPerpMarket(position.marketIndex);
489
528
  if (amountToClose) {
490
529
  if (amountToClose.eq(numericConstants_1.ZERO)) {
491
530
  return [(0, _1.calculateReservePrice)(market, oraclePriceData), numericConstants_1.ZERO];
@@ -522,45 +561,63 @@ class ClearingHouseUser {
522
561
  * calculates current user leverage across all positions
523
562
  * @returns : Precision TEN_THOUSAND
524
563
  */
525
- getLeverage(marginCategory) {
526
- const totalLiabilityValue = this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
527
- const totalAssetValue = this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
564
+ getLeverage() {
565
+ const totalLiabilityValue = this.getTotalLiabilityValue();
566
+ const totalAssetValue = this.getTotalAssetValue();
528
567
  if (totalAssetValue.eq(numericConstants_1.ZERO) && totalLiabilityValue.eq(numericConstants_1.ZERO)) {
529
568
  return numericConstants_1.ZERO;
530
569
  }
531
570
  return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(totalAssetValue);
532
571
  }
572
+ getTotalLiabilityValue() {
573
+ return this.getTotalPerpPositionValue(undefined, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, undefined, undefined, true));
574
+ }
575
+ getTotalAssetValue() {
576
+ return this.getSpotMarketAssetValue(undefined, undefined, true).add(this.getUnrealizedPNL(true, undefined, undefined));
577
+ }
533
578
  /**
534
579
  * calculates max allowable leverage exceeding hitting requirement category
535
- * @params category {Initial, Partial, Maintenance}
580
+ * @params category {Initial, Maintenance}
536
581
  * @returns : Precision TEN_THOUSAND
537
582
  */
538
583
  getMaxLeverage(marketIndex, category = 'Initial') {
539
584
  const market = this.clearingHouse.getPerpMarketAccount(marketIndex);
540
- const marginRatioCategory = (0, _1.calculateMarketMarginRatio)(market,
585
+ const totalAssetValue = this.getTotalAssetValue();
586
+ if (totalAssetValue.eq(numericConstants_1.ZERO)) {
587
+ return numericConstants_1.ZERO;
588
+ }
589
+ const totalLiabilityValue = this.getTotalLiabilityValue();
590
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(market,
541
591
  // worstCaseBaseAssetAmount.abs(),
542
592
  numericConstants_1.ZERO, // todo
543
593
  category);
544
- const maxLeverage = numericConstants_1.TEN_THOUSAND.mul(numericConstants_1.TEN_THOUSAND).div(new _1.BN(marginRatioCategory));
545
- return maxLeverage;
594
+ const freeCollateral = this.getFreeCollateral();
595
+ // how much more liabilities can be opened w remaining free collateral
596
+ const additionalLiabilities = freeCollateral
597
+ .mul(numericConstants_1.MARGIN_PRECISION)
598
+ .div(new _1.BN(marginRatio));
599
+ return totalLiabilityValue
600
+ .add(additionalLiabilities)
601
+ .mul(numericConstants_1.TEN_THOUSAND)
602
+ .div(totalAssetValue);
546
603
  }
547
604
  /**
548
605
  * calculates margin ratio: total collateral / |total position value|
549
606
  * @returns : Precision TEN_THOUSAND
550
607
  */
551
- getMarginRatio(marginCategory) {
552
- const totalLiabilityValue = this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
608
+ getMarginRatio() {
609
+ const totalLiabilityValue = this.getTotalLiabilityValue();
553
610
  if (totalLiabilityValue.eq(numericConstants_1.ZERO)) {
554
611
  return numericConstants_1.BN_MAX;
555
612
  }
556
- const totalAssetValue = this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
613
+ const totalAssetValue = this.getTotalAssetValue();
557
614
  return totalAssetValue.mul(numericConstants_1.TEN_THOUSAND).div(totalLiabilityValue);
558
615
  }
559
616
  canBeLiquidated() {
560
617
  const totalCollateral = this.getTotalCollateral();
561
618
  // if user being liq'd, can continue to be liq'd until total collateral above the margin requirement plus buffer
562
619
  let liquidationBuffer = undefined;
563
- if (this.getUserAccount().beingLiquidated) {
620
+ if (this.getUserAccount().isBeingLiquidated) {
564
621
  liquidationBuffer = new _1.BN(this.clearingHouse.getStateAccount().liquidationMarginBufferRatio);
565
622
  }
566
623
  const maintenanceRequirement = this.getMaintenanceMarginRequirement(liquidationBuffer);
@@ -628,13 +685,13 @@ class ClearingHouseUser {
628
685
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
629
686
  return new _1.BN(-1);
630
687
  const market = this.clearingHouse.getPerpMarketAccount(proposedPerpPosition.marketIndex);
631
- const proposedPerpPositionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, proposedPerpPosition, this.getOracleDataForMarket(market.marketIndex));
688
+ const proposedPerpPositionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, proposedPerpPosition, this.getOracleDataForPerpMarket(market.marketIndex));
632
689
  // total position value after trade
633
690
  const totalPositionValueAfterTrade = totalPositionValueExcludingTargetMarket.add(proposedPerpPositionValue);
634
691
  const marginRequirementExcludingTargetMarket = this.getUserAccount().perpPositions.reduce((totalMarginRequirement, position) => {
635
692
  if (position.marketIndex !== perpPosition.marketIndex) {
636
693
  const market = this.clearingHouse.getPerpMarketAccount(position.marketIndex);
637
- const positionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, position, this.getOracleDataForMarket(market.marketIndex));
694
+ const positionValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, position, this.getOracleDataForPerpMarket(market.marketIndex));
638
695
  const marketMarginRequirement = positionValue
639
696
  .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, position.baseAssetAmount.abs(), 'Maintenance')))
640
697
  .div(numericConstants_1.MARGIN_PRECISION);
@@ -672,13 +729,13 @@ class ClearingHouseUser {
672
729
  }
673
730
  let markPriceAfterTrade;
674
731
  if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
675
- markPriceAfterTrade = (0, _1.calculateReservePrice)(this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), this.getOracleDataForMarket(perpPosition.marketIndex));
732
+ markPriceAfterTrade = (0, _1.calculateReservePrice)(this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), this.getOracleDataForPerpMarket(perpPosition.marketIndex));
676
733
  }
677
734
  else {
678
735
  const direction = positionBaseSizeChange.gt(numericConstants_1.ZERO)
679
736
  ? _1.PositionDirection.LONG
680
737
  : _1.PositionDirection.SHORT;
681
- markPriceAfterTrade = (0, _1.calculateTradeSlippage)(direction, positionBaseSizeChange.abs(), this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), 'base', this.getOracleDataForMarket(perpPosition.marketIndex))[3]; // newPrice after swap
738
+ markPriceAfterTrade = (0, _1.calculateTradeSlippage)(direction, positionBaseSizeChange.abs(), this.clearingHouse.getPerpMarketAccount(perpPosition.marketIndex), 'base', this.getOracleDataForPerpMarket(perpPosition.marketIndex))[3]; // newPrice after swap
682
739
  }
683
740
  if (priceDelta.gt(markPriceAfterTrade)) {
684
741
  return new _1.BN(-1);
@@ -736,7 +793,7 @@ class ClearingHouseUser {
736
793
  const targetingSameSide = !currentPosition
737
794
  ? true
738
795
  : targetSide === currentPositionSide;
739
- const oracleData = this.getOracleDataForMarket(targetMarketIndex);
796
+ const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
740
797
  // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
741
798
  const oppositeSizeValueUSDC = targetingSameSide
742
799
  ? numericConstants_1.ZERO
@@ -791,10 +848,10 @@ class ClearingHouseUser {
791
848
  * @param tradeQuoteAmount
792
849
  * @returns leverageRatio : Precision TEN_THOUSAND
793
850
  */
794
- accountLeverageRatioAfterTrade(targetMarketIndex, tradeQuoteAmount, tradeSide) {
851
+ accountLeverageRatioAfterTrade(targetMarketIndex, tradeQuoteAmount, tradeSide, includeOpenOrders = true) {
795
852
  const currentPosition = this.getUserPosition(targetMarketIndex) ||
796
853
  this.getEmptyPosition(targetMarketIndex);
797
- const oracleData = this.getOracleDataForMarket(targetMarketIndex);
854
+ const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
798
855
  let currentPositionQuoteAmount = this.getPerpPositionValue(targetMarketIndex, oracleData);
799
856
  const currentSide = currentPosition && currentPosition.baseAssetAmount.isNeg()
800
857
  ? _1.PositionDirection.SHORT
@@ -806,19 +863,19 @@ class ClearingHouseUser {
806
863
  const currentPerpPositionAfterTrade = currentPositionQuoteAmount
807
864
  .add(tradeQuoteAmount)
808
865
  .abs();
809
- const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPerpPositionValueExcludingMarket(targetMarketIndex);
810
- const totalCollateral = this.getTotalCollateral();
811
- if (totalCollateral.gt(numericConstants_1.ZERO)) {
812
- const newLeverage = currentPerpPositionAfterTrade
813
- .add(totalPositionAfterTradeExcludingTargetMarket)
814
- .abs()
815
- .mul(numericConstants_1.TEN_THOUSAND)
816
- .div(totalCollateral);
817
- return newLeverage;
818
- }
819
- else {
820
- return new _1.BN(0);
866
+ const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPerpPositionValueExcludingMarket(targetMarketIndex, undefined, undefined, includeOpenOrders);
867
+ const totalAssetValue = this.getTotalAssetValue();
868
+ const totalPerpPositionValue = currentPerpPositionAfterTrade
869
+ .add(totalPositionAfterTradeExcludingTargetMarket)
870
+ .abs();
871
+ const totalLiabilitiesAfterTrade = totalPerpPositionValue.add(this.getSpotMarketLiabilityValue(undefined, undefined, undefined, false));
872
+ if (totalAssetValue.eq(numericConstants_1.ZERO) && totalLiabilitiesAfterTrade.eq(numericConstants_1.ZERO)) {
873
+ return numericConstants_1.ZERO;
821
874
  }
875
+ const newLeverage = totalLiabilitiesAfterTrade
876
+ .mul(numericConstants_1.TEN_THOUSAND)
877
+ .div(totalAssetValue);
878
+ return newLeverage;
822
879
  }
823
880
  /**
824
881
  * Calculates how much fee will be taken for a given sized trade
@@ -831,22 +888,65 @@ class ClearingHouseUser {
831
888
  .mul(new _1.BN(feeTier.feeNumerator))
832
889
  .div(new _1.BN(feeTier.feeDenominator));
833
890
  }
891
+ /**
892
+ * Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
893
+ * it will return the max withdrawal amount without opening a liability for the user
894
+ * @param marketIndex
895
+ * @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
896
+ */
897
+ getWithdrawalLimit(marketIndex, reduceOnly) {
898
+ const nowTs = new _1.BN(Math.floor(Date.now() / 1000));
899
+ const spotMarket = this.clearingHouse.getSpotMarketAccount(marketIndex);
900
+ const { borrowLimit, withdrawLimit } = (0, spotBalance_1.calculateWithdrawLimit)(spotMarket, nowTs);
901
+ const freeCollateral = this.getFreeCollateral();
902
+ const oracleData = this.getOracleDataForSpotMarket(marketIndex);
903
+ const precisionIncrease = numericConstants_1.TEN.pow(new _1.BN(spotMarket.decimals - 6));
904
+ const amountWithdrawable = freeCollateral
905
+ .mul(numericConstants_1.MARGIN_PRECISION)
906
+ .div(spotMarket.initialAssetWeight)
907
+ .mul(numericConstants_1.PRICE_PRECISION)
908
+ .div(oracleData.price)
909
+ .mul(precisionIncrease);
910
+ const userSpotPosition = this.getUserAccount().spotPositions.find((spotPosition) => (0, types_1.isVariant)(spotPosition.balanceType, 'deposit') &&
911
+ spotPosition.marketIndex == marketIndex);
912
+ const userSpotBalance = userSpotPosition
913
+ ? (0, spotBalance_1.getTokenAmount)(userSpotPosition.scaledBalance, this.clearingHouse.getSpotMarketAccount(marketIndex), _1.SpotBalanceType.DEPOSIT)
914
+ : numericConstants_1.ZERO;
915
+ const maxWithdrawValue = _1.BN.min(_1.BN.min(amountWithdrawable, userSpotBalance), withdrawLimit.abs());
916
+ if (reduceOnly) {
917
+ return _1.BN.max(maxWithdrawValue, numericConstants_1.ZERO);
918
+ }
919
+ else {
920
+ const weightedAssetValue = this.getSpotMarketAssetValue(marketIndex, 'Initial', false);
921
+ const freeCollatAfterWithdraw = userSpotBalance.gt(numericConstants_1.ZERO)
922
+ ? freeCollateral.sub(weightedAssetValue)
923
+ : freeCollateral;
924
+ const maxLiabilityAllowed = freeCollatAfterWithdraw
925
+ .mul(numericConstants_1.MARGIN_PRECISION)
926
+ .div(spotMarket.initialLiabilityWeight)
927
+ .mul(numericConstants_1.PRICE_PRECISION)
928
+ .div(oracleData.price)
929
+ .mul(precisionIncrease);
930
+ const maxBorrowValue = _1.BN.min(maxWithdrawValue.add(maxLiabilityAllowed), borrowLimit.abs());
931
+ return _1.BN.max(maxBorrowValue, numericConstants_1.ZERO);
932
+ }
933
+ }
834
934
  /**
835
935
  * Get the total position value, excluding any position coming from the given target market
836
936
  * @param marketToIgnore
837
937
  * @returns positionValue : Precision QUOTE_PRECISION
838
938
  */
839
- getTotalPerpPositionValueExcludingMarket(marketToIgnore) {
939
+ getTotalPerpPositionValueExcludingMarket(marketToIgnore, marginCategory, liquidationBuffer, includeOpenOrders) {
840
940
  const currentPerpPosition = this.getUserPosition(marketToIgnore) ||
841
941
  this.getEmptyPosition(marketToIgnore);
842
- const oracleData = this.getOracleDataForMarket(marketToIgnore);
942
+ const oracleData = this.getOracleDataForPerpMarket(marketToIgnore);
843
943
  let currentPerpPositionValueUSDC = numericConstants_1.ZERO;
844
944
  if (currentPerpPosition) {
845
945
  currentPerpPositionValueUSDC = this.getPerpPositionValue(marketToIgnore, oracleData);
846
946
  }
847
- return this.getTotalPerpPositionValue().sub(currentPerpPositionValueUSDC);
947
+ return this.getTotalPerpPositionValue(marginCategory, liquidationBuffer, includeOpenOrders).sub(currentPerpPositionValueUSDC);
848
948
  }
849
- getOracleDataForMarket(marketIndex) {
949
+ getOracleDataForPerpMarket(marketIndex) {
850
950
  const oracleKey = this.clearingHouse.getPerpMarketAccount(marketIndex).amm.oracle;
851
951
  const oracleData = this.clearingHouse.getOraclePriceDataAndSlot(oracleKey).data;
852
952
  return oracleData;
package/lib/config.d.ts CHANGED
@@ -6,6 +6,8 @@ declare type DriftConfig = {
6
6
  PYTH_ORACLE_MAPPING_ADDRESS: string;
7
7
  CLEARING_HOUSE_PROGRAM_ID: string;
8
8
  USDC_MINT_ADDRESS: string;
9
+ SERUM_V3: string;
10
+ V2_ALPHA_TICKET_MINT_ADDRESS: string;
9
11
  PERP_MARKETS: PerpMarketConfig[];
10
12
  SPOT_MARKETS: SpotMarketConfig[];
11
13
  };
package/lib/config.js CHANGED
@@ -7,8 +7,10 @@ exports.configs = {
7
7
  devnet: {
8
8
  ENV: 'devnet',
9
9
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
10
- CLEARING_HOUSE_PROGRAM_ID: 'DUZwKJKAk2C9S88BYvQzck1M1i5hySQjxB4zW6tJ29Nw',
10
+ CLEARING_HOUSE_PROGRAM_ID: 'FPVkWvcQgc4aCS8TrKo5c8GqTbKMauvzpADdqzRT2WbT',
11
11
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
12
+ SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
13
+ V2_ALPHA_TICKET_MINT_ADDRESS: 'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
12
14
  PERP_MARKETS: perpMarkets_1.DevnetPerpMarkets,
13
15
  SPOT_MARKETS: spotMarkets_1.DevnetSpotMarkets,
14
16
  },
@@ -17,6 +19,8 @@ exports.configs = {
17
19
  PYTH_ORACLE_MAPPING_ADDRESS: 'AHtgzX45WTKfkPG53L6WYhGEXwQkN1BVknET3sVsLL8J',
18
20
  CLEARING_HOUSE_PROGRAM_ID: 'dammHkt7jmytvbS3nHTxQNEcP59aE57nxwV21YdqEDN',
19
21
  USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
22
+ SERUM_V3: '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
23
+ V2_ALPHA_TICKET_MINT_ADDRESS: '',
20
24
  PERP_MARKETS: perpMarkets_1.MainnetMarkets,
21
25
  SPOT_MARKETS: spotMarkets_1.MainnetSpotMarkets,
22
26
  },
@@ -25,6 +25,7 @@ export declare const SPOT_MARKET_RATE_PRECISION_EXP: BN;
25
25
  export declare const SPOT_MARKET_RATE_PRECISION: BN;
26
26
  export declare const SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP: BN;
27
27
  export declare const SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION: BN;
28
+ export declare const SPOT_MARKET_UTILIZATION_PRECISION_EXP: BN;
28
29
  export declare const SPOT_MARKET_UTILIZATION_PRECISION: BN;
29
30
  export declare const SPOT_MARKET_WEIGHT_PRECISION: BN;
30
31
  export declare const SPOT_MARKET_BALANCE_PRECISION_EXP: BN;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
3
+ exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
4
  const web3_js_1 = require("@solana/web3.js");
5
5
  const __1 = require("../");
6
6
  exports.ZERO = new __1.BN(0);
@@ -28,7 +28,8 @@ exports.SPOT_MARKET_RATE_PRECISION_EXP = new __1.BN(6);
28
28
  exports.SPOT_MARKET_RATE_PRECISION = new __1.BN(10).pow(exports.SPOT_MARKET_RATE_PRECISION_EXP);
29
29
  exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = new __1.BN(10);
30
30
  exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = new __1.BN(10).pow(exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP);
31
- exports.SPOT_MARKET_UTILIZATION_PRECISION = new __1.BN(1000000);
31
+ exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = new __1.BN(6);
32
+ exports.SPOT_MARKET_UTILIZATION_PRECISION = new __1.BN(10).pow(exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP);
32
33
  exports.SPOT_MARKET_WEIGHT_PRECISION = new __1.BN(10000);
33
34
  exports.SPOT_MARKET_BALANCE_PRECISION_EXP = new __1.BN(9);
34
35
  exports.SPOT_MARKET_BALANCE_PRECISION = new __1.BN(10).pow(exports.SPOT_MARKET_BALANCE_PRECISION_EXP);
@@ -1,6 +1,6 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { NodeList } from './NodeList';
3
- import { MarketType, BN, ClearingHouse, Order, SpotMarketAccount, PerpMarketAccount, OraclePriceData, SlotSubscriber, UserMap, MarketTypeStr } from '..';
3
+ import { MarketType, BN, ClearingHouse, Order, SpotMarketAccount, PerpMarketAccount, OraclePriceData, SlotSubscriber, UserMapInterface, MarketTypeStr, StateAccount } from '..';
4
4
  import { PublicKey } from '@solana/web3.js';
5
5
  import { DLOBNode, TriggerOrderNode } from '..';
6
6
  export declare type MarketNodeLists = {
@@ -33,42 +33,49 @@ declare type Side = 'ask' | 'bid' | 'both' | 'nocross';
33
33
  export declare class DLOB {
34
34
  openOrders: Map<MarketTypeStr, Set<string>>;
35
35
  orderLists: Map<MarketTypeStr, Map<number, MarketNodeLists>>;
36
+ stateAccount: StateAccount;
36
37
  marketIndexToAccount: Map<MarketTypeStr, Map<number, PerpMarketAccount | SpotMarketAccount>>;
38
+ userMap: UserMapInterface;
37
39
  silent: boolean;
38
40
  initialized: boolean;
39
41
  /**
40
42
  *
41
43
  * @param perpMarkets The perp markets to maintain a DLOB for
42
44
  * @param spotMarkets The spot markets to maintain a DLOB for
45
+ * @param userMap map of all users
43
46
  * @param silent set to true to prevent logging on inserts and removals
44
47
  */
45
- constructor(perpMarkets: PerpMarketAccount[], spotMarkets: SpotMarketAccount[], silent?: boolean);
48
+ constructor(perpMarkets: PerpMarketAccount[], spotMarkets: SpotMarketAccount[], stateAccount: StateAccount, userMap: UserMapInterface, silent?: boolean);
46
49
  clear(): void;
47
50
  /**
48
51
  * initializes a new DLOB instance
49
52
  *
50
- * @param clearingHouse The ClearingHouse instance to use for price data
51
53
  * @returns a promise that resolves when the DLOB is initialized
52
54
  */
53
- init(clearingHouse: ClearingHouse, userMap?: UserMap): Promise<boolean>;
55
+ init(): Promise<boolean>;
54
56
  insertOrder(order: Order, userAccount: PublicKey, onInsert?: OrderBookCallback): void;
55
57
  trigger(order: Order, userAccount: PublicKey, onTrigger?: OrderBookCallback): void;
56
58
  getListForOrder(order: Order): NodeList<any> | undefined;
57
- findNodesToFill(marketIndex: number, vBid: BN | undefined, vAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
59
+ findNodesToFill(marketIndex: number, fallbackBid: BN | undefined, fallbackAsk: BN | undefined, slot: number, ts: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
58
60
  findCrossingNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
59
- findvAMMCrossingNodesToFill(marketIndex: number, vBid: BN, vAsk: BN, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
60
- findExpiredMarketNodesToFill(marketIndex: number, slot: number, marketType: MarketType): NodeToFill[];
61
+ findFallbackCrossingNodesToFill(marketIndex: number, fallbackBid: BN, fallbackAsk: BN, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
62
+ findExpiredNodesToFill(marketIndex: number, ts: number, marketType: MarketType): NodeToFill[];
61
63
  findJitAuctionNodesToFill(marketIndex: number, slot: number, marketType: MarketType): NodeToFill[];
62
64
  getMarketBids(marketIndex: number, marketType: MarketType): Generator<DLOBNode>;
63
65
  getMarketAsks(marketIndex: number, marketType: MarketType): Generator<DLOBNode>;
64
- getAsks(marketIndex: number, vAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
65
- getBids(marketIndex: number, vBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
66
+ getAsks(marketIndex: number, fallbackAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
67
+ getBids(marketIndex: number, fallbackBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
66
68
  findCrossingOrders(askNode: DLOBNode, bidNode: DLOBNode, oraclePriceData: OraclePriceData, slot: number): {
67
69
  crossingNodes: NodeToFill[];
68
70
  exhaustedSide: Side;
69
71
  };
70
- getBestAsk(marketIndex: number, vAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
71
- getBestBid(marketIndex: number, vBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
72
+ determineMakerAndTaker(askNode: DLOBNode, bidNode: DLOBNode): {
73
+ takerNode: DLOBNode;
74
+ makerNode: DLOBNode;
75
+ makerSide: Side;
76
+ };
77
+ getBestAsk(marketIndex: number, fallbackAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
78
+ getBestBid(marketIndex: number, fallbackBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
72
79
  findNodesToTrigger(marketIndex: number, slot: number, oraclePrice: BN, marketType: MarketType): NodeToTrigger[];
73
80
  printTopOfOrderLists(sdkConfig: any, clearingHouse: ClearingHouse, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType): void;
74
81
  }