@drift-labs/sdk 2.38.1-beta.0 → 2.38.1-beta.10

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 (54) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/fetch.js +2 -2
  3. package/lib/accounts/pollingDriftClientAccountSubscriber.js +2 -2
  4. package/lib/accounts/pollingUserStatsAccountSubscriber.js +2 -2
  5. package/lib/adminClient.d.ts +1 -0
  6. package/lib/adminClient.js +11 -0
  7. package/lib/config.d.ts +1 -0
  8. package/lib/config.js +2 -0
  9. package/lib/driftClient.d.ts +22 -2
  10. package/lib/driftClient.js +101 -15
  11. package/lib/examples/loadDlob.js +3 -1
  12. package/lib/examples/makeTradeExample.js +3 -1
  13. package/lib/idl/drift.json +36 -1
  14. package/lib/index.d.ts +3 -0
  15. package/lib/index.js +3 -0
  16. package/lib/jupiter/jupiterClient.d.ts +197 -0
  17. package/lib/jupiter/jupiterClient.js +48 -3
  18. package/lib/math/spotBalance.d.ts +6 -5
  19. package/lib/math/spotBalance.js +28 -11
  20. package/lib/math/spotMarket.d.ts +1 -1
  21. package/lib/math/spotMarket.js +2 -2
  22. package/lib/math/spotPosition.d.ts +16 -3
  23. package/lib/math/spotPosition.js +53 -9
  24. package/lib/oracles/strictOraclePrice.d.ts +8 -0
  25. package/lib/oracles/strictOraclePrice.js +17 -0
  26. package/lib/priorityFee/priorityFeeSubscriber.d.ts +22 -0
  27. package/lib/priorityFee/priorityFeeSubscriber.js +46 -0
  28. package/lib/tokenFaucet.js +1 -0
  29. package/lib/types.d.ts +4 -0
  30. package/lib/types.js +3 -0
  31. package/lib/user.d.ts +5 -4
  32. package/lib/user.js +71 -105
  33. package/package.json +2 -2
  34. package/src/accounts/fetch.ts +2 -2
  35. package/src/accounts/pollingDriftClientAccountSubscriber.ts +2 -2
  36. package/src/accounts/pollingUserStatsAccountSubscriber.ts +10 -8
  37. package/src/adminClient.ts +23 -0
  38. package/src/config.ts +3 -0
  39. package/src/driftClient.ts +173 -13
  40. package/src/examples/loadDlob.ts +1 -0
  41. package/src/examples/makeTradeExample.ts +1 -0
  42. package/src/idl/drift.json +36 -1
  43. package/src/index.ts +3 -0
  44. package/src/jupiter/jupiterClient.ts +246 -3
  45. package/src/math/spotBalance.ts +37 -11
  46. package/src/math/spotMarket.ts +7 -1
  47. package/src/math/spotPosition.ts +133 -18
  48. package/src/oracles/strictOraclePrice.ts +19 -0
  49. package/src/priorityFee/priorityFeeSubscriber.ts +75 -0
  50. package/src/tokenFaucet.ts +1 -0
  51. package/src/types.ts +4 -0
  52. package/src/user.ts +171 -228
  53. package/tests/dlob/helpers.ts +10 -7
  54. package/tests/user/test.ts +77 -4
@@ -8,11 +8,12 @@ const web3_js_1 = require("@solana/web3.js");
8
8
  const node_fetch_1 = __importDefault(require("node-fetch"));
