@drift-labs/sdk 0.1.36-master.4 → 0.1.36-master.7

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 (41) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +1 -0
  2. package/lib/accounts/bulkAccountLoader.js +4 -0
  3. package/lib/addresses.d.ts +1 -0
  4. package/lib/addresses.js +7 -1
  5. package/lib/admin.d.ts +5 -0
  6. package/lib/admin.js +68 -0
  7. package/lib/clearingHouse.d.ts +11 -3
  8. package/lib/clearingHouse.js +130 -4
  9. package/lib/clearingHouseUser.d.ts +5 -1
  10. package/lib/clearingHouseUser.js +28 -0
  11. package/lib/idl/clearing_house.json +988 -727
  12. package/lib/index.d.ts +1 -0
  13. package/lib/index.js +1 -0
  14. package/lib/math/oracles.d.ts +3 -0
  15. package/lib/math/oracles.js +26 -0
  16. package/lib/math/position.d.ts +1 -0
  17. package/lib/math/position.js +19 -1
  18. package/lib/math/trade.d.ts +10 -6
  19. package/lib/math/trade.js +68 -13
  20. package/lib/oracles/pythClient.js +1 -0
  21. package/lib/oracles/switchboardClient.js +3 -0
  22. package/lib/oracles/types.d.ts +1 -0
  23. package/lib/settlement.d.ts +4 -0
  24. package/lib/settlement.js +10 -0
  25. package/lib/types.d.ts +11 -0
  26. package/package.json +1 -1
  27. package/src/accounts/bulkAccountLoader.ts +5 -0
  28. package/src/addresses.ts +11 -0
  29. package/src/admin.ts +83 -0
  30. package/src/clearingHouse.ts +204 -4
  31. package/src/clearingHouseUser.ts +64 -1
  32. package/src/idl/clearing_house.json +988 -727
  33. package/src/index.ts +1 -0
  34. package/src/math/oracles.ts +36 -0
  35. package/src/math/position.ts +22 -0
  36. package/src/math/trade.ts +84 -16
  37. package/src/oracles/pythClient.ts +1 -0
  38. package/src/oracles/switchboardClient.ts +5 -0
  39. package/src/oracles/types.ts +1 -0
  40. package/src/settlement.ts +9 -0
  41. package/src/types.ts +12 -0
package/lib/index.d.ts CHANGED
@@ -25,6 +25,7 @@ export * from './math/funding';
25
25
  export * from './math/insuranceFund';
26
26
  export * from './math/market';
27
27
  export * from './math/position';
28
+ export * from './math/oracles';
28
29
  export * from './math/amm';
29
30
  export * from './math/trade';
30
31
  export * from './math/orders';
package/lib/index.js CHANGED
@@ -44,6 +44,7 @@ __exportStar(require("./math/funding"), exports);
44
44
  __exportStar(require("./math/insuranceFund"), exports);
45
45
  __exportStar(require("./math/market"), exports);
46
46
  __exportStar(require("./math/position"), exports);
47
+ __exportStar(require("./math/oracles"), exports);
47
48
  __exportStar(require("./math/amm"), exports);
48
49
  __exportStar(require("./math/trade"), exports);
49
50
  __exportStar(require("./math/orders"), exports);
