@drift-labs/sdk 0.1.24 → 0.1.25-master.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +1 -0
  2. package/lib/accounts/bulkAccountLoader.js +16 -2
  3. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +3 -3
  4. package/lib/accounts/pollingTokenAccountSubscriber.js +2 -2
  5. package/lib/accounts/pollingUserAccountSubscriber.js +4 -4
  6. package/lib/accounts/webSocketAccountSubscriber.js +2 -2
  7. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +1 -1
  8. package/lib/accounts/webSocketUserAccountSubscriber.js +2 -2
  9. package/lib/addresses.js +5 -1
  10. package/lib/admin.d.ts +1 -1
  11. package/lib/admin.js +15 -10
  12. package/lib/clearingHouse.js +26 -20
  13. package/lib/clearingHouseUser.js +18 -18
  14. package/lib/constants/markets.d.ts +4 -4
  15. package/lib/constants/markets.js +22 -0
  16. package/lib/constants/numericConstants.d.ts +1 -0
  17. package/lib/constants/numericConstants.js +2 -1
  18. package/lib/examples/makeTradeExample.js +6 -6
  19. package/lib/factory/oracleClient.d.ts +5 -0
  20. package/lib/factory/oracleClient.js +16 -0
  21. package/lib/idl/clearing_house.json +11 -1
  22. package/lib/idl/switchboard_v2.json +4663 -0
  23. package/lib/index.d.ts +4 -1
  24. package/lib/index.js +9 -2
  25. package/lib/math/amm.js +12 -12
  26. package/lib/math/conversion.js +1 -1
  27. package/lib/math/funding.d.ts +6 -6
  28. package/lib/math/funding.js +5 -17
  29. package/lib/math/market.js +2 -2
  30. package/lib/math/orders.js +9 -9
  31. package/lib/math/position.js +1 -1
  32. package/lib/math/trade.js +18 -18
  33. package/lib/mockUSDCFaucet.js +5 -1
  34. package/lib/oracles/pythClient.d.ts +14 -0
  35. package/lib/oracles/pythClient.js +53 -0
  36. package/lib/oracles/switchboardClient.d.ts +13 -0
  37. package/lib/oracles/switchboardClient.js +76 -0
  38. package/lib/oracles/types.d.ts +15 -0
  39. package/lib/oracles/types.js +2 -0
  40. package/lib/orderParams.d.ts +1 -1
  41. package/lib/orderParams.js +2 -2
  42. package/lib/orders.js +19 -19
  43. package/lib/tx/retryTxSender.js +1 -1
  44. package/lib/types.d.ts +1 -0
  45. package/package.json +2 -1
  46. package/src/accounts/bulkAccountLoader.ts +19 -0
  47. package/src/admin.ts +2 -0
  48. package/src/clearingHouse.ts +2 -0
  49. package/src/constants/markets.ts +26 -3
  50. package/src/constants/numericConstants.ts +1 -0
  51. package/src/factory/oracleClient.ts +22 -0
  52. package/src/idl/clearing_house.json +11 -1
  53. package/src/idl/switchboard_v2.json +4663 -0
  54. package/src/index.ts +4 -1
  55. package/src/math/funding.ts +9 -25
  56. package/src/oracles/pythClient.ts +49 -0
  57. package/src/oracles/switchboardClient.ts +87 -0
  58. package/src/oracles/types.ts +15 -0
  59. package/src/orderParams.ts +3 -2
  60. package/src/types.ts +1 -0
  61. package/lib/pythClient.d.ts +0 -7
  62. package/lib/pythClient.js +0 -25
  63. package/src/pythClient.ts +0 -15
package/lib/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
  export * from './mockUSDCFaucet';
4
- export * from './pythClient';
4
+ export * from './oracles/types';
5
+ export * from './oracles/pythClient';
6
+ export * from './oracles/switchboardClient';
5
7
  export * from './types';
6
8
  export * from './constants/markets';
7
9
  export * from './accounts/webSocketClearingHouseAccountSubscriber';
@@ -16,6 +18,7 @@ export * from './clearingHouseUser';
16
18
  export * from './clearingHouse';
17
19
  export * from './factory/clearingHouse';
18
20
  export * from './factory/clearingHouseUser';
21
+ export * from './factory/oracleClient';
19
22
  export * from './math/conversion';
20
23
  export * from './math/funding';
21
24
  export * from './math/insuranceFund';
