Overview
@drift-labs/common is the foundational package in the Drift Common monorepo, providing essential utilities, data clients, and helper functions for building applications on Drift Protocol. This package is framework-agnostic and can be used in Node.js, browser, or React Native environments.
Installation
npm install @drift-labs/common
Peer Dependencies
This package requires the following peer dependencies:
Key Features
Market Data Clients WebSocket and REST clients for real-time market data
Number Utilities Precise number formatting and BigNumber conversions
Configuration Management Environment-aware configuration for mainnet/devnet
Drift Class Wrapper High-level interface for Drift Protocol operations
Core Exports
Configuration
Initialize the package with your target environment:
import { Config , Initialize } from '@drift-labs/common' ;
import { DriftEnv } from '@drift-labs/sdk' ;
// Initialize for mainnet
const sdkConfig = Initialize ( DriftEnv . MainnetBeta );
// Access market configurations
const spotMarkets = Config . spotMarketsLookup ;
const perpMarkets = Config . perpMarketsLookup ;
console . log ( 'Initialized:' , Config . initialized ); // true
The Initialize function must be called before using market lookups. It populates the Config object with market configurations for quick access.
Market Data Clients
Candle Client
Fetch and subscribe to candlestick data for charting:
import { CandleClient } from '@drift-labs/common' ;
import { CandleResolution } from '@drift-labs/sdk' ;
const candleClient = new CandleClient ({
env: 'mainnet-beta' ,
});
// Fetch historical candles
const candles = await candleClient . fetchCandles ({
marketId: { marketType: 'perp' , marketIndex: 0 },
resolution: CandleResolution . ONE_HOUR ,
fromTs: Date . now () / 1000 - 86400 , // Last 24 hours
toTs: Date . now () / 1000 ,
});
// Subscribe to real-time updates
const subscription = candleClient . subscribe ({
marketId: { marketType: 'perp' , marketIndex: 0 },
resolution: CandleResolution . ONE_MINUTE ,
callback : ( candle ) => {
console . log ( 'New candle:' , candle );
},
});
// Unsubscribe when done
subscription . unsubscribe ();
The Candle Client implements intelligent caching for the most recent 1000 candles to minimize API requests. See the source code comments in clients/candleClient.ts:17 for implementation details.
DLOB WebSocket Client
Connect to the Decentralized Limit Order Book (DLOB) server:
import { DlobWebsocketClient } from '@drift-labs/common' ;
const dlobClient = new DlobWebsocketClient ({
url: 'wss://dlob.drift.trade/ws' ,
});
await dlobClient . connect ();
// Subscribe to market updates
dlobClient . subscribe ({
marketType: 'perp' ,
marketIndex: 0 ,
callback : ( update ) => {
console . log ( 'DLOB update:' , update );
},
});
Number Utilities
The NumLib class provides utilities for converting between BigNumbers and display formats:
import { NumLib } from '@drift-labs/common' ;
import { BN , QUOTE_PRECISION } from '@drift-labs/sdk' ;
// Convert BN to display number
const amount = new BN ( '1000000' ); // 1 USDC in base units
const displayAmount = NumLib . formatNum . toTradePrecision (
amount . toNumber () / QUOTE_PRECISION . toNumber ()
);
console . log ( displayAmount ); // "1.00"
// Format with locale
NumLib . setLocale ( 'en-US' );
const formatted = NumLib . formatNum . toTradePrecisionString ( 1234.567 , true );
console . log ( formatted ); // "1,234.57"
Use NumLib.formatNum.toTradePrecision for trading amounts to ensure consistent precision across your UI. See utils/NumLib.ts:56 for implementation.
Drift Class
High-level wrapper for common Drift Protocol operations:
import { Drift } from '@drift-labs/common' ;
import { Connection , Keypair } from '@solana/web3.js' ;
const connection = new Connection ( 'https://api.mainnet-beta.solana.com' );
const wallet = Keypair . generate ();
const drift = new Drift ({
connection ,
wallet ,
env: 'mainnet-beta' ,
});
await drift . subscribe ();
// Access account data
const user = drift . getUser ();
const positions = drift . getPositions ();
const collateral = drift . getCollateral ();
Utility Functions
Price Impact Calculation
import { calculatePriceImpact } from '@drift-labs/common' ;
const impact = calculatePriceImpact ({
entryPrice: 100 ,
exitPrice: 98 ,
side: 'long' ,
});
console . log ( impact ); // -2%
Priority Fee Helpers
import { getPriorityFeeEstimate } from '@drift-labs/common' ;
const priorityFee = await getPriorityFeeEstimate ( connection , {
transaction: tx ,
lookbackSlots: 150 ,
});
Token Utilities
import { getTokenAccount , getTokenBalance } from '@drift-labs/common' ;
import { PublicKey } from '@solana/web3.js' ;
const tokenAccount = await getTokenAccount (
connection ,
new PublicKey ( '...' )
);
const balance = await getTokenBalance ( connection , tokenAccount );
Environment Constants
Access environment-specific URLs and configurations:
import { EnvironmentConstants } from '@drift-labs/common' ;
const constants = EnvironmentConstants [ 'mainnet-beta' ];
console . log ( constants . driftEnv ); // 'mainnet-beta'
console . log ( constants . rpcEndpoint ); // Default RPC endpoint
Error Handling
The package includes error code mappings for Drift and Jupiter programs:
import { DriftErrors , JupV6Errors } from '@drift-labs/common' ;
// Decode Drift program errors
const errorCode = 6000 ;
const errorMessage = DriftErrors [ errorCode ];
console . log ( errorMessage );
// Decode Jupiter errors
const jupError = JupV6Errors [ errorCode ];
Advanced Features
WebSocket Multiplexing
The MultiplexWebSocket class allows multiple subscriptions over a single WebSocket connection:
import { MultiplexWebSocket } from '@drift-labs/common' ;
const ws = new MultiplexWebSocket ( 'wss://example.com/ws' );
ws . subscribe ( 'channel1' , ( data ) => {
console . log ( 'Channel 1:' , data );
});
ws . subscribe ( 'channel2' , ( data ) => {
console . log ( 'Channel 2:' , data );
});
ws . connect ();
See utils/MultiplexWebSocket.ts:1 for the full implementation and connection management logic.
Circular Buffers
Efficient data structures for time-series data:
import { CircularBuffer } from '@drift-labs/common' ;
const buffer = new CircularBuffer < number >( 100 ); // Max 100 items
buffer . push ( 1 );
buffer . push ( 2 );
buffer . push ( 3 );
const latest = buffer . peek (); // 3
const all = buffer . toArray (); // [1, 2, 3]
Shared Intervals
Optimize polling with shared intervals across components:
import { SharedInterval } from '@drift-labs/common' ;
const interval = new SharedInterval ( 1000 ); // 1 second
interval . subscribe (() => {
console . log ( 'Tick 1' );
});
interval . subscribe (() => {
console . log ( 'Tick 2' );
});
interval . start ();
// Both callbacks execute on the same interval
// Stops automatically when all subscriptions are removed
Use SharedInterval instead of multiple setInterval calls to reduce CPU usage. See utils/SharedInterval.ts:1.
Browser Support
The package includes browser-specific builds with polyfills:
{
"browser" : {
"./lib/utils/logger.js" : "./lib/utils/logger.browser.js"
}
}
Browser builds replace Node.js-specific modules (like winston) with browser-compatible alternatives.
TypeScript Support
Full type definitions are included:
import type {
MarketId ,
MarketSymbol ,
JsonCandle ,
UIEnv ,
} from '@drift-labs/common' ;
// All types are fully documented
const marketId : MarketId = {
marketType: 'perp' ,
marketIndex: 0 ,
};
Common Use Cases
Building a Trading Interface
import {
Initialize ,
Config ,
CandleClient ,
NumLib
} from '@drift-labs/common' ;
import { DriftEnv , CandleResolution } from '@drift-labs/sdk' ;
// 1. Initialize configuration
Initialize ( DriftEnv . MainnetBeta );
// 2. Get market info
const solPerpMarket = Config . perpMarketsLookup [ 0 ];
console . log ( 'Market:' , solPerpMarket . baseAssetSymbol );
// 3. Fetch price data
const candleClient = new CandleClient ({ env: 'mainnet-beta' });
const candles = await candleClient . fetchCandles ({
marketId: { marketType: 'perp' , marketIndex: 0 },
resolution: CandleResolution . ONE_HOUR ,
fromTs: Date . now () / 1000 - 86400 ,
toTs: Date . now () / 1000 ,
});
// 4. Format prices for display
const formattedPrices = candles . map ( candle => ({
time: candle . time ,
price: NumLib . formatNum . toTradePrecisionString ( candle . close ),
}));
Monitoring Account Data
import { Drift , DriftEvents } from '@drift-labs/common' ;
const drift = new Drift ({ connection , wallet , env: 'mainnet-beta' });
await drift . subscribe ();
// Listen for account updates
drift . eventEmitter . on ( DriftEvents . UPDATE , () => {
const positions = drift . getPositions ();
const collateral = drift . getCollateral ();
console . log ( 'Positions updated:' , positions );
console . log ( 'Collateral:' , collateral . toString ());
});
Package Structure
common-ts/
├── src/
│ ├── clients/ # Data clients (candles, DLOB, etc.)
│ ├── constants/ # Error codes and constants
│ ├── drift/ # Drift class and related utilities
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions and classes
│ ├── Config.ts # Configuration management
│ └── index.ts # Main export file
├── lib/ # Compiled output
├── package.json
└── tsconfig.json
React Package React hooks and components built on @drift-labs/common
API Reference Complete API documentation
SDK Documentation Official Drift SDK documentation
GitHub Repository View source code
Dependencies
@drift-labs/sdk: Core Drift Protocol SDK
@solana/web3.js: Solana Web3 library
@solana/spl-token: SPL Token utilities
rxjs: Reactive programming library
immer: Immutable state management
winston: Logging (Node.js)
typescript: TypeScript compiler
mocha: Testing framework
chai: Assertion library
esbuild: Fast bundler
Troubleshooting
Ensure your tsconfig.json has moduleResolution set to "node" and esModuleInterop enabled.
BigNumber precision issues
Always use the NumLib utilities when converting between BN and display formats to avoid floating-point errors.
WebSocket connection failures
Check that your environment allows WebSocket connections and that you’re using the correct URLs from EnvironmentConstants.
This package requires Node.js ^24.x.x. Ensure your environment meets this requirement.