@@ -0,0 +1,3 @@
1
+ import { AMM, OracleGuardRails } from '../types';
2
+ import { OraclePriceData } from '../oracles/types';
3
+ export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isOracleValid = void 0;
4
+ const numericConstants_1 = require("../constants/numericConstants");
5
+ const index_1 = require("../index");
6
+ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
7
+ const isOraclePriceNonPositive = oraclePriceData.price.lt(numericConstants_1.ZERO);
8
+ const isOraclePriceTooVolatile = oraclePriceData.price
9
+ .div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
10
+ .gt(oracleGuardRails.validity.tooVolatileRatio) ||
11
+ amm.lastOraclePriceTwap
12
+ .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
13
+ .gt(oracleGuardRails.validity.tooVolatileRatio);
14
+ const isConfidenceTooLarge = oraclePriceData.price
15
+ .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
16
+ .lt(oracleGuardRails.validity.confidenceIntervalMaxSize);
17
+ const oracleIsStale = oraclePriceData.slot
18
+ .sub(new index_1.BN(slot))
19
+ .gt(oracleGuardRails.validity.slotsBeforeStale);
20
+ return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
21
+ oracleIsStale ||
22
+ isOraclePriceNonPositive ||
23
+ isOraclePriceTooVolatile ||
24
+ isConfidenceTooLarge);
25
+ }
26
+ exports.isOracleValid = isOracleValid;
@@ -18,6 +18,7 @@ export declare function calculateBaseAssetValue(market: Market, userPosition: Us
18
18
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
19
19
  */
20
20
  export declare function calculatePositionPNL(market: Market, marketPosition: UserPosition, withFunding?: boolean): BN;
21
+ export declare function calculateSettledPositionPNL(market: Market, marketPosition: UserPosition): BN;
21
22
  /**
22
23
  *
23
24
  * @param market
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
3
+ exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculateSettledPositionPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
4
4
  const __1 = require("../");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const types_1 = require("../types");
7
7
  const amm_1 = require("./amm");
8
+ const settlement_1 = require("../settlement");
8
9
  /**
9
10
  * calculateBaseAssetValue
10
11
  * = market value of closing entire position
@@ -60,6 +61,23 @@ function calculatePositionPNL(market, marketPosition, withFunding = false) {
60
61
  return pnl;
61
62
  }
62
63
  exports.calculatePositionPNL = calculatePositionPNL;
64
+ function calculateSettledPositionPNL(market, marketPosition) {
65
+ let pnl = calculatePositionPNL(market, marketPosition);
66
+ if (pnl.gt(numericConstants_1.ZERO)) {
67
+ try {
68
+ pnl = pnl
69
+ .mul(new __1.BN(settlement_1.SETTLEMENT_RATIOS[marketPosition.marketIndex.toNumber()]))
70
+ .div(settlement_1.SETTLEMENT_RATIO_PRECISION);
71
+ }
72
+ catch (e) {
73
+ console.log(pnl.toString());
74
+ console.log(marketPosition.marketIndex.toNumber());
75
+ throw e;
76
+ }
77
+ }
78
+ return pnl;
79
+ }
80
+ exports.calculateSettledPositionPNL = calculateSettledPositionPNL;
63
81
  /**
64
82
  *
65
83
  * @param market
@@ -8,6 +8,8 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
8
8
  * @param direction
9
9
  * @param amount
10
10
  * @param market
11
+ * @param inputAssetType which asset is being traded
12
+ * @param useSpread whether to consider spread with calculating slippage
11
13
  * @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
12
14
  *
13
15
  * 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision MARK_PRICE_PRECISION
@@ -18,7 +20,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
18
20
  *
19
21
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
20
22
  */
21
- export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType): [BN, BN, BN, BN];
23
+ export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN, BN, BN];
22
24
  /**
23
25
  * Calculates acquired amounts for trade executed
24
26
  * @param direction
@@ -27,7 +29,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
27
29
  * @param inputAssetType
28
30
  * @param useSpread
29
31
  * @return
30
- * | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
32
+ * | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
31
33
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
32
34
  */
33
35
  export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN];
@@ -37,13 +39,15 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
37
39
  * @param market
38
40
  * @param targetPrice
39
41
  * @param pct optional default is 100% gap filling, can set smaller.
42
+ * @param outputAssetType which asset to trade.
43
+ * @param useSpread whether or not to consider the spread when calculating the trade size
40
44
  * @returns trade direction/size in order to push price to a targetPrice,
41
45
  *
