@drift-labs/sdk 2.0.11 → 2.0.12

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.
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventList = void 0;
4
+ class Node {
5
+ constructor(event, next, prev) {
6
+ this.event = event;
7
+ this.next = next;
8
+ this.prev = prev;
9
+ }
10
+ }
11
+ class EventList {
12
+ constructor(eventType, maxSize, sortFn, orderDirection) {
13
+ this.eventType = eventType;
14
+ this.maxSize = maxSize;
15
+ this.sortFn = sortFn;
16
+ this.orderDirection = orderDirection;
17
+ this.size = 0;
18
+ }
19
+ insert(event) {
20
+ this.size++;
21
+ const newNode = new Node(event);
22
+ if (this.head === undefined) {
23
+ this.head = this.tail = newNode;
24
+ return;
25
+ }
26
+ if (this.sortFn(this.head.event, newNode.event) ===
27
+ (this.orderDirection === 'asc' ? 'less than' : 'greater than')) {
28
+ this.head.prev = newNode;
29
+ newNode.next = this.head;
30
+ this.head = newNode;
31
+ }
32
+ else {
33
+ let currentNode = this.head;
34
+ while (currentNode.next !== undefined &&
35
+ this.sortFn(currentNode.next.event, newNode.event) !==
36
+ (this.orderDirection === 'asc' ? 'less than' : 'greater than')) {
37
+ currentNode = currentNode.next;
38
+ }
39
+ newNode.next = currentNode.next;
40
+ if (currentNode.next !== undefined) {
41
+ newNode.next.prev = newNode;
42
+ }
43
+ currentNode.next = newNode;
44
+ newNode.prev = currentNode;
45
+ }
46
+ if (this.size > this.maxSize) {
47
+ this.detach();
48
+ }
49
+ }
50
+ detach() {
51
+ const node = this.tail;
52
+ if (node.prev !== undefined) {
53
+ node.prev.next = node.next;
54
+ }
55
+ else {
56
+ this.head = node.next;
57
+ }
58
+ if (node.next !== undefined) {
59
+ node.next.prev = node.prev;
60
+ }
61
+ else {
62
+ this.tail = node.prev;
63
+ }
64
+ this.size--;
65
+ }
66
+ toArray() {
67
+ return Array.from(this);
68
+ }
69
+ *[Symbol.iterator]() {
70
+ let node = this.head;
71
+ while (node) {
72
+ yield node.event;
73
+ node = node.next;
74
+ }
75
+ }
76
+ }
77
+ exports.EventList = EventList;
@@ -49,12 +49,12 @@ export class PollingLogProvider implements LogProvider {
49
49
  skipHistory && this.firstFetch ? 1 : undefined
50
50
  );
51
51
 
52
- this.firstFetch = false;
53
-
54
52
  if (response === undefined) {
55
53
  return;
56
54
  }
57
55
 
56
+ this.firstFetch = false;
57
+
58
58
  const { mostRecentTx, transactionLogs } = response;
59
59
 
