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

All documented descriptions are for the following deployed programs IDs of the protocol.

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.json

This 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.

You must replace ~/.config/solana/my-keypair.json with your personal key.

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/

Latest Python dependencies can be found on GitHub https://github.com/drift-labs/driftpy/blob/master/pyproject.toml"

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

initializing a new drift user account requires some rent (~.035 SOL). this can be reclaimed upon deletion.

Alternatively you can export the private key of an existing user that has been initialized via the UI. This will allow you to use the same user account programatically.

TypeScript

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional

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.

Type
Description

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.

Type
Description

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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.

Parameter
Description

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

Parameter
Description
Optional
Default

orderParams

The order params

No

Python

Parameter
Description
Optional
Default

order_params

The order params

No

The order type is set to PERP / Perp() by default.

Placing Spot Order

TypeScript

Parameter
Description
Optional
Default

orderParams

The order params

No

Python

Parameter
Description
Optional
Default

order_params

The order params

No

The order type is set to SPOT / Spot() by default.

Placing Multiple Orders

TypeScript

Parameter
Description
Optional
Default

placeOrderParams

Parameters for place order instructions

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

orderId

The order being canceled

No

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

userOrderId

Unique order id specified by user when order was placed

No

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

cancelOrderParams

Parameters for cancel orders instruction

placeOrderParams

Parameters for place order instructions

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

orderId

The order id of order to modify

No

modifyOrderParams

The modify order params

Yes

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

userOrderId

The user order id of order to modify

No

modifyOrderParams

The modify order params

Yes

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

marketIndex

The market index for the spot market

No

Python

Parameter
Description
Optional
Default

market_index

The market index for the spot market

No

Get Perp Market Account

TypeScript

Parameter
Description
Optional
Default

marketIndex

The market index for the perp market

No

Python

Parameter
Description
Optional
Default

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:

1

Define order parameters

Define order parameters (see Order Params).

2

Generate and Sign order

Generate the signed order message and sign it using your wallet.

3

Submit to Swift API

Submit the signed message and signature to the Swift API.

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:

Parameter
Description
Optional

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

When signing as a delegate, make sure to:

1

Initialize the client as a delegate.

2

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.

In the below examples, it is important to note the difference between builderClient and userClient. Furthermore, Builder Codes are currently limted to Swift orders only.

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

sub_account_id

The sub account id of user to get

Yes

active sub account

Getting Deposit/Borrow Amounts

TypeScript

Parameter
Description
Optional
Default

marketIndex

Market index for the spot market

No

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

marketIndex

Market index for the perp market

No

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

orderId

Order id for the order you're getting

No

Python

Parameter
Description
Optional
Default

order_id

Order id for the order you're getting

No

Get Order By User Order Id

TypeScript

Parameter
Description
Optional
Default

userOrderId

User order id for the order you're getting

No

Python

Parameter
Description
Optional
Default

user_order_id

User order id for the order you're getting

No

Get Open Orders

Get Unrealized Perp Pnl

TypeScript

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

marketIndex

Whether to only return pnl for specific market

Yes

Python

Parameter
Description
Optional
Default

market_index

Whether to only return pnl for specific market

Yes

Get Total Collateral

TypeScript

Parameter
Description
Optional
Default

marginCategory

Initial or Maintenance

Yes

Initial

strict

Whether the calculation should be strict

Yes

false

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

marginCategory

Initial or Maintenance

Yes

Initial

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

includeOpenOrders

Whether to factor in open orders in position size

Yes

true

Python

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Parameter
Description
Optional
Default

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

Event Type
Description

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:

i=1ndipiwia + j=1npnljqpjwjpnl\sum_{i=1}^n d_i \cdot p_i \cdot w_i^a\ +\ \sum_{j=1}^n pnl_j \cdot qp_j \cdot w_j^{pnl}

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:

i=1nbipiwil + j=1nbajojqpjmj\sum_{i=1}^n b_i \cdot p_i \cdot w_i^l\ +\ \sum_{j=1}^n ba_j \cdot o_j \cdot qp_j \cdot m_j

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

Value
Precision
Constant

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.

Option
Type
Description
Default

-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:

Option / Flag
Type
Description

--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(...).

Parameter
Description
Optional
Default

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.

Parameter
Description
Optional
Default

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