UNPKG

@ox-fun/drift-sdk

Version:

SDK for Drift Protocol

89 lines (81 loc) 2.14 kB
import { parsePriceData } from '@pythnetwork/client'; import { Connection, PublicKey } from '@solana/web3.js'; import { OracleClient, OraclePriceData } from './types'; import { BN } from '@coral-xyz/anchor'; import { ONE, PRICE_PRECISION, QUOTE_PRECISION, TEN, } from '../constants/numericConstants'; export class PythClient implements OracleClient { private connection: Connection; private multiple: BN; private stableCoin: boolean; public constructor( connection: Connection, multiple = ONE, stableCoin = false ) { this.connection = connection; this.multiple = multiple; this.stableCoin = stableCoin; } public async getOraclePriceData( pricePublicKey: PublicKey ): Promise<OraclePriceData> { const accountInfo = await this.connection.getAccountInfo(pricePublicKey); return this.getOraclePriceDataFromBuffer(accountInfo.data); } public getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData { const priceData = parsePriceData(buffer); const confidence = convertPythPrice( priceData.confidence, priceData.exponent, this.multiple ); let price = convertPythPrice( priceData.aggregate.price, priceData.exponent, this.multiple ); if (this.stableCoin) { price = getStableCoinPrice(price, confidence); } return { price, slot: new BN(priceData.lastSlot.toString()), confidence, twap: convertPythPrice( priceData.twap.value, priceData.exponent, this.multiple ), twapConfidence: convertPythPrice( priceData.twac.value, priceData.exponent, this.multiple ), hasSufficientNumberOfDataPoints: true, }; } } export function convertPythPrice( price: number, exponent: number, multiple: BN ): BN { exponent = Math.abs(exponent); const pythPrecision = TEN.pow(new BN(exponent).abs()).div(multiple); return new BN(price * Math.pow(10, exponent)) .mul(PRICE_PRECISION) .div(pythPrecision); } const fiveBPS = new BN(500); function getStableCoinPrice(price: BN, confidence: BN): BN { if (price.sub(QUOTE_PRECISION).abs().lt(BN.min(confidence, fiveBPS))) { return QUOTE_PRECISION; } else { return price; } }