package/lib/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -16,7 +20,9 @@ Object.defineProperty(exports, "BN", { enumerable: true, get: function () { retu
16
20
  const web3_js_1 = require("@solana/web3.js");
17
21
  Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return web3_js_1.PublicKey; } });
18
22
  __exportStar(require("./mockUSDCFaucet"), exports);
19
- __exportStar(require("./pythClient"), exports);
23
+ __exportStar(require("./oracles/types"), exports);
24
+ __exportStar(require("./oracles/pythClient"), exports);
25
+ __exportStar(require("./oracles/switchboardClient"), exports);
20
26
  __exportStar(require("./types"), exports);
21
27
  __exportStar(require("./constants/markets"), exports);
22
28
  __exportStar(require("./accounts/webSocketClearingHouseAccountSubscriber"), exports);
@@ -31,6 +37,7 @@ __exportStar(require("./clearingHouseUser"), exports);
31
37
  __exportStar(require("./clearingHouse"), exports);
32
38
  __exportStar(require("./factory/clearingHouse"), exports);
33
39
  __exportStar(require("./factory/clearingHouseUser"), exports);
40
+ __exportStar(require("./factory/oracleClient"), exports);
34
41
  __exportStar(require("./math/conversion"), exports);
35
42
  __exportStar(require("./math/funding"), exports);
36
43
  __exportStar(require("./math/insuranceFund"), exports);
package/lib/math/amm.js CHANGED
@@ -36,7 +36,7 @@ exports.calculatePrice = calculatePrice;
36
36
  * @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
37
37
  */
