///
///
import { PublicKey } from '@solana/web3.js';
import { EventEmitter } from 'events';
import StrictEventEmitter from 'strict-event-emitter-types';
import { DriftClient } from './driftClient';
import { HealthComponents, MarginCategory, Order, PerpMarketAccount, PerpPosition, SpotPosition, UserAccount } from './types';
import { DataAndSlot, UserAccountEvents, UserAccountSubscriber } from './accounts/types';
import { BN, MarketType, PositionDirection, SpotMarketAccount } from '.';
import { OraclePriceData } from './oracles/types';
import { UserConfig } from './userConfig';
import { StrictOraclePrice } from './oracles/strictOraclePrice';
export declare class User {
driftClient: DriftClient;
userAccountPublicKey: PublicKey;
accountSubscriber: UserAccountSubscriber;
_isSubscribed: boolean;
eventEmitter: StrictEventEmitter;
get isSubscribed(): boolean;
set isSubscribed(val: boolean);
constructor(config: UserConfig);
/**
* Subscribe to User state accounts
* @returns SusbcriptionSuccess result
*/
subscribe(userAccount?: UserAccount): Promise;
/**
* Forces the accountSubscriber to fetch account updates from rpc
*/
fetchAccounts(): Promise;
unsubscribe(): Promise;
getUserAccount(): UserAccount;
forceGetUserAccount(): Promise;
getUserAccountAndSlot(): DataAndSlot | undefined;
getPerpPositionForUserAccount(userAccount: UserAccount, marketIndex: number): PerpPosition | undefined;
/**
* Gets the user's current position for a given perp market. If the user has no position returns undefined
* @param marketIndex
* @returns userPerpPosition
*/
getPerpPosition(marketIndex: number): PerpPosition | undefined;
getPerpPositionAndSlot(marketIndex: number): DataAndSlot;
getSpotPositionForUserAccount(userAccount: UserAccount, marketIndex: number): SpotPosition | undefined;
/**
* Gets the user's current position for a given spot market. If the user has no position returns undefined
* @param marketIndex
* @returns userSpotPosition
*/
getSpotPosition(marketIndex: number): SpotPosition | undefined;
getSpotPositionAndSlot(marketIndex: number): DataAndSlot;
getEmptySpotPosition(marketIndex: number): SpotPosition;
/**
* Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
* Positive if it is a deposit, negative if it is a borrow.
*
* @param marketIndex
*/
getTokenAmount(marketIndex: number): BN;
getEmptyPosition(marketIndex: number): PerpPosition;
getClonedPosition(position: PerpPosition): PerpPosition;
getOrderForUserAccount(userAccount: UserAccount, orderId: number): Order | undefined;
/**
* @param orderId
* @returns Order
*/
getOrder(orderId: number): Order | undefined;
getOrderAndSlot(orderId: number): DataAndSlot;
getOrderByUserIdForUserAccount(userAccount: UserAccount, userOrderId: number): Order | undefined;
/**
* @param userOrderId
* @returns Order
*/
getOrderByUserOrderId(userOrderId: number): Order | undefined;
getOrderByUserOrderIdAndSlot(userOrderId: number): DataAndSlot;
getOpenOrdersForUserAccount(userAccount?: UserAccount): Order[];
getOpenOrders(): Order[];
getOpenOrdersAndSlot(): DataAndSlot;
getUserAccountPublicKey(): PublicKey;
exists(): Promise;
/**
* calculates the total open bids/asks in a perp market (including lps)
* @returns : open bids
* @returns : open asks
*/
getPerpBidAsks(marketIndex: number): [BN, BN];
/**
* calculates the open bids and asks for an lp
* optionally pass in lpShares to see what bid/asks a user *would* take on
* @returns : lp open bids
* @returns : lp open asks
*/
getLPBidAsks(marketIndex: number, lpShares?: BN): [BN, BN];
/**
* calculates the market position if the lp position was settled
* @returns : the settled userPosition
* @returns : the dust base asset amount (ie, < stepsize)
* @returns : pnl from settle
*/
getPerpPositionWithLPSettle(marketIndex: number, originalPosition?: PerpPosition, burnLpShares?: boolean, includeRemainderInBaseAmount?: boolean): [PerpPosition, BN, BN];
/**
* calculates Buying Power = free collateral / initial margin ratio
* @returns : Precision QUOTE_PRECISION
*/
getPerpBuyingPower(marketIndex: number, collateralBuffer?: BN): BN;
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex: number, freeCollateral: BN, baseAssetAmount: BN): BN;
/**
* calculates Free Collateral = Total collateral - margin requirement
* @returns : Precision QUOTE_PRECISION
*/
getFreeCollateral(marginCategory?: MarginCategory): BN;
/**
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
*/
getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean): BN;
/**
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
*/
getInitialMarginRequirement(): BN;
/**
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
*/
getMaintenanceMarginRequirement(liquidationBuffer?: BN): BN;
getActivePerpPositionsForUserAccount(userAccount: UserAccount): PerpPosition[];
getActivePerpPositions(): PerpPosition[];
getActivePerpPositionsAndSlot(): DataAndSlot;
getActiveSpotPositionsForUserAccount(userAccount: UserAccount): SpotPosition[];
getActiveSpotPositions(): SpotPosition[];
getActiveSpotPositionsAndSlot(): DataAndSlot;
/**
* calculates unrealized position price pnl
* @returns : Precision QUOTE_PRECISION
*/
getUnrealizedPNL(withFunding?: boolean, marketIndex?: number, withWeightMarginCategory?: MarginCategory, strict?: boolean): BN;
/**
* calculates unrealized funding payment pnl
* @returns : Precision QUOTE_PRECISION
*/
getUnrealizedFundingPNL(marketIndex?: number): BN;
getSpotMarketAssetAndLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): {
totalAssetValue: BN;
totalLiabilityValue: BN;
};
getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
getSpotLiabilityValue(tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN): BN;
getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
getSpotAssetValue(tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory): BN;
getSpotPositionValue(marketIndex: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN;
/**
* calculates TotalCollateral: collateral + unrealized pnl
* @returns : Precision QUOTE_PRECISION
*/
getTotalCollateral(marginCategory?: MarginCategory, strict?: boolean): BN;
/**
* calculates User Health by comparing total collateral and maint. margin requirement
* @returns : number (value from [0, 100])
*/
getHealth(): number;
calculateWeightedPerpPositionValue(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
/**
* calculates position value of a single perp market in margin system
* @returns : Precision QUOTE_PRECISION
*/
getPerpMarketLiabilityValue(marketIndex: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
/**
* calculates sum of position value across all positions in margin system
* @returns : Precision QUOTE_PRECISION
*/
getTotalPerpPositionValue(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
/**
* calculates position value in margin system
* @returns : Precision QUOTE_PRECISION
*/
getPerpPositionValue(marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
getPositionSide(currentPosition: Pick): PositionDirection | undefined;
/**
* calculates average exit price (optionally for closing up to 100% of position)
* @returns : Precision PRICE_PRECISION
*/
getPositionEstimatedExitPriceAndPnl(position: PerpPosition, amountToClose?: BN, useAMMClose?: boolean): [BN, BN];
/**
* calculates current user leverage which is (total liability size) / (net asset value)
* @returns : Precision TEN_THOUSAND
*/
getLeverage(includeOpenOrders?: boolean): BN;
calculateLeverageFromComponents({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }: {
perpLiabilityValue: BN;
perpPnl: BN;
spotAssetValue: BN;
spotLiabilityValue: BN;
}): BN;
getLeverageComponents(includeOpenOrders?: boolean, marginCategory?: MarginCategory): {
perpLiabilityValue: BN;
perpPnl: BN;
spotAssetValue: BN;
spotLiabilityValue: BN;
};
getTotalLiabilityValue(marginCategory?: MarginCategory): BN;
getTotalAssetValue(marginCategory?: MarginCategory): BN;
getNetUsdValue(): BN;
/**
* Calculates the all time P&L of the user.
*
* Net withdraws + Net spot market value + Net unrealized P&L -
*/
getTotalAllTimePnl(): BN;
/**
* calculates max allowable leverage exceeding hitting requirement category
* for large sizes where imf factor activates, result is a lower bound
* @param marginCategory {Initial, Maintenance}
* @param isLp if calculating max leveraging for adding lp, need to add buffer
* @returns : Precision TEN_THOUSAND
*/
getMaxLeverageForPerp(perpMarketIndex: number, marginCategory?: MarginCategory, isLp?: boolean): BN;
/**
* calculates max allowable leverage exceeding hitting requirement category
* @param spotMarketIndex
* @param direction
* @returns : Precision TEN_THOUSAND
*/
getMaxLeverageForSpot(spotMarketIndex: number, direction: PositionDirection): BN;
/**
* calculates margin ratio: 1 / leverage
* @returns : Precision TEN_THOUSAND
*/
getMarginRatio(): BN;
canBeLiquidated(): {
canBeLiquidated: boolean;
marginRequirement: BN;
totalCollateral: BN;
};
isBeingLiquidated(): boolean;
isBankrupt(): boolean;
/**
* Checks if any user position cumulative funding differs from respective market cumulative funding
* @returns
*/
needsToSettleFundingPayment(): boolean;
/**
* Calculate the liquidation price of a spot position
* @param marketIndex
* @returns Precision : PRICE_PRECISION
*/
spotLiquidationPrice(marketIndex: number, positionBaseSizeChange?: BN): BN;
/**
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
* @param marketIndex
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
* @returns Precision : PRICE_PRECISION
*/
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN): BN;
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN): BN | undefined;
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN): BN;
/**
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
* @param positionMarketIndex
* @param closeQuoteAmount
* @returns : Precision PRICE_PRECISION
*/
liquidationPriceAfterClose(positionMarketIndex: number, closeQuoteAmount: BN): BN;
/**
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
*
* To Calculate Max Quote Available:
*
* Case 1: SameSide
* => Remaining quote to get to maxLeverage
*
* Case 2: NOT SameSide && currentLeverage <= maxLeverage
* => Current opposite position x2 + remaining to get to maxLeverage
*
* Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
* => strictly reduce current position size
*
* Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
* => current position + remaining to get to maxLeverage
*
* @param targetMarketIndex
* @param tradeSide
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
*/
getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean): BN;
/**
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
*
* @param targetMarketIndex
* @param direction
* @param currentQuoteAssetValue
* @param currentSpotMarketNetValue
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
*/
getMaxTradeSizeUSDCForSpot(targetMarketIndex: number, direction: PositionDirection, currentQuoteAssetValue?: BN, currentSpotMarketNetValue?: BN): BN;
/**
* Calculates the max amount of token that can be swapped from inMarket to outMarket
* Assumes swap happens at oracle price
*
* @param inMarketIndex
* @param outMarketIndex
* @param calculateSwap function to similate in to out swa
* @param iterationLimit how long to run appromixation before erroring out
*/
getMaxSwapAmount({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit, }: {
inMarketIndex: number;
outMarketIndex: number;
calculateSwap?: (inAmount: BN) => BN;
iterationLimit?: number;
}): {
inAmount: BN;
outAmount: BN;
leverage: BN;
};
cloneAndUpdateSpotPosition(position: SpotPosition, tokenAmount: BN, market: SpotMarketAccount): SpotPosition;
calculateSpotPositionFreeCollateralContribution(spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice): BN;
calculateSpotPositionLeverageContribution(spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice): {
totalAssetValue: BN;
totalLiabilityValue: BN;
};
/**
* Estimates what the user leverage will be after swap
* @param inMarketIndex
* @param outMarketIndex
* @param inAmount
* @param outAmount
*/
accountLeverageAfterSwap({ inMarketIndex, outMarketIndex, inAmount, outAmount, }: {
inMarketIndex: number;
outMarketIndex: number;
inAmount: BN;
outAmount: BN;
}): BN;
/**
* Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
* @param targetMarketIndex
* @param: targetMarketType
* @param tradeQuoteAmount
* @param tradeSide
* @param includeOpenOrders
* @returns leverageRatio : Precision TEN_THOUSAND
*/
accountLeverageRatioAfterTrade(targetMarketIndex: number, targetMarketType: MarketType, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
getUserFeeTier(marketType: MarketType): import("./types").FeeTier;
/**
* Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType
* @param marketType
* @param positionMarketIndex
* @returns : {takerFee: number, makerFee: number} Precision None
*/
getMarketFees(marketType: MarketType, marketIndex?: number): {
takerFee: number;
makerFee: number;
};
/**
* Calculates how much perp fee will be taken for a given sized trade
* @param quoteAmount
* @returns feeForQuote : Precision QUOTE_PRECISION
*/
calculateFeeForQuoteAmount(quoteAmount: BN, marketIndex?: number): BN;
/**
* Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
* it will return the max withdrawal amount without opening a liability for the user
* @param marketIndex
* @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
*/
getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN;
canBypassWithdrawLimits(marketIndex: number): {
canBypass: boolean;
netDeposits: BN;
depositAmount: BN;
maxDepositAmount: BN;
};
canMakeIdle(slot: BN): boolean;
getSafestTiers(): {
perpTier: number;
spotTier: number;
};
getHealthComponents({ marginCategory, }: {
marginCategory: MarginCategory;
}): HealthComponents;
/**
* Get the total position value, excluding any position coming from the given target market
* @param marketToIgnore
* @returns positionValue : Precision QUOTE_PRECISION
*/
private getTotalPerpPositionValueExcludingMarket;
private getOracleDataForPerpMarket;
private getOracleDataForSpotMarket;
}