@drift-labs/sdk-browser
Version:
SDK for Drift Protocol
242 lines (241 loc) • 12.9 kB
TypeScript
/// <reference types="bn.js" />
import { NodeList } from './NodeList';
import { BN } from '@coral-xyz/anchor';
import { DLOBNode, DLOBNodeType, TriggerOrderNode } from './DLOBNode';
import { DriftClient } from '../driftClient';
import { MarketType, MarketTypeStr, Order, PerpMarketAccount, PositionDirection, SpotMarketAccount, StateAccount } from '../types';
import { MMOraclePriceData, OraclePriceData } from '../oracles/types';
import { ProtectMakerParamsMap } from './types';
import { SlotSubscriber } from '../slot/SlotSubscriber';
import { UserMap } from '../userMap/userMap';
import { PublicKey } from '@solana/web3.js';
import { L2OrderBook, L2OrderBookGenerator, L3OrderBook } from './orderBookLevels';
export type DLOBOrder = {
user: PublicKey;
order: Order;
};
export type DLOBOrders = DLOBOrder[];
export type MarketNodeLists = {
restingLimit: {
ask: NodeList<'restingLimit'>;
bid: NodeList<'restingLimit'>;
};
floatingLimit: {
ask: NodeList<'floatingLimit'>;
bid: NodeList<'floatingLimit'>;
};
protectedFloatingLimit: {
ask: NodeList<'protectedFloatingLimit'>;
bid: NodeList<'protectedFloatingLimit'>;
};
takingLimit: {
ask: NodeList<'takingLimit'>;
bid: NodeList<'takingLimit'>;
};
market: {
ask: NodeList<'market'>;
bid: NodeList<'market'>;
};
trigger: {
above: NodeList<'trigger'>;
below: NodeList<'trigger'>;
};
signedMsg: {
ask: NodeList<'signedMsg'>;
bid: NodeList<'signedMsg'>;
};
};
type OrderBookCallback = () => void;
/**
* Receives a DLOBNode and is expected to return true if the node should
* be taken into account when generating, or false otherwise.
*
* Currently used in functions that rely on getBestNode
*/
export type DLOBFilterFcn = (node: DLOBNode) => boolean;
export type NodeToFill = {
node: DLOBNode;
makerNodes: DLOBNode[];
};
export type NodeToTrigger = {
node: TriggerOrderNode;
};
export declare class DLOB {
openOrders: Map<MarketTypeStr, Set<string>>;
orderLists: Map<MarketTypeStr, Map<number, MarketNodeLists>>;
maxSlotForRestingLimitOrders: number;
initialized: boolean;
protectedMakerParamsMap: ProtectMakerParamsMap;
constructor(protectedMakerParamsMap?: ProtectMakerParamsMap);
private init;
clear(): void;
/**
* initializes a new DLOB instance
*
* @returns a promise that resolves when the DLOB is initialized
*/
initFromUserMap(userMap: UserMap, slot: number): Promise<boolean>;
insertOrder(order: Order, userAccount: string, slot: number, isUserProtectedMaker: boolean, baseAssetAmount: BN, onInsert?: OrderBookCallback): void;
insertSignedMsgOrder(order: Order, userAccount: string, isUserProtectedMaker: boolean, baseAssetAmount?: BN, onInsert?: OrderBookCallback): void;
addOrderList(marketType: MarketTypeStr, marketIndex: number): void;
delete(order: Order, userAccount: PublicKey, slot: number, isUserProtectedMaker: boolean, onDelete?: OrderBookCallback): void;
getListForOnChainOrder(order: Order, slot: number, isProtectedMaker: boolean): NodeList<any> | undefined;
updateRestingLimitOrders(slot: number): void;
updateRestingLimitOrdersForMarketType(slot: number, marketTypeStr: MarketTypeStr): void;
getOrder(orderId: number, userAccount: PublicKey): Order | undefined;
findNodesToFill<T extends MarketType>(marketIndex: number, fallbackBid: BN | undefined, fallbackAsk: BN | undefined, slot: number, ts: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, stateAccount: StateAccount, marketAccount: T extends {
spot: unknown;
} ? SpotMarketAccount : PerpMarketAccount): NodeToFill[];
getMakerRebate(marketType: MarketType, stateAccount: StateAccount, marketAccount: PerpMarketAccount | SpotMarketAccount): {
makerRebateNumerator: number;
makerRebateDenominator: number;
};
mergeNodesToFill(restingLimitOrderNodesToFill: NodeToFill[], takingOrderNodesToFill: NodeToFill[]): NodeToFill[];
findRestingLimitOrderNodesToFill<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, makerRebateNumerator: number, makerRebateDenominator: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
findTakingNodesToFill<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid?: BN | undefined): NodeToFill[];
findTakingNodesCrossingMakerNodes<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, takerNodeGenerator: Generator<DLOBNode>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData) => Generator<DLOBNode>, doesCross: (takerPrice: BN | undefined, makerPrice: BN) => boolean): NodeToFill[];
findNodesCrossingFallbackLiquidity<T extends MarketType>(marketType: T, slot: number, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, nodeGenerator: Generator<DLOBNode>, doesCross: (nodePrice: BN | undefined) => boolean, minAuctionDuration: number): NodeToFill[];
findExpiredNodesToFill(marketIndex: number, ts: number, marketType: MarketType, slot?: BN): NodeToFill[];
findUnfillableReduceOnlyOrdersToCancel(marketIndex: number, marketType: MarketType, stepSize: BN): NodeToFill[];
getTakingBids<T extends MarketType>(marketIndex: number, marketType: T, slot: number, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
getTakingAsks<T extends MarketType>(marketIndex: number, marketType: T, slot: number, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
protected signedMsgGenerator(signedMsgOrderList: NodeList<'signedMsg'>, filter: (x: DLOBNode) => boolean): Generator<DLOBNode>;
protected getBestNode<T extends MarketTypeStr>(generatorList: Array<Generator<DLOBNode>>, oraclePriceData: T extends 'spot' ? OraclePriceData : MMOraclePriceData, slot: number, compareFcn: (bestDLOBNode: DLOBNode, currentDLOBNode: DLOBNode, slot: number, oraclePriceData: T extends 'spot' ? OraclePriceData : MMOraclePriceData) => boolean, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
getRestingLimitAsks<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
getRestingLimitBids<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
/**
* This will look at both the taking and resting limit asks
* @param marketIndex
* @param fallbackAsk
* @param slot
* @param marketType
* @param oraclePriceData
* @param filterFcn
*/
getAsks<T extends MarketType>(marketIndex: number, _fallbackAsk: BN | undefined, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
/**
* This will look at both the taking and resting limit bids
* @param marketIndex
* @param fallbackBid
* @param slot
* @param marketType
* @param oraclePriceData
* @param filterFcn
*/
getBids<T extends MarketType>(marketIndex: number, _fallbackBid: BN | undefined, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn): Generator<DLOBNode>;
findCrossingRestingLimitOrders<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData): NodeToFill[];
determineMakerAndTaker(askNode: DLOBNode, bidNode: DLOBNode): {
takerNode: DLOBNode;
makerNode: DLOBNode;
} | undefined;
getBestAsk<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData): BN | undefined;
getBestBid<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData): BN | undefined;
getStopLosses(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
getStopLossMarkets(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
getStopLossLimits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
getTakeProfits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
getTakeProfitMarkets(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
getTakeProfitLimits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
findNodesToTrigger(marketIndex: number, slot: number, triggerPrice: BN, marketType: MarketType, stateAccount: StateAccount): NodeToTrigger[];
printTop(driftClient: DriftClient, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType): void;
getDLOBOrders(): DLOBOrders;
getNodeLists(): Generator<NodeList<DLOBNodeType>>;
/**
* Get an L2 view of the order book for a given market.
*
* @param marketIndex
* @param marketType
* @param slot
* @param oraclePriceData
* @param depth how many levels of the order book to return
* @param fallbackL2Generators L2 generators for fallback liquidity e.g. vAMM {@link getVammL2Generator}, openbook {@link SerumSubscriber}
*/
getL2<T extends MarketType>({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackL2Generators, }: {
marketIndex: number;
marketType: T;
slot: number;
oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData;
depth: number;
fallbackL2Generators?: L2OrderBookGenerator[];
}): L2OrderBook;
/**
* Get an L3 view of the order book for a given market. Does not include fallback liquidity sources
*
* @param marketIndex
* @param marketType
* @param slot
* @param oraclePriceData
*/
getL3<T extends MarketType>({ marketIndex, marketType, slot, oraclePriceData, }: {
marketIndex: number;
marketType: T;
slot: number;
oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData;
}): L3OrderBook;
private estimateFillExactBaseAmountInForSide;
/**
*
* @param param.marketIndex the index of the market
* @param param.marketType the type of the market
* @param param.baseAmount the base amount in to estimate
* @param param.orderDirection the direction of the trade
* @param param.slot current slot for estimating dlob node price
* @param param.oraclePriceData the oracle price data
* @returns the estimated quote amount filled: QUOTE_PRECISION
*/
estimateFillWithExactBaseAmount<T extends MarketType>({ marketIndex, marketType, baseAmount, orderDirection, slot, oraclePriceData, }: {
marketIndex: number;
marketType: T;
baseAmount: BN;
orderDirection: PositionDirection;
slot: number;
oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData;
}): BN;
getBestMakers<T extends MarketType>({ marketIndex, marketType, direction, slot, oraclePriceData, numMakers, }: {
marketIndex: number;
marketType: T;
direction: PositionDirection;
slot: number;
oraclePriceData: T extends {
spot: unknown;
} ? OraclePriceData : MMOraclePriceData;
numMakers: number;
}): PublicKey[];
}
export {};