38
38
  function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDirection) {
39
- assert_1.assert(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
39
+ (0, assert_1.assert)(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
40
40
  let newQuoteAssetReserve;
41
41
  let newBaseAssetReserve;
42
42
  if (inputAssetType === 'quote') {
@@ -79,10 +79,10 @@ exports.calculateSwapOutput = calculateSwapOutput;
79
79
  * @param positionDirection
80
80
  */
81
81
  function getSwapDirection(inputAssetType, positionDirection) {
82
- if (types_1.isVariant(positionDirection, 'long') && inputAssetType === 'base') {
82
+ if ((0, types_1.isVariant)(positionDirection, 'long') && inputAssetType === 'base') {
83
83
  return types_1.SwapDirection.REMOVE;
84
84
  }
85
- if (types_1.isVariant(positionDirection, 'short') && inputAssetType === 'quote') {
85
+ if ((0, types_1.isVariant)(positionDirection, 'short') && inputAssetType === 'quote') {
86
86
  return types_1.SwapDirection.REMOVE;
87
87
  }
88
88
  return types_1.SwapDirection.ADD;
@@ -104,7 +104,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
104
104
  quoteAssetAmount: new anchor_1.BN(0),
105
105
  openOrders: new anchor_1.BN(0),
106
106
  };
107
- const currentValue = position_1.calculateBaseAssetValue(market, netUserPosition);
107
+ const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
108
108
  const marketNewK = Object.assign({}, market);
109
109
  marketNewK.amm = Object.assign({}, market.amm);
110
110
  marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
@@ -115,7 +115,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
115
115
  .div(denomenator);
116
116
  marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
117
117
  netUserPosition.quoteAssetAmount = currentValue;
118
- const cost = __1.calculatePositionPNL(marketNewK, netUserPosition);
118
+ const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
119
119
  const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
120
120
  const x = market.amm.baseAssetReserve;
121
121
  const y = market.amm.quoteAssetReserve;
@@ -134,7 +134,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
134
134
  .sub(numer1)
135
135
  .mul(market.amm.pegMultiplier)
136
136
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
137
- console.log(__1.convertToNumber(formulaCost, numericConstants_1.QUOTE_PRECISION));
137
+ console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
138
138
  // p.div(p.mul(x).add(delta)).sub()
139
139
  return cost;
140
140
  }
@@ -155,22 +155,22 @@ function calculateRepegCost(market, marketIndex, newPeg) {
155
155
  quoteAssetAmount: new anchor_1.BN(0),
156
156
  openOrders: new anchor_1.BN(0),
157
157
  };
158
- const currentValue = position_1.calculateBaseAssetValue(market, netUserPosition);
158
+ const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
159
159
  netUserPosition.quoteAssetAmount = currentValue;
160
- const prevMarketPrice = __1.calculateMarkPrice(market);
160
+ const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
161
161
  const marketNewPeg = Object.assign({}, market);
162
162
  marketNewPeg.amm = Object.assign({}, market.amm);
163
163
  // const marketNewPeg = JSON.parse(JSON.stringify(market));
164
164
  marketNewPeg.amm.pegMultiplier = newPeg;
165
- console.log('Price moves from', __1.convertToNumber(prevMarketPrice), 'to', __1.convertToNumber(__1.calculateMarkPrice(marketNewPeg)));
166
- const cost = __1.calculatePositionPNL(marketNewPeg, netUserPosition);
165
+ console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
166
+ const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
167
167
  const k = market.amm.sqrtK.mul(market.amm.sqrtK);
168
168
  const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
169
169
  const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
170
170
  const cost2 = deltaQuoteAssetReserves
171
171
  .mul(market.amm.pegMultiplier.sub(newPeg))
172
172
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
173
- console.log(__1.convertToNumber(cost2, numericConstants_1.QUOTE_PRECISION));
173
+ console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
174
174
  return cost;
175
175
  }
176
176
  exports.calculateRepegCost = calculateRepegCost;
@@ -200,7 +200,7 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
200
200
  .mul(amm.pegMultiplier)
201
201
  .div(limit_price)
202
202
  .div(numericConstants_1.PEG_PRECISION);
203
- const newBaseAssetReserve = __1.squareRootBN(newBaseAssetReserveSquared);
203
+ const newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
204
204
  if (newBaseAssetReserve.gt(amm.baseAssetReserve)) {
205
205
  return [
206
206
  newBaseAssetReserve.sub(amm.baseAssetReserve),
@@ -10,6 +10,6 @@ const convertToNumber = (bigNumber, precision = numericConstants_1.MARK_PRICE_PR
10
10
  };
11
11
  exports.convertToNumber = convertToNumber;
12
12
  const convertBaseAssetAmountToNumber = (baseAssetAmount) => {
13
- return exports.convertToNumber(baseAssetAmount, numericConstants_1.MARK_PRICE_PRECISION.mul(numericConstants_1.PEG_PRECISION));
13
+ return (0, exports.convertToNumber)(baseAssetAmount, numericConstants_1.MARK_PRICE_PRECISION.mul(numericConstants_1.PEG_PRECISION));
14
14
  };
15
15
  exports.convertBaseAssetAmountToNumber = convertBaseAssetAmountToNumber;
@@ -1,15 +1,15 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { PriceData } from '@pythnetwork/client';
4
3
  import { Market } from '../types';
4
+ import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  *
7
7
  * @param market
8
- * @param pythClient
8
+ * @param oraclePriceData
9
9
  * @param periodAdjustment
10
10
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
11
11
  */
12
- export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
12
+ export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
13
13
  /**
14
14
  *
15
15
  * @param market
@@ -18,7 +18,7 @@ export declare function calculateAllEstimatedFundingRate(market: Market, oracleP
18
18
  * @param estimationMethod
19
19
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
20
20
  */
21
- export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment: BN, estimationMethod: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
21
+ export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment: BN, estimationMethod: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
22
22
  /**
23
23
  *
24
24
  * @param market
@@ -26,7 +26,7 @@ export declare function calculateEstimatedFundingRate(market: Market, oraclePric
26
26
  * @param periodAdjustment
27
27
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
28
28
  */
29
- export declare function calculateLongShortFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
29
+ export declare function calculateLongShortFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
30
30
  /**
31
31
  *
32
32
  * @param market
@@ -34,7 +34,7 @@ export declare function calculateLongShortFundingRate(market: Market, oraclePric
34
34
  * @param periodAdjustment
35
35
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
36
36
  */
37
- export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
37
+ export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
38
38
  /**
39
39
  *
40
40
  * @param market
@@ -16,7 +16,7 @@ const market_1 = require("./market");
16
16
  /**
17
17
  *
18
18
  * @param market
19
- * @param pythClient
19
+ * @param oraclePriceData
20
20
  * @param periodAdjustment
21
21
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
22
22
  */
@@ -40,7 +40,7 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
40
40
  const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
41
41
  const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
42
42
  const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, secondsInHour.sub(timeSinceLastMarkChange));
43
- const baseAssetPriceWithMantissa = market_1.calculateMarkPrice(market);
43
+ const baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market);
44
44
  const markTwapWithMantissa = markTwapTimeSinceLastUpdate
45
45
  .mul(lastMarkTwapWithMantissa)
46
46
  .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
@@ -51,21 +51,9 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
51
51
  const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
52
52
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
53
53
  const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, secondsInHour.sub(timeSinceLastOracleTwapUpdate));
54
- // verify pyth input is positive for live update
55
- let oracleStablePriceNum = 0;
56
- let oracleInputCount = 0;
57
- if (oraclePriceData.price >= 0) {
58
- oracleStablePriceNum += oraclePriceData.price;
59
- oracleInputCount += 1;
60
- }
61
- if (oraclePriceData.previousPrice >= 0) {
62
- oracleStablePriceNum += oraclePriceData.previousPrice;
63
- oracleInputCount += 1;
64
- }
65
- oracleStablePriceNum = oracleStablePriceNum / oracleInputCount;
66
- const oraclePriceStableWithMantissa = new anchor_1.BN(oracleStablePriceNum * numericConstants_1.MARK_PRICE_PRECISION.toNumber());
54
+ const oraclePrice = oraclePriceData.price;
67
55
  let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
68
- const oracleLiveVsTwap = oraclePriceStableWithMantissa
56
+ const oracleLiveVsTwap = oraclePrice
69
57
  .sub(lastOracleTwapWithMantissa)
70
58
  .abs()
71
59
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
@@ -75,7 +63,7 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
75
63
  if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
76
64
  oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
77
65
  .mul(lastOracleTwapWithMantissa)
78
- .add(timeSinceLastMarkChange.mul(oraclePriceStableWithMantissa))
66
+ .add(timeSinceLastMarkChange.mul(oraclePrice))
79
67
  .div(timeSinceLastOracleTwapUpdate.add(oracleTwapTimeSinceLastUpdate));
80
68
  }
81
69
  const twapSpread = lastMarkTwapWithMantissa.sub(lastOracleTwapWithMantissa);
@@ -9,11 +9,11 @@ const amm_1 = require("./amm");
9
9
  * @return markPrice : Precision MARK_PRICE_PRECISION
10
10
  */
11
11
  function calculateMarkPrice(market) {
12
- return amm_1.calculatePrice(market.amm.baseAssetReserve, market.amm.quoteAssetReserve, market.amm.pegMultiplier);
12
+ return (0, amm_1.calculatePrice)(market.amm.baseAssetReserve, market.amm.quoteAssetReserve, market.amm.pegMultiplier);
13
13
  }
14
14
  exports.calculateMarkPrice = calculateMarkPrice;
15
15
  function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
16
- const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'base', baseAssetAmount.abs(), amm_1.getSwapDirection('base', direction));
16
+ const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', direction));
17
17
  const newAmm = Object.assign({}, market.amm);
18
18
  const newMarket = Object.assign({}, market);
19
19
  newMarket.amm = newAmm;
@@ -4,7 +4,7 @@ exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = expor
4
4
  const types_1 = require("../types");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  function isOrderRiskIncreasing(user, order) {
7
- if (types_1.isVariant(order.status, 'init')) {
7
+ if ((0, types_1.isVariant)(order.status, 'init')) {
8
8
  return false;
9
9
  }
10
10
  const position = user.getUserPosition(order.marketIndex) ||
@@ -14,12 +14,12 @@ function isOrderRiskIncreasing(user, order) {
14
14
  return true;
15
15
  }
16
16
  // if position is long and order is long
17
- if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
17
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
18
18
  return true;
19
19
  }
20
20
  // if position is short and order is short
21
21
  if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
22
- types_1.isVariant(order.direction, 'short')) {
22
+ (0, types_1.isVariant)(order.direction, 'short')) {
23
23
  return true;
24
24
  }
25
25
  const baseAssetAmountToFill = order.baseAssetAmount.sub(order.baseAssetAmountFilled);
@@ -31,7 +31,7 @@ function isOrderRiskIncreasing(user, order) {
31
31
  }
32
32
  exports.isOrderRiskIncreasing = isOrderRiskIncreasing;
33
33
  function isOrderRiskIncreasingInSameDirection(user, order) {
34
- if (types_1.isVariant(order.status, 'init')) {
34
+ if ((0, types_1.isVariant)(order.status, 'init')) {
35
35
  return false;
36
36
  }
37
37
  const position = user.getUserPosition(order.marketIndex) ||
@@ -41,30 +41,30 @@ function isOrderRiskIncreasingInSameDirection(user, order) {
41
41
  return true;
42
42
  }
43
43
  // if position is long and order is long
44
- if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
44
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
45
45
  return true;
46
46
  }
47
47
  // if position is short and order is short
48
48
  if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
49
- types_1.isVariant(order.direction, 'short')) {
49
+ (0, types_1.isVariant)(order.direction, 'short')) {
50
50
  return true;
51
51
  }
52
52
  return false;
53
53
  }