42
46
  * [
43
- * direction => direction of trade required, TODO-PRECISION
47
+ * direction => direction of trade required, PositionDirection
44
48
  * tradeSize => size of trade required, TODO-PRECISION
45
- * entryPrice => the entry price for the trade, TODO-PRECISION
46
- * targetPrice => the target price TODO-PRECISION
49
+ * entryPrice => the entry price for the trade, MARK_PRICE_PRECISION
50
+ * targetPrice => the target price MARK_PRICE_PRECISION
47
51
  * ]
48
52
  */
49
- export declare function calculateTargetPriceTrade(market: Market, targetPrice: BN, pct?: BN, outputAssetType?: AssetType): [PositionDirection, BN, BN, BN];
53
+ export declare function calculateTargetPriceTrade(market: Market, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, useSpread?: boolean): [PositionDirection, BN, BN, BN];
package/lib/math/trade.js CHANGED
@@ -8,12 +8,15 @@ const numericConstants_1 = require("../constants/numericConstants");
8
8
  const market_1 = require("./market");
9
9
  const amm_1 = require("./amm");
10
10
  const utils_1 = require("./utils");
11
+ const types_2 = require("../types");
11
12
  const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
12
13
  /**
13
14
  * Calculates avg/max slippage (price impact) for candidate trade
14
15
  * @param direction
15
16
  * @param amount
16
17
  * @param market
18
+ * @param inputAssetType which asset is being traded
19
+ * @param useSpread whether to consider spread with calculating slippage
17
20
  * @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
18
21
  *
19
22
  * 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision MARK_PRICE_PRECISION
@@ -24,14 +27,38 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
24
27
  *
25
28
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
26
29
  */
27
- function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote') {
28
- const oldPrice = (0, market_1.calculateMarkPrice)(market);
30
+ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
31
+ let oldPrice;
32
+ if (useSpread && market.amm.baseSpread > 0) {
33
+ if ((0, types_2.isVariant)(direction, 'long')) {
34
+ oldPrice = (0, market_1.calculateAskPrice)(market);
35
+ }
36
+ else {
37
+ oldPrice = (0, market_1.calculateBidPrice)(market);
38
+ }
39
+ }
40
+ else {
41
+ oldPrice = (0, market_1.calculateMarkPrice)(market);
42
+ }
29
43
  if (amount.eq(numericConstants_1.ZERO)) {
30
44
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
31
45
  }
32
- const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType);
46
+ const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, useSpread);
33
47
  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);
48
+ let amm;
49
+ if (useSpread && market.amm.baseSpread > 0) {
50
+ const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
51
+ amm = {
52
+ baseAssetReserve,
53
+ quoteAssetReserve,
54
+ sqrtK: market.amm.sqrtK,
55
+ pegMultiplier: market.amm.pegMultiplier,
56
+ };
57
+ }
58
+ else {
59
+ amm = market.amm;
60
+ }
61
+ const newPrice = (0, amm_1.calculatePrice)(amm.baseAssetReserve.sub(acquiredBase), amm.quoteAssetReserve.sub(acquiredQuote), amm.pegMultiplier);
35
62
  if (direction == types_1.PositionDirection.SHORT) {
36
63
  (0, assert_1.assert)(newPrice.lt(oldPrice));
37
64
  }
@@ -59,7 +86,7 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
59
86
  * @param inputAssetType
60
87
  * @param useSpread
61
88
  * @return
62
- * | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
89
+ * | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
63
90
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
64
91
  */
65
92
  function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
@@ -92,35 +119,50 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
92
119
  * @param market
93
120
  * @param targetPrice
94
121
  * @param pct optional default is 100% gap filling, can set smaller.
122
+ * @param outputAssetType which asset to trade.
123
+ * @param useSpread whether or not to consider the spread when calculating the trade size
95
124
  * @returns trade direction/size in order to push price to a targetPrice,
96
125
  *
