import { Bank, Serum3Market } from '@blockworks-foundation/mango-v4' import useJupiterMints from 'hooks/useJupiterMints' import { QuestionMarkCircleIcon } from '@heroicons/react/20/solid' import mangoStore from '@store/mangoStore' import Decimal from 'decimal.js' import useMangoAccount from 'hooks/useMangoAccount' import { useViewport } from 'hooks/useViewport' import { useTranslation } from 'next-i18next' import Image from 'next/legacy/image' import { useRouter } from 'next/router' import { useMemo } from 'react' import { formatDecimal, formatFixedDecimals } from 'utils/numbers' import { breakpoints } from 'utils/theme' import { calculateMarketPrice } from 'utils/tradeForm' import { LinkButton } from './Button' import { Table, Td, Th, TrBody, TrHead } from './TableElements' import useSelectedMarket from 'hooks/useSelectedMarket' const BalancesTable = () => { const { t } = useTranslation(['common', 'trade']) const { mangoAccount } = useMangoAccount() const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances) const group = mangoStore((s) => s.group) const { mangoTokens } = useJupiterMints() const { width } = useViewport() const showTableView = width ? width > breakpoints.md : false const banks = useMemo(() => { if (group) { const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({ key, value, })) const sortedBanks = mangoAccount ? rawBanks.sort( (a, b) => Math.abs( mangoAccount?.getTokenBalanceUi(b.value[0]) * b.value[0].uiPrice! ) - Math.abs( mangoAccount?.getTokenBalanceUi(a.value[0]) * a.value[0].uiPrice! ) ) : rawBanks return mangoAccount ? sortedBanks.filter( (b) => mangoAccount?.getTokenBalanceUi(b.value[0]) !== 0 ) : sortedBanks } return [] }, [group, mangoAccount]) return banks?.length ? ( showTableView ? ( {banks.map(({ key, value }) => { const bank = value[0] let logoURI if (mangoTokens.length) { logoURI = mangoTokens.find( (t) => t.address === bank.mint.toString() )!.logoURI } const inOrders = spotBalances[bank.mint.toString()]?.inOrders || 0.0 const unsettled = spotBalances[bank.mint.toString()]?.unsettled || 0.0 return ( ) })}
{t('token')} {t('balance')} {t('trade:in-orders')} {t('trade:unsettled')}
{logoURI ? ( ) : ( )}
{bank.name}

{mangoAccount ? `${formatFixedDecimals( mangoAccount.getTokenBalanceUi(bank) * bank.uiPrice!, true )}` : '$0.00'}

{formatDecimal(inOrders)}

{formatFixedDecimals(inOrders * bank.uiPrice!, true)}

{formatDecimal(unsettled)}

{formatFixedDecimals(unsettled * bank.uiPrice!, true)}

) : ( <> {banks.map(({ key, value }) => { const bank = value[0] let logoURI if (mangoTokens.length) { logoURI = mangoTokens.find( (t) => t.address === bank.mint.toString() )!.logoURI } const inOrders = spotBalances[bank.mint.toString()]?.inOrders || 0.0 const unsettled = spotBalances[bank.mint.toString()]?.unsettled || 0.0 return (
{logoURI ? ( ) : ( )}
{bank.name}

{mangoAccount ? formatDecimal( mangoAccount.getTokenBalanceUi(bank), bank.mintDecimals ) : 0}{' '} ( {mangoAccount ? `${formatFixedDecimals( mangoAccount.getTokenBalanceUi(bank) * bank.uiPrice!, true )}` : '$0.00'} )

{t('trade:in-orders')}:{' '} {formatDecimal(inOrders)}

{t('trade:unsettled')}:{' '} {formatDecimal(unsettled)}

) })} ) ) : (

{t('trade:no-balances')}

) } export default BalancesTable const Balance = ({ bank }: { bank: Bank }) => { const { mangoAccount } = useMangoAccount() const { selectedMarket } = useSelectedMarket() const { asPath } = useRouter() const handleBalanceClick = (balance: number, type: 'base' | 'quote') => { const set = mangoStore.getState().set const tradeForm = mangoStore.getState().tradeForm let price: number if (tradeForm.tradeType === 'Market') { const orderbook = mangoStore.getState().selectedMarket.orderbook const side = (balance > 0 && type === 'quote') || (balance < 0 && type === 'base') ? 'buy' : 'sell' price = calculateMarketPrice(orderbook, balance, side) } else { price = new Decimal(tradeForm.price).toNumber() } console.log('balance', balance) if (balance > 0) { if (type === 'quote') { set((s) => { s.tradeForm.baseSize = (balance / price).toString() s.tradeForm.quoteSize = balance.toString() }) } else { set((s) => { s.tradeForm.baseSize = balance.toString() s.tradeForm.quoteSize = (balance * price).toString() }) } } else { if (type === 'quote') { set((s) => { s.tradeForm.baseSize = (balance / price).toString() s.tradeForm.quoteSize = balance.toString() }) } else { set((s) => { s.tradeForm.baseSize = balance.toString() s.tradeForm.quoteSize = (balance * price).toString() }) } } } const balance = useMemo(() => { return mangoAccount ? mangoAccount.getTokenBalanceUi(bank) : 0 }, [mangoAccount]) const isBaseOrQuote = useMemo(() => { if (selectedMarket instanceof Serum3Market && asPath === '/trade') { if (bank.tokenIndex === selectedMarket.baseTokenIndex) { return 'base' } else if (bank.tokenIndex === selectedMarket.quoteTokenIndex) { return 'quote' } else return '' } }, [bank, selectedMarket]) return (

{balance ? ( isBaseOrQuote ? ( handleBalanceClick( parseFloat(formatDecimal(balance, bank.mintDecimals)), isBaseOrQuote ) } > {formatDecimal(balance, bank.mintDecimals)} ) : ( formatDecimal(balance, bank.mintDecimals) ) ) : ( 0 )}

) }