@drift-labs/sdk 0.1.19-master.1 → 0.1.21-master.3

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 (143) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +31 -0
  2. package/lib/accounts/bulkAccountLoader.js +177 -0
  3. package/lib/accounts/bulkUserSubscription.d.ts +7 -0
  4. package/lib/accounts/bulkUserSubscription.js +28 -0
  5. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
  7. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
  8. package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
  9. package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  10. package/lib/accounts/pollingUserAccountSubscriber.js +136 -0
  11. package/lib/accounts/types.d.ts +38 -3
  12. package/lib/accounts/utils.d.ts +1 -0
  13. package/lib/accounts/utils.js +7 -0
  14. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -3
  15. package/lib/accounts/webSocketAccountSubscriber.js +43 -12
  16. package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +8 -3
  17. package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +30 -4
  18. package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +6 -3
  19. package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +16 -4
  20. package/lib/addresses.d.ts +4 -1
  21. package/lib/addresses.js +28 -1
  22. package/lib/admin.d.ts +10 -4
  23. package/lib/admin.js +54 -17
  24. package/lib/assert/assert.d.ts +0 -1
  25. package/lib/clearingHouse.d.ts +39 -4
  26. package/lib/clearingHouse.js +334 -23
  27. package/lib/clearingHouseUser.d.ts +26 -20
  28. package/lib/clearingHouseUser.js +149 -118
  29. package/lib/config.d.ts +0 -1
  30. package/lib/constants/markets.d.ts +2 -2
  31. package/lib/constants/markets.js +28 -15
  32. package/lib/constants/numericConstants.d.ts +4 -2
  33. package/lib/constants/numericConstants.js +16 -17
  34. package/lib/examples/makeTradeExample.d.ts +0 -1
  35. package/lib/examples/makeTradeExample.js +6 -6
  36. package/lib/factory/clearingHouse.d.ts +25 -0
  37. package/lib/factory/clearingHouse.js +64 -0
  38. package/lib/factory/clearingHouseUser.d.ts +19 -0
  39. package/lib/factory/clearingHouseUser.js +34 -0
  40. package/lib/idl/clearing_house.json +1066 -39
  41. package/lib/index.d.ts +11 -3
  42. package/lib/index.js +12 -2
  43. package/lib/math/amm.d.ts +1 -1
  44. package/lib/math/amm.js +38 -15
  45. package/lib/math/conversion.d.ts +1 -2
  46. package/lib/math/conversion.js +1 -1
  47. package/lib/math/funding.d.ts +0 -1
  48. package/lib/math/funding.js +1 -1
  49. package/lib/math/insuranceFund.d.ts +2 -2
  50. package/lib/math/insuranceFund.js +3 -6
  51. package/lib/math/market.d.ts +2 -2
  52. package/lib/math/market.js +12 -2
  53. package/lib/math/orders.d.ts +3 -0
  54. package/lib/math/orders.js +32 -0
  55. package/lib/math/position.d.ts +6 -3
  56. package/lib/math/position.js +21 -10
  57. package/lib/math/trade.d.ts +0 -1
  58. package/lib/math/trade.js +16 -16
  59. package/lib/math/utils.d.ts +2 -2
  60. package/lib/math/utils.js +3 -3
  61. package/lib/mockUSDCFaucet.d.ts +2 -2
  62. package/lib/orderParams.d.ts +7 -0
  63. package/lib/orderParams.js +108 -0
  64. package/lib/orders.d.ts +6 -0
  65. package/lib/orders.js +136 -0
  66. package/lib/pythClient.d.ts +0 -1
  67. package/lib/pythClient.js +1 -1
  68. package/lib/token/index.d.ts +3 -0
  69. package/lib/token/index.js +38 -0
  70. package/lib/tx/defaultTxSender.d.ts +0 -1
  71. package/lib/tx/types.d.ts +0 -1
  72. package/lib/tx/utils.d.ts +0 -1
  73. package/lib/types.d.ts +147 -3
  74. package/lib/types.js +36 -1
  75. package/lib/util/computeUnits.d.ts +0 -1
  76. package/lib/util/tps.d.ts +0 -1
  77. package/lib/wallet.d.ts +0 -1
  78. package/package.json +11 -3
  79. package/src/accounts/bulkAccountLoader.ts +215 -0
  80. package/src/accounts/bulkUserSubscription.ts +28 -0
  81. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
  82. package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
  83. package/src/accounts/pollingUserAccountSubscriber.ts +194 -0
  84. package/src/accounts/types.ts +48 -1
  85. package/src/accounts/utils.ts +3 -0
  86. package/src/accounts/webSocketAccountSubscriber.ts +67 -17
  87. package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +51 -1
  88. package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +33 -3
  89. package/src/addresses.ts +37 -0
  90. package/src/admin.ts +92 -24
  91. package/src/clearingHouse.ts +455 -22
  92. package/src/clearingHouseUser.ts +190 -108
  93. package/src/constants/markets.ts +17 -1
  94. package/src/constants/numericConstants.ts +3 -1
  95. package/src/examples/makeTradeExample.ts +4 -1
  96. package/src/factory/clearingHouse.ts +125 -0
  97. package/src/factory/clearingHouseUser.ts +73 -0
  98. package/src/idl/clearing_house.json +1066 -39
  99. package/src/index.ts +11 -2
  100. package/src/math/amm.ts +47 -14
  101. package/src/math/conversion.ts +1 -1
  102. package/src/math/insuranceFund.ts +1 -1
  103. package/src/math/market.ts +28 -2
  104. package/src/math/orders.ts +44 -0
  105. package/src/math/position.ts +24 -4
  106. package/src/math/utils.ts +1 -1
  107. package/src/mockUSDCFaucet.ts +1 -1
  108. package/src/orderParams.ts +151 -0
  109. package/src/orders.ts +236 -0
  110. package/src/token/index.ts +37 -0
  111. package/src/types.ts +130 -2
  112. package/tsconfig.json +0 -1
  113. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +0 -1
  114. package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +0 -1
  115. package/lib/accounts/types.d.ts.map +0 -1
  116. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
  117. package/lib/addresses.d.ts.map +0 -1
  118. package/lib/admin.d.ts.map +0 -1
  119. package/lib/assert/assert.d.ts.map +0 -1
  120. package/lib/clearingHouse.d.ts.map +0 -1
  121. package/lib/clearingHouseUser.d.ts.map +0 -1
  122. package/lib/config.d.ts.map +0 -1
  123. package/lib/constants/markets.d.ts.map +0 -1
  124. package/lib/constants/numericConstants.d.ts.map +0 -1
  125. package/lib/examples/makeTradeExample.d.ts.map +0 -1
  126. package/lib/index.d.ts.map +0 -1
  127. package/lib/math/amm.d.ts.map +0 -1
  128. package/lib/math/conversion.d.ts.map +0 -1
  129. package/lib/math/funding.d.ts.map +0 -1
  130. package/lib/math/insuranceFund.d.ts.map +0 -1
  131. package/lib/math/market.d.ts.map +0 -1
  132. package/lib/math/position.d.ts.map +0 -1
  133. package/lib/math/trade.d.ts.map +0 -1
  134. package/lib/math/utils.d.ts.map +0 -1
  135. package/lib/mockUSDCFaucet.d.ts.map +0 -1
  136. package/lib/pythClient.d.ts.map +0 -1
  137. package/lib/tx/defaultTxSender.d.ts.map +0 -1
  138. package/lib/tx/types.d.ts.map +0 -1
  139. package/lib/tx/utils.d.ts.map +0 -1
  140. package/lib/types.d.ts.map +0 -1
  141. package/lib/util/computeUnits.d.ts.map +0 -1
  142. package/lib/util/tps.d.ts.map +0 -1
  143. package/lib/wallet.d.ts.map +0 -1
