Main SDK functions
By using any API provided by Drift Labs, you agree to the https://docs.drift.trade/legal-and-regulations/terms-of-use. If you do not agree to the foregoing, then do not use any such API.
Introduction
Drift Protocol is an open-sourced, decentralised exchange built on the Solana blockchain, enabling transparent and non-custodial trading on cryptocurrencies.
There are language bindings in Typescript and Python! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
This API documentation page is open sourced and available here was created with Slate. Feel free to submit questions/comments in Issues or suggest changes as a PR.
Program Addresses
It is strictly against the https://docs.drift.trade/legal-and-regulations/terms-of-use to use these interfaces from a Restricted Territory.
Authentication
To access and interact with a blockchain, such as Solana, you need a keypair, which consists of a public key and a private key. The private key should be kept secure and not shared with anyone else.
To generate a new keypair, you can use the Solana Tool Suite by running the following command on the command line:
solana-keygen new --outfile ~/.config/solana/my-keypair.jsonThis command will create a new keypair and store it in a JSON file located at ~/.config/solana/my-keypair.json.
To allow SDK code to use this keypair for authentication, you need to set the ANCHOR_WALLET environment variable to the path of the JSON file that contains the keypair. You can do this by running the following command:
This command sets the ANCHOR_WALLET environment variable to the path of the JSON file that contains your keypair, so that SDK code can access it when needed.
Client
Typescript
Install @drift-labs/sdk from npm using yarn:
Auto-generated documentation https://drift-labs.github.io/protocol-v2/sdk/
Python
Install driftpy from PyPI using pip:
Auto-generated documentation https://drift-labs.github.io/driftpy/
HTTP
Use the self-hosted HTTP API gateway
Connection
The connection object is used to send transactions to the Solana blockchain. It is used by the DriftClient to send transactions to the blockchain.
Wallet
The wallet used to sign solana transactions. The wallet can be created from a private key or from a keypair file.
Make sure this wallet has some SOL first. SOL is used to pay for transactions and is required as rent for account intializations.
Client Initialization
DriftClient can be initialized with a dummy wallet for read-only or testing purposes. A valid private key is only required when signing transactions.
TypeScript parameters
connection
Connection object specifying solana rpc url
No
wallet
The wallet used to sign transactions sent to solana blockchain
No
programId
Drift program id
Yes
dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH
env
devnet or mainnet-beta. Used to automatically derive market accounts to subscribe to if they're not explicitly set
Yes
perpMarketIndexes
Which perp markets accounts to subscribe to.
Yes
Derived based on env
spotMarketIndexes
Which spot markets accounts to subscribe to.
Yes
Derived based on env
oracleInfos
Which oracles accounts to subscribe to.
Yes
Derived based on env
accountSubscription
Whether to use websocket or polling to subscribe to on-chain accounts e.g. markets, users, oracle.
Yes
Websockets
opts
Transaction confirmation status options
Yes
{preflightCommitment: "processed", commitment: "processed"}
activeSubAccountId
Which sub account to use initially
Yes
0
subAccountIds
All the sub account ids to subscribe to. If this and authoritySubAccountMap are empty, subscribes to all sub account ids.
Yes
[]
authority
Which user account authority you're signing for. Only set if you're signing for delegated account.
Yes
wallet.publicKey
authoritySubAccountMap
Map of authority to sub account ids to subscribe to. Only necessary if using multiple delegate accounts. If this and subAccountIds are empty, subscribes to all sub account ids.
Yes
{}
includeDelegates
Whether or not to subscribe to delegates when subAccountIds and authoritySubAccountMap are empty
Yes
false
userStats
Whether or not to listen subscribe to user stats account.
Yes
false
Python parameters
connection
AsyncClient connection to the Solana cluster
No
wallet
Wallet object, can be Keypair or Wallet type
No
env
Drift environment, 'devnet' or 'mainnet'
Yes
"mainnet"
program_id
Drift program identifier
Yes
DRIFT_PROGRAM_ID
opts
Options for transaction confirmation status
Yes
DEFAULT_TX_OPTIONS
authority
Public key of the user account authority
Yes
None
account_subscription
Configuration for account subscriptions (websockets/polling)
Yes
AccountSubscriptionConfig.default()
perp_market_indexes
List of perpetual market indexes to interact with
Yes
None
spot_market_indexes
List of spot market indexes to interact with
Yes
None
oracle_infos
List of OracleInfo objects for market data
Yes
None
tx_params
Additional parameters for transactions
Yes
None
tx_version
Version of the transaction
Yes
None
tx_sender
Object handling the sending of transactions
Yes
None
active_sub_account_id
ID of the initially active sub-account
Yes
None
sub_account_ids
List of sub-account IDs to subscribe to
Yes
None
market_lookup_table
Public key for the market lookup table
Yes
None
Client Initialization for Delegate accounts
When subscribing to the client for delegate accounts, you have to be explicit about the following parameters:
User Initialization
TypeScript
subAccountId
The sub account id for the new user account.
Yes
0
name
Display name for the user account
Yes
Main Account
referrerInfo
The address of the referrer and referrer stats accounts
Yes
Python
sub_account_id
The sub account id for the new user account.
Yes
0
name
Display name for the user account
Yes
None
referrer_info
The address of the referrer and referrer stats accounts
Yes
None
Sub account ids are monotonic. The first user account created will have sub account id 0, the second will have sub account id 1, etc. The next sub account id can be found by calling driftClient.getNextSubAccountId() in TypeScript.
Updating User
Users accounts can update names, set custom max intial margin ratio, enable margin trading, and add a delegate account.
Switching Sub Accounts
TypeScript
subAccountId
The sub account to switch to
No
0
authority
The authority of the sub account you're signing for. Only needed for delegate accounts
Yes
Current authority
Python
sub_account_id
Identifier for the sub-account to be activated
No
Deleting User Account
If an account contains no assets or liabilites, a user account can be deleted to reclaim rent.
Depositing
TypeScript
amount
The amount to deposit in spot market's token mint precision
No
marketIndex
The spot market index you're depositing into
No
associatedTokenAccount
The public key of the token account you're depositing from. For sol, it can be the wallet's public key
No
None (will derive ATA)
subAccountId
The sub account you're depositing to
Yes
active sub account
reduceOnly
Whether the deposit should only reduce borrow
Yes
false
Python
amount
The amount to deposit in the spot market's token mint precision
No
spot_market_index
The index of the spot market where the deposit is made
No
user_token_account
The public key of the token account you're depositing from. For sol, it can be the wallet's public key
No
None (will derive ATA)
sub_account_id
The sub account to which the deposit is being made
Yes
Active sub-account
reduce_only
Whether the deposit should only reduce borrow
Yes
false
user_initialized
Indicates if the user is already initialized (used internally, typically)
Yes
true
Withdrawing
TypeScript
amount
The amount to withdraw in spot market's token mint precision
No
marketIndex
The spot market index you're withdrawing from
No
associatedTokenAccount
The public key of the token account you're withdrawing to. For sol, it can be the wallet's public key
No
reduceOnly
Whether the withdraw should only decrease a deposit and block a new borrow
Yes
false
Python
amount
The amount to withdraw in the spot market's token mint precision
No
market_index
The index of the spot market from which the withdrawal is made
No
user_token_account
The public key of the token account to which you are withdrawing
No
reduce_only
Whether the withdrawal should only decrease a deposit, blocking new borrows
Yes
false
sub_account_id
The sub account from which the withdrawal is made
Yes
None
Withdrawing can lead to a borrow if the user has no deposits in the market and the user has enough margin to cover it.
Transferring Deposits
TypeScript
amount
The amount to transfer in spot market's token mint precision
No
marketIndex
The spot market index you're transferring deposits in
No
fromSubAccountId
The sub account you're withdrawing from
No
toSubAccountId
The sub account you're depositing too
No
Python
amount
The amount to transfer in the spot market's token mint precision
No
market_index
The spot market index you're transferring deposits in
No
from_sub_account_id
The sub account from which the funds are withdrawn
No
to_sub_account_id
The sub account to which the funds are deposited
No
Transferring Positions
This function allows users to transfer a perpetual position from one sub account to another. Both accounts must belong to the same authority.
Typescript
fromSubAccountId
The sub-account ID from which the position will be transferred.
No
toSubAccountId
The destination sub-account ID to which the position will be transferred.
No
marketIndex
The index of the market where the position exists.
No
amount
The amount of the position to transfer between sub-accounts.
No
Order Types
TypeScript
MARKET, LIMIT, ORACLE orders all support auction parameters.
MARKET
Market order.
LIMIT
Limit order.
TRIGGER_MARKET
Stop / Take-profit market order.
TRIGGER_LIMIT
Stop / Take-profit limit order.
ORACLE
Market order using oracle offset for auction parameters.
Python
Market(), Limit(), Oracle() orders all support auction parameters.
Market()
Market order.
Limit()
Limit order.
TriggerMarket()
Stop / Take-profit market order.
TriggerLimit()
Stop / Take-profit limit order.
Oracle()
Market order using oracle offset for auction parameters.
Order Params
TypeScript
orderType
The type of order e.g. market, limit
No
marketIndex
The market to place order in
No
direction
The direction of order e.g. long (bid) or short (ask)
No
baseAssetAmount
The amount of base asset to buy or sell
No
marketType
The type of market order is for e.g. PERP or SPOT
Yes
Depends on method
price
The limit price for order
Yes
0
userOrderId
Unique order id specified by user
Yes
0
reduceOnly
If the order can only reduce positions
Yes
false
postOnly
If the order can only be a maker
PostOnlyParam
None
triggerPrice
at what price order is triggered. only applicable for triggerMarket and triggerLimit orders
Yes
triggerCondition
whether order is triggered above or below triggerPrice. only applicable for triggerMarket and triggerLimit orders
Yes
oraclePriceOffset
priceOffset for oracle derived limit price. only applicable for limit and oracle orders
Yes
auctionDuration
how many slots the auction lasts. only applicable for market and oracle orders
Yes
auctionStartPrice
the price the auction starts at
Yes
auctionEndPrice
the price the auction ends at
Yes
maxTs
the max timestamp (on-chain unix timestamp) before the order expires
Yes
bitFlags
add additional order hooks (e.g. enter high leverage mode)
Yes
Python
order_type
Type of order
No
market_index
Index of the market to place order in
No
direction
Direction of the order
No
base_asset_amount
Amount of base asset to buy or sell
No
market_type
Type of market
Yes
Depends on method
price
Limit price for the order
Yes
0
user_order_id
Unique order ID specified by user
Yes
0
reduce_only
Whether the order is only to reduce positions
Yes
false
post_only
If the order should only be a maker
Yes
PostOnlyParams.NONE()
immediate_or_cancel
Whether the order is immediate or cancel
Yes
false
max_ts
Max timestamp for the order expiry
Yes
None
trigger_price
Trigger price for trigger orders
Yes
None
trigger_condition
Condition for triggering the order
Yes
OrderTriggerCondition.Above()
oracle_price_offset
Offset for oracle-derived limit price
Yes
None
auction_duration
Duration of the auction in slots
Yes
None
auction_start_price
Starting price of the auction
Yes
None
auction_end_price
Ending price of the auction
Yes
None
Post Only Params
Drift orderbook is not a strict clob that enforces price-time priority. This is to maximize the parallelization of placing orders to take advantage of the solana runtime. To force an order to always be a maker, users most set the post only params. If a user order is set to post only, drift will check that an order does not cross the vamm spread, similar to how a traditional clob would check that an order doesn't cross the book's best bid/ask. If the post only is not used, a limit order can end up being a taker or maker.
None
Does not enforce being maker
MustPostOnly
Tx fails if order crosses the vamm
TryPostOnly
Order is skipped (not placed) and tx succeeds if order crosses the vamm
Slide
Order price is modified to be one tick below/above the vamm ask/bid
Placing Perp Order
Setting optimal order parameters
The Drift UI uses the Auction params endpoint to get the recommended order parameters for a market order, based on the DLOB. This endpoint is accessible here
TypeScript
orderParams
The order params
No
Python
order_params
The order params
No
The order type is set to PERP / Perp() by default.
Placing Spot Order
TypeScript
orderParams
The order params
No
Python
order_params
The order params
No
The order type is set to SPOT / Spot() by default.
Placing Multiple Orders
TypeScript
placeOrderParams
Parameters for place order instructions
Python
place_order_params
Parameters for place order instructions
Placing multiple orders in one tx can be cheaper than placing them in separate tx.
Placing Oracle Market Orders
Oracle market orders enable a user to define their auction params as an offset (or relative to) the oracle price.
Canceling Order
TypeScript
orderId
The order being canceled
No
Python
order_id
The order being canceled
No
sub_account_id
Sub account to cancel order under
Yes
None
Canceling Order By User Order Id
TypeScript
userOrderId
Unique order id specified by user when order was placed
No
Python
user_order_id
Unique order id specified by user when order was placed
No
sub_account_id
Sub account to cancel orders under
Yes
None
Cancel Orders
TypeScript
marketType
The market type of orders to cancel. Must be set if marketIndex set
Yes
marketIndex
The market index of orders to cancel. Must be set if marketType set
Yes
direction
The direction of orders to cancel.
Yes
Python
market_type
The market type of orders to cancel
Yes
None
market_index
The market index of orders to cancel
Yes
None
direction
The direction of orders to cancel
Yes
None
sub_account_id
The sub account from which to cancel orders
Yes
None
To cancel all orders, do not set any parameters.
Cancel and Place Orders
TypeScript
cancelOrderParams
Parameters for cancel orders instruction
placeOrderParams
Parameters for place order instructions
Python
cancel_params
Tuple with optional MarketType, market index, and PositionDirection for canceling orders
Yes
None
place_order_params
List of OrderParams for placing new orders
No
sub_account_id
The sub account to use
Yes
None
To cancel all orders, do not set any parameters.
Modify Order Params
TypeScript
orderId
The order id of order to modify
No
baseAssetAmount
The amount of base asset to buy or sell
Yes
direction
The direction of order e.g. long (bid) or short (ask)
Yes
limitPrice
The limit price for order
Yes
reduceOnly
If the order can only reduce positions
Yes
postOnly
If the order can only be a maker
Yes
triggerPrice
at what price order is triggered. only applicable for triggerMarket and triggerLimit orders
Yes
triggerCondition
whether order is triggered above or below triggerPrice. only applicable for triggerMarket and triggerLimit orders
Yes
oraclePriceOffset
priceOffset for oracle derived limit price. only applicable for limit and oracle orders
Yes
auctionDuration
how many slots the auction lasts. only applicable for market and oracle orders
Yes
auctionStartPrice
the price the auction starts at
Yes
auctionEndPrice
the price the auction ends at
Yes
maxTs
the max timestamp before the order expires
Yes
Python
direction
The direction of the order
Yes
None
base_asset_amount
Amount of base asset to buy or sell
Yes
None
price
Limit price for the order
Yes
None
reduce_only
If the order should only reduce positions
Yes
None
post_only
If the order should only be a maker order
Yes
None
immediate_or_cancel
Whether the order is immediate or cancel
Yes
None
max_ts
Max timestamp for order expiry
Yes
None
trigger_price
Trigger price for trigger orders
Yes
None
trigger_condition
Condition for triggering the order
Yes
None
oracle_price_offset
Offset for oracle-derived limit price
Yes
None
auction_duration
Duration of the auction in slots
Yes
None
auction_start_price
Starting price of the auction
Yes
None
auction_end_price
Ending price of the auction
Yes
None
policy
Policy for modifying the order
Yes
None
Modifying Order
TypeScript
orderId
The order id of order to modify
No
modifyOrderParams
The modify order params
Yes
Python
order_id
The order ID of the order to modify
No
modify_order_params
The parameters for modifying the order
No
sub_account_id
The sub account to use
Yes
None
Modify cancels and places a new order
For typescript, the orderId and modifyOrderParams are merged into a single object and some properties are prefixed with new e.g. newBaseAssetAmount
Modifying Order By User Order Id
TypeScript
userOrderId
The user order id of order to modify
No
modifyOrderParams
The modify order params
Yes
Python
user_order_id
The user order ID of the order to modify
No
modify_order_params
The parameters for modifying the order
No
sub_account_id
The sub-account ID associated with the order
Yes
None
Modify cancels and places a new order
For typescript, the userOrderId and modifyOrderParams are merged into a single object and some properties are prefixed with new e.g. newBaseAssetAmount
Settle Perp PNL
TypeScript
settleeUserAccountPublicKey
User address you're settling pnl for
No
settleeUserAccount
User account data you're settling pnl for
No
marketIndex
Market index for the perp market
No
Python
settlee_user_account_public_key
Public key of the user account to settle PNL for
No
settlee_user_account
User account data for PNL settlement
No
market_index
Index of the perpetual market for PNL settlement
No
Get Spot Market Account
TypeScript
marketIndex
The market index for the spot market
No
Python
market_index
The market index for the spot market
No
Get Perp Market Account
TypeScript
marketIndex
The market index for the perp market
No
Python
market_index
The market index for the perp market
No
Swift
Swift is an extension to Drift which enables users to place orders without needing to submit a transaction to the Solana network. Instead of having users submit transactions to the Solana network, users sign a message containing their order parameters and submit it to keepers and market makers offchain. Keepers and market makers then bundle the message with their transaction to fill user orders.
Orders have to be submitted to the Swift API: https://swift.drift.trade
Order setup
Similar to normal orders, order parameters need to be defined. Order parameters overview: https://drift-labs.github.io/v2-teacher/#order-params
To pass an order to Swift, the following steps are required:
Order example (market taker)
Sign order
Submit order to Swift API
When submitting an order, the POST request to the Swift API (/orders) must include the following parameters:
market_index
The type of order e.g. market, limit
No
market_type
The market to place order in
No
message
Signed order message
No
signature
Signature generated by signing the message
No
taker_authority
Public key of the user account for which the order is being placed(authority).
No
signing_authority
Public key of the signing authority (delegate) that signs the order message
Yes
Initialize the client as a delegate.
Double check that taker_pubkey and signing_authority are passed in correctly.
Builder Codes
Drift’s Builder Code (DBC) system enables any builder to build on top of Drift while earning fees for routing trades. Buildercodes are enabled by Swift, and are light to implement by design. The only difference to a normal Swift order, is that builderIdx and builderFee are added to the signed message.
Builder initialization
In order to receive fees, builders are required to have an existing Drift account, as well as set up a RevenueShareAccount
User initialization
RevenueShareEscrow Account
Each taker/user must initialize a RevenueShareEscrow account before they are able to start paying builder fees. In practice this is an on boarding step provided by the builder.
numOrders should be large enough to hold all open orders that the taker will have at any point. Since a user can have multiple subaccounts, it's recommended for builders to set numOrders to be more than 8.
Builder approval
Each taker must approve every builder with their max payable fee before builder fees can be charged. The max fee is expressed in tenth of a basis point (100 = 10 bps).
Order placement
Buildercodes are enabled by Swift, this is achieved by setting the builderIdx and builderFee in the signed message. The builder’s app constructs this place_order transaction, and sends it to the Swift server.
User
Get User
TypeScript
subAccountId
The sub account id of user to get
Yes
active sub account
authority
The authority of user to get. Only necessary if using multiple delegate accounts
Yes
current authority
Python
sub_account_id
The sub account id of user to get
Yes
active sub account
Getting Deposit/Borrow Amounts
TypeScript
marketIndex
Market index for the spot market
No
Python
market_index
Market index for the spot market
No
If token amount is greater than 0, it is a deposit. If less than zero, it is a borrow.
Get Perp Position
TypeScript
marketIndex
Market index for the perp market
No
Python
market_index
Market index for the perp market
No
If base amount is greater than 0, it is a long. If less than zero, it is a short.
Get Order
TypeScript
orderId
Order id for the order you're getting
No
Python
order_id
Order id for the order you're getting
No
Get Order By User Order Id
TypeScript
userOrderId
User order id for the order you're getting
No
Python
user_order_id
User order id for the order you're getting
No
Get Open Orders
Get Unrealized Perp Pnl
TypeScript
withFunding
Whether to include unsettled funding payments
Yes
false
marketIndex
Index of a specific market for PNL calculation
Yes
withWeightMarginCategory
To include margin category weighting in PNL calculation
Yes
strict
Whether the calculation should be strict
Yes
false
Python
with_funding
Whether to include unsettled funding payments
Yes
false
market_index
Index of a specific market for PNL calculation
Yes
with_weight_margin_category
To include margin category weighting in PNL calculation
Yes
strict
Whether the calculation should be strict
Yes
false
Get Unrealized Funding Pnl
TypeScript
marketIndex
Whether to only return pnl for specific market
Yes
Python
market_index
Whether to only return pnl for specific market
Yes
Get Total Collateral
TypeScript
marginCategory
Initial or Maintenance
Yes
Initial
strict
Whether the calculation should be strict
Yes
false
Python
margin_category
Initial or Maintenance
Yes
Initial
strict
Whether the calculation should be strict
Yes
false
Asset weights vary based on whether you're checking the initial or maintenance margin requirement. Initial is used for initial leverage extension, maintenance for determining liquidations.
Get Margin Requirement
TypeScript
marginCategory
The type of margin (Initial or Maintenance)
No
liquidationBuffer
Buffer value for liquidation calculation
Yes
strict
Whether the calculation should be strict
Yes
false
Python
margin_category
Type of margin, either Initial or Maintenance
Yes
MarginCategory.INITIAL
liquidation_buffer
Additional buffer value for liquidation calculation
Yes
0
strict
Whether the calculation should be strict
Yes
False
Liability weights (for borrows) and margin ratios (for perp positions) vary based on whether you're checking the initial or maintenance margin requirement. Initial is used for initial leverage extension, maintenance for determining liquidations.
Get Free Collateral
TypeScript
marginCategory
Initial or Maintenance
Yes
Initial
Python
marginCategory
Type of margin, either Initial or Maintenance
Yes
MarginCategory.INITIAL
Free collateral is the difference between your total collateral and your margin requirement.
Get Leverage
TypeScript
includeOpenOrders
Whether to factor in open orders in position size
Yes
true
Python
include_open_orders
Whether to factor in open orders in position size
Yes
True
Leverage is the total liability value (borrows plus total perp position) divided by net asset value (total assets plus total liabilities)
Events
Event Subscription
Subscribing to Drift Events is a core component necessary to react to events happening in Drift. The Drift SDK has an Event Subscriber class to help you do this.
You should also note that you can Serialize and Deserialize Drift Events using the Serializer class exported from the Drift Common library (@drift/common on npm). There are "UI" versions of the deserialized records available where the BN numbers have been cast into our own BigNum class which makes it easier to work with the numbers inside the records.
TypeScript
connection
Connection object specifying solana rpc url
No
program
Anchor program object used to deserialize events from transaction logs
No
options.eventTypes
Which events types to trigger event callbacks for
Yes
All events
options.maxTx
Max number of transactions to keep in memory
Yes
4096
options.maxEventsPerType
Max number of events per event type to keep in memory
Yes
4096
options.orderBy
Whether to sort the tx in memory by the order they occurred on chain ('blockchain') or received by client ('client')
Yes
'blockchain'
options.orderDir
Whether to sort the tx in memory to be most recent ('desc') or oldest ('asc')
Yes
'asc'
options.commitment
What transaction commitment to wait for
Yes
'confirmed'
options.logProviderConfig
How to get events: RPC Polling, RPC Websocket, or the Drift Events Server
Yes
{type: polling/websocket/events-server, url?: {events_server_url}} see Environment Constants for the Events Server URL to use
options.address
Which address to listen to events for. Defaults to drift program.
Yes
dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH
Python
connection
AsyncClient object specifying Solana RPC URL
No
program
Anchor program object used to deserialize events from transaction logs
No
options
Configuration options for event subscription
Yes
EventSubscriptionOptions.default()
- address
Address to listen to events for, defaults to Drift program
Yes
DRIFT_PROGRAM_ID
- event_types
Types of events to trigger event callbacks for
Yes
DEFAULT_EVENT_TYPES
- max_events_per_type
Maximum number of events per event type to keep in memory
Yes
4096
- order_by
Sort order of transactions, by 'blockchain' order or 'client' received order
Yes
"blockchain"
- order_dir
Sorting direction, either most recent ('desc') or oldest ('asc')
Yes
"asc"
- commitment
Transaction commitment level to wait for
Yes
"confirmed"
- max_tx
Maximum number of transactions to keep in memory
Yes
4096
- log_provider_config
Configuration for log provider, either websocket or polling
Yes
WebsocketLogProviderConfig()
- until_tx
Signature to listen until, used for log provider
Yes
None
Protocol events are recorded in transactions logs. To listen for events, one must subscribe to the drift program's transaction logs.
Event Types
DepositRecord
A record of a user depositing or withdrawing funds from protocol
FundingPaymentRecord
A record of a user paying/receiving funding payments
LiquidationRecord
A record of a user being liquidated
OrderRecord
A record of a user placing an order, including all of its parameters
OrderActionRecord
A record of a user action on an order, including place, cancel and fill
FundingRateRecord
A record of the funding rate changing
NewUserRecord
A record of a new user
SettlePnlRecord
A record of a user settling their pnl
LPRecord
A record of a user adding or removing passive perp liquidity
InsuranceFundRecord
A record of the insurance fund changing
SpotInterestRecord
A record of the spot interest changing
InsuranceFundStakeRecord
A record of a user staking or unstaking from the insurance fund
CurveRecord
A record of the amm curve updating
Listening to Perp Market Fills
Listening to User Fills
Getting Events Received By Type
This returns all the events that the event subscriber currently has stored in memory.
Getting Events By Transaction
This returns the events that the event subscriber currently has stored in memory for a given transaction.
Margin System
Drift offers a cross-collateral margining system, allowing users to utilize multiple assets as trading collateral.
The margining system tracks each user's total collateral, the weighted sum of the user's deposits and perp pnl, as well as their margin requirement, the weighted value out the user's outstanding borrow and perp positions.
Total collateral is calculated as:
Where
d_i is the deposit amount for spot market i
p_i is the price for spot market i
w_i^a is the asset weight for spot market i
pnl_j is the pnl for perp market j
qp_j is the quote asset price for perp market j
w_j^{pnl} is the pnl weight for perp market j
Margin requirement is calculated as:
Where
b_i is the borrow amount for spot market i
p_i is the price for spot market i
w_i^l is the liability weight for spot market i
ba_j is the base amount for perp market j
o_j is the price for perp/prediction market j
qp_j is the quote asset price for perp market j
m_j is the margin ratio for perp market j
The weights and margin ratios depend on whether you're calculating the initial or maintenance values.
The initial maintenance check governs leverage extension. To open a new perp position or borrow, a user's initial total collateral must be greater than their initial margin requirement.
The maintenance check governs when a user's position must be liquidated. If a user's maintenance total collateral drops below their maintenance margin requirement, a user's position can be liquidated to reduce their risk.
The prices used for deposits, borrows and perp quote assets differ between the initial and maintenance checks. The maintenance check uses the current oracle price. The initial check uses the min(oracle_price, oracle_twap) for deposits and positive perp pnl and max(oracle_price, oracle_twap) for borrows, negative perp pnl and perp base amount.
For prediction markets, the price used in the margin system depends on the direction of the position. For short positions (betting no), the margin system uses 1 - oracle price. For long position (betting yes), it uses the oracle price. This is the account for the user's worst case loss. E.g. if a user shorts at $.01, their worst case loss is $.99.
Numerical Precisions
To maintain numerical precision, the on-chain program stores all values as integers.
Getting a Current Perp Position
This prints the size of the current perp position in perp market index 0 (SOL-PERP)
Getting a Current Spot Position
This prints the current spot position in spot market index 0 (USDC). This value is the same as the value shown on the UI, it includes any accumulated interest.
Common precision values
perp base asset amount
1e9
BASE_PRECISION
perp quote asset amount
1e6
QUOTE_PRECISION
price
1e6
PRICE_PRECISION
funding rate
1e9
FUNDING_RATE_PRECISION
spot token amount
derived from token mint's decimals (USDC is 1e6, SOL is 1e9)
SpotMarketConfig.precision
spot token balance
1e9
SPOT_MARKET_BALANCE_PRECISION
margin ratio
1e4
MARGIN_PRECISION
asset/liability weight
1e4
SPOT_WEIGHT_PRECISION
imf weight precision
1e6
SPOT_IMF_PRECISION
Drift Vaults
Drift Vaults are permissionless programs that let users deposit and withdraw tokens from a shared pool managed by a single delegate. The delegate can only place or cancel orders on behalf of the vault, with no access to user funds.
A more indepth explanation of vaults can be found on the wiki.
Vault cli
Anyone can setup their own vault with desired configuration.
The cli utility to aid in the creation of vaults, can be found here.
Clone and install dependencies for the cli
Manager commands
The following commands are meant to be run by Vault Managers.
Initialize a new vault
This will initialize a new vault and update the manager as the delegate, unless --delegate is specified. Note that vault name must be unique.
-n, --name
<string>
Name of the vault to create
—
-i, --market-index
<number>
Spot market index to accept for deposits (0 = USDC)
"0"
-r, --redeem-period
<number>
Period (in seconds) depositors must wait after requesting a withdrawal
"604800" (7 days)
-x, --max-tokens
<number>
Maximum number of tokens (by market index) the vault can accept (0 = unlimited)
"0"
-m, --management-fee
<percent>
Annualized management fee charged to depositors
"0"
-s, --profit-share
<percent>
Percentage of profits charged by the manager
"0"
-p, --permissioned
flag
Makes the vault permissioned; depositors must be initialized by the manager
false
-a, --min-deposit-amount
<number>
Minimum token amount allowed for deposit
"0"
-d, --delegate
<publicKey>
Address to be set as the delegate of the vault
—
-h, --help
flag
Display help information for this command
—
Update vault
To update params in a vault:
--vault-address
<address>
Address of the vault to update
-r, --redeem-period
<number>
New redeem period in seconds (can only be lowered)
-x, --max-tokens
<number>
Max tokens the vault can accept
-a, --min-deposit-amount
<number>
Minimum token amount allowed to deposit
-m, --management-fee
<percent>
New management fee (can only be lowered)
-s, --profit-share
<percent>
New profit share percentage (can only be lowered)
-p, --permissioned
<boolean>
Set the vault as permissioned (true) or open (false)(default)
-h, --help
flag
Display help information for this command
Update margin trading
If you wish to trade with spot margin on the vault, you must enable margin trading:
Manager Deposit
Make a deposit into a vault as the manager (DEPOSIT_AMOUNT in human precision, e.g. 5 for 5 USDC):
Manager Withdraw
Make a withdraw request from a vault as the manager (SHARES in raw precision):
After the redeem period has passed, the manager can complete the withdraw:
Depositor Commands
Deposit into a vault
Permissioned Vaults
Permissioned vaults require the manager to initialize the VaultDepositor account before a depositor can deposit.
Initialize a VaultDepositor account for AUTHORITY_TO_ALLOW_DEPOSIT to deposit:
Permissioneless Vaults
Permissionless vaults allow anyone to deposit. The deposit instruction will initialize a VaultDepositor account if one does not exist. DEPOSIT_AMOUNT in human precision of the deposit token (e.g. 5 for 5 USDC).
Alternatively, you can pass in the VaultDepositor address directly:
Withdraw from a vault
Request a withdraw from a vault:
After the redeem period has passed, the depositor can complete the withdraw:
View only commands
To print out the current state of a Vault:
To print out the current state of a VaultDepositor:
Vault Manager UI template
The Vaults UI Template is a fullstack Next.js interface for managing and interacting with Drift Vaults.
Manager tools: create vaults, update parameters, manage delegate settings
User interface: deposit/withdraw, view vault and depositor history
Includes built-in API routes for vault creation, snapshot indexing, and analytics.
Jupiter Spot Swaps
You can perform Jupiter swaps directly from DriftClient, which fetches quotes from Jupiter and routes the transaction for the optimal rates.
TypeScript
To preview the quote before swapping, use jupiterClient.getQuote(...).
jupiterClient
Instance of JupiterClient used to get quotes and swap instructions
No
inMarketIndex
Drift spot market index for the input token
No
outMarketIndex
Drift spot market index for the output token
No
amount
Amount to swap, as a BN in spot market precision
No
slippageBps
Maximum allowed slippage in basis points
Yes
50
onlyDirectRoutes
If true, restricts swap to direct token pairs only
Yes
false
computeUnits
Override for compute budget
Yes
prioritizationFeeMicroLamports
Priority fee in micro lamports
Yes
userPublicKey
Override of user wallet
Yes
wallet.publicKey
Python
Unlike the Typescript SDK, DriftPy makes direct HTTP calls to Jupiter. The function returns a tuple of (instructions, address_lookup_tables) that can be sent using drift_client.send_ixs(). The Jupiter API URL is configurable via the JUPITER_URL environment variable.
out_market_idx
Drift spot market index for the output token
No
in_market_idx
Drift spot market index for the input token
No
amount
Amount to swap, in spot market precision
No
slippage_bps
Maximum allowed slippage in basis points
Yes
50
only_direct_routes
If true, restricts swap to direct token pairs only
Yes
False
quote
Pre-fetched Jupiter quote
Yes
None
reduce_only
SwapReduceOnly parameter
Yes
False
user_account_public_key
Override of user wallet
Yes
wallet.public_key
swap_mode
Swap mode
Yes
"ExactIn"
fee_account
Optional fee account
Yes
None
platform_fee_bps
Platform fee in basis points
Yes
None
max_accounts
Maximum number of accounts
Yes
50
Last updated