60
60
  for (const { txSig, slot, logs } of transactionLogs) {
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+ var __awaiter =
3
+ (this && this.__awaiter) ||
4
+ function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) {
6
+ return value instanceof P
7
+ ? value
8
+ : new P(function (resolve) {
9
+ resolve(value);
10
+ });
11
+ }
12
+ return new (P || (P = Promise))(function (resolve, reject) {
13
+ function fulfilled(value) {
14
+ try {
15
+ step(generator.next(value));
16
+ } catch (e) {
17
+ reject(e);
18
+ }
19
+ }
20
+ function rejected(value) {
21
+ try {
22
+ step(generator['throw'](value));
23
+ } catch (e) {
24
+ reject(e);
25
+ }
26
+ }
27
+ function step(result) {
28
+ result.done
29
+ ? resolve(result.value)
30
+ : adopt(result.value).then(fulfilled, rejected);
31
+ }
32
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
33
+ });
34
+ };
35
+ Object.defineProperty(exports, '__esModule', { value: true });
36
+ exports.getTokenAddress = void 0;
37
+ const anchor_1 = require('@project-serum/anchor');
38
+ const __1 = require('..');
39
+ const spl_token_1 = require('@solana/spl-token');
40
+ const web3_js_1 = require('@solana/web3.js');
41
+ const __2 = require('..');
42
+ const banks_1 = require('../constants/spotMarkets');
43
+ const getTokenAddress = (mintAddress, userPubKey) => {
44
+ return spl_token_1.Token.getAssociatedTokenAddress(
45
+ new web3_js_1.PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
46
+ spl_token_1.TOKEN_PROGRAM_ID,
47
+ new web3_js_1.PublicKey(mintAddress),
48
+ new web3_js_1.PublicKey(userPubKey)
49
+ );
50
+ };
51
+ exports.getTokenAddress = getTokenAddress;
52
+ const main = () =>
53
+ __awaiter(void 0, void 0, void 0, function* () {
54
+ // Initialize Drift SDK
55
+ const sdkConfig = __2.initialize({ env: 'devnet' });
56
+ // Set up the Wallet and Provider
57
+ const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
58
+ const keypair = web3_js_1.Keypair.fromSecretKey(
59
+ Uint8Array.from(JSON.parse(privateKey))
60
+ );
61
+ const wallet = new __1.Wallet(keypair);
62
+ // Set up the Connection
63
+ const rpcAddress = process.env.RPC_ADDRESS; // can use: https://api.devnet.solana.com for devnet; https://api.mainnet-beta.solana.com for mainnet;
64
+ const connection = new web3_js_1.Connection(rpcAddress);
65
+ // Set up the Provider
66
+ const provider = new anchor_1.AnchorProvider(
67
+ connection,
68
+ wallet,
69
+ anchor_1.AnchorProvider.defaultOptions()
70
+ );
71
+ // Check SOL Balance
72
+ const lamportsBalance = yield connection.getBalance(wallet.publicKey);
73
+ console.log('SOL balance:', lamportsBalance / Math.pow(10, 9));
74
+ // Misc. other things to set up
75
+ const usdcTokenAddress = yield exports.getTokenAddress(
76
+ sdkConfig.USDC_MINT_ADDRESS,
77
+ wallet.publicKey.toString()
78
+ );
79
+ // Set up the Drift Clearing House
80
+ const clearingHousePublicKey = new web3_js_1.PublicKey(
81
+ sdkConfig.DRIFT_PROGRAM_ID
82
+ );
83
+ const clearingHouse = new __2.ClearingHouse({
84
+ connection,
85
+ wallet: provider.wallet,
86
+ programID: clearingHousePublicKey,
87
+ });
88
+ yield clearingHouse.subscribe();
89
+ // Set up Clearing House user client
90
+ const user = new __2.ClearingHouseUser({
91
+ clearingHouse,
92
+ userAccountPublicKey: yield clearingHouse.getUserAccountPublicKey(),
93
+ });
94
+ //// Check if clearing house account exists for the current wallet
95
+ const userAccountExists = yield user.exists();
96
+ if (!userAccountExists) {
97
+ //// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
98
+ const depositAmount = new anchor_1.BN(10000).mul(__2.QUOTE_PRECISION);
99
+ yield clearingHouse.initializeUserAccountAndDepositCollateral(
100
+ depositAmount,
101
+ yield exports.getTokenAddress(
102
+ usdcTokenAddress.toString(),
103
+ wallet.publicKey.toString()
104
+ ),
105
+ banks_1.SpotMarkets['devnet'][0].marketIndex
106
+ );
107
+ }
108
+ yield user.subscribe();
109
+ // Get current price
110
+ const solMarketInfo = sdkConfig.PERP_MARKETS.find(
111
+ (market) => market.baseAssetSymbol === 'SOL'
112
+ );
113
+ const currentMarketPrice = __2.calculateMarkPrice(
114
+ clearingHouse.getMarketAccount(solMarketInfo.marketIndex),
115
+ undefined
116
+ );
117
+ const formattedPrice = __2.convertToNumber(
118
+ currentMarketPrice,
119
+ __2.PRICE_PRECISION
120
+ );
121
+ console.log(`Current Market Price is $${formattedPrice}`);
122
+ // Estimate the slippage for a $5000 LONG trade
123
+ const solMarketAccount = clearingHouse.getMarketAccount(
124
+ solMarketInfo.marketIndex
125
+ );
126
+ const longAmount = new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION);
127
+ const slippage = __2.convertToNumber(
128
+ __2.calculateTradeSlippage(
129
+ __2.PositionDirection.LONG,
130
+ longAmount,
131
+ solMarketAccount,
132
+ 'quote',
133
+ undefined
134
+ )[0],
135
+ __2.PRICE_PRECISION
136
+ );
137
+ console.log(
138
+ `Slippage for a $5000 LONG on the SOL market would be $${slippage}`
139
+ );
140
+ // Make a $5000 LONG trade
141
+ yield clearingHouse.openPosition(
142
+ __2.PositionDirection.LONG,
143
+ longAmount,
144
+ solMarketInfo.marketIndex
145
+ );
146
+ console.log(`LONGED $5000 SOL`);
147
+ // Reduce the position by $2000
148
+ const reduceAmount = new anchor_1.BN(2000).mul(__2.QUOTE_PRECISION);
149
+ yield clearingHouse.openPosition(
150
+ __2.PositionDirection.SHORT,
151
+ reduceAmount,
152
+ solMarketInfo.marketIndex
153
+ );
154
+ // Close the rest of the position
155
+ yield clearingHouse.closePosition(solMarketInfo.marketIndex);
156
+ });
157
+ main();
@@ -2070,6 +2070,34 @@
2070
2070
  }