97
126
  * [
98
- * direction => direction of trade required, TODO-PRECISION
127
+ * direction => direction of trade required, PositionDirection
99
128
  * tradeSize => size of trade required, TODO-PRECISION
100
- * entryPrice => the entry price for the trade, TODO-PRECISION
101
- * targetPrice => the target price TODO-PRECISION
129
+ * entryPrice => the entry price for the trade, MARK_PRICE_PRECISION
130
+ * targetPrice => the target price MARK_PRICE_PRECISION
102
131
  * ]
103
132
  */
104
- function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote') {
133
+ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', useSpread = true) {
105
134
  (0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
106
135
  (0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
107
136
  (0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
108
137
  const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
138
+ const bidPriceBefore = (0, market_1.calculateBidPrice)(market);
139
+ const askPriceBefore = (0, market_1.calculateAskPrice)(market);
140
+ let direction;
109
141
  if (targetPrice.gt(markPriceBefore)) {
110
142
  const priceGap = targetPrice.sub(markPriceBefore);
111
143
  const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
112
144
  targetPrice = markPriceBefore.add(priceGapScaled);
145
+ direction = types_1.PositionDirection.LONG;
113
146
  }
114
147
  else {
115
148
  const priceGap = markPriceBefore.sub(targetPrice);
116
149
  const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
117
150
  targetPrice = markPriceBefore.sub(priceGapScaled);
151
+ direction = types_1.PositionDirection.SHORT;
118
152
  }
119
- let direction;
120
153
  let tradeSize;
121
154
  let baseSize;
122
- const baseAssetReserveBefore = market.amm.baseAssetReserve;
123
- const quoteAssetReserveBefore = market.amm.quoteAssetReserve;
155
+ let baseAssetReserveBefore;
156
+ let quoteAssetReserveBefore;
157
+ if (useSpread && market.amm.baseSpread > 0) {
158
+ const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
159
+ baseAssetReserveBefore = baseAssetReserve;
160
+ quoteAssetReserveBefore = quoteAssetReserve;
161
+ }
162
+ else {
163
+ baseAssetReserveBefore = market.amm.baseAssetReserve;
164
+ quoteAssetReserveBefore = market.amm.quoteAssetReserve;
165
+ }
124
166
  const peg = market.amm.pegMultiplier;
125
167
  const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
126
168
  const k = invariant.mul(numericConstants_1.MARK_PRICE_PRECISION);
@@ -128,7 +170,20 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
128
170
  let quoteAssetReserveAfter;
129
171
  const biasModifier = new anchor_1.BN(1);
130
172
  let markPriceAfter;
131
- if (markPriceBefore.gt(targetPrice)) {
173
+ if (useSpread &&
174
+ targetPrice.lt(askPriceBefore) &&
175
+ targetPrice.gt(bidPriceBefore)) {
176
+ // no trade, market is at target
177
+ if (markPriceBefore.gt(targetPrice)) {
178
+ direction = types_1.PositionDirection.SHORT;
179
+ }
180
+ else {
181
+ direction = types_1.PositionDirection.LONG;
182
+ }
183
+ tradeSize = numericConstants_1.ZERO;
184
+ return [direction, tradeSize, targetPrice, targetPrice];
185
+ }
186
+ else if (markPriceBefore.gt(targetPrice)) {
132
187
  // overestimate y2
133
188
  baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
134
189
  quoteAssetReserveAfter = k
@@ -38,6 +38,7 @@ class PythClient {
38
38
  confidence: convertPythPrice(priceData.confidence, priceData.exponent),
39
39
  twap: convertPythPrice(priceData.twap.value, priceData.exponent),
40
40
  twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
41
+ hasSufficientNumberOfDataPoints: true,
41
42
  };
42
43
  });
43
44
  }
@@ -39,11 +39,14 @@ class SwitchboardClient {
39
39
  const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
40
40
  const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound
41
41
  .stdDeviation);
42
+ const hasSufficientNumberOfDataPoints = aggregatorAccountData.latestConfirmedRound.numSuccess >=
43
+ aggregatorAccountData.minOracleResults;
42
44
  const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
43
45
  return {
44
46
  price,
45
47
  slot,
46
48
  confidence,
49
+ hasSufficientNumberOfDataPoints,
47
50
  };
48
51
  });
