@drift-labs/sdk 2.149.0-beta.0 → 2.149.0-beta.1

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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.149.0-beta.0
1
+ 2.149.0-beta.1
@@ -0,0 +1,79 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@coral-xyz/anchor';
3
+ import { MarketType } from './types';
4
+ export type MarginCategory = 'Initial' | 'Maintenance' | 'Fill';
5
+ export type MarginCalculationMode = {
6
+ type: 'Standard';
7
+ } | {
8
+ type: 'Liquidation';
9
+ };
10
+ export declare class MarketIdentifier {
11
+ marketType: MarketType;
12
+ marketIndex: number;
13
+ private constructor();
14
+ static spot(marketIndex: number): MarketIdentifier;
15
+ static perp(marketIndex: number): MarketIdentifier;
16
+ equals(other: MarketIdentifier | undefined): boolean;
17
+ }
18
+ export declare class MarginContext {
19
+ marginType: MarginCategory;
20
+ mode: MarginCalculationMode;
21
+ strict: boolean;
22
+ ignoreInvalidDepositOracles: boolean;
23
+ isolatedMarginBuffers: Map<number, BN>;
24
+ crossMarginBuffer: BN;
25
+ private constructor();
26
+ static standard(marginType: MarginCategory): MarginContext;
27
+ static liquidation(crossMarginBuffer: BN, isolatedMarginBuffers: Map<number, BN>): MarginContext;
28
+ strictMode(strict: boolean): this;
29
+ ignoreInvalidDeposits(ignore: boolean): this;
30
+ setCrossMarginBuffer(crossMarginBuffer: BN): this;
31
+ setIsolatedMarginBuffers(isolatedMarginBuffers: Map<number, BN>): this;
32
+ setIsolatedMarginBuffer(marketIndex: number, isolatedMarginBuffer: BN): this;
33
+ }
34
+ export declare class IsolatedMarginCalculation {
35
+ marginRequirement: BN;
36
+ totalCollateral: BN;
37
+ totalCollateralBuffer: BN;
38
+ marginRequirementPlusBuffer: BN;
39
+ constructor();
40
+ getTotalCollateralPlusBuffer(): BN;
41
+ meetsMarginRequirement(): boolean;
42
+ meetsMarginRequirementWithBuffer(): boolean;
43
+ marginShortage(): BN;
44
+ }
45
+ export declare class MarginCalculation {
46
+ context: MarginContext;
47
+ totalCollateral: BN;
48
+ totalCollateralBuffer: BN;
49
+ marginRequirement: BN;
50
+ marginRequirementPlusBuffer: BN;
51
+ isolatedMarginCalculations: Map<number, IsolatedMarginCalculation>;
52
+ allDepositOraclesValid: boolean;
53
+ allLiabilityOraclesValid: boolean;
54
+ withPerpIsolatedLiability: boolean;
55
+ withSpotIsolatedLiability: boolean;
56
+ totalPerpLiabilityValue: BN;
57
+ trackedMarketMarginRequirement: BN;
58
+ fuelDeposits: number;
59
+ fuelBorrows: number;
60
+ fuelPositions: number;
61
+ constructor(context: MarginContext);
62
+ addCrossMarginTotalCollateral(delta: BN): void;
63
+ addCrossMarginRequirement(marginRequirement: BN, liabilityValue: BN): void;
64
+ addIsolatedMarginCalculation(marketIndex: number, depositValue: BN, pnl: BN, liabilityValue: BN, marginRequirement: BN): void;
65
+ addPerpLiabilityValue(perpLiabilityValue: BN): void;
66
+ updateAllDepositOraclesValid(valid: boolean): void;
67
+ updateAllLiabilityOraclesValid(valid: boolean): void;
68
+ updateWithSpotIsolatedLiability(isolated: boolean): void;
69
+ updateWithPerpIsolatedLiability(isolated: boolean): void;
70
+ getCrossTotalCollateralPlusBuffer(): BN;
71
+ meetsCrossMarginRequirement(): boolean;
72
+ meetsCrossMarginRequirementWithBuffer(): boolean;
73
+ meetsMarginRequirement(): boolean;
74
+ meetsMarginRequirementWithBuffer(): boolean;
75
+ getCrossFreeCollateral(): BN;
76
+ getIsolatedFreeCollateral(marketIndex: number): BN;
77
+ getIsolatedMarginCalculation(marketIndex: number): IsolatedMarginCalculation | undefined;
78
+ hasIsolatedMarginCalculation(marketIndex: number): boolean;
79
+ }
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarginCalculation = exports.IsolatedMarginCalculation = exports.MarginContext = exports.MarketIdentifier = void 0;
4
+ const numericConstants_1 = require("./constants/numericConstants");
5
+ const types_1 = require("./types");
6
+ class MarketIdentifier {
7
+ constructor(marketType, marketIndex) {
8
+ this.marketType = marketType;
9
+ this.marketIndex = marketIndex;
10
+ }
11
+ static spot(marketIndex) {
12
+ return new MarketIdentifier(types_1.MarketType.SPOT, marketIndex);
13
+ }
14
+ static perp(marketIndex) {
15
+ return new MarketIdentifier(types_1.MarketType.PERP, marketIndex);
16
+ }
17
+ equals(other) {
18
+ return (!!other &&
19
+ (0, types_1.isVariant)(this.marketType, (0, types_1.getVariant)(other.marketType)) &&
20
+ this.marketIndex === other.marketIndex);
21
+ }
22
+ }
23
+ exports.MarketIdentifier = MarketIdentifier;
24
+ class MarginContext {
25
+ constructor(marginType) {
26
+ this.marginType = marginType;
27
+ this.mode = { type: 'Standard' };
28
+ this.strict = false;
29
+ this.ignoreInvalidDepositOracles = false;
30
+ this.isolatedMarginBuffers = new Map();
31
+ }
32
+ static standard(marginType) {
33
+ return new MarginContext(marginType);
34
+ }
35
+ static liquidation(crossMarginBuffer, isolatedMarginBuffers) {
36
+ const ctx = new MarginContext('Maintenance');
37
+ ctx.mode = { type: 'Liquidation' };
38
+ ctx.crossMarginBuffer = crossMarginBuffer;
39
+ ctx.isolatedMarginBuffers = isolatedMarginBuffers;
40
+ return ctx;
41
+ }
42
+ strictMode(strict) {
43
+ this.strict = strict;
44
+ return this;
45
+ }
46
+ ignoreInvalidDeposits(ignore) {
47
+ this.ignoreInvalidDepositOracles = ignore;
48
+ return this;
49
+ }
50
+ setCrossMarginBuffer(crossMarginBuffer) {
51
+ this.crossMarginBuffer = crossMarginBuffer;
52
+ return this;
53
+ }
54
+ setIsolatedMarginBuffers(isolatedMarginBuffers) {
55
+ this.isolatedMarginBuffers = isolatedMarginBuffers;
56
+ return this;
57
+ }
58
+ setIsolatedMarginBuffer(marketIndex, isolatedMarginBuffer) {
59
+ this.isolatedMarginBuffers.set(marketIndex, isolatedMarginBuffer);
60
+ return this;
61
+ }
62
+ }
63
+ exports.MarginContext = MarginContext;
64
+ class IsolatedMarginCalculation {
65
+ constructor() {
66
+ this.marginRequirement = numericConstants_1.ZERO;
67
+ this.totalCollateral = numericConstants_1.ZERO;
68
+ this.totalCollateralBuffer = numericConstants_1.ZERO;
69
+ this.marginRequirementPlusBuffer = numericConstants_1.ZERO;
70
+ }
71
+ getTotalCollateralPlusBuffer() {
72
+ return this.totalCollateral.add(this.totalCollateralBuffer);
73
+ }
74
+ meetsMarginRequirement() {
75
+ return this.totalCollateral.gte(this.marginRequirement);
76
+ }
77
+ meetsMarginRequirementWithBuffer() {
78
+ return this.getTotalCollateralPlusBuffer().gte(this.marginRequirementPlusBuffer);
79
+ }
80
+ marginShortage() {
81
+ const shortage = this.marginRequirementPlusBuffer.sub(this.getTotalCollateralPlusBuffer());
82
+ return shortage.isNeg() ? numericConstants_1.ZERO : shortage;
83
+ }
84
+ }
85
+ exports.IsolatedMarginCalculation = IsolatedMarginCalculation;
86
+ class MarginCalculation {
87
+ constructor(context) {
88
+ this.context = context;
89
+ this.totalCollateral = numericConstants_1.ZERO;
90
+ this.totalCollateralBuffer = numericConstants_1.ZERO;
91
+ this.marginRequirement = numericConstants_1.ZERO;
92
+ this.marginRequirementPlusBuffer = numericConstants_1.ZERO;
93
+ this.isolatedMarginCalculations = new Map();
94
+ this.allDepositOraclesValid = true;
95
+ this.allLiabilityOraclesValid = true;
96
+ this.withPerpIsolatedLiability = false;
97
+ this.withSpotIsolatedLiability = false;
98
+ this.totalPerpLiabilityValue = numericConstants_1.ZERO;
99
+ this.trackedMarketMarginRequirement = numericConstants_1.ZERO;
100
+ this.fuelDeposits = 0;
101
+ this.fuelBorrows = 0;
102
+ this.fuelPositions = 0;
103
+ }
104
+ addCrossMarginTotalCollateral(delta) {
105
+ const crossMarginBuffer = this.context.crossMarginBuffer;
106
+ this.totalCollateral = this.totalCollateral.add(delta);
107
+ if (crossMarginBuffer.gt(numericConstants_1.ZERO) && delta.isNeg()) {
108
+ this.totalCollateralBuffer = this.totalCollateralBuffer.add(delta.mul(crossMarginBuffer).div(numericConstants_1.MARGIN_PRECISION));
109
+ }
110
+ }
111
+ addCrossMarginRequirement(marginRequirement, liabilityValue) {
112
+ const crossMarginBuffer = this.context.crossMarginBuffer;
113
+ this.marginRequirement = this.marginRequirement.add(marginRequirement);
114
+ if (crossMarginBuffer.gt(numericConstants_1.ZERO)) {
115
+ this.marginRequirementPlusBuffer = this.marginRequirementPlusBuffer.add(marginRequirement.add(liabilityValue.mul(crossMarginBuffer).div(numericConstants_1.MARGIN_PRECISION)));
116
+ }
117
+ }
118
+ addIsolatedMarginCalculation(marketIndex, depositValue, pnl, liabilityValue, marginRequirement) {
119
+ var _a;
120
+ const totalCollateral = depositValue.add(pnl);
121
+ const isolatedMarginBuffer = (_a = this.context.isolatedMarginBuffers.get(marketIndex)) !== null && _a !== void 0 ? _a : numericConstants_1.ZERO;
122
+ const totalCollateralBuffer = isolatedMarginBuffer.gt(numericConstants_1.ZERO) && pnl.isNeg()
123
+ ? pnl.mul(isolatedMarginBuffer).div(numericConstants_1.MARGIN_PRECISION)
124
+ : numericConstants_1.ZERO;
125
+ const marginRequirementPlusBuffer = isolatedMarginBuffer.gt(numericConstants_1.ZERO)
126
+ ? marginRequirement.add(liabilityValue.mul(isolatedMarginBuffer).div(numericConstants_1.MARGIN_PRECISION))
127
+ : marginRequirement;
128
+ const iso = new IsolatedMarginCalculation();
129
+ iso.marginRequirement = marginRequirement;
130
+ iso.totalCollateral = totalCollateral;
131
+ iso.totalCollateralBuffer = totalCollateralBuffer;
132
+ iso.marginRequirementPlusBuffer = marginRequirementPlusBuffer;
133
+ this.isolatedMarginCalculations.set(marketIndex, iso);
134
+ }
135
+ addPerpLiabilityValue(perpLiabilityValue) {
136
+ this.totalPerpLiabilityValue =
137
+ this.totalPerpLiabilityValue.add(perpLiabilityValue);
138
+ }
139
+ updateAllDepositOraclesValid(valid) {
140
+ this.allDepositOraclesValid = this.allDepositOraclesValid && valid;
141
+ }
142
+ updateAllLiabilityOraclesValid(valid) {
143
+ this.allLiabilityOraclesValid = this.allLiabilityOraclesValid && valid;
144
+ }
145
+ updateWithSpotIsolatedLiability(isolated) {
146
+ this.withSpotIsolatedLiability = this.withSpotIsolatedLiability || isolated;
147
+ }
148
+ updateWithPerpIsolatedLiability(isolated) {
149
+ this.withPerpIsolatedLiability = this.withPerpIsolatedLiability || isolated;
150
+ }
151
+ getCrossTotalCollateralPlusBuffer() {
152
+ return this.totalCollateral.add(this.totalCollateralBuffer);
153
+ }
154
+ meetsCrossMarginRequirement() {
155
+ return this.totalCollateral.gte(this.marginRequirement);
156
+ }
157
+ meetsCrossMarginRequirementWithBuffer() {
158
+ return this.getCrossTotalCollateralPlusBuffer().gte(this.marginRequirementPlusBuffer);
159
+ }
160
+ meetsMarginRequirement() {
161
+ if (!this.meetsCrossMarginRequirement())
162
+ return false;
163
+ for (const [, iso] of this.isolatedMarginCalculations) {
164
+ if (!iso.meetsMarginRequirement())
165
+ return false;
166
+ }
167
+ return true;
168
+ }
169
+ meetsMarginRequirementWithBuffer() {
170
+ if (!this.meetsCrossMarginRequirementWithBuffer())
171
+ return false;
172
+ for (const [, iso] of this.isolatedMarginCalculations) {
173
+ if (!iso.meetsMarginRequirementWithBuffer())
174
+ return false;
175
+ }
176
+ return true;
177
+ }
178
+ getCrossFreeCollateral() {
179
+ const free = this.totalCollateral.sub(this.marginRequirement);
180
+ return free.isNeg() ? numericConstants_1.ZERO : free;
181
+ }
182
+ getIsolatedFreeCollateral(marketIndex) {
183
+ const iso = this.isolatedMarginCalculations.get(marketIndex);
184
+ if (!iso)
185
+ throw new Error('InvalidMarginCalculation: missing isolated calc');
186
+ const free = iso.totalCollateral.sub(iso.marginRequirement);
187
+ return free.isNeg() ? numericConstants_1.ZERO : free;
188
+ }
189
+ getIsolatedMarginCalculation(marketIndex) {
190
+ return this.isolatedMarginCalculations.get(marketIndex);
191
+ }
192
+ hasIsolatedMarginCalculation(marketIndex) {
193
+ return this.isolatedMarginCalculations.has(marketIndex);
194
+ }
195
+ }
196
+ exports.MarginCalculation = MarginCalculation;
@@ -19,7 +19,7 @@ export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosi
19
19
  */