2071
2071
  ]
2072
2072
  },
2073
+ {
2074
+ "name": "updateSerumFulfillmentConfigStatus",
2075
+ "accounts": [
2076
+ {
2077
+ "name": "state",
2078
+ "isMut": false,
2079
+ "isSigner": false
2080
+ },
2081
+ {
2082
+ "name": "serumFulfillmentConfig",
2083
+ "isMut": true,
2084
+ "isSigner": false
2085
+ },
2086
+ {
2087
+ "name": "admin",
2088
+ "isMut": true,
2089
+ "isSigner": true
2090
+ }
2091
+ ],
2092
+ "args": [
2093
+ {
2094
+ "name": "status",
2095
+ "type": {
2096
+ "defined": "SpotFulfillmentConfigStatus"
2097
+ }
2098
+ }
2099
+ ]
2100
+ },
2073
2101
  {
2074
2102
  "name": "updateSerumVault",
2075
2103
  "accounts": [
@@ -4184,7 +4212,7 @@
4184
4212
  {
4185
4213
  "name": "status",
4186
4214
  "type": {
4187
- "defined": "SpotFulfillmentStatus"
4215
+ "defined": "SpotFulfillmentConfigStatus"
4188
4216
  }
4189
4217
  },
4190
4218
  {
@@ -6206,7 +6234,7 @@
6206
6234
  }
6207
6235
  },
6208
6236
  {
6209
- "name": "SpotFulfillmentStatus",
6237
+ "name": "SpotFulfillmentConfigStatus",
6210
6238
  "type": {
6211
6239
  "kind": "enum",
6212
6240
  "variants": [
@@ -8423,6 +8451,16 @@
8423
8451
  "code": 6218,
8424
8452
  "name": "InvalidPerpPosition",
8425
8453
  "msg": "Invalid Perp Position"
8454
+ },
8455
+ {
8456
+ "code": 6219,
8457
+ "name": "InvalidLiquidation",
8458
+ "msg": "Invalid Liquidation"
8459
+ },
8460
+ {
8461
+ "code": 6220,
8462
+ "name": "SpotFulfillmentConfigDisabled",
8463
+ "msg": "Spot Fulfullment Config Disabled"
8426
8464
  }
8427
8465
  ]
8428
8466
  }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTokenAccount = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ function parseTokenAccount(data) {
7
+ const accountInfo = spl_token_1.AccountLayout.decode(data);
8
+ accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint);
9
+ accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner);
10
+ accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount);
11
+ if (accountInfo.delegateOption === 0) {
12
+ accountInfo.delegate = null;
13
+ // eslint-disable-next-line new-cap
14
+ accountInfo.delegatedAmount = new spl_token_1.u64(0);
15
+ }
16
+ else {
17
+ accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
18
+ accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount);
19
+ }
20
+ accountInfo.isInitialized = accountInfo.state !== 0;
21
+ accountInfo.isFrozen = accountInfo.state === 2;
22
+ if (accountInfo.isNativeOption === 1) {
23
+ accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative);
24
+ accountInfo.isNative = true;
25
+ }
26
+ else {
27
+ accountInfo.rentExemptReserve = null;
28
+ accountInfo.isNative = false;
29
+ }
30
+ if (accountInfo.closeAuthorityOption === 0) {
31
+ accountInfo.closeAuthority = null;
32
+ }
33
+ else {
34
+ accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority);
35
+ }
36
+ return accountInfo;
37
+ }
38
+ exports.parseTokenAccount = parseTokenAccount;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapInTx = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const COMPUTE_UNITS_DEFAULT = 200000;
6
+ function wrapInTx(instruction, computeUnits = 600000 // TODO, requires less code change
7
+ ) {
8
+ const tx = new web3_js_1.Transaction();
9
+ if (computeUnits != COMPUTE_UNITS_DEFAULT) {
10
+ tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
11
+ units: computeUnits,
12
+ additionalFee: 0,
13
+ }));
14
+ }
15
+ return tx.add(instruction);
16
+ }
17
+ exports.wrapInTx = wrapInTx;
package/src/types.ts CHANGED
@@ -173,6 +173,11 @@ export class SettlePnlExplanation {
173
173
  static readonly EXPIRED_POSITION = { expiredPosition: {} };
174
174
  }