49
52
  }
@@ -6,6 +6,7 @@ export declare type OraclePriceData = {
6
6
  price: BN;
7
7
  slot: BN;
8
8
  confidence: BN;
9
+ hasSufficientNumberOfDataPoints: boolean;
9
10
  twap?: BN;
10
11
  twapConfidence?: BN;
11
12
  };
@@ -0,0 +1,4 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@project-serum/anchor';
3
+ export declare const SETTLEMENT_RATIO_PRECISION: BN;
4
+ export declare const SETTLEMENT_RATIOS: number[];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SETTLEMENT_RATIOS = exports.SETTLEMENT_RATIO_PRECISION = void 0;
4
+ const anchor_1 = require("@project-serum/anchor");
5
+ exports.SETTLEMENT_RATIO_PRECISION = new anchor_1.BN(1000000);
6
+ exports.SETTLEMENT_RATIOS = [
7
+ 291786, 243613, 712271, 293771, 555181, 604938, 241133, 218489, 251741,
8
+ 883058, 51614, 531737, 956092, 106424, 727107, 477277, 217325, 127477, 248561,
9
+ 565938, 59349,
10
+ ];
package/lib/types.d.ts CHANGED
@@ -275,6 +275,12 @@ export declare type OrderStateAccount = {
275
275
  orderFillerRewardStructure: OrderFillerRewardStructure;
276
276
  minOrderQuoteAssetAmount: BN;
277
277
  };
278
+ export declare type SettlementStateAccount = {
279
+ totalSettlementValue: BN;
280
+ collateralAvailableToClaim: BN;
281
+ collateralClaimed: BN;
282
+ enabled: boolean;
283
+ };
278
284
  export declare type MarketsAccount = {
279
285
  markets: Market[];
280
286
  };
@@ -337,6 +343,11 @@ export declare type UserAccount = {
337
343
  totalTokenDiscount: BN;
338
344
  totalReferralReward: BN;
339
345
  totalRefereeDiscount: BN;
346
+ settledPositionValue: BN;
347
+ collateralClaimed: BN;
348
+ lastCollateralAvailableToClaim: BN;
349
+ forgoPositionSettlement: number;
350
+ hasSettledPosition: number;
340
351
  };
