refactor to use hook useSelectedMarket
This commit is contained in:
parent
1ce76d3924
commit
38a3db06df
|
@ -33,24 +33,24 @@ const BalancesTable = () => {
|
|||
const showTableView = width ? width > breakpoints.md : false
|
||||
|
||||
const banks = useMemo(() => {
|
||||
if (!group) return []
|
||||
if (!group || !mangoAccount) return []
|
||||
|
||||
const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({
|
||||
key,
|
||||
value,
|
||||
balance: mangoAccount?.getTokenBalanceUi(value[0]),
|
||||
balance: mangoAccount.getTokenBalanceUi(value[0]),
|
||||
}))
|
||||
const sortedBanks = mangoAccount
|
||||
? rawBanks
|
||||
.sort(
|
||||
(a, b) =>
|
||||
Math.abs(b.balance! * b.value[0].uiPrice) -
|
||||
Math.abs(a.balance! * a.value[0].uiPrice)
|
||||
Math.abs(b.balance * b.value[0].uiPrice) -
|
||||
Math.abs(a.balance * a.value[0].uiPrice)
|
||||
)
|
||||
.filter((c) => {
|
||||
return (
|
||||
Math.abs(
|
||||
floorToDecimal(c.balance!, c.value[0].mintDecimals).toNumber()
|
||||
floorToDecimal(c.balance, c.value[0].mintDecimals).toNumber()
|
||||
) > 0 ||
|
||||
spotBalances[c.value[0].mint.toString()]?.unsettled > 0 ||
|
||||
spotBalances[c.value[0].mint.toString()]?.inOrders > 0
|
||||
|
@ -59,7 +59,7 @@ const BalancesTable = () => {
|
|||
: rawBanks
|
||||
|
||||
return sortedBanks
|
||||
}, [group, mangoAccount])
|
||||
}, [group, mangoAccount, spotBalances])
|
||||
|
||||
return banks?.length ? (
|
||||
showTableView ? (
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
import { PerpMarket } from '@blockworks-foundation/mango-v4'
|
||||
import Change from '@components/shared/Change'
|
||||
import { useCoingecko } from 'hooks/useCoingecko'
|
||||
import useOraclePrice from 'hooks/useOraclePrice'
|
||||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useMemo } from 'react'
|
||||
import { getDecimalCount } from 'utils/numbers'
|
||||
import MarketSelectDropdown from './MarketSelectDropdown'
|
||||
import PerpFundingRate from './PerpFundingRate'
|
||||
|
||||
const AdvancedMarketHeader = () => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
const { serumOrPerpMarket, baseSymbol, price } = useSelectedMarket()
|
||||
const { data: tokenPrices } = useCoingecko()
|
||||
const oraclePrice = useOraclePrice()
|
||||
|
||||
const baseSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split('/')[0]
|
||||
}, [selectedMarket])
|
||||
const coingeckoData = useMemo(() => {
|
||||
return tokenPrices.find((asset) =>
|
||||
baseSymbol === 'soETH'
|
||||
? asset.symbol === 'ETH'
|
||||
: asset.symbol === baseSymbol
|
||||
)
|
||||
}, [baseSymbol, tokenPrices])
|
||||
|
||||
const coingeckoData = tokenPrices.find((asset) =>
|
||||
baseSymbol === 'soETH'
|
||||
? asset.symbol === 'ETH'
|
||||
: asset.symbol === baseSymbol
|
||||
)
|
||||
|
||||
const change = coingeckoData
|
||||
? ((coingeckoData.prices[coingeckoData.prices.length - 1][1] -
|
||||
coingeckoData.prices[0][1]) /
|
||||
coingeckoData.prices[0][1]) *
|
||||
100
|
||||
: 0
|
||||
const change = useMemo(() => {
|
||||
return coingeckoData
|
||||
? ((coingeckoData.prices[coingeckoData.prices.length - 1][1] -
|
||||
coingeckoData.prices[0][1]) /
|
||||
coingeckoData.prices[0][1]) *
|
||||
100
|
||||
: 0
|
||||
}, [coingeckoData])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col bg-th-bkg-1 md:h-12 md:flex-row md:items-center">
|
||||
|
@ -40,8 +39,10 @@ const AdvancedMarketHeader = () => {
|
|||
<div id="trade-step-two" className="flex-col md:ml-6">
|
||||
<div className="text-xs text-th-fgd-4">{t('trade:oracle-price')}</div>
|
||||
<div className="font-mono text-xs text-th-fgd-2">
|
||||
{oraclePrice ? (
|
||||
`$${oraclePrice}`
|
||||
{price ? (
|
||||
`$${price.toFixed(
|
||||
getDecimalCount(serumOrPerpMarket?.tickSize || 0.01)
|
||||
)}`
|
||||
) : (
|
||||
<span className="text-th-fgd-4">–</span>
|
||||
)}
|
||||
|
@ -51,7 +52,7 @@ const AdvancedMarketHeader = () => {
|
|||
<div className="text-xs text-th-fgd-4">{t('rolling-change')}</div>
|
||||
<Change change={change} size="small" suffix="%" />
|
||||
</div>
|
||||
{selectedMarket instanceof PerpMarket ? (
|
||||
{serumOrPerpMarket instanceof PerpMarket ? (
|
||||
<div className="ml-6 flex-col">
|
||||
<div className="text-xs text-th-fgd-4">
|
||||
{t('trade:funding-rate')}
|
||||
|
|
|
@ -13,7 +13,7 @@ import Tooltip from '@components/shared/Tooltip'
|
|||
import mangoStore from '@store/mangoStore'
|
||||
import Decimal from 'decimal.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import NumberFormat, {
|
||||
NumberFormatValues,
|
||||
SourceInfo,
|
||||
|
@ -31,7 +31,6 @@ import { SIZE_INPUT_UI_KEY, SOUND_SETTINGS_KEY } from 'utils/constants'
|
|||
import SpotButtonGroup from './SpotButtonGroup'
|
||||
import PerpButtonGroup from './PerpButtonGroup'
|
||||
import SolBalanceWarnings from '@components/shared/SolBalanceWarnings'
|
||||
import useJupiterMints from 'hooks/useJupiterMints'
|
||||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||
import { getDecimalCount } from 'utils/numbers'
|
||||
import LogoWithFallback from '@components/shared/LogoWithFallback'
|
||||
|
@ -56,8 +55,6 @@ const AdvancedTradeForm = () => {
|
|||
const { t } = useTranslation(['common', 'trade'])
|
||||
const { mangoAccount } = useMangoAccount()
|
||||
const tradeForm = mangoStore((s) => s.tradeForm)
|
||||
const { mangoTokens } = useJupiterMints()
|
||||
const { selectedMarket, price: oraclePrice } = useSelectedMarket()
|
||||
const [useMargin, setUseMargin] = useState(true)
|
||||
const [placingOrder, setPlacingOrder] = useState(false)
|
||||
const [tradeFormSizeUi] = useLocalStorageState(SIZE_INPUT_UI_KEY, 'Slider')
|
||||
|
@ -68,44 +65,14 @@ const AdvancedTradeForm = () => {
|
|||
)
|
||||
const { connected } = useWallet()
|
||||
const { handleConnect } = useEnhancedWallet()
|
||||
|
||||
const baseSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split(/-|\//)[0]
|
||||
}, [selectedMarket])
|
||||
|
||||
const baseLogoURI = useMemo(() => {
|
||||
if (!baseSymbol || !mangoTokens.length) return ''
|
||||
const token =
|
||||
mangoTokens.find((t) => t.symbol === baseSymbol) ||
|
||||
mangoTokens.find((t) => t.symbol?.includes(baseSymbol))
|
||||
if (token) {
|
||||
return token.logoURI
|
||||
}
|
||||
return ''
|
||||
}, [baseSymbol, mangoTokens])
|
||||
|
||||
const quoteBank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !selectedMarket) return
|
||||
const tokenIdx =
|
||||
selectedMarket instanceof Serum3Market
|
||||
? selectedMarket.quoteTokenIndex
|
||||
: selectedMarket?.settleTokenIndex
|
||||
return group?.getFirstBankByTokenIndex(tokenIdx)
|
||||
}, [selectedMarket])
|
||||
|
||||
const quoteSymbol = useMemo(() => {
|
||||
return quoteBank?.name
|
||||
}, [quoteBank])
|
||||
|
||||
const quoteLogoURI = useMemo(() => {
|
||||
if (!quoteSymbol || !mangoTokens.length) return ''
|
||||
const token = mangoTokens.find((t) => t.symbol === quoteSymbol)
|
||||
if (token) {
|
||||
return token.logoURI
|
||||
}
|
||||
return ''
|
||||
}, [quoteSymbol, mangoTokens])
|
||||
const {
|
||||
selectedMarket,
|
||||
price: oraclePrice,
|
||||
baseLogoURI,
|
||||
baseSymbol,
|
||||
quoteLogoURI,
|
||||
quoteSymbol,
|
||||
} = useSelectedMarket()
|
||||
|
||||
const setTradeType = useCallback((tradeType: 'Limit' | 'Market') => {
|
||||
set((s) => {
|
||||
|
@ -192,6 +159,10 @@ const AdvancedTradeForm = () => {
|
|||
})
|
||||
}, [])
|
||||
|
||||
const handleSetMargin = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||
setUseMargin(e.target.checked)
|
||||
}, [])
|
||||
|
||||
const [tickDecimals, tickSize] = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !selectedMarket) return [1, 0.1]
|
||||
|
@ -548,10 +519,7 @@ const AdvancedTradeForm = () => {
|
|||
placement="left"
|
||||
content={t('trade:tooltip-enable-margin')}
|
||||
>
|
||||
<Checkbox
|
||||
checked={useMargin}
|
||||
onChange={(e) => setUseMargin(e.target.checked)}
|
||||
>
|
||||
<Checkbox checked={useMargin} onChange={handleSetMargin}>
|
||||
{t('trade:margin')}
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
|
|
|
@ -182,7 +182,12 @@ const depth = 40
|
|||
|
||||
const Orderbook = () => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const { selectedMarket, serumOrPerpMarket: market } = useSelectedMarket()
|
||||
const {
|
||||
selectedMarket,
|
||||
serumOrPerpMarket: market,
|
||||
baseSymbol,
|
||||
quoteSymbol,
|
||||
} = useSelectedMarket()
|
||||
|
||||
const [isScrolled, setIsScrolled] = useState(false)
|
||||
const [orderbookData, setOrderbookData] = useState<any | null>(null)
|
||||
|
@ -483,8 +488,12 @@ const Orderbook = () => {
|
|||
) : null}
|
||||
</div>
|
||||
<div className="grid grid-cols-2 px-4 pt-2 pb-1 text-xxs text-th-fgd-4">
|
||||
<div className="col-span-1 text-right">{t('trade:size')}</div>
|
||||
<div className="col-span-1 text-right">{t('price')}</div>
|
||||
<div className="col-span-1 text-right">
|
||||
{t('trade:size')} ({baseSymbol})
|
||||
</div>
|
||||
<div className="col-span-1 text-right">
|
||||
{t('price')} ({quoteSymbol})
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="hide-scroll relative h-full overflow-y-scroll"
|
||||
|
|
|
@ -50,15 +50,12 @@ const RecentTrades = () => {
|
|||
}
|
||||
}, [fills, previousFills, soundSettings])
|
||||
|
||||
const { selectedMarket, serumOrPerpMarket: market } = useSelectedMarket()
|
||||
|
||||
const baseSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split(/-|\//)[0]
|
||||
}, [selectedMarket])
|
||||
|
||||
const quoteSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split(/-|\//)[1]
|
||||
}, [selectedMarket])
|
||||
const {
|
||||
selectedMarket,
|
||||
serumOrPerpMarket: market,
|
||||
baseSymbol,
|
||||
quoteSymbol,
|
||||
} = useSelectedMarket()
|
||||
|
||||
// const fetchRecentTrades = useCallback(async () => {
|
||||
// if (!market) return
|
||||
|
|
|
@ -5,15 +5,16 @@ import MarketLogos from './MarketLogos'
|
|||
|
||||
const TableMarketName = ({ market }: { market: PerpMarket | Serum3Market }) => {
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
|
||||
return selectedMarket?.name === market.name ? (
|
||||
<div className="flex items-center">
|
||||
<MarketLogos market={market!} />
|
||||
<MarketLogos market={market} />
|
||||
<span className="whitespace-nowrap">{market.name}</span>
|
||||
</div>
|
||||
) : (
|
||||
<Link href={`/trade?name=${market.name}`}>
|
||||
<div className="default-transition flex items-center underline md:hover:text-th-fgd-3 md:hover:no-underline">
|
||||
<MarketLogos market={market!} />
|
||||
<MarketLogos market={market} />
|
||||
<span className="whitespace-nowrap">{market.name}</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import { Serum3Market } from '@blockworks-foundation/mango-v4'
|
||||
import { getDecimalCount } from 'utils/numbers'
|
||||
import useMangoGroup from './useMangoGroup'
|
||||
import useSelectedMarket from './useSelectedMarket'
|
||||
|
||||
export default function useOraclePrice() {
|
||||
const { group } = useMangoGroup()
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
|
||||
if (!group || !selectedMarket) return false
|
||||
|
||||
let price
|
||||
let market
|
||||
if (selectedMarket instanceof Serum3Market) {
|
||||
price = group.getFirstBankByTokenIndex(
|
||||
selectedMarket?.baseTokenIndex
|
||||
).uiPrice
|
||||
market = group.getSerum3ExternalMarket(selectedMarket.serumMarketExternal)
|
||||
} else {
|
||||
price = selectedMarket.uiPrice
|
||||
market = selectedMarket
|
||||
}
|
||||
return price && market ? price.toFixed(getDecimalCount(market.tickSize)) : ''
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
import { Serum3Market } from '@blockworks-foundation/mango-v4'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { useMemo } from 'react'
|
||||
import useJupiterMints from './useJupiterMints'
|
||||
import useMangoGroup from './useMangoGroup'
|
||||
|
||||
export default function useSelectedMarket() {
|
||||
const { group } = useMangoGroup()
|
||||
const selectedMarket = mangoStore((s) => s.selectedMarket.current)
|
||||
const { mangoTokens } = useJupiterMints()
|
||||
|
||||
const price: number = useMemo(() => {
|
||||
if (!group) return 0
|
||||
|
@ -31,5 +33,51 @@ export default function useSelectedMarket() {
|
|||
}
|
||||
}, [selectedMarket])
|
||||
|
||||
return { selectedMarket, price, serumOrPerpMarket }
|
||||
const baseSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split(/-|\//)[0]
|
||||
}, [selectedMarket])
|
||||
|
||||
const baseLogoURI = useMemo(() => {
|
||||
if (!baseSymbol || !mangoTokens.length) return ''
|
||||
const token =
|
||||
mangoTokens.find((t) => t.symbol === baseSymbol) ||
|
||||
mangoTokens.find((t) => t.symbol?.includes(baseSymbol))
|
||||
if (token) {
|
||||
return token.logoURI
|
||||
}
|
||||
return ''
|
||||
}, [baseSymbol, mangoTokens])
|
||||
|
||||
const quoteBank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !selectedMarket) return
|
||||
const tokenIdx =
|
||||
selectedMarket instanceof Serum3Market
|
||||
? selectedMarket.quoteTokenIndex
|
||||
: selectedMarket?.settleTokenIndex
|
||||
return group?.getFirstBankByTokenIndex(tokenIdx)
|
||||
}, [selectedMarket])
|
||||
|
||||
const quoteSymbol = useMemo(() => {
|
||||
return quoteBank?.name
|
||||
}, [quoteBank])
|
||||
|
||||
const quoteLogoURI = useMemo(() => {
|
||||
if (!quoteSymbol || !mangoTokens.length) return ''
|
||||
const token = mangoTokens.find((t) => t.symbol === quoteSymbol)
|
||||
if (token) {
|
||||
return token.logoURI
|
||||
}
|
||||
return ''
|
||||
}, [quoteSymbol, mangoTokens])
|
||||
|
||||
return {
|
||||
selectedMarket,
|
||||
price,
|
||||
serumOrPerpMarket,
|
||||
baseSymbol,
|
||||
quoteSymbol,
|
||||
baseLogoURI,
|
||||
quoteLogoURI,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue