Skip to Content
DevelopersMarket MakersMarket Maker Quickstart

Market Maker Quickstart

Get a simple market maker running in under 10 minutes. This guide shows how to place two-sided quotes that automatically update with oracle prices.

Prerequisites

  • Node.js + TypeScript project
  • Drift SDK installed: npm i @drift-labs/sdk
  • Funded Solana account with USDC collateral
  • Basic familiarity with async/await

⚠️ RPC choice matters: The default https://api.mainnet-beta.solana.com is rate-limited and unsuitable for production bots. Use a dedicated RPC provider (Helius, Triton, etc.) or you’ll hit 429 errors within minutes. For WebSocket subscriptions, you need a provider that supports accountSubscribe.

Step 1: Initialize DriftClient

Set up your connection and subscribe to market data.

View DriftClient import

import { Connection } from "@solana/web3.js"; import { Wallet, DriftClient, loadKeypair } from "@drift-labs/sdk"; const connection = new Connection("https://api.mainnet-beta.solana.com"); const wallet = new Wallet(loadKeypair("~/.config/solana/id.json")); const driftClient = new DriftClient({ connection, wallet, env: "mainnet-beta", }); await driftClient.subscribe(); // Initialize your user account (if first time) // const [txSig] = await driftClient.initializeUserAccount(0);
Class DriftClientReference ↗
NameTypeDefault
connectionConnection
walletIWallet
programProgram<Idl>
providerAnchorProvider
envDriftEnv
optsConfirmOptions
useHotWalletAdminboolean
usersMap<string, User>
userStatsUserStats
activeSubAccountIdnumber
userAccountSubscriptionConfigUserSubscriptionConfig
userStatsAccountSubscriptionConfigUserStatsSubscriptionConfig
accountSubscriberDriftClientAccountSubscriber
eventEmitterStrictEventEmitter<EventEmitter, DriftClientAccountEvents>
metricsEventEmitterStrictEventEmitter<EventEmitter, DriftClientMetricsEvents>
_isSubscribedboolean
txSenderTxSender
perpMarketLastSlotCacheMap<number, number>
spotMarketLastSlotCacheMap<number, number>
mustIncludePerpMarketIndexesSet<number>
mustIncludeSpotMarketIndexesSet<number>
authorityPublicKey
marketLookupTablePublicKey

Deprecated: use marketLookupTables

lookupTableAccountAddressLookupTableAccount

Deprecated: use lookupTableAccounts

marketLookupTablesPublicKey[]
lookupTableAccountsAddressLookupTableAccount[]
includeDelegatesboolean
authoritySubAccountMapMap<string, number[]>
skipLoadUsersboolean
txVersionTransactionVersion
txParamsTxParams
enableMetricsEventsboolean
txHandlerTxHandler
receiverProgramProgram<PythSolanaReceiver>
wormholeProgramProgram<WormholeCoreBridgeSolana>
sbOnDemandProgramdIdPublicKey
sbOnDemandProgramProgram<Idl>
sbProgramFeedConfigsMap<string, any>
isSubscribedboolean
getPrePlaceOrderIxsany
getUserMapKey(subAccountId: number, authority: PublicKey) => string
createUser(subAccountId: number, accountSubscriptionConfig: UserSubscriptionConfig, authority?: PublicKey | undefined) => User
subscribe() => Promise<boolean>
subscribeUsers() => Promise<boolean>[]
fetchAccounts() => Promise<void>

Forces the accountSubscriber to fetch account updates from rpc

unsubscribe() => Promise<void>
unsubscribeUsers() => Promise<void>[]
statePublicKeyPublicKey
getStatePublicKey() => Promise<PublicKey>
signerPublicKeyPublicKey
getSignerPublicKey() => PublicKey
getStateAccount() => StateAccount
forceGetStateAccount() => Promise<StateAccount>

Forces a fetch to rpc before returning accounts. Useful for anchor tests.

getPerpMarketAccount(marketIndex: number) => PerpMarketAccount | undefined
forceGetPerpMarketAccount(marketIndex: number) => Promise<PerpMarketAccount | undefined>

Forces a fetch to rpc before returning accounts. Useful for anchor tests.

getPerpMarketAccounts() => PerpMarketAccount[]
getSpotMarketAccount(marketIndex: number) => SpotMarketAccount | undefined
forceGetSpotMarketAccount(marketIndex: number) => Promise<SpotMarketAccount | undefined>

Forces a fetch to rpc before returning accounts. Useful for anchor tests.

getSpotMarketAccounts() => SpotMarketAccount[]
getQuoteSpotMarketAccount() => SpotMarketAccount
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey, oracleSource: OracleSource) => DataAndSlot<OraclePriceData> | undefined
getSerumV3FulfillmentConfig(serumMarket: PublicKey) => Promise<SerumV3FulfillmentConfigAccount>
getSerumV3FulfillmentConfigs() => Promise<SerumV3FulfillmentConfigAccount[]>
getPhoenixV1FulfillmentConfig(phoenixMarket: PublicKey) => Promise<PhoenixV1FulfillmentConfigAccount>
getPhoenixV1FulfillmentConfigs() => Promise<PhoenixV1FulfillmentConfigAccount[]>
getOpenbookV2FulfillmentConfig(openbookMarket: PublicKey) => Promise<OpenbookV2FulfillmentConfigAccount>
getOpenbookV2FulfillmentConfigs() => Promise<OpenbookV2FulfillmentConfigAccount[]>
fetchMarketLookupTableAccount() => Promise<AddressLookupTableAccount>

Deprecated: use fetchAllLookupTableAccounts()

fetchAllLookupTableAccounts() => Promise<AddressLookupTableAccount[]>
getTxVersionForNewWalletany
updateWallet(newWallet: IWallet, subAccountIds?: number[] | undefined, activeSubAccountId?: number | undefined, includeDelegates?: boolean | undefined, authoritySubaccountMap?: Map<string, number[]> | undefined) => Promise<...>

Update the wallet to use for drift transactions and linked user account

emulateAccount(emulateAuthority: PublicKey) => Promise<boolean>

Update the subscribed accounts to a given authority, while leaving the connected wallet intact. This allows a user to emulate another user’s account on the UI and sign permissionless transactions with their own wallet.

switchActiveUser(subAccountId: number, authority?: PublicKey | undefined) => Promise<void>
addUser(subAccountId: number, authority?: PublicKey | undefined, userAccount?: UserAccount | undefined) => Promise<boolean>
addAndSubscribeToUsers(authority?: PublicKey | undefined) => Promise<boolean>

Adds and subscribes to users based on params set by the constructor or by updateWallet.

getInitializeUserAccountIxs(subAccountId?: number | undefined, name?: string | undefined, referrerInfo?: ReferrerInfo | undefined, poolId?: number | undefined) => Promise<[TransactionInstruction[], PublicKey]>

Returns the instructions to initialize a user account and the public key of the user account.

initializeUserAccount(subAccountId?: number | undefined, name?: string | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined) => Promise<[...]>

Initializes a user account and returns the transaction signature and the public key of the user account.

getInitializeUserStatsIx(overrides?: { externalWallet?: PublicKey; } | undefined) => Promise<TransactionInstruction>
initializeSignedMsgUserOrders(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<[string, PublicKey]>
getInitializeSignedMsgUserOrdersAccountIx(authority: PublicKey, numOrders: number, overrides?: { externalWallet?: PublicKey; } | undefined) => Promise<[PublicKey, TransactionInstruction]>
resizeSignedMsgUserOrders(authority: PublicKey, numOrders: number, userSubaccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
getResizeSignedMsgUserOrdersInstruction(authority: PublicKey, numOrders: number, userSubaccountId?: number | undefined) => Promise<TransactionInstruction>
initializeSignedMsgWsDelegatesAccount(authority: PublicKey, delegates?: PublicKey[] | undefined, txParams?: TxParams | undefined) => Promise<string>
getInitializeSignedMsgWsDelegatesAccountIx(authority: PublicKey, delegates?: PublicKey[] | undefined) => Promise<TransactionInstruction>
initializeRevenueShare(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getInitializeRevenueShareIx(authority: PublicKey, overrides?: { payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>
initializeRevenueShareEscrow(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<string>
getInitializeRevenueShareEscrowIx(authority: PublicKey, numOrders: number, overrides?: { payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>
migrateReferrer(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getMigrateReferrerIx(authority: PublicKey) => Promise<TransactionInstruction>
resizeRevenueShareEscrowOrders(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<string>
getResizeRevenueShareEscrowOrdersIx(authority: PublicKey, numOrders: number) => Promise<TransactionInstruction>
changeApprovedBuilder(builder: PublicKey, maxFeeTenthBps: number, add: boolean, txParams?: TxParams | undefined) => Promise<string>

Creates the transaction to add or update an approved builder. This allows the builder to receive revenue share from referrals.

getChangeApprovedBuilderIx(builder: PublicKey, maxFeeTenthBps: number, add: boolean, overrides?: { authority?: PublicKey; payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>

Creates the transaction instruction to add or update an approved builder. This allows the builder to receive revenue share from referrals.

addSignedMsgWsDelegate(authority: PublicKey, delegate: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getAddSignedMsgWsDelegateIx(authority: PublicKey, delegate: PublicKey) => Promise<TransactionInstruction>
removeSignedMsgWsDelegate(authority: PublicKey, delegate: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getRemoveSignedMsgWsDelegateIx(authority: PublicKey, delegate: PublicKey) => Promise<TransactionInstruction>
initializeFuelOverflow(authority?: PublicKey | undefined) => Promise<string>
getInitializeFuelOverflowIx(authority?: PublicKey | undefined) => Promise<TransactionInstruction>
sweepFuel(authority?: PublicKey | undefined) => Promise<string>
getSweepFuelIx(authority?: PublicKey | undefined) => Promise<TransactionInstruction>
getInitializeUserInstructionsany
getNextSubAccountId() => Promise<number>
initializeReferrerName(name: string) => Promise<string>
updateUserName(name: string, subAccountId?: number | undefined) => Promise<string>
updateUserCustomMarginRatio(updates: { marginRatio: number; subAccountId: number; }[], txParams?: TxParams | undefined) => Promise<string>
getUpdateUserCustomMarginRatioIx(marginRatio: number, subAccountId?: number | undefined) => Promise<TransactionInstruction>
getUpdateUserPerpPositionCustomMarginRatioIx(perpMarketIndex: number, marginRatio: number, subAccountId?: number | undefined, overrides?: { userAccountPublicKey?: PublicKey; authority?: PublicKey; signingAuthority?: PublicKey; } | undefined) => Promise<...>
updateUserPerpPositionCustomMarginRatio(perpMarketIndex: number, marginRatio: number, subAccountId?: number | undefined, txParams?: TxParams | undefined, enterHighLeverageMode?: boolean | undefined) => Promise<...>
getUpdateUserMarginTradingEnabledIx(marginTradingEnabled: boolean, subAccountId?: number | undefined, userAccountPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
updateUserMarginTradingEnabled(updates: { marginTradingEnabled: boolean; subAccountId: number; }[]) => Promise<string>
getUpdateUserDelegateIx(delegate: PublicKey, overrides: { subAccountId?: number; userAccountPublicKey?: PublicKey; authority?: PublicKey; }) => Promise<TransactionInstruction>
updateUserDelegate(delegate: PublicKey, subAccountId?: number | undefined) => Promise<string>
updateUserAdvancedLp(updates: { advancedLp: boolean; subAccountId: number; }[]) => Promise<string>
getUpdateAdvancedDlpIx(advancedLp: boolean, subAccountId: number) => Promise<TransactionInstruction>
updateUserReduceOnly(updates: { reduceOnly: boolean; subAccountId: number; }[]) => Promise<string>
getUpdateUserReduceOnlyIx(reduceOnly: boolean, subAccountId: number) => Promise<TransactionInstruction>
updateUserPoolId(updates: { poolId: number; subAccountId: number; }[]) => Promise<string>
getUpdateUserPoolIdIx(poolId: number, subAccountId: number) => Promise<TransactionInstruction>
fetchAllUserAccounts(includeIdle?: boolean | undefined) => Promise<ProgramAccount<UserAccount>[]>
getUserAccountsForDelegate(delegate: PublicKey) => Promise<UserAccount[]>
getUserAccountsAndAddressesForAuthority(authority: PublicKey) => Promise<ProgramAccount<UserAccount>[]>
getUserAccountsForAuthority(authority: PublicKey) => Promise<UserAccount[]>
getReferredUserStatsAccountsByReferrer(referrer: PublicKey) => Promise<UserStatsAccount[]>
getReferrerNameAccountsForAuthority(authority: PublicKey) => Promise<ReferrerNameAccount[]>
deleteUser(subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
getUserDeletionIx(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
forceDeleteUser(userAccountPublicKey: PublicKey, userAccount: UserAccount, txParams?: TxParams | undefined) => Promise<string>
getForceDeleteUserIx(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<TransactionInstruction>
deleteSignedMsgUserOrders(txParams?: TxParams | undefined) => Promise<string>
getSignedMsgUserOrdersDeletionIx(authority: PublicKey) => Promise<TransactionInstruction>
isSignedMsgUserOrdersAccountInitialized(authority: PublicKey) => Promise<boolean>

Checks if a SignedMsg User Orders account exists for the given authority. The account pubkey is derived using the program ID and authority as seeds. Makes an RPC call to check if the account exists on-chain.

reclaimRent(subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
getReclaimRentIx(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
getUser(subAccountId?: number | undefined, authority?: PublicKey | undefined) => User
hasUser(subAccountId?: number | undefined, authority?: PublicKey | undefined) => boolean
getUsers() => User[]
getUserStats() => UserStats
fetchReferrerNameAccount(name: string) => Promise<ReferrerNameAccount | undefined>
userStatsAccountPublicKeyPublicKey
getUserStatsAccountPublicKey() => PublicKey
getUserAccountPublicKey(subAccountId?: number | undefined, authority?: PublicKey | undefined) => Promise<PublicKey>
getUserAccount(subAccountId?: number | undefined, authority?: PublicKey | undefined) => UserAccount | undefined
forceGetUserAccount(subAccountId?: number | undefined, authority?: PublicKey | undefined) => Promise<UserAccount | undefined>

Forces a fetch to rpc before returning accounts. Useful for anchor tests.

getUserAccountAndSlot(subAccountId?: number | undefined, authority?: PublicKey | undefined) => DataAndSlot<UserAccount> | undefined
getSpotPosition(marketIndex: number, subAccountId?: number | undefined) => SpotPosition | undefined
getQuoteAssetTokenAmount() => BN
getIsolatedPerpPositionTokenAmount(perpMarketIndex: number, subAccountId?: number | undefined) => BN
getTokenAmount(marketIndex: number) => BN

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.

convertToSpotPrecision(marketIndex: number, amount: any) => BN

Converts an amount to the spot precision for a given market. The spot market precision is based on the token mint decimals.

convertToPerpPrecision(amount: any) => BN

Converts an amount to the perp precision. The perp market precision is BASE_PRECISION (1e9).

convertToPricePrecision(amount: any) => BN

Converts an amount to the price precision. The perp market precision is PRICE_PRECISION (1e6).

mustIncludeMarketsInIx({ perpMarketIndexes, spotMarketIndexes, }: { perpMarketIndexes: number[]; spotMarketIndexes: number[]; }) => void

Each drift instruction must include perp and sport market accounts in the ix remaining accounts. Use this function to force a subset of markets to be included in the remaining accounts for every ix

getRemainingAccounts(params: RemainingAccountParams) => AccountMeta[]
addPerpMarketToRemainingAccountMaps(marketIndex: number, writable: boolean, oracleAccountMap: Map<string, AccountMeta>, spotMarketAccountMap: Map<number, AccountMeta>, perpMarketAccountMap: Map<...>) => void
addSpotMarketToRemainingAccountMaps(marketIndex: number, writable: boolean, oracleAccountMap: Map<string, AccountMeta>, spotMarketAccountMap: Map<number, AccountMeta>) => void
addBuilderToRemainingAccounts(builders: PublicKey[], remainingAccounts: AccountMeta[]) => void
getRemainingAccountMapsForUsers(userAccounts: UserAccount[]) => { oracleAccountMap: Map<string, AccountMeta>; spotMarketAccountMap: Map<number, AccountMeta>; perpMarketAccountMap: Map<...>; }
getOrder(orderId: number, subAccountId?: number | undefined) => Order | undefined
getOrderByUserId(userOrderId: number, subAccountId?: number | undefined) => Order | undefined
getAssociatedTokenAccount(marketIndex: number, useNative?: boolean | undefined, tokenProgram?: PublicKey | undefined, authority?: PublicKey | undefined, allowOwnerOffCurve?: boolean | undefined) => Promise<...>

Get the associated token address for the given spot market

createAssociatedTokenAccountIdempotentInstruction(account: PublicKey, payer: PublicKey, owner: PublicKey, mint: PublicKey, tokenProgram?: PublicKey | undefined) => TransactionInstruction
getDepositTxnIx(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<...>
buildSwiftDepositTx(signedOrderParams: SignedMsgOrderParams, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, depositAmount: BN, depositSpotMarketIndex: number, tradePerpMarketIndex: number, subAccountId: number, takerAssociatedTokenAccount: PublicKey, initSwiftAccoun...
createDepositTxn(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, txParams?: TxParams | undefined, initSwiftAccount?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>
deposit(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, txParams?: TxParams | undefined, initSwiftAccount?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>

Deposit funds into the given spot market

getDepositInstruction(amount: BN, marketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, userInitialized?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>
checkIfAccountExistsany
getWrappedSolAccountCreationIxs(amount: BN, includeRent?: boolean | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<{ ixs: TransactionInstruction[]; signers: Signer[]; pubkey: PublicKey; }>
getTokenProgramForSpotMarket(spotMarketAccount: SpotMarketAccount) => PublicKey
isToken2022(spotMarketAccount: SpotMarketAccount) => boolean
isTransferHook(spotMarketAccount: SpotMarketAccount) => boolean
addTokenMintToRemainingAccounts(spotMarketAccount: SpotMarketAccount, remainingAccounts: AccountMeta[]) => void
addExtraAccountMetasToRemainingAccounts(mint: PublicKey, remainingAccounts: AccountMeta[]) => Promise<void>
getAssociatedTokenAccountCreationIx(tokenMintAddress: PublicKey, associatedTokenAddress: PublicKey, tokenProgram: PublicKey) => TransactionInstruction
createInitializeUserAccountAndDepositCollateralIxs(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, customMaxMarginRatio?: number | undefined, poolId?: number | undefined, overrid...
createInitializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, txParams?: TxParams | undefined, customMaxMarginRatio?: number | undefined, poo...
initializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, txParams?: TxParams | undefined, customMaxMarginRatio?: number | undefined, poo...

Creates the User account for a user, and deposits some initial collateral

initializeUserAccountForDevnet(subAccountId: number, name: string, marketIndex: number, tokenFaucet: TokenFaucet, amount: BN, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined) => Promise<...>
getWithdrawalIxs(amount: BN, marketIndex: number, associatedTokenAddress: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined, _updateFuel?: boolean | undefined) => Promise<...>
withdraw(amount: BN, marketIndex: number, associatedTokenAddress: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined, txParams?: TxParams | undefined, updateFuel?: boolean | undefined) => Promise<...>

Withdraws from a user account. If deposit doesn’t already exist, creates a borrow

withdrawAllDustPositions(subAccountId?: number | undefined, txParams?: TxParams | undefined, opts?: { dustPositionCountCallback?: (count: number) => void; } | undefined) => Promise<string | undefined>
getWithdrawIx(amount: BN, marketIndex: number, userTokenAccount: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined) => Promise<TransactionInstruction>
transferDeposit(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number, txParams?: TxParams | undefined) => Promise<string>

Withdraws from the fromSubAccount and deposits into the toSubAccount

getTransferDepositIx(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number) => Promise<TransactionInstruction>
transferPools(depositFromMarketIndex: number, depositToMarketIndex: number, borrowFromMarketIndex: number, borrowToMarketIndex: number, depositAmount: any, borrowAmount: any, fromSubAccountId: number, toSubAccountId: number, txParams?: TxParams | undefined) => Promise<...>
getTransferPoolsIx(depositFromMarketIndex: number, depositToMarketIndex: number, borrowFromMarketIndex: number, borrowToMarketIndex: number, depositAmount: any, borrowAmount: any, fromSubAccountId: number, toSubAccountId: number, isToNewSubAccount?: boolean | undefined) => Promise<...>
transferPerpPosition(fromSubAccountId: number, toSubAccountId: number, marketIndex: number, amount: BN, txParams?: TxParams | undefined) => Promise<string>
getTransferPerpPositionIx(fromSubAccountId: number, toSubAccountId: number, marketIndex: number, amount: BN) => Promise<TransactionInstruction>
depositIntoIsolatedPerpPosition(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
getDepositIntoIsolatedPerpPositionIx(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined) => Promise<TransactionInstruction>
transferIsolatedPerpPositionDeposit(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, txParams?: TxParams | undefined, trySettle?: boolean | undefined, noBuffer?: boolean | undefined) => Promise<...>
getTransferIsolatedPerpPositionDepositIx(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, noAmountBuffer?: boolean | undefined, signingAuthority?: PublicKey | undefined) => Promise<TransactionInstruction>
withdrawFromIsolatedPerpPosition(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
getWithdrawFromIsolatedPerpPositionIxsBundle(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, userTokenAccount?: PublicKey | undefined) => Promise<TransactionInstruction[]>
getWithdrawFromIsolatedPerpPositionIx(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined) => Promise<TransactionInstruction>
updateSpotMarketCumulativeInterest(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
updateSpotMarketCumulativeInterestIx(marketIndex: number) => Promise<TransactionInstruction>
settleLP(settleeUserAccountPublicKey: PublicKey, marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
settleLPIx(settleeUserAccountPublicKey: PublicKey, marketIndex: number) => Promise<TransactionInstruction>
removePerpLpShares(marketIndex: number, sharesToBurn?: any, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
removePerpLpSharesInExpiringMarket(marketIndex: number, userAccountPublicKey: PublicKey, sharesToBurn?: any, txParams?: TxParams | undefined) => Promise<string>
getRemovePerpLpSharesInExpiringMarket(marketIndex: number, userAccountPublicKey: PublicKey, sharesToBurn?: any) => Promise<TransactionInstruction>
getRemovePerpLpSharesIx(marketIndex: number, sharesToBurn?: any, subAccountId?: number | undefined) => Promise<TransactionInstruction>
addPerpLpShares(amount: BN, marketIndex: number, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
getAddPerpLpSharesIx(amount: BN, marketIndex: number, subAccountId?: number | undefined) => Promise<TransactionInstruction>
getQuoteValuePerLpShare(marketIndex: number) => BN
openPosition(direction: PositionDirection, amount: BN, marketIndex: number, limitPrice?: any, subAccountId?: number | undefined) => Promise<string>

Deprecated: use placePerpOrder or placeAndTakePerpOrder instead

sendSignedTx(tx: VersionedTransaction | Transaction, opts?: ConfirmOptions | undefined) => Promise<string>
prepareMarketOrderTxs(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[] | undefined, txParams?: TxParams | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, referrerInfo?: ReferrerInfo | undefined, cancelExistingOrders?: boolean | undefined,...
sendMarketOrderAndGetSignedFillTx(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[] | undefined, txParams?: TxParams | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, referrerInfo?: ReferrerInfo | undefined, cancelExistingOrders?: boolean | undefined,...

Sends a market order and returns a signed tx which can fill the order against the vamm, which the caller can use to fill their own order if required.

placePerpOrder(orderParams: OptionalOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
getPlacePerpOrderIx(orderParams: OptionalOrderParams, subAccountId?: number | undefined, depositToTradeArgs?: { isMakingNewAccount: boolean; depositMarketIndex: number; } | undefined) => Promise<...>
updateAMMs(marketIndexes: number[], txParams?: TxParams | undefined) => Promise<string>
getUpdateAMMsIx(marketIndexes: number[]) => Promise<TransactionInstruction>
settleExpiredMarket(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getSettleExpiredMarketIx(marketIndex: number) => Promise<TransactionInstruction>
settleExpiredMarketPoolsToRevenuePool(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getSettleExpiredMarketPoolsToRevenuePoolIx(perpMarketIndex: number) => Promise<TransactionInstruction>
cancelOrder(orderId?: number | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, overrides?: { withdrawIsolatedDepositAmount?: any; } | undefined) => Promise<...>
getCancelOrderIx(orderId?: number | undefined, subAccountId?: number | undefined) => Promise<TransactionInstruction>
cancelOrderByUserId(userOrderId: number, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
getCancelOrderByUserIdIx(userOrderId: number, subAccountId?: number | undefined) => Promise<TransactionInstruction>
cancelOrdersByIds(orderIds?: number[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, user?: User | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<...>

Sends a transaction to cancel the provided order ids.

getCancelOrdersByIdsIx(orderIds?: number[] | undefined, subAccountId?: number | undefined, user?: User | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<TransactionInstruction>

Returns the transaction instruction to cancel the provided order ids.

cancelOrders(marketType?: MarketType | undefined, marketIndex?: number | undefined, direction?: PositionDirection | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
getCancelOrdersIx(marketType: MarketType | null, marketIndex: number | null, direction: PositionDirection | null, subAccountId?: number | undefined) => Promise<...>
cancelAndPlaceOrders(cancelOrderParams: { marketType?: MarketType; marketIndex?: number; direction?: PositionDirection; }, placeOrderParams: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
placeOrders(params: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined, optionalIxs?: TransactionInstruction[] | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined, optionalIxs?: TransactionInstruction[] | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
getPlaceOrdersIx(params: OptionalOrderParams[], subAccountId?: number | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<TransactionInstruction>
getPlaceOrdersAndSetPositionMaxLevIx(params: OptionalOrderParams[], positionMaxLev: number, subAccountId?: number | undefined) => Promise<TransactionInstruction[]>
fillPerpOrder(userAccountPublicKey: PublicKey, user: UserAccount, order?: Pick<Order, "marketIndex" | "orderId"> | undefined, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined, fillerSubAccountId?: number | undefined, fillerAuthority?: PublicKey | undefined,...
getFillPerpOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Pick<Order, "marketIndex" | "orderId">, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, fillerSubAccountId?: number | undefined, isSignedMsg?: boolean | undefined, fillerAuthority?: PublicKey | undefined, has...
getRevertFillIx(fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
placeSpotOrder(orderParams: OptionalOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
preparePlaceSpotOrderTx(orderParams: OptionalOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<{ placeSpotOrderTx: Transaction | VersionedTransaction; }>
getPlaceSpotOrderIx(orderParams: OptionalOrderParams, subAccountId?: number | undefined) => Promise<TransactionInstruction>
fillSpotOrder(userAccountPublicKey: PublicKey, user: UserAccount, order?: Pick<Order, "marketIndex" | "orderId"> | undefined, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount | OpenbookV2FulfillmentConfigAccount | undefined, makerInfo?: MakerInfo | ... 1 more ... | undefined, referrerInfo?:...
getFillSpotOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order?: Pick<Order, "marketIndex" | "orderId"> | undefined, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount | OpenbookV2FulfillmentConfigAccount | undefined, makerInfo?: MakerInfo | ... 1 more ... | undefined, referre...
addSpotFulfillmentAccounts(marketIndex: number, remainingAccounts: AccountMeta[], fulfillmentConfig?: SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount | OpenbookV2FulfillmentConfigAccount | undefined) => void
addSerumRemainingAccounts(marketIndex: number, remainingAccounts: AccountMeta[], fulfillmentConfig: SerumV3FulfillmentConfigAccount) => void
addPhoenixRemainingAccounts(marketIndex: number, remainingAccounts: AccountMeta[], fulfillmentConfig: PhoenixV1FulfillmentConfigAccount) => void
addOpenbookRemainingAccounts(marketIndex: number, remainingAccounts: AccountMeta[], fulfillmentConfig: OpenbookV2FulfillmentConfigAccount) => void
swap({ swapClient, jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, v6, quote, onlyDirectRoutes, }: { swapClient?: UnifiedSwapClient | SwapClient; jupiterClient?: JupiterClient; outMarketIndex: number; inMarketIndex: n...

Swap tokens in drift account using titan or jupiter Deprecated: Use swapClient instead. Legacy parameter for backward compatibility

getTitanSwapIx({ titanClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, userAccountPublicKey, }: { titanClient: TitanClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; inAssociatedToken...
getJupiterSwapIxV6({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, quote, reduceOnly, userAccountPublicKey, }: { jupiterClient: JupiterClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; inAs...
getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, userAccountPublicKey, }: { outMarketIndex: number; inMarketIndex: number; amountIn: BN; inTokenAccount: PublicKey; outTokenAccount: PublicKey; limitPrice?: any; reduceOnly?: SwapReduceOnly; userAccountPublicKey?: Pub...

Get the drift begin_swap and end_swap instructions

getSwapIxV2({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, userAccountPublicKey, }: { swapClient: UnifiedSwapClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; in...
stakeForMSOL({ amount }: { amount: BN; }) => Promise<TxSigAndSlot>
getStakeForMSOLIx({ amount, userAccountPublicKey, }: { amount: BN; userAccountPublicKey?: PublicKey; }) => Promise<TransactionInstruction[]>
triggerOrder(userAccountPublicKey: PublicKey, user: UserAccount, order: Order, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
getTriggerOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Order, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
forceCancelOrders(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
getForceCancelOrdersIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
updateUserIdle(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
getUpdateUserIdleIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
logUserBalances(userAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getLogUserBalancesIx(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
updateUserFuelBonus(userAccountPublicKey: PublicKey, user: UserAccount, userAuthority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getUpdateUserFuelBonusIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, userAuthority: PublicKey) => Promise<TransactionInstruction>
updateUserStatsReferrerStatus(userAuthority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getUpdateUserStatsReferrerStatusIx(userAuthority: PublicKey) => Promise<TransactionInstruction>
updateUserOpenOrdersCount(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
getUpdateUserOpenOrdersCountIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, successCondition?: PlaceAndTakeOrderSuccessCondition | undefined, auctionDurationPercentage?: number | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise...
preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | u...
placeAndTakePerpWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | u...
getPlaceAndTakePerpOrderIx(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, referrerInfo?: ReferrerInfo | undefined, successCondition?: PlaceAndTakeOrderSuccessCondition | undefined, auctionDurationPercentage?: number | undefined, subAccountId?: number | undefined, overrides?: { ...; } | undefined) => Promis...
placeAndMakePerpOrder(orderParams: OptionalOrderParams, takerInfo: TakerInfo, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
getPlaceAndMakePerpOrderIx(orderParams: OptionalOrderParams, takerInfo: TakerInfo, referrerInfo?: ReferrerInfo | undefined, subAccountId?: number | undefined) => Promise<...>
signSignedMsgOrderParamsMessage(orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => SignedMsgOrderParams
buildDepositAndPlaceSignedMsgOrderRequest(depositTx: VersionedTransaction, orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => { ...; }

Builds a deposit and place request for Swift service

encodeSignedMsgOrderParamsMessage(orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => Buffer
decodeSignedMsgOrderParamsMessage(encodedMessage: Buffer, delegateSigner?: boolean | undefined) => SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage
signMessage(message: Uint8Array<ArrayBufferLike>, keypair?: Keypair | undefined) => Buffer
placeSignedMsgTakerOrder(signedSignedMsgOrderParams: SignedMsgOrderParams, marketIndex: number, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined, txParams?: TxParams | undefined...
getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams: SignedMsgOrderParams, marketIndex: number, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined) => Promise<...>
placeAndMakeSignedMsgPerpOrder(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array<ArrayBufferLike>, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | und...
getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array<ArrayBufferLike>, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo | undefined, subAccountId?: number | u...
preparePlaceAndTakeSpotOrder(orderParams: OptionalOrderParams, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | undefined, makerInfo?: MakerInfo | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
placeAndTakeSpotOrder(orderParams: OptionalOrderParams, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | undefined, makerInfo?: MakerInfo | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
getPlaceAndTakeSpotOrderIx(orderParams: OptionalOrderParams, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | undefined, makerInfo?: MakerInfo | undefined, referrerInfo?: ReferrerInfo | undefined, subAccountId?: number | undefined) => Promise<...>
placeAndMakeSpotOrder(orderParams: OptionalOrderParams, takerInfo: TakerInfo, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
getPlaceAndMakeSpotOrderIx(orderParams: OptionalOrderParams, takerInfo: TakerInfo, fulfillmentConfig?: SerumV3FulfillmentConfigAccount | undefined, referrerInfo?: ReferrerInfo | undefined, subAccountId?: number | undefined) => Promise<...>
closePosition(marketIndex: number, limitPrice?: any, subAccountId?: number | undefined) => Promise<string>

Deprecated: use placePerpOrder or placeAndTakePerpOrder instead

modifyPerpOrder(orderId: number, newBaseAmount?: any, newLimitPrice?: any, newOraclePriceOffset?: number | undefined) => Promise<string>

Modifies an open order by closing it and replacing it with a new order. Deprecated: use modifyOrder instead

modifyPerpOrderByUserOrderId(userOrderId: number, newBaseAmount?: any, newLimitPrice?: any, newOraclePriceOffset?: number | undefined) => Promise<string>

Modifies an open order by closing it and replacing it with a new order. Deprecated: use modifyOrderByUserOrderId instead

modifyOrder(orderParams: { orderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; newOraclePriceOffset?: number; newTriggerPrice?: any; newTriggerCondition?: OrderTriggerCondition; ... 7 more ...; policy?: number; }, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Pr...

Modifies an open order (spot or perp) by closing it and replacing it with a new order.

getModifyOrderIx({ orderId, newDirection, newBaseAmount, newLimitPrice, newOraclePriceOffset, newTriggerPrice, newTriggerCondition, auctionDuration, auctionStartPrice, auctionEndPrice, reduceOnly, postOnly, bitFlags, maxTs, policy, }: { orderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; new...
modifyOrderByUserOrderId(orderParams: { userOrderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; newOraclePriceOffset?: number; newTriggerPrice?: any; newTriggerCondition?: OrderTriggerCondition; ... 7 more ...; maxTs?: any; }, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Pr...

Modifies an open order by closing it and replacing it with a new order.

getModifyOrderByUserIdIx({ userOrderId, newDirection, newBaseAmount, newLimitPrice, newOraclePriceOffset, newTriggerPrice, newTriggerCondition, auctionDuration, auctionStartPrice, auctionEndPrice, reduceOnly, postOnly, bitFlags, maxTs, policy, }: { userOrderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: ...
settlePNLs(users: { settleeUserAccountPublicKey: PublicKey; settleeUserAccount: UserAccount; }[], marketIndexes: number[], opts?: { filterInvalidMarkets?: boolean; } | undefined, txParams?: TxParams | undefined) => Promise<...>
getSettlePNLsIxs(users: { settleeUserAccountPublicKey: PublicKey; settleeUserAccount: UserAccount; }[], marketIndexes: number[], revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
settlePNL(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, optionalIxs?: TransactionInstruction[] | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
settlePNLIx(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
settleMultiplePNLs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined, txParams?: TxParams | undefined) => Promise<...>
settleMultiplePNLsMultipleTxs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams | undefined, optionalIxs?: TransactionInstruction[] | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
settleMultiplePNLsIx(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, overrides?: { authority?: PublicKey; } | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
getSetUserStatusToBeingLiquidatedIx(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<TransactionInstruction>
setUserStatusToBeingLiquidated(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<string>
liquidatePerp(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getLiquidatePerpIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
liquidatePerpWithFill(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getLiquidatePerpWithFillIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], liquidatorSubAccountId?: number | undefined) => Promise<...>
liquidateSpot(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getLiquidateSpotIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
getJupiterLiquidateSpotWithSwapIxV6({ jupiterClient, liabilityMarketIndex, assetMarketIndex, swapAmount, assetTokenAccount, liabilityTokenAccount, slippageBps, swapMode, onlyDirectRoutes, quote, userAccount, userAccountPublicKey, userStatsAccountPublicKey, liquidatorSubAccountId, maxAccounts, }: { jupiterClient: JupiterClient; liabilityMarketIndex: n...
getLiquidateSpotWithSwapIx({ liabilityMarketIndex, assetMarketIndex, swapAmount: swapAmount, assetTokenAccount, liabilityTokenAccount, userAccount, userAccountPublicKey, userStatsAccountPublicKey, liquidatorSubAccountId, }: { liabilityMarketIndex: number; assetMarketIndex: number; swapAmount: BN; assetTokenAccount: PublicKey; liabilityTokenA...

Get the drift liquidate_spot_with_swap instructions

getInsuranceFundSwapIx({ inMarketIndex, outMarketIndex, amountIn, inTokenAccount, outTokenAccount, }: { inMarketIndex: number; outMarketIndex: number; amountIn: BN; inTokenAccount: PublicKey; outTokenAccount: PublicKey; }) => Promise<{ beginSwapIx: TransactionInstruction; endSwapIx: TransactionInstruction; }>
liquidateBorrowForPerpPnl(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getLiquidateBorrowForPerpPnlIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
liquidatePerpPnlForDeposit(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, assetMarketIndex: number, maxPnlTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getLiquidatePerpPnlForDepositIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, assetMarketIndex: number, maxPnlTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
resolvePerpBankruptcy(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getResolvePerpBankruptcyIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, liquidatorSubAccountId?: number | undefined) => Promise<TransactionInstruction>
resolveSpotBankruptcy(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
getResolveSpotBankruptcyIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, liquidatorSubAccountId?: number | undefined) => Promise<TransactionInstruction>
updateFundingRate(perpMarketIndex: number, oracle: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getUpdateFundingRateIx(perpMarketIndex: number, oracle: PublicKey) => Promise<TransactionInstruction>
updatePrelaunchOracle(perpMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getUpdatePrelaunchOracleIx(perpMarketIndex: number) => Promise<TransactionInstruction>
updatePerpBidAskTwap(perpMarketIndex: number, makers: [PublicKey, PublicKey][], txParams?: TxParams | undefined) => Promise<string>
getUpdatePerpBidAskTwapIx(perpMarketIndex: number, makers: [PublicKey, PublicKey][]) => Promise<TransactionInstruction>
settleFundingPayment(userAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getSettleFundingPaymentIx(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
triggerEvent(eventName: keyof DriftClientAccountEvents, data?: any) => void
getOracleDataForPerpMarket(marketIndex: number) => OraclePriceData
getMMOracleDataForPerpMarket(marketIndex: number) => MMOraclePriceData
getOracleDataForSpotMarket(marketIndex: number) => OraclePriceData
initializeInsuranceFundStake(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getInitializeInsuranceFundStakeIx(marketIndex: number) => Promise<TransactionInstruction>
getAddInsuranceFundStakeIx(marketIndex: number, amount: BN, collateralAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
addInsuranceFundStake({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, txParams, }: { marketIndex: number; amount: BN; collateralAccountPublicKey: PublicKey; initializeStakeAccount?: boolean; fromSubaccount?: boolean; txParams?: TxParams; }) => Promise<...>

Add to an insurance fund stake and optionally initialize the account

getAddInsuranceFundStakeIxs({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, }: { marketIndex: number; amount: BN; collateralAccountPublicKey: PublicKey; initializeStakeAccount?: boolean; fromSubaccount?: boolean; }) => Promise<TransactionInstruction[]>

Get instructions to add to an insurance fund stake and optionally initialize the account

requestRemoveInsuranceFundStake(marketIndex: number, amount: BN, txParams?: TxParams | undefined) => Promise<string>
cancelRequestRemoveInsuranceFundStake(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
removeInsuranceFundStake(marketIndex: number, collateralAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
updateUserQuoteAssetInsuranceStake(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getUpdateUserQuoteAssetInsuranceStakeIx(authority: PublicKey) => Promise<TransactionInstruction>
updateUserGovTokenInsuranceStake(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
getUpdateUserGovTokenInsuranceStakeIx(authority: PublicKey) => Promise<TransactionInstruction>
settleRevenueToInsuranceFund(spotMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getSettleRevenueToInsuranceFundIx(spotMarketIndex: number) => Promise<TransactionInstruction>
resolvePerpPnlDeficit(spotMarketIndex: number, perpMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
getResolvePerpPnlDeficitIx(spotMarketIndex: number, perpMarketIndex: number) => Promise<TransactionInstruction>
getDepositIntoSpotMarketRevenuePoolIx(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
depositIntoSpotMarketRevenuePool(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey) => Promise<string>

This ix will donate your funds to drift revenue pool. It does not deposit into your user account

getPerpMarketExtendedInfo(marketIndex: number) => PerpMarketExtendedInfo
getMarketFees(marketType: MarketType, marketIndex?: number | undefined, user?: User | undefined, enteringHighLeverageMode?: boolean | undefined) => { takerFee: number; makerFee: number; }

Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType

getMarketIndexAndType(name: string) => { marketIndex: number; marketType: MarketType; } | undefined

Returns the market index and type for a given market name E.g. “SOL-PERP” -> { marketIndex: 0, marketType: MarketType.PERP }

getReceiverProgram() => Program<PythSolanaReceiver>
getSwitchboardOnDemandProgram() => Promise<Program<Idl>>
postPythPullOracleUpdateAtomic(vaaString: string, feedId: string) => Promise<string>
postMultiPythPullOracleUpdatesAtomic(vaaString: string, feedIds: string[]) => Promise<string>
getPostPythPullOracleUpdateAtomicIxs(vaaString: string, feedIds: string | string[], numSignatures?: number | undefined) => Promise<TransactionInstruction[]>
getSinglePostPythPullOracleAtomicIxany
updatePythPullOracle(vaaString: string, feedId: string) => Promise<string>
getUpdatePythPullOracleIxs(params: { merklePriceUpdate: { message: Buffer; proof: number[][]; }; }, feedId: string, encodedVaaAddress: PublicKey) => Promise<TransactionInstruction>
postPythLazerOracleUpdate(feedIds: number[], pythMessageHex: string) => Promise<string>
getPostPythLazerOracleUpdateIxs(feedIds: number[], pythMessageHex: string, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined) => Promise<TransactionInstruction[]>
getPostManySwitchboardOnDemandUpdatesAtomicIxs(feeds: PublicKey[], recentSlothash?: Slothash | undefined, numSignatures?: number | undefined) => Promise<TransactionInstruction[] | undefined>
getPostSwitchboardOnDemandUpdateAtomicIx(feed: PublicKey, recentSlothash?: Slothash | undefined, numSignatures?: number | undefined) => Promise<TransactionInstruction | undefined>
postSwitchboardOnDemandUpdate(feed: PublicKey, recentSlothash?: Slothash | undefined, numSignatures?: number | undefined) => Promise<string>
getBuildEncodedVaaIxsany
enableUserHighLeverageMode(subAccountId: number, txParams?: TxParams | undefined) => Promise<string>
getEnableHighLeverageModeIx(subAccountId: number, depositToTradeArgs?: { isMakingNewAccount: boolean; depositMarketIndex: number; orderMarketIndex: number; } | undefined, overrides?: { user?: User; signingAuthority?: PublicKey; } | undefined) => Promise<...>
disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount | undefined, txParams?: TxParams | undefined) => Promise<string>
getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount | undefined, maintenance?: boolean | undefined) => Promise<TransactionInstruction>
fetchHighLeverageModeConfig() => Promise<HighLeverageModeConfig>
fetchProtectedMakerModeConfig() => Promise<ProtectedMakerModeConfig>
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey | undefined, txParams?: TxParams | undefined) => Promise<string>
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey | undefined) => Promise<TransactionInstruction>
getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number) => Promise<TransactionInstruction>
pauseSpotMarketDepositWithdraw(spotMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
updateMmOracleNative(marketIndex: number, oraclePrice: BN, oracleSequenceId: BN) => Promise<string>
getUpdateMmOracleNativeIx(marketIndex: number, oraclePrice: BN, oracleSequenceId: BN) => Promise<TransactionInstruction>
updateAmmSpreadAdjustmentNative(marketIndex: number, ammSpreadAdjustment: number) => Promise<string>
getUpdateAmmSpreadAdjustmentNativeIx(marketIndex: number, ammSpreadAdjustment: number) => TransactionInstruction
getLpPoolAccount(lpPoolId: number) => Promise<LPPoolAccount>
getConstituentTargetBaseAccount(lpPoolId: number) => Promise<ConstituentTargetBaseAccount>
getAmmCache() => Promise<AmmCache>
updateLpConstituentTargetBase(lpPoolId: number, constituents: PublicKey[], txParams?: TxParams | undefined) => Promise<string>
getUpdateLpConstituentTargetBaseIx(lpPoolId: number, constituents: PublicKey[]) => Promise<TransactionInstruction>
updateLpPoolAum(lpPool: LPPoolAccount, spotMarketIndexOfConstituents: number[], txParams?: TxParams | undefined) => Promise<string>
getUpdateLpPoolAumIxs(lpPool: LPPoolAccount, spotMarketIndexOfConstituents: number[]) => Promise<TransactionInstruction>
updateAmmCache(perpMarketIndexes: number[], txParams?: TxParams | undefined) => Promise<string>
getUpdateAmmCacheIx(perpMarketIndexes: number[]) => Promise<TransactionInstruction>
updateConstituentOracleInfo(constituent: ConstituentAccount) => Promise<string>
getUpdateConstituentOracleInfoIx(constituent: ConstituentAccount) => Promise<TransactionInstruction>
lpPoolSwap(inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, lpPool: PublicKey, userAuthority: PublicKey, txParams?: TxParams | undefined) => Promise<...>
getLpPoolSwapIx(inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, lpPool: PublicKey, userAuthority: PublicKey) => Promise<TransactionInstruction>
viewLpPoolSwapFees(inMarketIndex: number, outMarketIndex: number, inAmount: BN, inTargetWeight: BN, outTargetWeight: BN, lpPool: PublicKey, constituentTargetBase: PublicKey, constituentInTokenAccount: PublicKey, constituentOutTokenAccount: PublicKey, inConstituent: PublicKey, outConstituent: PublicKey, txParams?: TxParams | undefined...
getViewLpPoolSwapFeesIx(inMarketIndex: number, outMarketIndex: number, inAmount: BN, inTargetWeight: BN, outTargetWeight: BN, lpPool: PublicKey, constituentTargetBase: PublicKey, constituentInTokenAccount: PublicKey, constituentOutTokenAccount: PublicKey, inConstituent: PublicKey, outConstituent: PublicKey) => Promise<...>
getCreateLpPoolTokenAccountIx(lpPool: LPPoolAccount) => Promise<TransactionInstruction>
createLpPoolTokenAccount(lpPool: LPPoolAccount, txParams?: TxParams | undefined) => Promise<string>
lpPoolAddLiquidity({ inMarketIndex, inAmount, minMintAmount, lpPool, txParams, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
getLpPoolAddLiquidityIx({ inMarketIndex, inAmount, minMintAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction[]>
viewLpPoolAddLiquidityFees({ inMarketIndex, inAmount, lpPool, txParams, }: { inMarketIndex: number; inAmount: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
getViewLpPoolAddLiquidityFeesIx({ inMarketIndex, inAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction>
lpPoolRemoveLiquidity({ outMarketIndex, lpToBurn, minAmountOut, lpPool, txParams, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
getLpPoolRemoveLiquidityIx({ outMarketIndex, lpToBurn, minAmountOut, lpPool, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction[]>
viewLpPoolRemoveLiquidityFees({ outMarketIndex, lpToBurn, lpPool, txParams, }: { outMarketIndex: number; lpToBurn: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
getViewLpPoolRemoveLiquidityFeesIx({ outMarketIndex, lpToBurn, lpPool, }: { outMarketIndex: number; lpToBurn: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction>
getAllLpPoolAddLiquidityIxs({ inMarketIndex, inAmount, minMintAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; }, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined, view?: boolean | undefined) => Promise<...>
getAllLpPoolRemoveLiquidityIxs({ outMarketIndex, lpToBurn, minAmountOut, lpPool, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; }, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined, view?: boolean | undefined) => Promise<...>
getAllUpdateLpPoolAumIxs(lpPool: LPPoolAccount, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined) => Promise<TransactionInstruction[]>
getAllUpdateConstituentTargetBaseIxs(perpMarketIndexes: number[], lpPool: LPPoolAccount, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined) => Promise<...>
getAllLpPoolSwapIxs(lpPool: LPPoolAccount, constituentMap: ConstituentMap, inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, userAuthority: PublicKey) => Promise<...>
settlePerpToLpPool(lpPoolId: number, perpMarketIndexes: number[]) => Promise<string>
getSettlePerpToLpPoolIx(lpPoolId: number, perpMarketIndexes: number[]) => Promise<TransactionInstruction>
getAllSettlePerpToLpPoolIxs(lpPoolId: number, marketIndexes: number[]) => Promise<TransactionInstruction[]>
handleSignedTransactionany

Below here are the transaction sending functions

handlePreSignedTransactionany
isVersionedTransactionany
sendTransaction(tx: VersionedTransaction | Transaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>

Send a transaction.

buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined, recentBlockhash?: Readonly<...> | undefined, optionalIxs?: Transactio...
buildBulkTransactions(instructions: (TransactionInstruction | TransactionInstruction[])[], txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
buildTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
buildAndSignTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
isOrderIncreasingPosition(orderParams: OptionalOrderParams, subAccountId: number) => boolean

Step 2: Get oracle price

Read the current oracle price to calculate your bid/ask spread.

import { PRICE_PRECISION, convertToNumber } from "@drift-labs/sdk"; const marketIndex = 0; // SOL-PERP const oracle = driftClient.getOracleDataForPerpMarket(marketIndex); const oraclePrice = convertToNumber(oracle.price, PRICE_PRECISION); console.log(`Oracle price: $${oraclePrice}`);
Method DriftClient.getOracleDataForPerpMarketReference ↗
Parameters:
NameTypeDefault
marketIndexnumber
Returns:
OraclePriceData

Step 3: Place two-sided quotes

Place a bid (buy) below oracle and an ask (sell) above oracle. Using PostOnlyParams.MUST_POST_ONLY ensures your orders never cross and you always earn maker rebates.

import { PRICE_PRECISION, convertToNumber, MarketType, OrderType, PositionDirection, PostOnlyParams } from "@drift-labs/sdk"; const marketIndex = 0; // SOL-PERP const spread = 0.5; // $0.50 spread on each side const size = 0.1; // 0.1 SOL per order // Fetch oracle price for spread calculation const oracle = driftClient.getOracleDataForPerpMarket(marketIndex); const oraclePrice = convertToNumber(oracle.price, PRICE_PRECISION); const bidPrice = oraclePrice - spread; const askPrice = oraclePrice + spread; await driftClient.placeOrders([ { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex, direction: PositionDirection.LONG, baseAssetAmount: driftClient.convertToPerpPrecision(size), price: driftClient.convertToPricePrecision(bidPrice), postOnly: PostOnlyParams.MUST_POST_ONLY, }, { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex, direction: PositionDirection.SHORT, baseAssetAmount: driftClient.convertToPerpPrecision(size), price: driftClient.convertToPricePrecision(askPrice), postOnly: PostOnlyParams.MUST_POST_ONLY, }, ]); console.log(`Placed bid @ $${bidPrice}, ask @ $${askPrice}`);
Method DriftClient.placeOrdersReference ↗
Parameters:
NameTypeDefault
paramsOrderParams[]
txParamsTxParams
subAccountIdnumber
optionalIxsTransactionInstruction[]
isolatedPositionDepositAmountany
Returns:
Promise<string>

Step 4: Monitor and update

Check for fills and cancel/replace orders when the oracle moves. This complete example runs a loop that refreshes quotes every 10 seconds.

import { PRICE_PRECISION, BASE_PRECISION, convertToNumber, MarketType, OrderType, PositionDirection, PostOnlyParams, } from "@drift-labs/sdk"; const marketIndex = 0; const spread = 0.5; const size = 0.1; setInterval(async () => { try { // Check current position const user = driftClient.getUser(); const position = user.getPerpPosition(marketIndex); if (position) { const posSize = convertToNumber(position.baseAssetAmount, BASE_PRECISION); console.log(`Current position: ${posSize} SOL`); } // Cancel all existing orders for this market await driftClient.cancelOrders(MarketType.PERP, marketIndex); // Re-fetch oracle price const oracle = driftClient.getOracleDataForPerpMarket(marketIndex); const oraclePrice = convertToNumber(oracle.price, PRICE_PRECISION); const bidPrice = oraclePrice - spread; const askPrice = oraclePrice + spread; // Place fresh two-sided quotes await driftClient.placeOrders([ { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex, direction: PositionDirection.LONG, baseAssetAmount: driftClient.convertToPerpPrecision(size), price: driftClient.convertToPricePrecision(bidPrice), postOnly: PostOnlyParams.MUST_POST_ONLY, }, { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex, direction: PositionDirection.SHORT, baseAssetAmount: driftClient.convertToPerpPrecision(size), price: driftClient.convertToPricePrecision(askPrice), postOnly: PostOnlyParams.MUST_POST_ONLY, }, ]); console.log(`Updated quotes: bid $${bidPrice.toFixed(2)} / ask $${askPrice.toFixed(2)}`); } catch (err) { console.error("Error updating quotes:", err); } }, 10_000); // Update every 10 seconds
Method DriftClient.cancelOrdersReference ↗
Parameters:
NameTypeDefault
marketTypeMarketType
marketIndexnumber
directionPositionDirection
txParamsTxParams
subAccountIdnumber
Returns:
Promise<string>

Tip: This cancel-and-replace approach sends ~2 transactions every 10 seconds. For production, consider oracle offset orders which float with the oracle automatically and require only ~30 txs/day.

Next steps

This basic example gets you started, but production market makers need:

  • Oracle offset orders , orders that automatically track oracle price, drastically reducing transactions (Normal MM)
  • Inventory management , adjust spread based on position size (Normal MM)
  • Risk controls , position limits, health checks, emergency cancel (Bot Architecture)
  • JIT participation , compete in auctions for better fills (JIT-only MM)
  • Efficient subscriptions , WebSocket or gRPC for lower latency (Bot Architecture)
  • Multiple markets , quote across markets simultaneously

Common pitfalls

  • Forgetting PostOnlyParams , without it, your “maker” orders can cross the spread and execute as taker, paying fees instead of earning rebates
  • Using PRICE_PRECISION wrong , oracle prices are in PRICE_PRECISION (1e6), base amounts in BASE_PRECISION (1e9). Mixing them up causes orders at wildly wrong prices
  • Not initializing user account , first-time users must call driftClient.initializeUserAccount() before placing orders. The SDK will throw User account not found otherwise
  • 32-order limit , each Drift subaccount supports a maximum of 32 open orders. Cancel stale orders or use multiple subaccounts for multi-market strategies

For production patterns and best practices, see:

Last updated on