341
352
  export declare type UserOrdersAccount = {
342
353
  orders: Order[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.36-master.4",
3
+ "version": "0.1.36-master.7",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -24,6 +24,7 @@ export class BulkAccountLoader {
24
24
  loadPromise?: Promise<void>;
25
25
  loadPromiseResolver: () => void;
26
26
  lastTimeLoadingPromiseCleared = Date.now();
27
+ mostRecentSlot = 0;
27
28
 
28
29
  public constructor(
29
30
  connection: Connection,
@@ -159,6 +160,10 @@ export class BulkAccountLoader {
159
160
 
160
161
  const newSlot = rpcResponse.result.context.slot;
161
162
 
163
+ if (newSlot > this.mostRecentSlot) {
164
+ this.mostRecentSlot = newSlot;
165
+ }
166
+
162
167
  for (const i in accountsToLoad) {
163
168
  const accountToLoad = accountsToLoad[i];
164
169
  const key = accountToLoad.publicKey.toString();
package/src/addresses.ts CHANGED
@@ -69,3 +69,14 @@ export async function getUserOrdersAccountPublicKey(
69
69
  await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount)
70
70
  )[0];
71
71
  }
72
+
73
+ export async function getSettlementStatePublicKey(
74
+ programId: PublicKey
75
+ ): Promise<PublicKey> {
76
+ return (
77
+ await anchor.web3.PublicKey.findProgramAddress(
78
+ [Buffer.from(anchor.utils.bytes.utf8.encode('settlement_state'))],
79
+ programId
80
+ )
81
+ )[0];
82
+ }
package/src/admin.ts CHANGED
@@ -18,6 +18,8 @@ import {
18
18
  getClearingHouseStateAccountPublicKey,
19
19
  getClearingHouseStateAccountPublicKeyAndNonce,
20
20
  getOrderStateAccountPublicKeyAndNonce,
21
+ getSettlementStatePublicKey,
22
+ getUserAccountPublicKey,
21
23
  } from './addresses';
22
24
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
23
25
  import { ClearingHouse } from './clearingHouse';
@@ -733,4 +735,85 @@ export class Admin extends ClearingHouse {
733
735
  },
734
736
  });
735
737
  }
738
+
739
+ public async transferFromInsuranceVaultToCollateralVault(): Promise<TransactionSignature> {
740
+ const state = await this.getStateAccount();
741
+ return await this.program.rpc.transferFromInsuranceVaultToCollateralVault({
742
+ accounts: {
743
+ admin: this.wallet.publicKey,
744
+ state: await this.getStatePublicKey(),
745
+ insuranceVault: state.insuranceVault,
746
+ insuranceVaultAuthority: state.insuranceVaultAuthority,
747
+ collateralVault: state.collateralVault,
748
+ tokenProgram: TOKEN_PROGRAM_ID,
749
+ },
750
+ });
751
+ }
752
+
753
+ public async adminUpdateUserForgoSettlement(
754
+ authority: PublicKey
755
+ ): Promise<TransactionSignature> {
756
+ const user = await getUserAccountPublicKey(
757
+ this.program.programId,
758
+ authority
759
+ );
760
+
761
+ return await this.program.rpc.adminUpdateUserForgoSettlement({
762
+ accounts: {
763
+ admin: this.wallet.publicKey,
764
+ state: await this.getStatePublicKey(),
765
+ user: user,
766
+ },
767
+ });
768
+ }
769
+
770
+ public async initializeSettlementState(): Promise<TransactionSignature> {
771
+ const settlementState = await getSettlementStatePublicKey(
772
+ this.program.programId
773
+ );
774
+
775
+ const settlementSize = await this.getTotalSettlementSize();
776
+
777
+ return await this.program.rpc.initializeSettlementState(settlementSize, {
778
+ accounts: {
779
+ admin: this.wallet.publicKey,
780
+ state: await this.getStatePublicKey(),
781
+ settlementState: settlementState,
782
+ rent: SYSVAR_RENT_PUBKEY,
783
+ systemProgram: anchor.web3.SystemProgram.programId,
784
+ collateralVault: (await this.getStateAccount()).collateralVault,
785
+ },
786
+ });
787
+ }
788
+
789
+ public async updateSettlementState(): Promise<TransactionSignature> {
790
+ const settlementState = await getSettlementStatePublicKey(
791
+ this.program.programId
792
+ );
793
+
794
+ return await this.program.rpc.updateSettlementState({
795
+ accounts: {
796
+ admin: this.wallet.publicKey,
797
+ state: await this.getStatePublicKey(),
798
+ settlementState: settlementState,
799
+ collateralVault: (await this.getStateAccount()).collateralVault,
800
+ },
801
+ });
802
+ }
803
+
804
+ public async updateSettlementStateEnabled(
805
+ enabled: boolean
806
+ ): Promise<TransactionSignature> {
807
+ const settlementState = await getSettlementStatePublicKey(
808
+ this.program.programId
809
+ );
810
+
811
+ return await this.program.rpc.updateSettlementStateEnabled(enabled, {
812
+ accounts: {
813
+ admin: this.wallet.publicKey,
814
+ state: await this.getStatePublicKey(),
815
+ settlementState: settlementState,
816
+ },
817
+ });
818
+ }
736
819
  }