175
175
 
176
+ export class SpotFulfillmentConfigStatus {
177
+ static readonly ENABLED = { enabled: {} };
178
+ static readonly DISABLED = { disabled: {} };
179
+ }
180
+
176
181
  export class StakeAction {
177
182
  static readonly STAKE = { stake: {} };
178
183
  static readonly UNSTAKE_REQUEST = { unstakeRequest: {} };
package/src/user.ts CHANGED
@@ -64,6 +64,7 @@ import {
64
64
  getWorstCaseTokenAmounts,
65
65
  isSpotPositionAvailable,
66
66
  } from './math/spotPosition';
67
+
67
68
  export class User {
68
69
  driftClient: DriftClient;
69
70
  userAccountPublicKey: PublicKey;
@@ -410,6 +411,16 @@ export class User {
410
411
  return this.getMarginRequirement('Maintenance', liquidationBuffer);
411
412
  }
412
413
 
414
+ public getActivePerpPositions(): PerpPosition[] {
415
+ return this.getUserAccount().perpPositions.filter(
416
+ (pos) =>
417
+ !pos.baseAssetAmount.eq(ZERO) ||
418
+ !pos.quoteAssetAmount.eq(ZERO) ||
419
+ !(pos.openOrders == 0) ||
420
+ !pos.lpShares.eq(ZERO)
421
+ );
422
+ }
423
+
413
424
  /**
414
425
  * calculates unrealized position price pnl
415
426
  * @returns : Precision QUOTE_PRECISION
@@ -420,10 +431,8 @@ export class User {
420
431
  withWeightMarginCategory?: MarginCategory
421
432
  ): BN {
422
433
  const quoteSpotMarket = this.driftClient.getQuoteSpotMarketAccount();
423
- return this.getUserAccount()
424
- .perpPositions.filter((pos) =>
425
- marketIndex ? pos.marketIndex === marketIndex : true
426
- )
434
+ return this.getActivePerpPositions()
435
+ .filter((pos) => (marketIndex ? pos.marketIndex === marketIndex : true))
427
436
  .reduce((unrealizedPnl, perpPosition) => {
428
437
  const market = this.driftClient.getPerpMarketAccount(
429
438
  perpPosition.marketIndex
@@ -757,6 +766,53 @@ export class User {
757
766
  );
758
767
  }
759
768
 
769
+ /**
770
+ * calculates User Health by comparing total collateral and maint. margin requirement
771
+ * @returns : number (value from [0, 100])
772
+ */
773
+ public getHealth(): number {
774
+ const userAccount = this.getUserAccount();
775
+
776
+ if (
777
+ isVariant(userAccount.status, 'beingLiquidated') ||
778
+ isVariant(userAccount.status, 'bankrupt')
779
+ ) {
780
+ return 0;
781
+ }
782
+
783
+ const totalCollateral = this.getTotalCollateral('Maintenance');
784
+ const maintenanceMarginReq = this.getMaintenanceMarginRequirement();
785
+
786
+ let health: number;
787
+
788
+ if (maintenanceMarginReq.eq(ZERO) && totalCollateral.gte(ZERO)) {
789
+ health = 100;
790
+ } else if (totalCollateral.lte(ZERO)) {
791
+ health = 0;
792
+ } else {
793
+ // const totalCollateral = this.getTotalCollateral('Initial');
794
+ // const maintenanceMarginReq = this.getMaintenanceMarginRequirement();
795
+
796
+ const marginRatio =
797
+ this.getMarginRatio().toNumber() / MARGIN_PRECISION.toNumber();
798
+
799
+ const maintenanceRatio =
800
+ (maintenanceMarginReq.toNumber() / totalCollateral.toNumber()) *
801
+ marginRatio;
802
+
803
+ const healthP1 = Math.max(0, (marginRatio - maintenanceRatio) * 100) + 1;
804
+
805
+ health = Math.min(1, Math.log(healthP1) / Math.log(100)) * 100;
806
+ if (health > 1) {
807
+ health = Math.round(health);
808
+ } else {
809
+ health = Math.round(health * 100) / 100;
810
+ }
811
+ }
812
+
813
+ return health;
814
+ }
815
+
760
816
  /**
761
817
  * calculates sum of position value across all positions in margin system
762
818
  * @returns : Precision QUOTE_PRECISION
@@ -766,7 +822,7 @@ export class User {
766
822
  liquidationBuffer?: BN,
767
823
  includeOpenOrders?: boolean
768
824
  ): BN {
769
- return this.getUserAccount().perpPositions.reduce(
825
+ return this.getActivePerpPositions().reduce(
770
826
  (totalPerpValue, perpPosition) => {
771
827
  const market = this.driftClient.getPerpMarketAccount(
772
828
  perpPosition.marketIndex
@@ -955,15 +1011,20 @@ export class User {
955
1011
  return totalLiabilityValue.mul(TEN_THOUSAND).div(totalAssetValue);
956
1012
  }
957
1013
 
958
- getTotalLiabilityValue(): BN {
959
- return this.getTotalPerpPositionValue(undefined, undefined, true).add(
960
- this.getSpotMarketLiabilityValue(undefined, undefined, undefined, true)
1014
+ getTotalLiabilityValue(marginCategory?: MarginCategory): BN {
1015
+ return this.getTotalPerpPositionValue(marginCategory, undefined, true).add(
1016
+ this.getSpotMarketLiabilityValue(
1017
+ undefined,
1018
+ marginCategory,
1019
+ undefined,
1020
+ true
1021
+ )
961
1022
  );
962
1023
  }
963
1024
 
964
- getTotalAssetValue(): BN {
965
- return this.getSpotMarketAssetValue(undefined, undefined, true).add(
966
- this.getUnrealizedPNL(true, undefined, undefined)
1025
+ getTotalAssetValue(marginCategory?: MarginCategory): BN {
1026
+ return this.getSpotMarketAssetValue(undefined, marginCategory, true).add(
1027
+ this.getUnrealizedPNL(true, undefined, marginCategory)
967
1028
  );
968
1029
  }
969
1030
 
@@ -1008,14 +1069,14 @@ export class User {
1008
1069
  * calculates margin ratio: total collateral / |total position value|
1009
1070
  * @returns : Precision TEN_THOUSAND
1010
1071
  */
1011
- public getMarginRatio(): BN {
1012
- const totalLiabilityValue = this.getTotalLiabilityValue();
1072
+ public getMarginRatio(marginCategory?: MarginCategory): BN {
1073
+ const totalLiabilityValue = this.getTotalLiabilityValue(marginCategory);
1013
1074
 
1014
1075
  if (totalLiabilityValue.eq(ZERO)) {
1015
1076
  return BN_MAX;
1016
1077
  }
1017
1078
 
1018
- const totalAssetValue = this.getTotalAssetValue();
1079
+ const totalAssetValue = this.getTotalAssetValue(marginCategory);
1019
1080
 
1020
1081
  return totalAssetValue.mul(TEN_THOUSAND).div(totalLiabilityValue);
1021
1082
  }
@@ -1081,7 +1142,64 @@ export class User {
1081
1142
  }
1082
1143
 
1083
1144
  /**
1084
- * Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
1145
+ * Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
1146
+ * @param PerpPosition
1147
+ * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
1148
+ * @param partial
1149
+ * @returns Precision : PRICE_PRECISION
1150
+ */
1151
+ public spotLiquidationPrice(
1152
+ spotPosition: Pick<SpotPosition, 'marketIndex'>
1153
+ ): BN {
1154
+ const currentSpotPosition = this.getSpotPosition(spotPosition.marketIndex);
1155
+
1156
+ const mtc = this.getTotalCollateral('Maintenance');
1157
+ const mmr = this.getMaintenanceMarginRequirement();
1158
+
1159
+ const deltaValueToLiq = mtc.sub(mmr); // QUOTE_PRECISION
1160
+
1161
+ const currentSpotMarket = this.driftClient.getSpotMarketAccount(
1162
+ spotPosition.marketIndex
1163
+ );
1164
+ const tokenAmount = getTokenAmount(
1165
+ currentSpotPosition.scaledBalance,
1166
+ currentSpotMarket,
1167
+ currentSpotPosition.balanceType
1168
+ );
1169
+ const tokenAmountQP = tokenAmount
1170
+ .mul(QUOTE_PRECISION)
1171
+ .div(new BN(10 ** currentSpotMarket.decimals));
1172
+
1173
+ if (tokenAmountQP.abs().eq(ZERO)) {
1174
+ return new BN(-1);
1175
+ }
1176
+ let liqPriceDelta: BN;
1177
+ if (isVariant(currentSpotPosition.balanceType, 'borrow')) {
1178
+ liqPriceDelta = deltaValueToLiq
1179
+ .mul(PRICE_PRECISION)
1180
+ .mul(SPOT_MARKET_WEIGHT_PRECISION)
1181
+ .div(tokenAmountQP)
1182
+ .div(new BN(currentSpotMarket.maintenanceLiabilityWeight));
1183
+ } else {
1184
+ liqPriceDelta = deltaValueToLiq
1185
+ .mul(PRICE_PRECISION)
1186
+ .mul(SPOT_MARKET_WEIGHT_PRECISION)
1187
+ .div(tokenAmountQP)
1188
+ .div(new BN(currentSpotMarket.maintenanceAssetWeight))
1189
+ .mul(new BN(-1));
1190
+ }
1191
+
1192
+ const currentPrice = this.driftClient.getOracleDataForSpotMarket(
1193
+ spotPosition.marketIndex
1194
+ ).price;
1195
+
1196
+ const liqPrice = currentPrice.add(liqPriceDelta);
1197
+
1198
+ return liqPrice;
1199
+ }
1200
+
1201
+ /**
1202
+ * Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
1085
1203
  * @param PerpPosition
1086
1204
  * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
1087
1205
  * @param partial
@@ -5,14 +5,6 @@ import {
5
5
  bulkPollingUserSubscribe,
6
6
  OrderRecord,
7
7
  UserSubscriptionConfig,
8
- WrappedEvent,
9
- DepositRecord,
10
- FundingPaymentRecord,
11
- LiquidationRecord,
12
- OrderActionRecord,
13
- SettlePnlRecord,
14
- NewUserRecord,
15
- LPRecord,
16
8
  } from '..';
17
9
  import { ProgramAccount } from '@project-serum/anchor';
18
10
 
@@ -128,42 +120,6 @@ export class UserMap implements UserMapInterface {
128
120
  }
129
121
  }
130
122
 
131
- public async updateWithEventRecord(record: WrappedEvent<any>) {
132
- if (record.eventType === 'DepositRecord') {
133
- const depositRecord = record as DepositRecord;
134
- await this.mustGet(depositRecord.user.toString());
135
- } else if (record.eventType === 'FundingPaymentRecord') {
136
- const fundingPaymentRecord = record as FundingPaymentRecord;
137
- await this.mustGet(fundingPaymentRecord.user.toString());
138
- } else if (record.eventType === 'LiquidationRecord') {
139
- const liqRecord = record as LiquidationRecord;
140
-
141
- await this.mustGet(liqRecord.user.toString());
142
- await this.mustGet(liqRecord.liquidator.toString());
143
- } else if (record.eventType === 'OrderRecord') {
144
- const orderRecord = record as OrderRecord;
145
- await this.updateWithOrderRecord(orderRecord);
146
- } else if (record.eventType === 'OrderActionRecord') {
147
- const actionRecord = record as OrderActionRecord;
148
-
149
- if (actionRecord.taker) {
150
- await this.mustGet(actionRecord.taker.toString());
151
- }
152
- if (actionRecord.maker) {
153
- await this.mustGet(actionRecord.maker.toString());
154
- }
155
- } else if (record.eventType === 'SettlePnlRecord') {
156
- const settlePnlRecord = record as SettlePnlRecord;
157
- await this.mustGet(settlePnlRecord.user.toString());
158
- } else if (record.eventType === 'NewUserRecord') {
159
- const newUserRecord = record as NewUserRecord;
160
- await this.mustGet(newUserRecord.user.toString());
161
- } else if (record.eventType === 'LPRecord') {
162
- const lpRecord = record as LPRecord;
163
- await this.mustGet(lpRecord.user.toString());
164
- }
165
- }
166
-
167
123
  public values(): IterableIterator<User> {
168
124
  return this.userMap.values();
169
125
  }