20
20
  export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: Pick<OraclePriceData, 'price'>, includeOpenOrders?: boolean): BN;
21
21
  export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): BN;
22
- export declare function calculateWorstCasePerpLiabilityValue(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): {
22
+ export declare function calculateWorstCasePerpLiabilityValue(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN, includeOpenOrders?: boolean): {
23
23
  worstCaseBaseAssetAmount: BN;
24
24
  worstCaseLiabilityValue: BN;
25
25
  };
@@ -89,10 +89,16 @@ function calculateWorstCaseBaseAssetAmount(perpPosition, perpMarket, oraclePrice
89
89
  return calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice).worstCaseBaseAssetAmount;
90
90
  }
91
91
  exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
92
- function calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice) {
92
+ function calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice, includeOpenOrders = true) {
93
+ const isPredictionMarket = (0, types_1.isVariant)(perpMarket.contractType, 'prediction');
94
+ if (!includeOpenOrders) {
95
+ return {
96
+ worstCaseBaseAssetAmount: perpPosition.baseAssetAmount,
97
+ worstCaseLiabilityValue: calculatePerpLiabilityValue(perpPosition.baseAssetAmount, oraclePrice, isPredictionMarket),
98
+ };
99
+ }
93
100
  const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
94
101
  const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
95
- const isPredictionMarket = (0, types_1.isVariant)(perpMarket.contractType, 'prediction');
96
102
  const allBidsLiabilityValue = calculatePerpLiabilityValue(allBids, oraclePrice, isPredictionMarket);
97
103
  const allAsksLiabilityValue = calculatePerpLiabilityValue(allAsks, oraclePrice, isPredictionMarket);
98
104
  if (allAsksLiabilityValue.gte(allBidsLiabilityValue)) {
@@ -11,7 +11,7 @@ export type OrderFillSimulation = {
11
11
  weightedTokenValue: BN;
12
12
  freeCollateralContribution: any;
13
13
  };
14
- export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory, customMarginRatio?: number): OrderFillSimulation;
14
+ export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory, customMarginRatio?: number, includeOpenOrders?: boolean): OrderFillSimulation;
15
15
  export declare function calculateWeightedTokenValue(tokenAmount: BN, tokenValue: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory, customMarginRatio?: number): {
16
16
  weight: BN;
17
17
  weightedTokenValue: BN;
@@ -8,10 +8,11 @@ function isSpotPositionAvailable(position) {
8
8
  return position.scaledBalance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
9
9
  }
10
10
  exports.isSpotPositionAvailable = isSpotPositionAvailable;
11
- function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, customMarginRatio) {
11
+ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, customMarginRatio, includeOpenOrders = true) {
12
12
  const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
13
13
  const tokenValue = (0, spotBalance_1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
14
- if (spotPosition.openBids.eq(numericConstants_1.ZERO) && spotPosition.openAsks.eq(numericConstants_1.ZERO)) {
14
+ if ((spotPosition.openBids.eq(numericConstants_1.ZERO) && spotPosition.openAsks.eq(numericConstants_1.ZERO)) ||
15
+ !includeOpenOrders) {
15
16
  const { weight, weightedTokenValue } = calculateWeightedTokenValue(tokenAmount, tokenValue, strictOraclePrice.current, spotMarketAccount, marginCategory, customMarginRatio);
16
17
  return {
17
18
  tokenAmount,
@@ -1195,6 +1195,11 @@ export type PerpPosition = {
1195
1195
  isolatedPositionScaledBalance: BN;
1196
1196
  positionFlag: number;
1197
1197
  };
1198
+ export declare class PositionFlag {
1199
+ static readonly IsolatedPosition = 1;
1200
+ static readonly BeingLiquidated = 2;
1201
+ static readonly Bankruptcy = 4;
1202
+ }
1198
1203
  export type UserStatsAccount = {
1199
1204
  numberOfSubAccounts: number;
1200
1205
  numberOfSubAccountsCreated: number;
@@ -1860,4 +1865,9 @@ export type CacheInfo = {
1860
1865
  export type AmmCache = {
1861
1866
  cache: CacheInfo[];
1862
1867
  };
1868
+ export type AccountLiquidatableStatus = {
1869
+ canBeLiquidated: boolean;
1870
+ marginRequirement: BN;
1871
+ totalCollateral: BN;
1872
+ };
1863
1873
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConstituentLpOperation = exports.ConstituentStatus = exports.OracleValidity = exports.SwapReduceOnly = exports.PlaceAndTakeOrderSuccessCondition = exports.FuelOverflowStatus = exports.ReferrerStatus = exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.OrderParamsBitFlag = exports.PostOnlyParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.SettlePnlMode = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderBitFlag = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSourceNum = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.TokenProgramFlag = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.MarginMode = exports.UserStatus = exports.InsuranceFundOperation = exports.SpotOperation = exports.PerpOperation = exports.MarketStatus = exports.FeatureBitFlags = exports.ExchangeStatus = void 0;
3
+ exports.ConstituentLpOperation = exports.ConstituentStatus = exports.OracleValidity = exports.SwapReduceOnly = exports.PlaceAndTakeOrderSuccessCondition = exports.FuelOverflowStatus = exports.ReferrerStatus = exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.OrderParamsBitFlag = exports.PostOnlyParams = exports.PositionFlag = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.SettlePnlMode = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderBitFlag = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSourceNum = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.TokenProgramFlag = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.MarginMode = exports.UserStatus = exports.InsuranceFundOperation = exports.SpotOperation = exports.PerpOperation = exports.MarketStatus = exports.FeatureBitFlags = exports.ExchangeStatus = void 0;
4
4
  const numericConstants_1 = require("./constants/numericConstants");
5
5
  // # Utility Types / Enums / Constants
6
6
  var ExchangeStatus;
@@ -353,6 +353,12 @@ LiquidationType.SPOT_BANKRUPTCY = {
353
353
  LiquidationType.LIQUIDATE_SPOT = {
354
354
  liquidateSpot: {},
355
355
  };
356
+ class PositionFlag {
357
+ }
358
+ exports.PositionFlag = PositionFlag;
359
+ PositionFlag.IsolatedPosition = 1;
360
+ PositionFlag.BeingLiquidated = 2;
361
+ PositionFlag.Bankruptcy = 4;
356
362
  class PostOnlyParams {
357
363
  }
358
364
  exports.PostOnlyParams = PostOnlyParams;
@@ -4,7 +4,7 @@ import { PublicKey } from '@solana/web3.js';
4
4
  import { EventEmitter } from 'events';
5
5
  import StrictEventEmitter from 'strict-event-emitter-types';
6
6
  import { DriftClient } from './driftClient';
7
- import { HealthComponent, HealthComponents, MarginCategory, Order, PerpMarketAccount, PerpPosition, SpotPosition, UserAccount, UserStatus } from './types';
7
+ import { HealthComponent, HealthComponents, MarginCategory, Order, PerpMarketAccount, PerpPosition, SpotPosition, UserAccount, UserStatus, AccountLiquidatableStatus } from './types';
8
8
  import { DataAndSlot, UserAccountEvents, UserAccountSubscriber } from './accounts/types';
9
9
  import { BN } from '@coral-xyz/anchor';
10
10
  import { MarketType, PositionDirection, SpotMarketAccount } from './types';
@@ -12,6 +12,8 @@ import { UserStats } from './userStats';
12
12
  import { OraclePriceData } from './oracles/types';
13
13
  import { UserConfig } from './userConfig';
14
14
  import { StrictOraclePrice } from './oracles/strictOraclePrice';
15
+ import { IsolatedMarginCalculation, MarginCalculation } from './marginCalculation';
16
+ export type MarginType = 'Cross' | 'Isolated';
15
17
  export declare class User {
16
18
  driftClient: DriftClient;
17
19
  userAccountPublicKey: PublicKey;
@@ -60,6 +62,7 @@ export declare class User {
60
62
  */
61
63
  getTokenAmount(marketIndex: number): BN;
62
64
  getEmptyPosition(marketIndex: number): PerpPosition;
65
+ getIsolatePerpPositionTokenAmount(perpMarketIndex: number): BN;
63
66
  getClonedPosition(position: PerpPosition): PerpPosition;
64
67
  getOrderForUserAccount(userAccount: UserAccount, orderId: number): Order | undefined;
65
68
  /**
@@ -96,19 +99,32 @@ export declare class User {
96
99
  * calculates Free Collateral = Total collateral - margin requirement
97
100
  * @returns : Precision QUOTE_PRECISION
98
101
  */
99
- getFreeCollateral(marginCategory?: MarginCategory, enterHighLeverageMode?: any): BN;
102
+ getFreeCollateral(marginCategory?: MarginCategory, enterHighLeverageMode?: boolean, perpMarketIndex?: number): BN;
100
103
  /**
101
- * @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
104
+ * @deprecated Use the overload that includes { marginType, perpMarketIndex }
102
105
  */
103
- getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean, includeOpenOrders?: boolean, enteringHighLeverage?: any): BN;
106
+ getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean, includeOpenOrders?: boolean, enteringHighLeverage?: boolean): BN;
107
+ /**
108
+ * Calculates the margin requirement based on the specified parameters.
109
+ *
110
+ * @param marginCategory - The category of margin to calculate ('Initial' or 'Maintenance').
111
+ * @param liquidationBuffer - Optional buffer amount to consider during liquidation scenarios.
112
+ * @param strict - Optional flag to enforce strict margin calculations.
113
+ * @param includeOpenOrders - Optional flag to include open orders in the margin calculation.
114
+ * @param enteringHighLeverage - Optional flag indicating if the user is entering high leverage mode.
115
+ * @param perpMarketIndex - Optional index of the perpetual market. Required if marginType is 'Isolated'.
116
+ *
117
+ * @returns The calculated margin requirement as a BN (BigNumber).
118
+ */
119
+ getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean, includeOpenOrders?: boolean, enteringHighLeverage?: boolean, perpMarketIndex?: number): BN;
104
120
  /**
105
121
  * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
106
122
  */
107
- getInitialMarginRequirement(enterHighLeverageMode?: any): BN;
123
+ getInitialMarginRequirement(enterHighLeverageMode?: boolean, perpMarketIndex?: number): BN;
108
124
  /**
109
125
  * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
110
126
  */
111
- getMaintenanceMarginRequirement(liquidationBuffer?: BN): BN;
127
+ getMaintenanceMarginRequirement(liquidationBuffer?: BN, perpMarketIndex?: number): BN;
112
128
  getActivePerpPositionsForUserAccount(userAccount: UserAccount): PerpPosition[];
113
129
  getActivePerpPositions(): PerpPosition[];
114
130
  getActivePerpPositionsAndSlot(): DataAndSlot<PerpPosition[]>;
@@ -147,13 +163,13 @@ export declare class User {
147
163
  * calculates TotalCollateral: collateral + unrealized pnl
148
164
  * @returns : Precision QUOTE_PRECISION
149
165
  */
150
- getTotalCollateral(marginCategory?: MarginCategory, strict?: boolean, includeOpenOrders?: boolean, liquidationBuffer?: BN): BN;
151
- getLiquidationBuffer(): BN | undefined;
166
+ getTotalCollateral(marginCategory?: MarginCategory, strict?: boolean, includeOpenOrders?: boolean, liquidationBuffer?: BN, perpMarketIndex?: number): BN;
167
+ getLiquidationBuffer(): Map<number | 'cross', BN>;
152
168
  /**
153
169
  * calculates User Health by comparing total collateral and maint. margin requirement
154
170
  * @returns : number (value from [0, 100])
155
171
  */
156
- getHealth(): number;
172
+ getHealth(perpMarketIndex?: number): number;
157
173
  calculateWeightedPerpPositionLiability(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, enteringHighLeverage?: any): BN;
158
174
  /**
159
175
  * calculates position value of a single perp market in margin system
@@ -185,14 +201,14 @@ export declare class User {
185
201
  * calculates current user leverage which is (total liability size) / (net asset value)
186
202
  * @returns : Precision TEN_THOUSAND
187
203
  */
188
- getLeverage(includeOpenOrders?: boolean): BN;
204
+ getLeverage(includeOpenOrders?: boolean, perpMarketIndex?: number): BN;
189
205
  calculateLeverageFromComponents({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }: {
190
206
  perpLiabilityValue: BN;
191
207
  perpPnl: BN;
192
208
  spotAssetValue: BN;
193
209
  spotLiabilityValue: BN;
194
210
  }): BN;
195
- getLeverageComponents(includeOpenOrders?: boolean, marginCategory?: MarginCategory): {
211
+ getLeverageComponents(includeOpenOrders?: boolean, marginCategory?: MarginCategory, perpMarketIndex?: number): {
196
212
  perpLiabilityValue: BN;
197
213
  perpPnl: BN;
198
214
  spotAssetValue: BN;
@@ -230,12 +246,25 @@ export declare class User {
230
246
  * @returns : Precision TEN_THOUSAND
231
247
  */
232
248
  getMarginRatio(): BN;
233
- canBeLiquidated(): {
234
- canBeLiquidated: boolean;
235
- marginRequirement: BN;
236
- totalCollateral: BN;
249
+ canBeLiquidated(): AccountLiquidatableStatus & {
250
+ isolatedPositions: Map<number, AccountLiquidatableStatus>;
237
251
  };
252
+ /**
253
+ * New API: Returns liquidation status for cross and each isolated perp position.
254
+ * Map keys:
255
+ * - 'cross' for cross margin
256
+ * - marketIndex (number) for each isolated perp position
257
+ */
258
+ getLiquidationStatuses(marginCalc?: MarginCalculation): Map<'cross' | number, AccountLiquidatableStatus>;
238
259
  isBeingLiquidated(): boolean;
260
+ isCrossMarginBeingLiquidated(): boolean;
261
+ /** Returns true if cross margin is currently below maintenance requirement (no buffer). */
262
+ canCrossMarginBeLiquidated(marginCalc?: MarginCalculation): boolean;
263
+ hasIsolatedPositionBeingLiquidated(): boolean;
264
+ isIsolatedPositionBeingLiquidated(perpMarketIndex: number): boolean;
265
+ /** Returns true if any isolated perp position is currently below its maintenance requirement (no buffer). */
266
+ getLiquidatableIsolatedPositions(marginCalc?: MarginCalculation): number[];
267
+ canIsolatedPositionMarginBeLiquidated(isolatedMarginCalculation: IsolatedMarginCalculation): boolean;
239
268
  hasStatus(status: UserStatus): boolean;
240
269
  isBankrupt(): boolean;
241
270
  isHighLeverageMode(marginCategory: MarginCategory): boolean;
@@ -260,7 +289,7 @@ export declare class User {
260
289
  * @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
261
290
  * @returns Precision : PRICE_PRECISION
262
291
  */
263
- liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean, offsetCollateral?: BN, enteringHighLeverage?: any): BN;
292
+ liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean, offsetCollateral?: BN, enteringHighLeverage?: boolean, marginType?: MarginType): BN;
264
293
  calculateEntriesEffectOnFreeCollateral(market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN, includeOpenOrders: boolean, enteringHighLeverage?: any, marginCategory?: MarginCategory): BN;
265
294
  calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, oraclePrice: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean, enteringHighLeverage?: any): BN | undefined;
266
295
  calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory): BN;
@@ -395,4 +424,15 @@ export declare class User {
395
424
  activePerpPositions: number[];
396
425
  activeSpotPositions: number[];
397
426
  };
427
+ /**
428
+ * Compute a consolidated margin snapshot once, without caching.
429
+ * Consumers can use this to avoid duplicating work across separate calls.
430
+ */
431
+ getMarginCalculation(marginCategory?: MarginCategory, opts?: {
432
+ strict?: boolean;
433
+ includeOpenOrders?: boolean;
434
+ enteringHighLeverage?: boolean;
435
+ liquidationBufferMap?: Map<number | 'cross', BN>;
436
+ }): MarginCalculation;
437
+ private isPerpPositionIsolated;
398
438
  }