54
54
  exports.isOrderRiskIncreasingInSameDirection = isOrderRiskIncreasingInSameDirection;
55
55
  function isOrderReduceOnly(user, order) {
56
- if (types_1.isVariant(order.status, 'init')) {
56
+ if ((0, types_1.isVariant)(order.status, 'init')) {
57
57
  return false;
58
58
  }
59
59
  const position = user.getUserPosition(order.marketIndex) ||
60
60
  user.getEmptyPosition(order.marketIndex);
61
61
  // if position is long and order is long
62
- if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
62
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
63
63
  return false;
64
64
  }
65
65
  // if position is short and order is short
66
66
  if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
67
- types_1.isVariant(order.direction, 'short')) {
67
+ (0, types_1.isVariant)(order.direction, 'short')) {
68
68
  return false;
69
69
  }
70
70
  return order.baseAssetAmount.abs().lte(position.baseAssetAmount.abs());
@@ -17,7 +17,7 @@ function calculateBaseAssetValue(market, userPosition) {
17
17
  return numericConstants_1.ZERO;
18
18
  }
19
19
  const directionToClose = findDirectionToClose(userPosition);
20
- const [newQuoteAssetReserve, _] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'base', userPosition.baseAssetAmount.abs(), amm_1.getSwapDirection('base', directionToClose));
20
+ const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
21
21
  switch (directionToClose) {
22
22
  case types_1.PositionDirection.SHORT:
23
23
  return market.amm.quoteAssetReserve
package/lib/math/trade.js CHANGED
@@ -25,18 +25,18 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
25
25
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
26
26
  */
27
27
  function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote') {
28
- const oldPrice = market_1.calculateMarkPrice(market);
28
+ const oldPrice = (0, market_1.calculateMarkPrice)(market);
29
29
  if (amount.eq(numericConstants_1.ZERO)) {
30
30
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
31
31
  }
32
32
  const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType);
