From 2c40c7ec81c3096f4e56d8013a620033876f60ac Mon Sep 17 00:00:00 2001 From: Chester Sim Date: Thu, 22 May 2025 23:26:53 +0800 Subject: [PATCH] refactor(common-ts): add step and tick size for ui market --- common-ts/src/types/UIMarket.ts | 95 +++++++++++++++++++++++++++++++-- common-ts/src/types/index.ts | 4 ++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/common-ts/src/types/UIMarket.ts b/common-ts/src/types/UIMarket.ts index 5046725..2d98b6e 100644 --- a/common-ts/src/types/UIMarket.ts +++ b/common-ts/src/types/UIMarket.ts @@ -5,17 +5,24 @@ import { PerpMarkets, SpotMarkets, SpotMarketConfig, + SpotMarketAccount, + PerpMarketAccount, + BN, + BigNum, + BASE_PRECISION_EXP, + QUOTE_PRECISION_EXP, } from '@drift-labs/sdk'; import { MarketId } from './MarketId'; import invariant from 'tiny-invariant'; import { USDC_SPOT_MARKET_INDEX } from '../constants'; import { ENUM_UTILS } from '../utils'; import { Config } from '../Config'; +import { MarketAccount } from '../types'; const useAsyncMarketConfigs = process.env.NEXT_PUBLIC_USE_ASYNC_MARKET_CONFIGS === 'true'; -export class UIMarket { +export abstract class UIMarket { static perpMarkets = PerpMarkets['mainnet-beta']; static spotMarkets = SpotMarkets['mainnet-beta']; static perpMarketIds = PerpMarkets['mainnet-beta'].map((m) => @@ -63,16 +70,24 @@ export class UIMarket { ); } + static create(marketIndex: number, marketType: MarketType) { + return marketType === MarketType.PERP + ? new PerpUIMarket(marketIndex) + : new SpotUIMarket(marketIndex); + } + static createSpotMarket(marketIndex: number) { - return new UIMarket(marketIndex, MarketType.SPOT); + return new SpotUIMarket(marketIndex); } static createPerpMarket(marketIndex: number) { - return new UIMarket(marketIndex, MarketType.PERP); + return new PerpUIMarket(marketIndex); } static fromMarketId(marketId: MarketId) { - return new UIMarket(marketId.marketIndex, marketId.marketType); + return marketId.isPerp + ? new PerpUIMarket(marketId.marketIndex) + : new SpotUIMarket(marketId.marketIndex); } static checkIsPredictionMarket(marketConfig: PerpMarketConfig) { @@ -140,4 +155,76 @@ export class UIMarket { return baseAssetSymbol; } + + protected geDisplayDpFromSize(size: BN, precisionExp: BN) { + const formattedSize = BigNum.from(size, precisionExp).prettyPrint(); + if (formattedSize.includes('.')) { + return formattedSize.split('.')[1].length; + } + return 0; + } + + abstract baseDisplayDp(marketAccount: MarketAccount): number; + + abstract priceDisplayDp(marketAccount: MarketAccount): number; + + abstract getStepSize(marketAccount: MarketAccount): BN; + + abstract getTickSize(marketAccount: MarketAccount): BN; +} + +export class PerpUIMarket extends UIMarket { + constructor(marketIndex: number) { + super(marketIndex, MarketType.PERP); + } + + baseDisplayDp(marketAccount: PerpMarketAccount) { + return this.geDisplayDpFromSize( + (marketAccount as PerpMarketAccount).amm.orderStepSize, + BASE_PRECISION_EXP + ); + } + + priceDisplayDp(marketAccount: PerpMarketAccount) { + return this.geDisplayDpFromSize( + (marketAccount as PerpMarketAccount).amm.orderTickSize, + QUOTE_PRECISION_EXP + ); + } + + getStepSize(marketAccount: PerpMarketAccount) { + return (marketAccount as PerpMarketAccount).amm.orderStepSize; + } + + getTickSize(marketAccount: PerpMarketAccount) { + return (marketAccount as PerpMarketAccount).amm.orderTickSize; + } +} + +export class SpotUIMarket extends UIMarket { + constructor(marketIndex: number) { + super(marketIndex, MarketType.SPOT); + } + + baseDisplayDp(marketAccount: SpotMarketAccount) { + return this.geDisplayDpFromSize( + (marketAccount as SpotMarketAccount).orderStepSize, + (this.market as SpotMarketConfig).precisionExp + ); + } + + priceDisplayDp(marketAccount: SpotMarketAccount) { + return this.geDisplayDpFromSize( + (marketAccount as SpotMarketAccount).orderTickSize, + QUOTE_PRECISION_EXP + ); + } + + getStepSize(marketAccount: SpotMarketAccount) { + return (marketAccount as SpotMarketAccount).orderStepSize; + } + + getTickSize(marketAccount: SpotMarketAccount) { + return (marketAccount as SpotMarketAccount).orderTickSize; + } } diff --git a/common-ts/src/types/index.ts b/common-ts/src/types/index.ts index 07463ef..88a019e 100644 --- a/common-ts/src/types/index.ts +++ b/common-ts/src/types/index.ts @@ -2,7 +2,9 @@ import { BN, BigNum, MarketType, + PerpMarketAccount, SpotBalanceType, + SpotMarketAccount, SpotPosition, TradeSide, } from '@drift-labs/sdk'; @@ -273,3 +275,5 @@ export type TradeOffsetPrice = | 'mark' | 'entry' | 'bestOffer'; + +export type MarketAccount = PerpMarketAccount | SpotMarketAccount;