9
9
  class JupiterClient {
10
10
  constructor({ connection }) {
11
- this.url = 'https://quote-api.jup.ag/v4';
11
+ this.url = 'https://quote-api.jup.ag';
12
12
  this.lookupTableCahce = new Map();
13
13
  this.connection = connection;
14
14
  }
15
15
  /**
16
+ * ** @deprecated - use getQuote
16
17
  * Get routes for a swap
17
18
  * @param inputMint the mint of the input token
18
19
  * @param outputMint the mint of the output token
@@ -30,17 +31,61 @@ class JupiterClient {
30
31
  swapMode,
31
32
  onlyDirectRoutes: onlyDirectRoutes.toString(),
32
33
  }).toString();
33
- const { data: routes } = await (await (0, node_fetch_1.default)(`https://quote-api.jup.ag/v4/quote?${params}`)).json();
34
+ const { data: routes } = await (await (0, node_fetch_1.default)(`${this.url}/v4/quote?${params}`)).json();
34
35
  return routes;
35
36
  }
36
37
  /**
38
+ * Get routes for a swap
39
+ * @param inputMint the mint of the input token
40
+ * @param outputMint the mint of the output token
41
+ * @param amount the amount of the input token
42
+ * @param slippageBps the slippage tolerance in basis points
43
+ * @param swapMode the swap mode (ExactIn or ExactOut)
44
+ * @param onlyDirectRoutes whether to only return direct routes
45
+ */
46
+ async getQuote({ inputMint, outputMint, amount, slippageBps = 50, swapMode = 'ExactIn', onlyDirectRoutes = false, }) {
47
+ const params = new URLSearchParams({
48
+ inputMint: inputMint.toString(),
49
+ outputMint: outputMint.toString(),
50
+ amount: amount.toString(),
51
+ slippageBps: slippageBps.toString(),
52
+ swapMode,
53
+ onlyDirectRoutes: onlyDirectRoutes.toString(),
54
+ }).toString();
55
+ const quote = await (await (0, node_fetch_1.default)(`${this.url}/v6/quote?${params}`)).json();
56
+ return quote;
57
+ }
58
+ /**
59
+ * Get a swap transaction for quote
60
+ * @param quoteResponse quote to perform swap
61
+ * @param userPublicKey the signer's wallet public key
62
+ * @param slippageBps the slippage tolerance in basis points
63
+ */
64
+ async getSwap({ quote, userPublicKey, slippageBps = 50, }) {
65
+ const resp = await (await (0, node_fetch_1.default)(`${this.url}/v6/swap`, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
69
+ },
70
+ body: JSON.stringify({
71
+ quoteResponse: quote,
72
+ userPublicKey,
73
+ slippageBps,
74
+ }),
75
+ })).json();
76
+ const { swapTransaction } = resp;
77
+ const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
78
+ return web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
79
+ }
80
+ /**
81
+ * ** @deprecated - use getSwap
37
82
  * Get a swap transaction for a route
38
83
  * @param route the route to perform swap
39
84
  * @param userPublicKey the signer's wallet public key
40
85
  * @param slippageBps the slippage tolerance in basis points
41
86
  */