33
- const entryPrice = amm_1.calculatePrice(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
34
- const newPrice = amm_1.calculatePrice(market.amm.baseAssetReserve.sub(acquiredBase), market.amm.quoteAssetReserve.sub(acquiredQuote), market.amm.pegMultiplier);
33
+ const entryPrice = (0, amm_1.calculatePrice)(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
34
+ const newPrice = (0, amm_1.calculatePrice)(market.amm.baseAssetReserve.sub(acquiredBase), market.amm.quoteAssetReserve.sub(acquiredQuote), market.amm.pegMultiplier);
35
35
  if (direction == types_1.PositionDirection.SHORT) {
36
- assert_1.assert(newPrice.lt(oldPrice));
36
+ (0, assert_1.assert)(newPrice.lt(oldPrice));
37
37
  }
38
38
  else {
39
- assert_1.assert(oldPrice.lt(newPrice));
39
+ (0, assert_1.assert)(oldPrice.lt(newPrice));
40
40
  }
41
41
  const pctMaxSlippage = newPrice
42
42
  .sub(oldPrice)
@@ -64,11 +64,11 @@ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType
64
64
  if (amount.eq(numericConstants_1.ZERO)) {
65
65
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
66
66
  }
67
- const swapDirection = amm_1.getSwapDirection(inputAssetType, direction);
68
- const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, inputAssetType, amount, swapDirection);
67
+ const swapDirection = (0, amm_1.getSwapDirection)(inputAssetType, direction);
68
+ const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, inputAssetType, amount, swapDirection);
69
69
  const acquiredBase = market.amm.baseAssetReserve.sub(newBaseAssetReserve);
70
70
  let acquiredQuote = market.amm.quoteAssetReserve.sub(newQuoteAssetReserve);
71
- if (inputAssetType === 'base' && types_1.isVariant(swapDirection, 'remove')) {
71
+ if (inputAssetType === 'base' && (0, types_1.isVariant)(swapDirection, 'remove')) {
72
72
  acquiredQuote = acquiredQuote.sub(numericConstants_1.ONE);
73
73
  }
74
74
  return [acquiredBase, acquiredQuote];
@@ -90,10 +90,10 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
90
90
  * ]
