diff --git a/components/trade/Orderbook.tsx b/components/trade/Orderbook.tsx index 5945307f..da4e0c4a 100644 --- a/components/trade/Orderbook.tsx +++ b/components/trade/Orderbook.tsx @@ -17,7 +17,11 @@ import Decimal from 'decimal.js' import Tooltip from '@components/shared/Tooltip' import GroupSize from './GroupSize' // import { useViewport } from 'hooks/useViewport' -import { BookSide, Serum3Market } from '@blockworks-foundation/mango-v4' +import { + BookSide, + PerpMarket, + Serum3Market, +} from '@blockworks-foundation/mango-v4' import useSelectedMarket from 'hooks/useSelectedMarket' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' import { OrderbookFeed } from '@blockworks-foundation/mango-feeds' @@ -33,6 +37,7 @@ import { import { OrderbookData, OrderbookL2 } from 'types' import isEqual from 'lodash/isEqual' import { useViewport } from 'hooks/useViewport' +import TokenLogo from '@components/shared/TokenLogo' const sizeCompacter = Intl.NumberFormat('en', { maximumFractionDigits: 6, @@ -51,6 +56,7 @@ const Orderbook = () => { const [useOrderbookFeed, setUseOrderbookFeed] = useState(false) const orderbookElRef = useRef(null) const [isScrolled, setIsScrolled] = useState(false) + const [sizeInBase, setSizeInBase] = useState(true) // const [useOrderbookFeed, setUseOrderbookFeed] = useState( // localStorage.getItem(USE_ORDERBOOK_FEED_KEY) !== null // ? localStorage.getItem(USE_ORDERBOOK_FEED_KEY) === 'true' @@ -60,6 +66,23 @@ const Orderbook = () => { const [orderbookData, setOrderbookData] = useState(null) const currentOrderbookData = useRef() + const [baseBank, quoteBank] = useMemo(() => { + const { group } = mangoStore.getState() + if (!market || !group) return [undefined, undefined] + if (market instanceof PerpMarket) { + const baseTokenName = market.name.split('-')[0] + const base = group.banksMapByName.get(baseTokenName)?.[0] + const quote = group.getFirstBankByTokenIndex(market.settleTokenIndex) + return [base, quote] + } else { + const base = group.getFirstBankByMint(market.baseMintAddress) + const quote = group.getFirstBankByMint(market.quoteMintAddress) + return [base, quote] + } + }, [market]) + + console.log(baseBank, quoteBank) + const depth = useMemo(() => { return isDesktop ? 30 : 12 }, [isDesktop]) @@ -454,7 +477,7 @@ const Orderbook = () => { return (
-
+
{market ? ( <>

{t('trade:grouping')}:

@@ -475,9 +498,43 @@ const Orderbook = () => { ) : null}
-
+
{t('price')}
-
{t('trade:size')}
+
+ {t('trade:size')} + {baseBank && quoteBank ? ( +
+ + + + + + +
+ ) : null} +
{ orderbookData?.asks[index].cumulativeSizePercent } grouping={grouping} + sizeInBase={sizeInBase} /> ) : null}
@@ -559,6 +617,7 @@ const Orderbook = () => { orderbookData?.bids[index].cumulativeSizePercent } grouping={grouping} + sizeInBase={sizeInBase} /> ) : null}
@@ -582,6 +641,7 @@ const OrderbookRow = ({ cumulativeSizePercent, tickSize, grouping, + sizeInBase, }: { side: 'buy' | 'sell' price: number @@ -596,6 +656,7 @@ const OrderbookRow = ({ grouping: number minOrderSize: number tickSize: number + sizeInBase: boolean }) => { const element = useRef(null) const [animationSettings] = useLocalStorageState( @@ -618,10 +679,21 @@ const OrderbookRow = ({ }, [price, size]) const formattedSize = useMemo(() => { - return minOrderSize && !isNaN(size) - ? floorToDecimal(size, getDecimalCount(minOrderSize)) - : new Decimal(size ?? -1) - }, [size, minOrderSize]) + if (!minOrderSize || isNaN(size)) return new Decimal(size ?? -1) + const sizeToShow = sizeInBase + ? size + : new Decimal(size).mul(new Decimal(price)).toNumber() + const decimals = sizeInBase + ? getDecimalCount(minOrderSize) + : getDecimalCount(tickSize) + return floorToDecimal(sizeToShow, decimals) + }, [minOrderSize, price, size, sizeInBase, tickSize]) + + // const formattedSize = useMemo(() => { + // return minOrderSize && !isNaN(size) + // ? floorToDecimal(size, getDecimalCount(minOrderSize)) + // : new Decimal(size ?? -1) + // }, [size, minOrderSize, sizeInBase, tickSize]) const formattedPrice = useMemo(() => { return tickSize && !isNaN(price) @@ -647,16 +719,28 @@ const OrderbookRow = ({ const handleSizeClick = useCallback(() => { const set = mangoStore.getState().set set((state) => { - state.tradeForm.baseSize = formattedSize.toString() + if (sizeInBase) { + state.tradeForm.baseSize = formattedSize.toString() + } else { + state.tradeForm.quoteSize = formattedSize.toString() + } if (formattedSize && state.tradeForm.price) { - const quoteSize = floorToDecimal( - formattedSize.mul(new Decimal(state.tradeForm.price)), - getDecimalCount(tickSize), - ) - state.tradeForm.quoteSize = quoteSize.toString() + if (sizeInBase) { + const quoteSize = floorToDecimal( + formattedSize.mul(new Decimal(state.tradeForm.price)), + getDecimalCount(tickSize), + ) + state.tradeForm.quoteSize = quoteSize.toString() + } else { + const baseSize = floorToDecimal( + formattedSize.div(new Decimal(state.tradeForm.price)), + getDecimalCount(minOrderSize), + ) + state.tradeForm.baseSize = baseSize.toString() + } } }) - }, [formattedSize, tickSize]) + }, [formattedSize, minOrderSize, size, sizeInBase, tickSize]) const groupingDecimalCount = useMemo( () => getDecimalCount(grouping), diff --git a/public/locales/en/trade.json b/public/locales/en/trade.json index 035f63ad..b0838600 100644 --- a/public/locales/en/trade.json +++ b/public/locales/en/trade.json @@ -106,6 +106,7 @@ "tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled", "tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.", "tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled", + "tooltip-size-base-quote": "Show size in {{token}}", "tooltip-private-counterparty": "Counterparty has Private Account enabled", "tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at", "tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly", diff --git a/public/locales/es/trade.json b/public/locales/es/trade.json index ac9eb0c6..13690f8b 100644 --- a/public/locales/es/trade.json +++ b/public/locales/es/trade.json @@ -106,6 +106,7 @@ "tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled", "tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.", "tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled", + "tooltip-size-base-quote": "Show size in {{token}}", "tooltip-private-counterparty": "Counterparty has Private Account enabled", "tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at", "tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly", diff --git a/public/locales/ru/trade.json b/public/locales/ru/trade.json index ac9eb0c6..13690f8b 100644 --- a/public/locales/ru/trade.json +++ b/public/locales/ru/trade.json @@ -106,6 +106,7 @@ "tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled", "tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.", "tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled", + "tooltip-size-base-quote": "Show size in {{token}}", "tooltip-private-counterparty": "Counterparty has Private Account enabled", "tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at", "tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly", diff --git a/public/locales/zh/trade.json b/public/locales/zh/trade.json index 234f661c..c882ec3d 100644 --- a/public/locales/zh/trade.json +++ b/public/locales/zh/trade.json @@ -111,6 +111,7 @@ "tooltip-insured": "如果发生破产,{{tokenOrMarket}}损失是否可以从保险基金中归还", "tooltip-ioc": "IOC交易若不吃单就会被取消。任何无法立刻成交的部分将被取消", "tooltip-post": "Post交易若不挂单就会被取消。", + "tooltip-size-base-quote": "Show size in {{token}}", "tooltip-private-counterparty": "Counterparty has Private Account enabled", "tooltip-slippage": "当前价格与您的交易将执行的价格之间的差值的估计", "tooltip-stable-price": "稳定价格用于一个安全机制。此机制可以限制用户在预言机价格快速波动时下风险高的订单", diff --git a/public/locales/zh_tw/trade.json b/public/locales/zh_tw/trade.json index cb885342..8a115d16 100644 --- a/public/locales/zh_tw/trade.json +++ b/public/locales/zh_tw/trade.json @@ -106,6 +106,7 @@ "tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還", "tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消", "tooltip-post": "Post交易若不掛單就會被取消。", + "tooltip-size-base-quote": "Show size in {{token}}", "tooltip-private-counterparty": "Counterparty has Private Account enabled", "tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計", "tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",