42
87
  async getSwapTransaction({ route, userPublicKey, slippageBps = 50, }) {
43
- const resp = await (await (0, node_fetch_1.default)(`${this.url}/swap`, {
88
+ const resp = await (await (0, node_fetch_1.default)(`${this.url}/v4/swap`, {
44
89
  method: 'POST',
45
90
  headers: {
46
91
  'Content-Type': 'application/json',
@@ -1,6 +1,7 @@
1
1
  import { SpotMarketAccount, SpotBalanceType, MarginCategory } from '../types';
2
2
  import { BN } from '@coral-xyz/anchor';
3
3
  import { OraclePriceData } from '../oracles/types';
4
+ import { StrictOraclePrice } from '../oracles/strictOraclePrice';
4
5
  /**
5
6
  * Calculates the balance of a given token amount including any accumulated interest. This
6
7
  * is the same as `SpotPosition.scaledBalance`.
@@ -33,11 +34,10 @@ export declare function getSignedTokenAmount(tokenAmount: BN, balanceType: SpotB
33
34
  *
34
35
  * @param {BN} tokenAmount - The amount of tokens to calculate the value for (from `getTokenAmount`)
35
36
  * @param {number} spotDecimals - The number of decimals in the token.
36
- * @param {OraclePriceData} oraclePriceData - The oracle price data (typically a token/USD oracle).
37
- * @param {BN} oraclePriceTwap - The Time-Weighted Average Price of the oracle.
37
+ * @param {StrictOraclePrice} strictOraclePrice - Contains oracle price and 5min twap.
38
38
  * @return {BN} The calculated value of the given token amount, scaled by `PRICE_PRECISION`
39
39
  */
40
- export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData, oraclePriceTwap: BN): BN;
40
+ export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: number, strictOraclePrice: StrictOraclePrice): BN;
41
41
  /**
42
42
  * Calculates the value of a given token amount in relation to an oracle price data
43
43
  *
@@ -46,8 +46,9 @@ export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: numbe
46
46
  * @param {OraclePriceData} oraclePriceData - The oracle price data (typically a token/USD oracle).
47
47
  * @return {BN} The value of the token based on the oracle, scaled by `PRICE_PRECISION`
48
48
  */
49
- export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData): BN;
50
- export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
49
+ export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: Pick<OraclePriceData, 'price'>): BN;
50
+ export declare function calculateAssetWeight(balanceAmount: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
51
+ export declare function calculateScaledInitialAssetWeight(spotMarket: SpotMarketAccount, oraclePrice: BN): BN;
51
52
  export declare function calculateLiabilityWeight(size: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
52
53
  export declare function calculateUtilization(bank: SpotMarketAccount, delta?: any): BN;
53
54
  /**
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateWithdrawLimit = exports.calculateTokenUtilizationLimits = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateSpotMarketBorrowCapacity = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
3
+ exports.calculateWithdrawLimit = exports.calculateTokenUtilizationLimits = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateSpotMarketBorrowCapacity = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateScaledInitialAssetWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
4
4
  const types_1 = require("../types");
5
5
  const anchor_1 = require("@coral-xyz/anchor");
6
6
  const numericConstants_1 = require("../constants/numericConstants");
@@ -69,20 +69,19 @@ exports.getSignedTokenAmount = getSignedTokenAmount;
69
69
  *
70
70
  * @param {BN} tokenAmount - The amount of tokens to calculate the value for (from `getTokenAmount`)
71
71
  * @param {number} spotDecimals - The number of decimals in the token.
72
- * @param {OraclePriceData} oraclePriceData - The oracle price data (typically a token/USD oracle).
73
- * @param {BN} oraclePriceTwap - The Time-Weighted Average Price of the oracle.
72
+ * @param {StrictOraclePrice} strictOraclePrice - Contains oracle price and 5min twap.
74
73
  * @return {BN} The calculated value of the given token amount, scaled by `PRICE_PRECISION`
75
74
  */
76
- function getStrictTokenValue(tokenAmount, spotDecimals, oraclePriceData, oraclePriceTwap) {
75
+ function getStrictTokenValue(tokenAmount, spotDecimals, strictOraclePrice) {
77
76
  if (tokenAmount.eq(numericConstants_1.ZERO)) {
78
77
  return numericConstants_1.ZERO;
79
78
  }
80
- let price = oraclePriceData.price;
81
- if (tokenAmount.gt(numericConstants_1.ZERO)) {
82
- price = anchor_1.BN.min(oraclePriceData.price, oraclePriceTwap);
79
+ let price;
80
+ if (tokenAmount.gte(numericConstants_1.ZERO)) {
81
+ price = strictOraclePrice.min();
83
82
  }
84
83
  else {
85
- price = anchor_1.BN.max(oraclePriceData.price, oraclePriceTwap);
84
+ price = strictOraclePrice.max();
86
85
  }
87
86
  const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(spotDecimals));
88
87
  return tokenAmount.mul(price).div(precisionDecrease);
@@ -104,7 +103,7 @@ function getTokenValue(tokenAmount, spotDecimals, oraclePriceData) {
104
103
  return tokenAmount.mul(oraclePriceData.price).div(precisionDecrease);
105
104
  }
106
105
  exports.getTokenValue = getTokenValue;
107
- function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
106
+ function calculateAssetWeight(balanceAmount, oraclePrice, spotMarket, marginCategory) {
108
107
  const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
109
108
  let sizeInAmmReservePrecision;
110
109
  if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
@@ -118,18 +117,36 @@ function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
118
117
  let assetWeight;
119
118
  switch (marginCategory) {
120
119
  case 'Initial':
121
- assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.initialAssetWeight));
120
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), calculateScaledInitialAssetWeight(spotMarket, oraclePrice));
122
121
  break;
123
122
  case 'Maintenance':
124
123
  assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceAssetWeight));
125
124
  break;
126
125
  default:
127
- assetWeight = new anchor_1.BN(spotMarket.initialAssetWeight);
126
+ assetWeight = calculateScaledInitialAssetWeight(spotMarket, oraclePrice);
128
127
  break;
129
128
  }
130
129
  return assetWeight;
131
130
  }
132
131
  exports.calculateAssetWeight = calculateAssetWeight;
132
+ function calculateScaledInitialAssetWeight(spotMarket, oraclePrice) {
133
+ if (spotMarket.scaleInitialAssetWeightStart.eq(numericConstants_1.ZERO)) {
134
+ return new anchor_1.BN(spotMarket.initialAssetWeight);
135
+ }
136
+ const deposits = getTokenAmount(spotMarket.depositBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
137
+ const depositsValue = getTokenValue(deposits, spotMarket.decimals, {
138
+ price: oraclePrice,
139
+ });
140
+ if (depositsValue.lt(spotMarket.scaleInitialAssetWeightStart)) {
141
+ return new anchor_1.BN(spotMarket.initialAssetWeight);
142
+ }
143
+ else {
144
+ return new anchor_1.BN(spotMarket.initialAssetWeight)
145
+ .mul(spotMarket.scaleInitialAssetWeightStart)
146
+ .div(depositsValue);
147
+ }
148
+ }
149
+ exports.calculateScaledInitialAssetWeight = calculateScaledInitialAssetWeight;
133
150
  function calculateLiabilityWeight(size, spotMarket, marginCategory) {
134
151
  const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
135
152
  let sizeInAmmReservePrecision;
@@ -1,4 +1,4 @@
1
1
  import { BN } from '@coral-xyz/anchor';
2
2
  import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
3
3
  export declare function castNumberToSpotPrecision(value: number | BN, spotMarket: SpotMarketAccount): BN;
4
- export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
4
+ export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, oraclePrice: BN, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
@@ -14,9 +14,9 @@ function castNumberToSpotPrecision(value, spotMarket) {
14
14
  }
15
15
  }
16
16
  exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
17
- function calculateSpotMarketMarginRatio(market, marginCategory, size, balanceType) {
17
+ function calculateSpotMarketMarginRatio(market, oraclePrice, marginCategory, size, balanceType) {
18
18
  if ((0, types_1.isVariant)(balanceType, 'deposit')) {
19
- const assetWeight = (0, spotBalance_1.calculateAssetWeight)(size, market, marginCategory);
19
+ const assetWeight = (0, spotBalance_1.calculateAssetWeight)(size, oraclePrice, market, marginCategory);
20
20
  return numericConstants_1.MARGIN_PRECISION.sub(assetWeight).toNumber();
21
21
  }
22
22
  else {
@@ -1,5 +1,18 @@
1
- import { SpotMarketAccount, SpotPosition } from '../types';
1
+ import { MarginCategory, SpotMarketAccount, SpotPosition } from '../types';
2
2
  import { BN } from '@coral-xyz/anchor';
3
- import { OraclePriceData } from '../oracles/types';
3
+ import { StrictOraclePrice } from '../oracles/strictOraclePrice';
4
4
  export declare function isSpotPositionAvailable(position: SpotPosition): boolean;
5
- export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
5
+ export type OrderFillSimulation = {
6
+ tokenAmount: BN;
7
+ ordersValue: BN;
8
+ tokenValue: BN;
9
+ weight: BN;
10
+ weightedTokenValue: BN;
11
+ freeCollateralContribution: any;
12
+ };
13
+ export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory): OrderFillSimulation;
14
+ export declare function calculateWeightedTokenValue(tokenAmount: BN, tokenValue: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): {
15
+ weight: BN;
16
+ weightedTokenValue: BN;
17
+ };
18
+ export declare function simulateOrderFill(tokenAmount: BN, tokenValue: BN, openOrders: BN, strictOraclePrice: StrictOraclePrice, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): OrderFillSimulation;
@@ -1,23 +1,67 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWorstCaseTokenAmounts = exports.isSpotPositionAvailable = void 0;
3
+ exports.simulateOrderFill = exports.calculateWeightedTokenValue = exports.getWorstCaseTokenAmounts = exports.isSpotPositionAvailable = void 0;
4
4
  const numericConstants_1 = require("../constants/numericConstants");
5
5
  const spotBalance_1 = require("./spotBalance");
6
6
  function isSpotPositionAvailable(position) {
7
7
  return position.scaledBalance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
8
8
  }
9
9
  exports.isSpotPositionAvailable = isSpotPositionAvailable;
10
- function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, oraclePriceData) {
10
+ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory) {
11
11
  const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
12
- const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
13
- const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
14
- if (tokenAmountAllBidsFill.abs().gt(tokenAmountAllAsksFill.abs())) {
15
- const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openBids.neg(), spotMarketAccount.decimals, oraclePriceData);
16
- return [tokenAmountAllBidsFill, worstCaseQuoteTokenAmount];
12
+ const tokenValue = (0, spotBalance_1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
13
+ if (spotPosition.openBids.eq(numericConstants_1.ZERO) && spotPosition.openAsks.eq(numericConstants_1.ZERO)) {
14
+ const { weight, weightedTokenValue } = calculateWeightedTokenValue(tokenAmount, tokenValue, strictOraclePrice.current, spotMarketAccount, marginCategory);
15
+ return {
16
+ tokenAmount,
17
+ ordersValue: numericConstants_1.ZERO,
18
+ tokenValue,
19
+ weight,
20
+ weightedTokenValue,
21
+ freeCollateralContribution: weightedTokenValue,
22
+ };
23
+ }
24
+ const bidsSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openBids, strictOraclePrice, spotMarketAccount, marginCategory);
25
+ const asksSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openAsks, strictOraclePrice, spotMarketAccount, marginCategory);
26
+ if (asksSimulation.freeCollateralContribution.lt(bidsSimulation.freeCollateralContribution)) {
27
+ return asksSimulation;
17
28
  }
18
29
  else {
19
- const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openAsks.neg(), spotMarketAccount.decimals, oraclePriceData);
20
- return [tokenAmountAllAsksFill, worstCaseQuoteTokenAmount];
30
+ return bidsSimulation;
21
31
  }
22
32
  }
23
33
  exports.getWorstCaseTokenAmounts = getWorstCaseTokenAmounts;
34
+ function calculateWeightedTokenValue(tokenAmount, tokenValue, oraclePrice, spotMarket, marginCategory) {
35
+ let weight;
36
+ if (tokenValue.gte(numericConstants_1.ZERO)) {
37
+ weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, oraclePrice, spotMarket, marginCategory);
38
+ }
39
+ else {
40
+ weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount.abs(), spotMarket, marginCategory);
41
+ }
42
+ return {
43
+ weight: weight,
44
+ weightedTokenValue: tokenValue
45
+ .mul(weight)
46
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION),
47
+ };
48
+ }
49
+ exports.calculateWeightedTokenValue = calculateWeightedTokenValue;
50
+ function simulateOrderFill(tokenAmount, tokenValue, openOrders, strictOraclePrice, spotMarket, marginCategory) {
51
+ const ordersValue = (0, spotBalance_1.getTokenValue)(openOrders.neg(), spotMarket.decimals, {
52
+ price: strictOraclePrice.max(),
53
+ });
54
+ const tokenAmountAfterFill = tokenAmount.add(openOrders);
55
+ const tokenValueAfterFill = tokenValue.add(ordersValue.neg());
56
+ const { weight, weightedTokenValue: weightedTokenValueAfterFill } = calculateWeightedTokenValue(tokenAmountAfterFill, tokenValueAfterFill, strictOraclePrice.current, spotMarket, marginCategory);
57
+ const freeCollateralContribution = weightedTokenValueAfterFill.add(ordersValue);
58
+ return {
59
+ tokenAmount: tokenAmountAfterFill,
60
+ ordersValue: ordersValue,
61
+ tokenValue: tokenValueAfterFill,
62
+ weight,
63
+ weightedTokenValue: weightedTokenValueAfterFill,
64
+ freeCollateralContribution,
65
+ };
66
+ }
67
+ exports.simulateOrderFill = simulateOrderFill;
@@ -0,0 +1,8 @@
1
+ import { BN } from '@coral-xyz/anchor';
2
+ export declare class StrictOraclePrice {
3
+ current: BN;
4
+ twap?: BN;
5
+ constructor(current: BN, twap?: BN);
6
+ max(): BN;
7
+ min(): BN;
8
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StrictOraclePrice = void 0;
4
+ const anchor_1 = require("@coral-xyz/anchor");
5
+ class StrictOraclePrice {
6
+ constructor(current, twap) {
7
+ this.current = current;
8
+ this.twap = twap;
9
+ }
10
+ max() {
11
+ return this.twap ? anchor_1.BN.max(this.twap, this.current) : this.current;
12
+ }
13
+ min() {
14
+ return this.twap ? anchor_1.BN.min(this.twap, this.current) : this.current;
15
+ }
16
+ }
17
+ exports.StrictOraclePrice = StrictOraclePrice;
@@ -0,0 +1,22 @@
1
+ /// <reference types="node" />
2
+ import { Connection, PublicKey } from '@solana/web3.js';
3
+ export declare class PriorityFeeSubscriber {
4
+ connection: Connection;
5
+ frequencyMs: number;
6
+ addresses: PublicKey[];
7
+ slotsToCheck: number;
8
+ intervalId?: NodeJS.Timer;
9
+ latestPriorityFee: number;
10
+ avgPriorityFee: number;
11
+ maxPriorityFee: number;
12
+ lastSlotSeen: number;
13
+ constructor({ connection, frequencyMs, addresses, slotsToCheck, }: {
14
+ connection: Connection;
15
+ frequencyMs: number;
16
+ addresses: PublicKey[];
17
+ slotsToCheck?: number;
18
+ });
19
+ subscribe(): Promise<void>;
20
+ load(): Promise<void>;
21
+ unsubscribe(): Promise<void>;
22
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PriorityFeeSubscriber = void 0;
4
+ class PriorityFeeSubscriber {
5
+ constructor({ connection, frequencyMs, addresses, slotsToCheck = 10, }) {
6
+ this.latestPriorityFee = 0;
7
+ // avg of last {slotsToCheck} slots
8
+ this.avgPriorityFee = 0;
9
+ // max of last {slotsToCheck} slots
10
+ this.maxPriorityFee = 0;
11
+ this.lastSlotSeen = 0;
12
+ this.connection = connection;
13
+ this.frequencyMs = frequencyMs;
14
+ this.addresses = addresses;
15
+ this.slotsToCheck = slotsToCheck;
16
+ }
17
+ async subscribe() {
18
+ if (this.intervalId) {
19
+ return;
20
+ }
21
+ this.intervalId = setInterval(this.load.bind(this), this.frequencyMs);
22
+ }
23
+ async load() {
24
+ var _a, _b, _c;
25
+ // @ts-ignore
26
+ const rpcJSONResponse = await this.connection._rpcRequest('getRecentPrioritizationFees', [this.addresses]);
27
+ const descResults = (_c = (_b = (_a = rpcJSONResponse === null || rpcJSONResponse === void 0 ? void 0 : rpcJSONResponse.result) === null || _a === void 0 ? void 0 : _a.sort((a, b) => b.slot - a.slot)) === null || _b === void 0 ? void 0 : _b.slice(0, this.slotsToCheck)) !== null && _c !== void 0 ? _c : [];
28
+ if (!(descResults === null || descResults === void 0 ? void 0 : descResults.length))
29
+ return;
30
+ const mostRecentResult = descResults[0];
31
+ this.latestPriorityFee = mostRecentResult.prioritizationFee;
32
+ this.lastSlotSeen = mostRecentResult.slot;
33
+ this.avgPriorityFee =
34
+ descResults.reduce((a, b) => {
35
+ return a + b.prioritizationFee;
36
+ }, 0) / descResults.length;
37
+ this.maxPriorityFee = Math.max(...descResults.map((result) => result.prioritizationFee));
38
+ }
39
+ async unsubscribe() {
40
+ if (this.intervalId) {
41
+ clearInterval(this.intervalId);
42
+ this.intervalId = undefined;
43
+ }
44
+ }
45
+ }
46
+ exports.PriorityFeeSubscriber = PriorityFeeSubscriber;
@@ -37,6 +37,7 @@ class TokenFaucet {
37
37
  this.connection = connection;
38
38
  this.wallet = wallet;
39
39
  this.opts = opts || anchor_1.AnchorProvider.defaultOptions();
40
+ // @ts-ignore
40
41
  const provider = new anchor_1.AnchorProvider(connection, wallet, this.opts);
41
42
  this.provider = provider;
42
43
  this.program = new anchor_1.Program(token_faucet_json_1.default, programId, provider);
package/lib/types.d.ts CHANGED
@@ -242,6 +242,9 @@ export declare class OrderActionExplanation {
242
242
  static readonly ORDER_FILLED_WITH_SERUM: {
243
243
  orderFillWithSerum: {};
244
244
  };
245
+ static readonly ORDER_FILLED_WITH_PHOENIX: {
246
+ orderFillWithPhoenix: {};
247
+ };
245
248
  static readonly REDUCE_ONLY_ORDER_INCREASED_POSITION: {
246
249
  reduceOnlyOrderIncreasedPosition: {};
247
250
  };
@@ -721,6 +724,7 @@ export type SpotMarketAccount = {
721
724
  maintenanceLiabilityWeight: number;
722
725
  liquidatorFee: number;
723
726
  imfFactor: number;
727
+ scaleInitialAssetWeightStart: BN;
724
728
  withdrawGuardThreshold: BN;
725
729
  depositTokenTwap: BN;
726
730
  borrowTokenTwap: BN;
package/lib/types.js CHANGED
@@ -156,6 +156,9 @@ OrderActionExplanation.RISK_INCREASING_ORDER = {
156
156
  OrderActionExplanation.ORDER_FILLED_WITH_SERUM = {
157
157
  orderFillWithSerum: {},
158
158
  };
159
+ OrderActionExplanation.ORDER_FILLED_WITH_PHOENIX = {
160
+ orderFillWithPhoenix: {},
161
+ };
159
162
  OrderActionExplanation.REDUCE_ONLY_ORDER_INCREASED_POSITION = {
160
163
  reduceOnlyOrderIncreasedPosition: {},
161
164
  };
package/lib/user.d.ts CHANGED
@@ -8,6 +8,7 @@ import { UserAccountSubscriber, UserAccountEvents, DataAndSlot } from './account
8
8
  import { PositionDirection, BN, SpotMarketAccount, MarketType } from '.';
9
9
  import { OraclePriceData } from './oracles/types';
10
10
  import { UserConfig } from './userConfig';
11
+ import { StrictOraclePrice } from './oracles/strictOraclePrice';
11
12
  export declare class User {
12
13
  driftClient: DriftClient;
13
14
  userAccountPublicKey: PublicKey;
@@ -138,9 +139,9 @@ export declare class User {
138
139
  totalLiabilityValue: BN;
139
140
  };
140
141
  getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
141
- getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN, strict?: boolean, now?: BN): BN;
142
+ getSpotLiabilityValue(tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN): BN;
142
143
  getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
143
- getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, strict?: boolean, now?: BN): BN;
144
+ getSpotAssetValue(tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory): BN;
144
145
  getSpotPositionValue(marketIndex: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
145
146
  getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN;
146
147
  /**
@@ -306,8 +307,8 @@ export declare class User {
306
307
  leverage: BN;
307
308
  };
308
309
  cloneAndUpdateSpotPosition(position: SpotPosition, tokenAmount: BN, market: SpotMarketAccount): SpotPosition;
309
- calculateSpotPositionFreeCollateralContribution(spotPosition: SpotPosition): BN;
310
- calculateSpotPositionLeverageContribution(spotPosition: SpotPosition): {
310
+ calculateSpotPositionFreeCollateralContribution(spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice): BN;
311
+ calculateSpotPositionLeverageContribution(spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice): {
311
312
  totalAssetValue: BN;
312
313
  totalLiabilityValue: BN;
313
314
  };