91
91
  */
92
92
  function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote') {
93
- assert_1.assert(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
94
- assert_1.assert(targetPrice.gt(numericConstants_1.ZERO));
95
- assert_1.assert(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
96
- const markPriceBefore = market_1.calculateMarkPrice(market);
93
+ (0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
94
+ (0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
95
+ (0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
96
+ const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
97
97
  if (targetPrice.gt(markPriceBefore)) {
98
98
  const priceGap = targetPrice.sub(markPriceBefore);
99
99
  const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
@@ -118,11 +118,11 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
118
118
  let markPriceAfter;
119
119
  if (markPriceBefore.gt(targetPrice)) {
120
120
  // overestimate y2
121
- baseAssetReserveAfter = utils_1.squareRootBN(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
121
+ baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
122
122
  quoteAssetReserveAfter = k
123
123
  .div(numericConstants_1.MARK_PRICE_PRECISION)
124
124
  .div(baseAssetReserveAfter);
125
- markPriceAfter = amm_1.calculatePrice(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
125
+ markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
126
126
  direction = types_1.PositionDirection.SHORT;
127
127
  tradeSize = quoteAssetReserveBefore
128
128
  .sub(quoteAssetReserveAfter)
@@ -133,11 +133,11 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
133
133
  }
134
134
  else if (markPriceBefore.lt(targetPrice)) {
135
135
  // underestimate y2
136
- baseAssetReserveAfter = utils_1.squareRootBN(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
136
+ baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
137
137
  quoteAssetReserveAfter = k
138
138
  .div(numericConstants_1.MARK_PRICE_PRECISION)
139
139
  .div(baseAssetReserveAfter);
140
- markPriceAfter = amm_1.calculatePrice(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
140
+ markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
141
141
  direction = types_1.PositionDirection.LONG;
142
142
  tradeSize = quoteAssetReserveAfter
143
143
  .sub(quoteAssetReserveBefore)
@@ -164,8 +164,8 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
164
164
  .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
165
165
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
166
166
  .div(baseSize.abs());
167
- assert_1.assert(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
168
- assert_1.assert(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
167
+ (0, assert_1.assert)(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
168
+ (0, assert_1.assert)(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
169
169
  tp2.toString() +
170
170
  '>=' +
171
171
  tp1.toString() +
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="bn.js" />
3
+ import { PriceData } from '@pythnetwork/client';
4
+ import { Connection, PublicKey } from '@solana/web3.js';
5
+ import { OraclePriceData } from './types';
6
+ import { BN } from '@project-serum/anchor';
7
+ export declare class PythClient {
8
+ private connection;
9
+ constructor(connection: Connection);
10
+ getPriceData(pricePublicKey: PublicKey): Promise<PriceData>;
11
+ getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
12
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
13
+ }
14
+ export declare function convertPythPrice(price: number, exponent: number): BN;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.convertPythPrice = exports.PythClient = void 0;
13
+ const client_1 = require("@pythnetwork/client");
14
+ const anchor_1 = require("@project-serum/anchor");
15
+ const numericConstants_1 = require("../constants/numericConstants");
16
+ class PythClient {
17
+ constructor(connection) {
18
+ this.connection = connection;
19
+ }
20
+ getPriceData(pricePublicKey) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const account = yield this.connection.getAccountInfo(pricePublicKey);
23
+ return (0, client_1.parsePriceData)(account.data);
24
+ });
25
+ }
26
+ getOraclePriceData(pricePublicKey) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
29
+ return this.getOraclePriceDataFromBuffer(accountInfo.data);
30
+ });
31
+ }
32
+ getOraclePriceDataFromBuffer(buffer) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const priceData = (0, client_1.parsePriceData)(buffer);
35
+ return {
36
+ price: convertPythPrice(priceData.price, priceData.exponent),
37
+ slot: new anchor_1.BN(priceData.lastSlot.toString()),
38
+ confidence: convertPythPrice(priceData.confidence, priceData.exponent),
39
+ twap: convertPythPrice(priceData.twap.value, priceData.exponent),
40
+ twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
41
+ };
42
+ });
43
+ }
44
+ }
45
+ exports.PythClient = PythClient;
46
+ function convertPythPrice(price, exponent) {
47
+ exponent = Math.abs(exponent);
48
+ const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs());
49
+ return new anchor_1.BN(price * Math.pow(10, exponent))
50
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
51
+ .div(pythPrecision);
52
+ }
53
+ exports.convertPythPrice = convertPythPrice;
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ import { Connection, PublicKey } from '@solana/web3.js';
3
+ import { DriftEnv } from '../config';
4
+ import { Program } from '@project-serum/anchor';
5
+ import { OracleClient, OraclePriceData } from './types';
6
+ export declare class SwitchboardClient implements OracleClient {
7
+ connection: Connection;
8
+ env: DriftEnv;
9
+ constructor(connection: Connection, env: DriftEnv);
10
+ getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
11
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
12
+ getProgram(): Promise<Program>;
13
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SwitchboardClient = void 0;
16
+ const switchboard_v2_1 = require("@switchboard-xyz/switchboard-v2");
17
+ const web3_js_1 = require("@solana/web3.js");
18
+ const anchor_1 = require("@project-serum/anchor");
19
+ const numericConstants_1 = require("../constants/numericConstants");
20
+ const wallet_1 = require("../wallet");
21
+ const switchboard_v2_json_1 = __importDefault(require("../idl/switchboard_v2.json"));
22
+ // cache switchboard program for every client object since itll always be the same
23
+ const programMap = new Map();
24
+ class SwitchboardClient {
25
+ constructor(connection, env) {
26
+ this.connection = connection;
27
+ this.env = env;
28
+ }
29
+ getOraclePriceData(pricePublicKey) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
32
+ return this.getOraclePriceDataFromBuffer(accountInfo.data);
33
+ });
34
+ }
35
+ getOraclePriceDataFromBuffer(buffer) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ const program = yield this.getProgram();
38
+ const aggregatorAccountData = program.account.aggregatorAccountData.coder.accounts.decode('AggregatorAccountData', buffer);
39
+ const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
40
+ const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound
41
+ .stdDeviation);
42
+ const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
43
+ return {
44
+ price,
45
+ slot,
46
+ confidence,
47
+ };
48
+ });
49
+ }
50
+ getProgram() {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ if (programMap.has(this.env)) {
53
+ return programMap.get(this.env);
54
+ }
55
+ const program = yield getSwitchboardProgram(this.env, this.connection);
56
+ programMap.set(this.env, program);
57
+ return program;
58
+ });
59
+ }
60
+ }
61
+ exports.SwitchboardClient = SwitchboardClient;
62
+ function getSwitchboardProgram(env, connection) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ const DEFAULT_KEYPAIR = web3_js_1.Keypair.fromSeed(new Uint8Array(32).fill(1));
65
+ const programId = (0, switchboard_v2_1.getSwitchboardPid)(env);
66
+ const wallet = new wallet_1.Wallet(DEFAULT_KEYPAIR);
67
+ const provider = new anchor_1.Provider(connection, wallet, {});
68
+ return new anchor_1.Program(switchboard_v2_json_1.default, programId, provider);
69
+ });
70
+ }
71
+ function convertSwitchboardDecimal(switchboardDecimal) {
72
+ const switchboardPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(switchboardDecimal.scale));
73
+ return switchboardDecimal.mantissa
74
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
75
+ .div(switchboardPrecision);
76
+ }
@@ -0,0 +1,15 @@
1
+ /// <reference types="bn.js" />
2
+ /// <reference types="node" />
3
+ import { BN } from '@project-serum/anchor';
4
+ import { PublicKey } from '@solana/web3.js';
5
+ export declare type OraclePriceData = {
6
+ price: BN;
7
+ slot: BN;
8
+ confidence: BN;
9
+ twap?: BN;
10
+ twapConfidence?: BN;
11
+ };
12
+ export interface OracleClient {
13
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
14
+ getOraclePriceData(publicKey: PublicKey): Promise<OraclePriceData>;
15
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { OrderParams, OrderTriggerCondition, PositionDirection } from './types';
3
3
  import { BN } from '@project-serum/anchor';
4
- export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
4
+ export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean): OrderParams;
5
5
  export declare function getTriggerMarketOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
6
6
  export declare function getTriggerLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
7
7
  export declare function getMarketOrderParams(marketIndex: BN, direction: PositionDirection, quoteAssetAmount: BN, baseAssetAmount: BN, reduceOnly: boolean, price?: BN, discountToken?: boolean, referrer?: boolean): OrderParams;