Skip to Content
DevelopersDrift SDKSetup

Setup

The examples below use placeholders like <RPC_URL> and <KEYPAIR_PATH>.

Program Addresses

The Drift program id is environment-specific. In most cases you’ll use the default program id baked into the SDK config for devnet or mainnet-beta.

Wallet / Authentication

To interact with Solana you need a keypair. One common approach for bots is to point ANCHOR_WALLET (or your own env var) at a JSON keypair file.

solana-keygen new --outfile ~/.config/solana/my-keypair.json export ANCHOR_WALLET=~/.config/solana/my-keypair.json

Install

npm i @drift-labs/sdk

Create a Drift Client

At a minimum you provide a Solana connection, a wallet, and the env. Then call subscribe() to start receiving account updates.

import { Connection } from "@solana/web3.js"; import { DriftClient, Wallet, loadKeypair } from "@drift-labs/sdk"; const connection = new Connection("<RPC_URL>", "confirmed"); const wallet = new Wallet(loadKeypair("<KEYPAIR_PATH>")); const driftClient = new DriftClient({ connection, wallet, env: "mainnet-beta", }); await driftClient.subscribe();

DriftClient class reference https://drift-labs.github.io/protocol-v2/sdk/classes/DriftClient.html 

await driftClient.unsubscribe();

Account Subscriptions (WebSocket vs Polling)

For most bots, websocket subscriptions are the easiest way to keep markets and users up to date. For read-only workflows or when you need tighter control over RPC load, you can switch to polling with a BulkAccountLoader.

View BulkAccountLoader import

import { BulkAccountLoader } from "@drift-labs/sdk";
Class BulkAccountLoaderReference ↗
NameTypeDefault
connectionConnection
commitmentCommitment
pollingFrequencynumber
accountsToLoadMap<string, AccountToLoad>
bufferAndSlotMapMap<string, BufferAndSlot>
errorCallbacksMap<string, (e: any) => void>
intervalIdTimeout
loadPromisePromise<void>
loadPromiseResolver() => void
lastTimeLoadingPromiseClearednumber
mostRecentSlotnumber
addAccount(publicKey: PublicKey, callback: (buffer: Buffer, slot: number) => void) => Promise<string>
removeAccount(publicKey: PublicKey, callbackId: string) => void
addErrorCallbacks(callback: (error: Error) => void) => string
removeErrorCallbacks(callbackId: string) => void
chunks<T>(array: readonly T[], size: number) => T[][]
load() => Promise<void>
loadChunk(accountsToLoadChunks: AccountToLoad[][]) => Promise<void>
handleAccountCallbacks(accountToLoad: AccountToLoad, buffer: Buffer, slot: number) => void
getBufferAndSlot(publicKey: PublicKey) => BufferAndSlot | undefined
getSlot() => number
startPolling() => void
stopPolling() => void
log(msg: string) => void
updatePollingFrequency(pollingFrequency: number) => void
import { BulkAccountLoader } from "@drift-labs/sdk"; const accountLoader = new BulkAccountLoader(connection, "confirmed", 0); const driftClient = new DriftClient({ connection, wallet, env: "mainnet-beta", accountSubscription: { type: "polling", accountLoader, }, // Optional: explicitly list markets/oracles to load. // perpMarketIndexes: [0, 1], // spotMarketIndexes: [0], // oracleInfos: [{ publicKey: ORACLE_PUBKEY, source: ORACLE_SOURCE }], });

Multiple Subaccounts

if (!driftClient.hasUser(1)) { await driftClient.addUser(1); }
Method DriftClient.hasUserReference ↗
Parameters:
NameTypeDefault
subAccountIdnumber
authorityPublicKey
Returns:
boolean
await driftClient.addUser(1);
Method DriftClient.addUserReference ↗
Parameters:
NameTypeDefault
subAccountIdnumber
authorityPublicKey
userAccountUserAccount
Returns:
Promise<boolean>

Program ID

import { DRIFT_PROGRAM_ID } from "@drift-labs/sdk"; // The Drift program's public key on mainnet-beta. // Use this when deriving PDAs or referencing the program directly. console.log(DRIFT_PROGRAM_ID.toBase58());

High Leverage Mode

import { getHighLeverageModeConfigPublicKey } from "@drift-labs/sdk"; const pda = getHighLeverageModeConfigPublicKey(driftClient.program.programId); const config = await driftClient.program.account.highLeverageModeConfig.fetch(pda);
Last updated on