@@ -8,28 +8,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.ClearingHouseUser = void 0;
16
- const bn_js_1 = __importDefault(require("bn.js"));
17
13
  const position_1 = require("./math/position");
18
14
  const numericConstants_1 = require("./constants/numericConstants");
19
- const defaultUserAccountSubscriber_1 = require("./accounts/defaultUserAccountSubscriber");
20
15
  const _1 = require(".");
21
16
  const addresses_1 = require("./addresses");
17
+ const clearingHouseUser_1 = require("./factory/clearingHouseUser");
22
18
  class ClearingHouseUser {
23
19
  constructor(clearingHouse, authority, accountSubscriber) {
24
- this.isSubscribed = false;
20
+ this._isSubscribed = false;
25
21
  this.clearingHouse = clearingHouse;
26
22
  this.authority = authority;
27
23
  this.accountSubscriber = accountSubscriber;
28
24
  this.eventEmitter = this.accountSubscriber.eventEmitter;
29
25
  }
26
+ get isSubscribed() {
27
+ return this._isSubscribed && this.accountSubscriber.isSubscribed;
28
+ }
29
+ set isSubscribed(val) {
30
+ this._isSubscribed = val;
31
+ }
32
+ /**
33
+ * @deprecated You should use getClearingHouseUser factory method instead
34
+ * @param clearingHouse
35
+ * @param authority
36
+ * @returns
37
+ */
30
38
  static from(clearingHouse, authority) {
31
- const accountSubscriber = new defaultUserAccountSubscriber_1.DefaultUserAccountSubscriber(clearingHouse.program, authority);
32
- return new ClearingHouseUser(clearingHouse, authority, accountSubscriber);
39
+ if (clearingHouse.accountSubscriber.type !== 'websocket')
40
+ throw 'This method only works for clearing houses with a websocket account listener. Try using the getClearingHouseUser factory method to initialize a ClearingHouseUser instead';
41
+ const config = clearingHouseUser_1.getWebSocketClearingHouseUserConfig(clearingHouse, authority);
42
+ return clearingHouseUser_1.getClearingHouseUser(config);
33
43
  }
34
44
  /**
35
45
  * Subscribe to ClearingHouseUser state accounts
@@ -63,6 +73,9 @@ class ClearingHouseUser {
63
73
  getUserPositionsAccount() {
64
74
  return this.accountSubscriber.getUserPositionsAccount();
65
75
  }
76
+ getUserOrdersAccount() {
77
+ return this.accountSubscriber.getUserOrdersAccount();
78
+ }
66
79
  /**
67
80
  * Gets the user's current position for a given market. If the user has no position returns undefined
68
81
  * @param marketIndex
@@ -77,17 +90,41 @@ class ClearingHouseUser {
77
90
  lastCumulativeFundingRate: numericConstants_1.ZERO,
78
91
  marketIndex,
79
92
  quoteAssetAmount: numericConstants_1.ZERO,
93
+ openOrders: numericConstants_1.ZERO,
80
94
  };
81
95
  }
96
+ /**
97
+ * @param orderId
98
+ * @returns Order
99
+ */
100
+ getOrder(orderId) {
101
+ return this.getUserOrdersAccount().orders.find((order) => order.orderId.eq(orderId));
102
+ }
103
+ /**
104
+ * @param userOrderId
105
+ * @returns Order
106
+ */
107
+ getOrderByUserOrderId(userOrderId) {
108
+ return this.getUserOrdersAccount().orders.find((order) => order.userOrderId === userOrderId);
109
+ }
82
110
  getUserAccountPublicKey() {
83
111
  return __awaiter(this, void 0, void 0, function* () {
84
112
  if (this.userAccountPublicKey) {
85
113
  return this.userAccountPublicKey;
86
114
  }
87
- this.userAccountPublicKey = yield (0, addresses_1.getUserAccountPublicKey)(this.clearingHouse.program.programId, this.authority);
115
+ this.userAccountPublicKey = yield addresses_1.getUserAccountPublicKey(this.clearingHouse.program.programId, this.authority);
88
116
  return this.userAccountPublicKey;
89
117
  });
90
118
  }
119
+ getUserOrdersAccountPublicKey() {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ if (this.userOrdersAccountPublicKey) {
122
+ return this.userOrdersAccountPublicKey;
123
+ }
124
+ this.userOrdersAccountPublicKey = yield _1.getUserOrdersAccountPublicKey(this.clearingHouse.program.programId, yield this.getUserAccountPublicKey());
125
+ return this.userOrdersAccountPublicKey;
126
+ });
127
+ }
91
128
  exists() {
92
129
  return __awaiter(this, void 0, void 0, function* () {
93
130
  const userAccountPublicKey = yield this.getUserAccountPublicKey();
@@ -122,7 +159,7 @@ class ClearingHouseUser {
122
159
  .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
123
160
  .reduce((pnl, marketPosition) => {
124
161
  const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
125
- return pnl.add((0, _1.calculatePositionPNL)(market, marketPosition, withFunding));
162
+ return pnl.add(_1.calculatePositionPNL(market, marketPosition, withFunding));
126
163
  }, numericConstants_1.ZERO);
127
164
  }
128
165
  /**
@@ -134,7 +171,7 @@ class ClearingHouseUser {
134
171
  .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
135
172
  .reduce((pnl, marketPosition) => {
136
173
  const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
137
- return pnl.add((0, _1.calculatePositionFundingPNL)(market, marketPosition));
174
+ return pnl.add(_1.calculatePositionFundingPNL(market, marketPosition));
138
175
  }, numericConstants_1.ZERO);
139
176
  }
140
177
  /**
@@ -143,7 +180,7 @@ class ClearingHouseUser {
143
180
  */
144
181
  getTotalCollateral() {
145
182
  var _a;
146
- return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new bn_js_1.default(0));
183
+ return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new _1.BN(0));
147
184
  }
148
185
  /**
149
186
  * calculates sum of position value across all positions
@@ -152,7 +189,7 @@ class ClearingHouseUser {
152
189
  getTotalPositionValue() {
153
190
  return this.getUserPositionsAccount().positions.reduce((positionValue, marketPosition) => {
154
191
  const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
155
- return positionValue.add((0, _1.calculateBaseAssetValue)(market, marketPosition));
192
+ return positionValue.add(_1.calculateBaseAssetValue(market, marketPosition));
156
193
  }, numericConstants_1.ZERO);
157
194
  }
158
195
  /**
@@ -162,7 +199,7 @@ class ClearingHouseUser {
162
199
  getPositionValue(marketIndex) {
163
200
  const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
164
201
  const market = this.clearingHouse.getMarket(userPosition.marketIndex);
165
- return (0, _1.calculateBaseAssetValue)(market, userPosition);
202
+ return _1.calculateBaseAssetValue(market, userPosition);
166
203
  }
167
204
  getPositionSide(currentPosition) {
168
205
  if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
@@ -181,10 +218,10 @@ class ClearingHouseUser {
181
218
  */
182
219
  getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
183
220
  const market = this.clearingHouse.getMarket(position.marketIndex);
184
- const entryPrice = (0, position_1.calculateEntryPrice)(position);
221
+ const entryPrice = position_1.calculateEntryPrice(position);
185
222
  if (amountToClose) {
186
223
  if (amountToClose.eq(numericConstants_1.ZERO)) {
187
- return [(0, _1.calculateMarkPrice)(market), numericConstants_1.ZERO];
224
+ return [_1.calculateMarkPrice(market), numericConstants_1.ZERO];
188
225
  }
189
226
  position = {
190
227
  baseAssetAmount: amountToClose,
@@ -193,7 +230,7 @@ class ClearingHouseUser {
193
230
  quoteAssetAmount: position.quoteAssetAmount,
194
231
  };
195
232
  }
196
- const baseAssetValue = (0, _1.calculateBaseAssetValue)(market, position);
233
+ const baseAssetValue = _1.calculateBaseAssetValue(market, position);
197
234
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
198
235
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
199
236
  }
@@ -300,7 +337,7 @@ class ClearingHouseUser {
300
337
 
301
338
  for 10x long, BTC down $400:
302
339
  3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
303
- const currentPrice = (0, _1.calculateMarkPrice)(this.clearingHouse.getMarket(targetMarket.marketIndex));
340
+ const currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
304
341
  const totalCollateralUSDC = this.getTotalCollateral();
305
342
  // calculate the total position value ignoring any value from the target market of the trade
306
343
  const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
@@ -311,11 +348,12 @@ class ClearingHouseUser {
311
348
  const proposedMarketPosition = {
312
349
  marketIndex: targetMarket.marketIndex,
313
350
  baseAssetAmount: currentMarketPositionBaseSize.add(positionBaseSizeChange),
314
- lastCumulativeFundingRate: new bn_js_1.default(0),
315
- quoteAssetAmount: new bn_js_1.default(0),
351
+ lastCumulativeFundingRate: new _1.BN(0),
352
+ quoteAssetAmount: new _1.BN(0),
353
+ openOrders: new _1.BN(0),
316
354
  };
317
355
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
318
- const proposedMarketPositionValueUSDC = (0, _1.calculateBaseAssetValue)(market, proposedMarketPosition);
356
+ const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
319
357
  // total position value after trade
320
358
  const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
321
359
  let totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
@@ -329,7 +367,7 @@ class ClearingHouseUser {
329
367
  // if the position value after the trade is less than total collateral, there is no liq price
330
368
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
331
369
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
332
- return new bn_js_1.default(-1);
370
+ return new _1.BN(-1);
333
371
  }
334
372
  // get current margin ratio based on current collateral and proposed total position value
335
373
  let marginRatio;
@@ -356,7 +394,7 @@ class ClearingHouseUser {
356
394
  if (numericConstants_1.TEN_THOUSAND.lte(pctChange)) {
357
395
  // no liquidation price, position is a fully/over collateralized long
358
396
  // handle as NaN on UI
359
- return new bn_js_1.default(-1);
397
+ return new _1.BN(-1);
360
398
  }
361
399
  pctChange = numericConstants_1.TEN_THOUSAND.sub(pctChange);
362
400
  }
@@ -373,19 +411,19 @@ class ClearingHouseUser {
373
411
  liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
374
412
  // solves formula for example calc below
375
413
  /* example: assume BTC price is $40k (examine 10% up/down)
376
-
377
- if 10k deposit and levered 10x short BTC => BTC up $400 means:
378
- 1. higher base_asset_value (+$4k)
379
- 2. lower collateral (-$4k)
380
- 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
381
-
382
- for 10x long, BTC down $400:
383
- 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
414
+
415
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
416
+ 1. higher base_asset_value (+$4k)
417
+ 2. lower collateral (-$4k)
418
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
419
+
420
+ for 10x long, BTC down $400:
421
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
384
422
  const tc = this.getTotalCollateral();
385
423
  const tpv = this.getTotalPositionValue();
386
424
  const partialLev = 16;
387
425
  const maintLev = 20;
388
- const thisLev = partial ? new bn_js_1.default(partialLev) : new bn_js_1.default(maintLev);
426
+ const thisLev = partial ? new _1.BN(partialLev) : new _1.BN(maintLev);
389
427
  // calculate the total position value ignoring any value from the target market of the trade
390
428
  const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
391
429
  const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
@@ -397,10 +435,11 @@ class ClearingHouseUser {
397
435
  marketIndex: targetMarket.marketIndex,
398
436
  baseAssetAmount: proposedBaseAssetAmount,
399
437
  lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
400
- quoteAssetAmount: new bn_js_1.default(0),
438
+ quoteAssetAmount: new _1.BN(0),
439
+ openOrders: new _1.BN(0),
401
440
  };
402
441
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
403
- const proposedMarketPositionValueUSDC = (0, _1.calculateBaseAssetValue)(market, proposedMarketPosition);
442
+ const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
404
443
  // total position value after trade
405
444
  const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
406
445
  let totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
@@ -417,37 +456,37 @@ class ClearingHouseUser {
417
456
  .mul(thisLev)
418
457
  .sub(tpv)
419
458
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
420
- .div(thisLev.add(new bn_js_1.default(1)));
459
+ .div(thisLev.add(new _1.BN(1)));
421
460
  }
422
461
  else {
423
462
  priceDelt = tc
424
463
  .mul(thisLev)
425
464
  .sub(tpv)
426
465
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
427
- .div(thisLev.sub(new bn_js_1.default(1)));
466
+ .div(thisLev.sub(new _1.BN(1)));
428
467
  }
429
468
  let currentPrice;
430
469
  if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
431
- currentPrice = (0, _1.calculateMarkPrice)(this.clearingHouse.getMarket(targetMarket.marketIndex));
470
+ currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
432
471
  }
433
472
  else {
434
473
  const direction = positionBaseSizeChange.gt(numericConstants_1.ZERO)
435
474
  ? _1.PositionDirection.LONG
436
475
  : _1.PositionDirection.SHORT;
437
- currentPrice = (0, _1.calculateTradeSlippage)(direction, positionBaseSizeChange.abs(), this.clearingHouse.getMarket(targetMarket.marketIndex), 'base')[3]; // newPrice after swap
476
+ currentPrice = _1.calculateTradeSlippage(direction, positionBaseSizeChange.abs(), this.clearingHouse.getMarket(targetMarket.marketIndex), 'base')[3]; // newPrice after swap
438
477
  }
439
478
  // if the position value after the trade is less than total collateral, there is no liq price
440
479
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
441
480
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
442
- return new bn_js_1.default(-1);
481
+ return new _1.BN(-1);
443
482
  }
444
483
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
445
- return new bn_js_1.default(-1);
484
+ return new _1.BN(-1);
446
485
  const eatMargin2 = priceDelt
447
486
  .mul(numericConstants_1.AMM_RESERVE_PRECISION)
448
487
  .div(proposedBaseAssetAmount);
449
488
  if (eatMargin2.gt(currentPrice)) {
450
- return new bn_js_1.default(-1);
489
+ return new _1.BN(-1);
451
490
  }
452
491
  const liqPrice = currentPrice.sub(eatMargin2);
453
492
  return liqPrice;
@@ -474,86 +513,42 @@ class ClearingHouseUser {
474
513
  }
475
514
  /**
476
515
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
477
- *
478
- * To Calculate Max Quote Available:
479
- *
480
- * Case 1: SameSide
481
- * => Remaining quote to get to maxLeverage
482
- *
483
- * Case 2: NOT SameSide && currentLeverage <= maxLeverage
484
- * => Current opposite position x2 + remaining to get to maxLeverage
485
- *
486
- * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
487
- * => strictly reduce current position size
488
- *
489
- * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
490
- * => current position + remaining to get to maxLeverage
491
- *
492
516
  * @param marketIndex
493
517
  * @param tradeSide
494
518
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
495
519
  * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
496
520
  */
497
521
  getMaxTradeSizeUSDC(targetMarketIndex, tradeSide, userMaxLeverageSetting) {
522
+ // inline function which get's the current position size on the opposite side of the target trade
523
+ const getOppositePositionValueUSDC = () => {
524
+ if (!currentPosition)
525
+ return numericConstants_1.ZERO;
526
+ const side = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
527
+ if (side === 'long' && (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
528
+ return this.getPositionValue(targetMarketIndex);
529
+ }
530
+ else if (side === 'short' &&
531
+ !(currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
532
+ return this.getPositionValue(targetMarketIndex);
533
+ }
534
+ return numericConstants_1.ZERO;
535
+ };
498
536
  const currentPosition = this.getUserPosition(targetMarketIndex) ||
499
537
  this.getEmptyPosition(targetMarketIndex);
500
- const targetSide = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
501
- const currentPositionSide = (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())
502
- ? 'short'
503
- : 'long';
504
- const targettingSameSide = !currentPosition
505
- ? true
506
- : targetSide === currentPositionSide;
507
- // 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.
508
- const oppositeSizeValueUSDC = targettingSameSide
509
- ? numericConstants_1.ZERO
510
- : this.getPositionValue(targetMarketIndex);
511
538
  // get current leverage
512
539
  const currentLeverage = this.getLeverage();
513
- const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
540
+ // remaining leverage
541
+ // let remainingLeverage = userMaxLeverageSetting;
542
+ const remainingLeverage = _1.BN.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
514
543
  // get total collateral
515
544
  const totalCollateral = this.getTotalCollateral();
516
545
  // position side allowed based purely on current leverage
517
546
  let maxPositionSize = remainingLeverage
518
547
  .mul(totalCollateral)
519
548
  .div(numericConstants_1.TEN_THOUSAND);
520
- if (userMaxLeverageSetting.sub(currentLeverage).gte(numericConstants_1.ZERO)) {
521
- if (oppositeSizeValueUSDC.eq(numericConstants_1.ZERO)) {
522
- // case 1 : Regular trade where current total position less than max, and no opposite position to account for
523
- // do nothing
524
- }
525
- else {
526
- // case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
527
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
528
- }
529
- }
530
- else {
531
- // current leverage is greater than max leverage - can only reduce position size
532
- if (!targettingSameSide) {
533
- const currentPositionQuoteSize = this.getPositionValue(targetMarketIndex);
534
- const currentTotalQuoteSize = currentLeverage
535
- .mul(totalCollateral)
536
- .div(numericConstants_1.TEN_THOUSAND);
537
- const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(currentPositionQuoteSize);
538
- const quoteValueOfMaxLeverage = userMaxLeverageSetting
539
- .mul(totalCollateral)
540
- .div(numericConstants_1.TEN_THOUSAND);
541
- if (otherPositionsTotalQuoteSize
542
- .sub(currentPositionQuoteSize)
543
- .gte(quoteValueOfMaxLeverage)) {
544
- // case 3: Can only reduce the current position because it will still be greater than max leverage
545
- maxPositionSize = currentPositionQuoteSize;
546
- }
547
- else {
548
- // case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
549
- const allowedQuoteSizeAfterClosingCurrentPosition = quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
550
- maxPositionSize = currentPositionQuoteSize.add(allowedQuoteSizeAfterClosingCurrentPosition);
551
- }
552
- }
553
- else {
554
- // do nothing if targetting same side
555
- }
556
- }
549
+ // 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.
550
+ const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
551
+ maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new _1.BN(2)));
557
552
  // subtract oneMillionth of maxPositionSize
558
553
  // => to avoid rounding errors when taking max leverage
559
554
  const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
@@ -582,18 +577,12 @@ class ClearingHouseUser {
582
577
  .add(tradeQuoteAmount)
583
578
  .abs();
584
579
  const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(targetMarketIndex);
585
- const totalCollateral = this.getTotalCollateral();
586
- if (totalCollateral.gt(numericConstants_1.ZERO)) {
587
- const newLeverage = currentMarketPositionAfterTrade
588
- .add(totalPositionAfterTradeExcludingTargetMarket)
589
- .abs()
590
- .mul(numericConstants_1.TEN_THOUSAND)
591
- .div(totalCollateral);
592
- return newLeverage;
593
- }
594
- else {
595
- return new bn_js_1.default(0);
596
- }
580
+ const newLeverage = currentMarketPositionAfterTrade
581
+ .add(totalPositionAfterTradeExcludingTargetMarket)
582
+ .abs()
583
+ .mul(numericConstants_1.TEN_THOUSAND)
584
+ .div(this.getTotalCollateral());
585
+ return newLeverage;
597
586
  }
598
587
  /**
599
588
  * Calculates how much fee will be taken for a given sized trade
@@ -616,9 +605,51 @@ class ClearingHouseUser {
616
605
  this.getEmptyPosition(marketToIgnore);
617
606
  let currentMarketPositionValueUSDC = numericConstants_1.ZERO;
618
607
  if (currentMarketPosition) {
619
- currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore);
608
+ const market = this.clearingHouse.getMarket(currentMarketPosition.marketIndex);
609
+ currentMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, currentMarketPosition);
620
610
  }
621
611
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
622
612
  }
613
+ canFillOrder(order) {
614
+ const userAccount = this.getUserAccount();
615
+ const userPositionsAccount = this.getUserPositionsAccount();
616
+ const userPosition = this.getUserPosition(order.marketIndex);
617
+ const market = this.clearingHouse.getMarket(order.marketIndex);
618
+ if (position_1.isEmptyPosition(userPosition)) {
619
+ return false;
620
+ }
621
+ const newState = _1.calculateNewStateAfterOrder(userAccount, userPosition, market, order);
622
+ if (newState === null) {
623
+ return false;
624
+ }
625
+ const [userAccountAfter, userPositionAfter, marketAfter] = newState;
626
+ const totalPositionValue = userPositionsAccount.positions.reduce((positionValue, marketPosition) => {
627
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
628
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
629
+ market = marketAfter;
630
+ marketPosition = userPositionAfter;
631
+ }
632
+ return positionValue.add(_1.calculateBaseAssetValue(market, marketPosition));
633
+ }, numericConstants_1.ZERO);
634
+ if (totalPositionValue.eq(numericConstants_1.ZERO)) {
635
+ return true;
636
+ }
637
+ const unrealizedPnL = userPositionsAccount.positions.reduce((pnl, marketPosition) => {
638
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
639
+ pnl = pnl.add(_1.calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION));
640
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
641
+ market = marketAfter;
642
+ marketPosition = userPositionAfter;
643
+ }
644
+ // update
645
+ return pnl.add(_1.calculatePositionPNL(market, marketPosition, false));
646
+ }, numericConstants_1.ZERO);
647
+ const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
648
+ const marginRatioAfter = totalCollateral
649
+ .mul(numericConstants_1.TEN_THOUSAND)
650
+ .div(totalPositionValue);
651
+ const marginRatioInitial = this.clearingHouse.getStateAccount().marginRatioInitial;
652
+ return marginRatioAfter.gte(marginRatioInitial);
653
+ }
623
654
  }
624
655
  exports.ClearingHouseUser = ClearingHouseUser;
package/lib/config.d.ts CHANGED
@@ -21,4 +21,3 @@ export declare const initialize: (props: {
21
21
  overrideEnv?: Partial<DriftConfig>;
22
22
  }) => DriftConfig;
23
23
  export {};
24
- //# sourceMappingURL=config.d.ts.map
@@ -1,4 +1,5 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../';
2
3
  declare type Market = {
3
4
  symbol: string;
4
5
  baseAssetSymbol: string;
@@ -9,4 +10,3 @@ declare type Market = {
9
10
  };
10
11
  export declare const Markets: Market[];
11
12
  export {};
12
- //# sourceMappingURL=markets.d.ts.map
@@ -1,15 +1,12 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Markets = void 0;
7
- const bn_js_1 = __importDefault(require("bn.js"));
4
+ const __1 = require("../");
8
5
  exports.Markets = [
9
6
  {
10
7
  symbol: 'SOL-PERP',
11
8
  baseAssetSymbol: 'SOL',
12
- marketIndex: new bn_js_1.default(0),
9
+ marketIndex: new __1.BN(0),
13
10
  devnetPythOracle: 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix',
14
11
  mainnetPythOracle: 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG',
15
12
  launchTs: 1635209696886,
@@ -17,7 +14,7 @@ exports.Markets = [
17
14
  {
18
15
  symbol: 'BTC-PERP',
19
16
  baseAssetSymbol: 'BTC',
20
- marketIndex: new bn_js_1.default(1),
17
+ marketIndex: new __1.BN(1),
21
18
  devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
22
19
  mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
23
20
  launchTs: 1637691088868,
@@ -25,7 +22,7 @@ exports.Markets = [
25
22
  {
26
23
  symbol: 'ETH-PERP',
27
24
  baseAssetSymbol: 'ETH',
28
- marketIndex: new bn_js_1.default(2),
25
+ marketIndex: new __1.BN(2),
29
26
  devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
30
27
  mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
31
28
  launchTs: 1637691133472,
@@ -33,7 +30,7 @@ exports.Markets = [
33
30
  {
34
31
  symbol: 'LUNA-PERP',
35
32
  baseAssetSymbol: 'LUNA',
36
- marketIndex: new bn_js_1.default(3),
33
+ marketIndex: new __1.BN(3),
37
34
  devnetPythOracle: '8PugCXTAHLM9kfLSQWe2njE5pzAgUdpPk3Nx5zSm7BD3',
38
35
  mainnetPythOracle: '5bmWuR1dgP4avtGYMNKLuxumZTVKGgoN2BCMXWDNL9nY',
39
36
  launchTs: 1638821738525,
@@ -41,7 +38,7 @@ exports.Markets = [
41
38
  {
42
39
  symbol: 'AVAX-PERP',
43
40
  baseAssetSymbol: 'AVAX',
44
- marketIndex: new bn_js_1.default(4),
41
+ marketIndex: new __1.BN(4),
45
42
  devnetPythOracle: 'FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz',
46
43
  mainnetPythOracle: 'Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU',
47
44
  launchTs: 1639092501080,
@@ -49,7 +46,7 @@ exports.Markets = [
49
46
  {
50
47
  symbol: 'BNB-PERP',
51
48
  baseAssetSymbol: 'BNB',
52
- marketIndex: new bn_js_1.default(5),
49
+ marketIndex: new __1.BN(5),
53
50
  devnetPythOracle: 'GwzBgrXb4PG59zjce24SF2b9JXbLEjJJTBkmytuEZj1b',
54
51
  mainnetPythOracle: '4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN',
55
52
  launchTs: 1639523193012,
@@ -57,7 +54,7 @@ exports.Markets = [
57
54
  {
58
55
  symbol: 'MATIC-PERP',
59
56
  baseAssetSymbol: 'MATIC',
60
- marketIndex: new bn_js_1.default(6),
57
+ marketIndex: new __1.BN(6),
61
58
  devnetPythOracle: 'FBirwuDFuRAu4iSGc7RGxN5koHB7EJM1wbCmyPuQoGur',
62
59
  mainnetPythOracle: '7KVswB9vkCgeM3SHP7aGDijvdRAHK8P5wi9JXViCrtYh',
63
60
  launchTs: 1641488603564,
@@ -65,7 +62,7 @@ exports.Markets = [
65
62
  {
66
63
  symbol: 'ATOM-PERP',
67
64
  baseAssetSymbol: 'ATOM',
68
- marketIndex: new bn_js_1.default(7),
65
+ marketIndex: new __1.BN(7),
69
66
  devnetPythOracle: '7YAze8qFUMkBnyLVdKT4TFUUFui99EwS5gfRArMcrvFk',
70
67
  mainnetPythOracle: 'CrCpTerNqtZvqLcKqz1k13oVeXV9WkMD2zA9hBKXrsbN',
71
68
  launchTs: 1641920238195,
@@ -73,7 +70,7 @@ exports.Markets = [
73
70
  {
74
71
  symbol: 'DOT-PERP',
75
72
  baseAssetSymbol: 'DOT',
76
- marketIndex: new bn_js_1.default(8),
73
+ marketIndex: new __1.BN(8),
77
74
  devnetPythOracle: '4dqq5VBpN4EwYb7wyywjjfknvMKu7m78j9mKZRXTj462',
78
75
  mainnetPythOracle: 'EcV1X1gY2yb4KXxjVQtTHTbioum2gvmPnFk4zYAt7zne',
79
76
  launchTs: 1642629253786,
@@ -81,7 +78,7 @@ exports.Markets = [
81
78
  {
82
79
  symbol: 'ADA-PERP',
83
80
  baseAssetSymbol: 'ADA',
84
- marketIndex: new bn_js_1.default(9),
81
+ marketIndex: new __1.BN(9),
85
82
  devnetPythOracle: '8oGTURNmSQkrBS1AQ5NjB2p8qY34UVmMA9ojrw8vnHus',
86
83
  mainnetPythOracle: '3pyn4svBbxJ9Wnn3RVeafyLWfzie6yC5eTig2S62v9SC',
87
84
  launchTs: 1643084413000,
@@ -89,11 +86,27 @@ exports.Markets = [
89
86
  {
90
87
  symbol: 'ALGO-PERP',
91
88
  baseAssetSymbol: 'ALGO',
92
- marketIndex: new bn_js_1.default(10),
89
+ marketIndex: new __1.BN(10),
93
90
  devnetPythOracle: 'c1A946dY5NHuVda77C8XXtXytyR3wK1SCP3eA9VRfC3',
94
91
  mainnetPythOracle: 'HqFyq1wh1xKvL7KDqqT7NJeSPdAqsDqnmBisUC2XdXAX',
95
92
  launchTs: 1643686767000,
96
93
  },
94
+ {
95
+ symbol: 'FTT-PERP',
96
+ baseAssetSymbol: 'FTT',
97
+ marketIndex: new __1.BN(11),
98
+ devnetPythOracle: '6vivTRs5ZPeeXbjo7dfburfaYDWoXjBtdtuYgQRuGfu',
99
+ mainnetPythOracle: '8JPJJkmDScpcNmBRKGZuPuG2GYAveQgP3t5gFuMymwvF',
100
+ launchTs: 1644382122000,
101
+ },
102
+ {
103
+ symbol: 'LTC-PERP',
104
+ baseAssetSymbol: 'LTC',
105
+ marketIndex: new __1.BN(12),
106
+ devnetPythOracle: 'BLArYBCUYhdWiY8PCUTpvFE21iaJq85dvxLk9bYMobcU',
107
+ mainnetPythOracle: '8RMnV1eD55iqUFJLMguPkYBkq8DCtx81XcmAja93LvRR',
108
+ launchTs: 1645027429000,
109
+ },
97
110
  // {
98
111
  // symbol: 'mSOL-PERP',
99
112
  // baseAssetSymbol: 'mSOL',
@@ -1,6 +1,8 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../';
2
3
  export declare const ZERO: BN;
3
4
  export declare const ONE: BN;
5
+ export declare const TWO: BN;
4
6
  export declare const TEN_THOUSAND: BN;
5
7
  export declare const BN_MAX: BN;
6
8
  export declare const MAX_LEVERAGE: BN;
@@ -11,7 +13,7 @@ export declare const MARK_PRICE_PRECISION: BN;
11
13
  export declare const FUNDING_PAYMENT_PRECISION: BN;
12
14
  export declare const PEG_PRECISION: BN;
13
15
  export declare const AMM_RESERVE_PRECISION: BN;
16
+ export declare const BASE_PRECISION: BN;
14
17
  export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
15
18
  export declare const PRICE_TO_QUOTE_PRECISION: BN;
16
19
  export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
17
- //# sourceMappingURL=numericConstants.d.ts.map