Users
How it works
A user account is the onchain account that holds your positions, orders, and collateral on Drift. Each wallet can create multiple user accounts (called subaccounts), identified by a numeric ID (0, 1, 2, etc.). All subaccounts under the same wallet share cross-margin, meaning collateral and risk are calculated across all of them together.
User accounts store your perp positions (long/short), spot balances (deposits/borrows), open orders, and leverage settings. When you interact with Drift (place orders, deposit, trade), you’re modifying data in your user account. The account is a Solana PDA (Program Derived Address) owned by the Drift program.
Subaccounts are useful for separating strategies, isolating risk between different trading styles, or delegating specific accounts to bots while keeping others manual. You can switch between subaccounts using the SDK, and each one maintains its own positions and orders while sharing the wallet’s overall collateral pool.
SDK Usage
Most write actions in Drift are done through DriftClient. For account-level reads (positions, orders, health), you’ll typically use a User.
Initialize a User Account
Create a new Drift user subaccount (PDA) for your wallet and return the transaction signature + user account address.
// Assumes you already constructed and subscribed `driftClient`.
const [txSig, userAccountPublicKey] = await driftClient.initializeUserAccount(0, "my-account");
console.log(txSig, userAccountPublicKey.toBase58());Method DriftClient.initializeUserAccountReference ↗
Method DriftClient.initializeUserAccountReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
name | string | No |
referrerInfo | ReferrerInfo | No |
txParams | TxParams | No |
| Returns |
|---|
Promise<[string, PublicKey]> |
Get the Next Subaccount ID
Return the next available subaccount ID for this client instance.
const nextId = driftClient.getNextSubAccountId();
console.log(nextId);Method DriftClient.getNextSubAccountIdReference ↗
Method DriftClient.getNextSubAccountIdReference ↗| Returns |
|---|
Promise<number> |
Get a User and Subscribe
Import the User class and subscribe to account updates for a specific user instance.
import { User } from "@drift-labs/sdk";
const user = driftClient.getUser();
await user.subscribe();Class UserReference ↗
Class UserReference ↗| Property | Type | Required |
|---|---|---|
driftClient | DriftClient | Yes |
userAccountPublicKey | PublicKey | Yes |
accountSubscriber | UserAccountSubscriber | Yes |
_isSubscribed | boolean | Yes |
eventEmitter | StrictEventEmitter<EventEmitter, UserAccountEvents> | Yes |
isSubscribed | boolean | Yes |
subscribe | (userAccount?: UserAccount | undefined) => Promise<boolean>Subscribe to User state accounts | Yes |
fetchAccounts | () => Promise<void>Forces the accountSubscriber to fetch account updates from rpc | Yes |
unsubscribe | () => Promise<void> | Yes |
getUserAccount | () => UserAccount | Yes |
forceGetUserAccount | () => Promise<UserAccount> | Yes |
getUserAccountAndSlot | () => DataAndSlot<UserAccount> | undefined | Yes |
getPerpPositionForUserAccount | (userAccount: UserAccount, marketIndex: number) => PerpPosition | undefined | Yes |
getPerpPosition | (marketIndex: number) => PerpPosition | undefinedGets the user's current position for a given perp market. If the user has no position returns undefined | Yes |
getPerpPositionOrEmpty | (marketIndex: number) => PerpPosition | Yes |
getPerpPositionAndSlot | (marketIndex: number) => DataAndSlot<PerpPosition | undefined> | Yes |
getSpotPositionForUserAccount | (userAccount: UserAccount, marketIndex: number) => SpotPosition | undefined | Yes |
getSpotPosition | (marketIndex: number) => SpotPosition | undefinedGets the user's current position for a given spot market. If the user has no position returns undefined | Yes |
getSpotPositionAndSlot | (marketIndex: number) => DataAndSlot<SpotPosition | undefined> | Yes |
getEmptySpotPosition | (marketIndex: number) => SpotPosition | Yes |
getTokenAmount | (marketIndex: number) => BNReturns 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. | Yes |
getEmptyPosition | (marketIndex: number) => PerpPosition | Yes |
isPositionEmpty | (position: PerpPosition) => boolean | Yes |
getIsolatePerpPositionTokenAmount | (perpMarketIndex: number) => BN | Yes |
getClonedPosition | (position: PerpPosition) => PerpPosition | Yes |
getOrderForUserAccount | (userAccount: UserAccount, orderId: number) => Order | undefined | Yes |
getOrder | (orderId: number) => Order | undefined | Yes |
getOrderAndSlot | (orderId: number) => DataAndSlot<Order | undefined> | Yes |
getOrderByUserIdForUserAccount | (userAccount: UserAccount, userOrderId: number) => Order | undefined | Yes |
getOrderByUserOrderId | (userOrderId: number) => Order | undefined | Yes |
getOrderByUserOrderIdAndSlot | (userOrderId: number) => DataAndSlot<Order | undefined> | Yes |
getOpenOrdersForUserAccount | (userAccount?: UserAccount | undefined) => Order[] | Yes |
getOpenOrders | () => Order[] | Yes |
getOpenOrdersAndSlot | () => DataAndSlot<Order[]> | Yes |
getUserAccountPublicKey | () => PublicKey | Yes |
exists | () => Promise<boolean> | Yes |
getPerpBidAsks | (marketIndex: number) => [BN, BN]calculates the total open bids/asks in a perp market (including lps) | Yes |
getPerpBuyingPower | (marketIndex: number, collateralBuffer?: any, enterHighLeverageMode?: any, maxMarginRatio?: any, positionType?: "isolated" | "cross" | undefined) => BNcalculates Buying Power = free collateral / initial margin ratio | Yes |
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount | (marketIndex: number, freeCollateral: BN, baseAssetAmount: BN, enterHighLeverageMode?: any, perpMarketMaxMarginRatio?: any) => BN | Yes |
getFreeCollateral | (marginCategory?: MarginCategory | undefined, enterHighLeverageMode?: boolean | undefined, perpMarketIndex?: number | undefined) => BNcalculates Free Collateral = Total collateral - margin requirement | Yes |
getMarginRequirement | { (marginCategory: MarginCategory, liquidationBuffer?: any, strict?: boolean | undefined, includeOpenOrders?: boolean | undefined, enteringHighLeverage?: boolean | undefined): BN; (marginCategory: MarginCategory, liquidationBuffer?: any, strict?: boolean | undefined, includeOpenOrders?: boolean | undefined, entering...Calculates the margin requirement based on the specified parameters. | Yes |
getInitialMarginRequirement | (enterHighLeverageMode?: boolean | undefined, perpMarketIndex?: number | undefined) => BN | Yes |
getMaintenanceMarginRequirement | (liquidationBuffer?: any, perpMarketIndex?: number | undefined) => BN | Yes |
getActivePerpPositionsForUserAccount | (userAccount: UserAccount) => PerpPosition[] | Yes |
getActivePerpPositions | () => PerpPosition[] | Yes |
getActivePerpPositionsAndSlot | () => DataAndSlot<PerpPosition[]> | Yes |
getActiveSpotPositionsForUserAccount | (userAccount: UserAccount) => SpotPosition[] | Yes |
getActiveSpotPositions | () => SpotPosition[] | Yes |
getActiveSpotPositionsAndSlot | () => DataAndSlot<SpotPosition[]> | Yes |
getUnrealizedPNL | (withFunding?: boolean | undefined, marketIndex?: number | undefined, withWeightMarginCategory?: MarginCategory | undefined, strict?: boolean | undefined, liquidationBuffer?: any) => BNcalculates unrealized position price pnl | Yes |
getUnrealizedFundingPNL | (marketIndex?: number | undefined) => BNcalculates unrealized funding payment pnl | Yes |
getFuelBonus | (now: BN, includeSettled?: boolean | undefined, includeUnsettled?: boolean | undefined, givenUserStats?: UserStats | undefined) => { depositFuel: BN; borrowFuel: BN; positionFuel: BN; takerFuel: BN; makerFuel: BN; insuranceFuel: BN; } | Yes |
getSpotMarketAssetAndLiabilityValue | (marketIndex?: number | undefined, marginCategory?: MarginCategory | undefined, liquidationBuffer?: any, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, now?: any) => { ...; } | Yes |
getSpotMarketLiabilityValue | (marketIndex?: number | undefined, marginCategory?: MarginCategory | undefined, liquidationBuffer?: any, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, now?: any) => BN | Yes |
getSpotLiabilityValue | (tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory | undefined, liquidationBuffer?: any) => BN | Yes |
getSpotMarketAssetValue | (marketIndex?: number | undefined, marginCategory?: MarginCategory | undefined, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, now?: any) => BN | Yes |
getSpotAssetValue | (tokenAmount: BN, strictOraclePrice: StrictOraclePrice, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory | undefined) => BN | Yes |
getSpotPositionValue | (marketIndex: number, marginCategory?: MarginCategory | undefined, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, now?: any) => BN | Yes |
getNetSpotMarketValue | (withWeightMarginCategory?: MarginCategory | undefined) => BN | Yes |
getTotalCollateral | (marginCategory?: MarginCategory | undefined, strict?: boolean | undefined, includeOpenOrders?: boolean | undefined, liquidationBuffer?: any, perpMarketIndex?: number | undefined) => BNcalculates TotalCollateral: collateral + unrealized pnl | Yes |
getLiquidationBuffer | () => Map<number | "cross", BN> | Yes |
getHealth | (perpMarketIndex?: number | undefined) => numbercalculates User Health by comparing total collateral and maint. margin requirement | Yes |
calculateWeightedPerpPositionLiability | (perpPosition: PerpPosition, marginCategory?: MarginCategory | undefined, liquidationBuffer?: any, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, enteringHighLeverage?: any) => BN | Yes |
getPerpMarketLiabilityValue | (marketIndex: number, marginCategory?: MarginCategory | undefined, liquidationBuffer?: any, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined) => BNcalculates position value of a single perp market in margin system | Yes |
getTotalPerpPositionLiability | (marginCategory?: MarginCategory | undefined, liquidationBuffer?: any, includeOpenOrders?: boolean | undefined, strict?: boolean | undefined, enteringHighLeverage?: any) => BNcalculates sum of position value across all positions in margin system | Yes |
getPerpPositionValue | (marketIndex: number, oraclePriceData: Pick<OraclePriceData, "price">, includeOpenOrders?: boolean | undefined) => BNcalculates position value based on oracle | Yes |
getPerpLiabilityValue | (marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean | undefined) => BNcalculates position liabiltiy value in margin system | Yes |
getPositionSide | (currentPosition: Pick<PerpPosition, "baseAssetAmount">) => PositionDirection | undefined | Yes |
getPositionEstimatedExitPriceAndPnl | (position: PerpPosition, amountToClose?: any, useAMMClose?: boolean | undefined) => [BN, BN]calculates average exit price (optionally for closing up to 100% of position) | Yes |
getLeverage | (includeOpenOrders?: boolean | undefined, perpMarketIndex?: number | undefined) => BNcalculates current user leverage which is (total liability size) / (net asset value) | Yes |
calculateLeverageFromComponents | ({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }: { perpLiabilityValue: BN; perpPnl: BN; spotAssetValue: BN; spotLiabilityValue: BN; }) => BN | Yes |
getLeverageComponents | (includeOpenOrders?: boolean | undefined, marginCategory?: MarginCategory | undefined, perpMarketIndex?: number | undefined) => { perpLiabilityValue: BN; perpPnl: BN; spotAssetValue: BN; spotLiabilityValue: BN; } | Yes |
isDustDepositPosition | (spotMarketAccount: SpotMarketAccount) => boolean | Yes |
getSpotMarketAccountsWithDustPosition | () => SpotMarketAccount[] | Yes |
getTotalLiabilityValue | (marginCategory?: MarginCategory | undefined) => BN | Yes |
getTotalAssetValue | (marginCategory?: MarginCategory | undefined) => BN | Yes |
getNetUsdValue | () => BN | Yes |
getTotalAllTimePnl | () => BNCalculates the all time P&L of the user.
Net withdraws + Net spot market value + Net unrealized P&L - | Yes |
getMaxLeverageForPerp | (perpMarketIndex: number, _marginCategory?: MarginCategory | undefined, isLp?: boolean | undefined, enterHighLeverageMode?: any) => BNcalculates max allowable leverage exceeding hitting requirement category
for large sizes where imf factor activates, result is a lower bound | Yes |
getMaxLeverageForSpot | (spotMarketIndex: number, direction: PositionDirection) => BNcalculates max allowable leverage exceeding hitting requirement category | Yes |
getMarginRatio | () => BNcalculates margin ratio: 1 / leverage | Yes |
canBeLiquidated | () => AccountLiquidatableStatus & { isolatedPositions: Map<number, AccountLiquidatableStatus>; } | Yes |
getLiquidationStatuses | (marginCalc?: MarginCalculation | undefined) => Map<number | "cross", AccountLiquidatableStatus>New API: Returns liquidation status for cross and each isolated perp position.
Map keys:
- 'cross' for cross margin
- marketIndex (number) for each isolated perp position | Yes |
isBeingLiquidated | () => boolean | Yes |
isCrossMarginBeingLiquidated | () => boolean | Yes |
canCrossMarginBeLiquidated | (marginCalc?: MarginCalculation | undefined) => booleanReturns true if cross margin is currently below maintenance requirement (no buffer). | Yes |
hasIsolatedPositionBeingLiquidated | () => boolean | Yes |
isIsolatedPositionBeingLiquidated | (perpMarketIndex: number) => boolean | Yes |
getLiquidatableIsolatedPositions | (marginCalc?: MarginCalculation | undefined) => number[]Returns true if any isolated perp position is currently below its maintenance requirement (no buffer). | Yes |
canIsolatedPositionMarginBeLiquidated | (isolatedMarginCalculation: IsolatedMarginCalculation) => boolean | Yes |
hasStatus | (status: UserStatus) => boolean | Yes |
isBankrupt | () => boolean | Yes |
isHighLeverageMode | (marginCategory: MarginCategory) => boolean | Yes |
needsToSettleFundingPayment | () => booleanChecks if any user position cumulative funding differs from respective market cumulative funding | Yes |
spotLiquidationPrice | (marketIndex: number, positionBaseSizeChange?: any) => BNCalculate the liquidation price of a spot position | Yes |
liquidationPrice | (marketIndex: number, positionBaseSizeChange?: any, estimatedEntryPrice?: any, marginCategory?: MarginCategory | undefined, includeOpenOrders?: boolean | undefined, offsetCollateral?: any, enteringHighLeverage?: boolean | undefined, marginType?: MarginType | undefined) => BNCalculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade | Yes |
calculateEntriesEffectOnFreeCollateral | (market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN, includeOpenOrders: boolean, enteringHighLeverage?: any, marginCategory?: MarginCategory | undefined) => BN | Yes |
calculateFreeCollateralDeltaForPerp | (market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, oraclePrice: BN, marginCategory?: MarginCategory | undefined, includeOpenOrders?: boolean | undefined, enteringHighLeverage?: any) => any | Yes |
calculateFreeCollateralDeltaForSpot | (market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory | undefined) => BN | Yes |
liquidationPriceAfterClose | (positionMarketIndex: number, closeQuoteAmount: BN, estimatedEntryPrice?: any) => BNCalculates the estimated liquidation price for a position after closing a quote amount of the position. | Yes |
getMarginUSDCRequiredForTrade | (targetMarketIndex: number, baseSize: BN, estEntryPrice?: any, perpMarketMaxMarginRatio?: number | undefined) => BN | Yes |
getCollateralDepositRequiredForTrade | (targetMarketIndex: number, baseSize: BN, collateralIndex: number, perpMarketMaxMarginRatio?: number | undefined) => BN | Yes |
getMaxTradeSizeUSDCForPerp | (targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean | undefined, enterHighLeverageMode?: any, maxMarginRatio?: any, positionType?: "isolated" | "cross" | undefined) => { ...; }Separates the max trade size into two parts:
- tradeSize: The maximum trade size for target direction
- oppositeSideTradeSize: the trade size for closing the opposite direction | Yes |
getMaxTradeSizeUSDCForSpot | (targetMarketIndex: number, direction: PositionDirection, currentQuoteAssetValue?: any, currentSpotMarketNetValue?: any) => BNGet the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc. | Yes |
getMaxSwapAmount | ({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit, }: { inMarketIndex: number; outMarketIndex: number; calculateSwap?: (inAmount: BN) => BN; iterationLimit?: number; }) => { inAmount: BN; outAmount: BN; leverage: BN; }Calculates the max amount of token that can be swapped from inMarket to outMarket
Assumes swap happens at oracle price | Yes |
cloneAndUpdateSpotPosition | (position: SpotPosition, tokenAmount: BN, market: SpotMarketAccount) => SpotPosition | Yes |
calculateSpotPositionFreeCollateralContribution | (spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice) => BN | Yes |
calculateSpotPositionLeverageContribution | (spotPosition: SpotPosition, strictOraclePrice: StrictOraclePrice) => { totalAssetValue: BN; totalLiabilityValue: BN; } | Yes |
accountLeverageAfterSwap | ({ inMarketIndex, outMarketIndex, inAmount, outAmount, }: { inMarketIndex: number; outMarketIndex: number; inAmount: BN; outAmount: BN; }) => BNEstimates what the user leverage will be after swap | Yes |
accountLeverageRatioAfterTrade | (targetMarketIndex: number, targetMarketType: MarketType, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean | undefined) => BNReturns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position | Yes |
getUserFeeTier | (marketType: MarketType, now?: any) => FeeTier | Yes |
calculateFeeForQuoteAmount | (quoteAmount: BN, marketIndex?: number | undefined, enteringHighLeverageMode?: boolean | undefined) => BNCalculates how much perp fee will be taken for a given sized trade | Yes |
getWithdrawalLimit | (marketIndex: number, reduceOnly?: boolean | undefined) => BNCalculates 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 | Yes |
canBypassWithdrawLimits | (marketIndex: number) => { canBypass: boolean; netDeposits: BN; depositAmount: BN; maxDepositAmount: BN; } | Yes |
canMakeIdle | (slot: BN) => boolean | Yes |
getSafestTiers | () => { perpTier: number; spotTier: number; } | Yes |
getPerpPositionHealth | ({ marginCategory, perpPosition, oraclePriceData, quoteOraclePriceData, includeOpenOrders, }: { marginCategory: MarginCategory; perpPosition: PerpPosition; oraclePriceData?: OraclePriceData; quoteOraclePriceData?: OraclePriceData; includeOpenOrders?: boolean; }) => HealthComponent | Yes |
getHealthComponents | ({ marginCategory, }: { marginCategory: MarginCategory; }) => HealthComponents | Yes |
getTotalPerpPositionValueExcludingMarket | anyGet the total position value, excluding any position coming from the given target market | Yes |
getMMOracleDataForPerpMarket | any | Yes |
getOracleDataForPerpMarket | any | Yes |
getOracleDataForSpotMarket | any | Yes |
getActivePositions | () => { activePerpPositions: number[]; activeSpotPositions: number[]; }Get the active perp and spot positions of the user. | Yes |
getMarginCalculation | (marginCategory?: MarginCategory | undefined, opts?: { strict?: boolean; includeOpenOrders?: boolean; enteringHighLeverage?: boolean; liquidationBufferMap?: Map<number | "cross", BN>; } | undefined) => MarginCalculationCompute the full margin calculation for the user's account.
Prioritize using this function instead of calling getMarginRequirement or getTotalCollateral multiple times.
Consumers can use this to avoid duplicating work across separate calls. | Yes |
isPerpPositionIsolated | (perpPosition: PerpPosition) => boolean | Yes |
Get active subaccount user
Get the User object for the currently active subaccount.
const user = driftClient.getUser();Method DriftClient.getUserReference ↗
Method DriftClient.getUserReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
authority | PublicKey | No |
| Returns |
|---|
User |
Get a specific subaccount user
Get the User object for a specific subaccount ID.
const user = driftClient.getUser(1);Method DriftClient.getUserReference ↗
Method DriftClient.getUserReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
authority | PublicKey | No |
| Returns |
|---|
User |
Read account via User
Read raw onchain UserAccount data from a User instance.
const account = driftClient.getUser().getUserAccount();
console.log(account);Method User.getUserAccountReference ↗
Method User.getUserAccountReference ↗| Returns |
|---|
UserAccount |
Read account via DriftClient
Read raw onchain UserAccount data directly from DriftClient for the active subaccount.
const account = driftClient.getUserAccount();
console.log(account);Method DriftClient.getUserAccountReference ↗
Method DriftClient.getUserAccountReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
authority | PublicKey | No |
| Returns |
|---|
UserAccount | undefined |
Refresh user accounts
Force-refresh subscribed user-related accounts from RPC.
const user = driftClient.getUser(0);
await user.fetchAccounts();Method User.fetchAccountsReference ↗
Method User.fetchAccountsReference ↗| Returns |
|---|
Promise<void> |
Derived Addresses (User Account)
User accounts are Program Derived Addresses (PDAs) - deterministic addresses generated from seeds (the program ID, wallet authority, and subaccount ID). PDAs are a Solana concept that lets you calculate an account’s address without making an RPC call.
This is useful when you need to reference a user account address before fetching it, such as when constructing transactions or querying multiple accounts in parallel.
For a deeper understanding of PDAs and program structure, see Program Structure.
Derive the user account PDA for a given subaccount without an RPC fetch.
const userAccountPublicKey = await driftClient.getUserAccountPublicKey(0);
console.log(userAccountPublicKey.toBase58());Method DriftClient.getUserAccountPublicKeyReference ↗
Method DriftClient.getUserAccountPublicKeyReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
authority | PublicKey | No |
| Returns |
|---|
Promise<PublicKey> |
Query User State (Orders / Positions)
Get token amount (deposit vs borrow)
Return your token balance for a spot market as a signed value (+ deposit, - borrow).
import { BN } from "@drift-labs/sdk";
const user = driftClient.getUser();
const tokenAmount = user.getTokenAmount(0);
const isDeposit = tokenAmount.gte(new BN(0));
const isBorrow = tokenAmount.lt(new BN(0));
console.log({ tokenAmount: tokenAmount.toString(), isDeposit, isBorrow });Method User.getTokenAmountReference ↗
Method User.getTokenAmountReference ↗| Parameter | Type | Required |
|---|---|---|
marketIndex | number | Yes |
| Returns |
|---|
BN |
Get a perp position
Get your perp position record for a market index (or undefined if no position exists).
const position = driftClient.getUser().getPerpPosition(0);
console.log(position?.baseAssetAmount.toString());Method User.getPerpPositionReference ↗
Method User.getPerpPositionReference ↗| Parameter | Type | Required |
|---|---|---|
marketIndex | number | Yes |
| Returns |
|---|
PerpPosition | undefined |
Get an order by order id
Look up a specific order using its internal Drift orderId.
const order = driftClient.getUser().getOrder(1);
console.log(order);Method User.getOrderReference ↗
Method User.getOrderReference ↗| Parameter | Type | Required |
|---|---|---|
orderId | number | Yes |
| Returns |
|---|
Order | undefined |
Get an order by user order id
Look up a specific order using your custom userOrderId.
const order = driftClient.getUser().getOrderByUserOrderId(1);
console.log(order);Method User.getOrderByUserOrderIdReference ↗
Method User.getOrderByUserOrderIdReference ↗| Parameter | Type | Required |
|---|---|---|
userOrderId | number | Yes |
| Returns |
|---|
Order | undefined |
Get all open orders
Return all currently open (unfilled/uncancelled) orders for this user.
const orders = driftClient.getUser().getOpenOrders();
console.log(orders.length);Method User.getOpenOrdersReference ↗
Method User.getOpenOrdersReference ↗| Returns |
|---|
Order[] |
Active Subaccount
The active subaccount is the default subaccount that DriftClient methods operate on when you don’t explicitly specify a subaccount ID. By default, the active subaccount is 0.
Many SDK methods use the active subaccount implicitly:
driftClient.getUser()- returns the User for the active subaccountdriftClient.getUserAccount()- returns the account data for the active subaccountdriftClient.placePerpOrder(orderParams)- places an order on the active subaccountdriftClient.getSpotPosition(marketIndex)- gets position from the active subaccountdriftClient.getPerpPosition(marketIndex)- gets position from the active subaccount
You can change which subaccount is active using switchActiveUser(), or you can explicitly pass a subaccount ID to methods that support it (like getUser(subAccountId)).
Switch Active Subaccount
Change the active subaccount context used by default in DriftClient methods.
// Switch to subaccount 1.
await driftClient.switchActiveUser(1);Method DriftClient.switchActiveUserReference ↗
Method DriftClient.switchActiveUserReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | Yes |
authority | PublicKey | No |
| Returns |
|---|
Promise<void> |
Update Delegate
A delegate is another wallet that can trade on behalf of your user account without being able to withdraw funds. This is useful for allowing trading bots to manage positions while keeping withdrawal authority secure.
Learn more: Delegated Accounts
Set or update the delegate authority allowed to trade on a subaccount.
import { PublicKey } from "@solana/web3.js";
await driftClient.updateUserDelegate(new PublicKey("<DELEGATE_PUBKEY>"), 0);Method DriftClient.updateUserDelegateReference ↗
Method DriftClient.updateUserDelegateReference ↗| Parameter | Type | Required |
|---|---|---|
delegate | PublicKey | Yes |
subAccountId | number | No |
| Returns |
|---|
Promise<string> |
Update Margin Settings
Margin trading settings control how your account can use leverage and borrow against collateral. You can enable/disable margin trading or set custom margin ratios to control risk.
Learn more: Margin
Enable or disable margin trading permissions for one or more subaccounts.
await driftClient.updateUserMarginTradingEnabled([
{ marginTradingEnabled: true, subAccountId: 0 },
]);Method DriftClient.updateUserMarginTradingEnabledReference ↗
Method DriftClient.updateUserMarginTradingEnabledReference ↗| Parameter | Type | Required |
|---|---|---|
updates | { marginTradingEnabled: boolean; subAccountId: number; }[] | Yes |
| Returns |
|---|
Promise<string> |
Set a custom margin ratio cap for one or more subaccounts.
// marginRatio is a number scaled by 10000 (MARGIN_PRECISION)
// e.g. 10000 = 1x max leverage, 5000 = 2x, 2000 = 5x
await driftClient.updateUserCustomMarginRatio([
{ marginRatio: 5000, subAccountId: 0 }, // 2x max leverage
]);Method DriftClient.updateUserCustomMarginRatioReference ↗
Method DriftClient.updateUserCustomMarginRatioReference ↗| Parameter | Type | Required |
|---|---|---|
updates | { marginRatio: number; subAccountId: number; }[] | Yes |
txParams | TxParams | No |
| Returns |
|---|
Promise<string> |
Delete a User Account
If a subaccount has no assets/liabilities, it can be deleted to reclaim rent.
Delete an empty subaccount and close its user account.
await driftClient.deleteUser(1);Method DriftClient.deleteUserReference ↗
Method DriftClient.deleteUserReference ↗| Parameter | Type | Required |
|---|---|---|
subAccountId | number | No |
txParams | TxParams | No |
| Returns |
|---|
Promise<string> |