Oracles provide external price data to Drift Protocol markets. The protocol supports multiple oracle sources including Pyth, Switchboard, and custom oracle implementations.
Get Oracle Price Data
Retrieve oracle price data for a market:
import { OracleSource } from '@drift-labs/sdk';
const perpMarket = driftClient.getPerpMarketAccount(0);
const oraclePriceData = driftClient.getOraclePriceDataAndSlot(
perpMarket.amm.oracle,
perpMarket.amm.oracleSource
);
console.log('Price:', oraclePriceData.data.price.toString());
console.log('Slot:', oraclePriceData.slot.toString());
OraclePriceData Structure
The OraclePriceData type contains price and confidence information from an oracle.
Current oracle price in PRICE_PRECISION (1e6)
Solana slot when the price was updated
Price confidence interval in PRICE_PRECISION (1e6)
hasSufficientNumberOfDataPoints
Whether the oracle has sufficient data points for reliability
Time-weighted average price (if available)
Confidence interval for TWAP (if available)
Maximum price for pre-launch markets only
Sequence identifier for the price update
Oracle Sources
Drift Protocol supports multiple oracle sources:
Standard Pyth oracle with default price scaling
Pyth oracle with 1000x price scaling
Pyth oracle with 1,000,000x price scaling
Pyth pull oracle with 1000x scaling
Pyth pull oracle with 1,000,000x scaling
Switchboard on-demand oracle
Fixed price oracle for quote asset (USDC = $1)
Pyth pull stablecoin oracle
Pyth Lazer oracle (low-latency)
Pyth Lazer with 1000x scaling
Pyth Lazer with 1,000,000x scaling
Pyth Lazer stablecoin oracle
Validate Oracle
Check if oracle data is valid:
import { isOracleValid, OracleValidity } from '@drift-labs/sdk';
const perpMarket = driftClient.getPerpMarketAccount(0);
const oraclePriceData = driftClient.getOraclePriceDataAndSlot(
perpMarket.amm.oracle,
perpMarket.amm.oracleSource
);
const state = driftClient.getStateAccount();
const currentSlot = new BN(await driftClient.connection.getSlot());
const validity = isOracleValid(
perpMarket.amm,
oraclePriceData.data,
state.oracleGuardRails.validity,
currentSlot
);
if (validity === OracleValidity.Valid) {
console.log('Oracle is valid');
} else {
console.log('Oracle validity issue:', OracleValidity[validity]);
}
Check Oracle Divergence
Check if oracle price diverges too much from mark price:
import { isOracleTooDivergent, calculateReservePrice } from '@drift-labs/sdk';
const perpMarket = driftClient.getPerpMarketAccount(0);
const oraclePriceData = driftClient.getOraclePriceDataAndSlot(
perpMarket.amm.oracle,
perpMarket.amm.oracleSource
);
const state = driftClient.getStateAccount();
const reservePrice = calculateReservePrice(perpMarket, oraclePriceData.data);
const isDivergent = isOracleTooDivergent(
reservePrice,
oraclePriceData.data.price,
state.oracleGuardRails.priceDivergence.markOraclePercentDivergence
);
if (isDivergent) {
console.log('Oracle price diverges from mark price');
}
OracleInfo Type
Oracle configuration for a market:
type OracleInfo = {
publicKey: PublicKey; // Oracle account address
source: OracleSource; // Oracle source type
};
Price Precision
All prices in Drift Protocol use PRICE_PRECISION (1e6):
import { PRICE_PRECISION } from '@drift-labs/sdk';
// Convert oracle price to UI price
const uiPrice = oraclePriceData.data.price.toNumber() / PRICE_PRECISION.toNumber();
console.log('UI Price: $', uiPrice);
// Convert UI price to oracle price
const oraclePrice = PRICE_PRECISION.muln(30); // $30