fix: updated the account balances and added debts (#325)

This commit is contained in:
Linkie Link 2023-07-28 21:37:54 +02:00 committed by GitHub
parent fec03d030f
commit 1eec100907
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 58 deletions

View File

@ -19,15 +19,43 @@ import { DISPLAY_CURRENCY_KEY } from 'constants/localStore'
import useLocalStorage from 'hooks/useLocalStorage' import useLocalStorage from 'hooks/useLocalStorage'
import usePrices from 'hooks/usePrices' import usePrices from 'hooks/usePrices'
import { BNCoin } from 'types/classes/BNCoin' import { BNCoin } from 'types/classes/BNCoin'
import { byDenom } from 'utils/array'
import { getAssetByDenom } from 'utils/assets' import { getAssetByDenom } from 'utils/assets'
import { convertToDisplayAmount, demagnify } from 'utils/formatters' import { convertLiquidityRateToAPR, convertToDisplayAmount, demagnify } from 'utils/formatters'
import { BN } from 'utils/helpers' import { BN } from 'utils/helpers'
import { convertAprToApy } from 'utils/parsers'
interface Props { interface Props {
data: Account account: Account
lendingData: LendingMarketTableData[]
borrowingData: BorrowMarketTableData[]
} }
export const AccountBalancesTable = (props: Props) => { function calculatePositionValues(
type: 'deposits' | 'borrowing' | 'lending',
asset: Asset,
prices: BNCoin[],
displayCurrencyDenom: string,
position: BNCoin,
apy: number,
) {
const { amount, denom } = position
return {
type,
symbol: asset.symbol,
size: demagnify(amount, asset),
value: convertToDisplayAmount(
BNCoin.fromDenomAndBigNumber(denom, amount),
displayCurrencyDenom,
prices,
).toString(),
denom,
amount: type === 'borrowing' ? amount.negated() : amount,
apy,
}
}
export default function AccountBalancesTable(props: Props) {
const [displayCurrency] = useLocalStorage<string>( const [displayCurrency] = useLocalStorage<string>(
DISPLAY_CURRENCY_KEY, DISPLAY_CURRENCY_KEY,
DEFAULT_SETTINGS.displayCurrency, DEFAULT_SETTINGS.displayCurrency,
@ -35,48 +63,35 @@ export const AccountBalancesTable = (props: Props) => {
const { data: prices } = usePrices() const { data: prices } = usePrices()
const [sorting, setSorting] = React.useState<SortingState>([]) const [sorting, setSorting] = React.useState<SortingState>([])
const balanceData = React.useMemo<AccountBalanceRow[]>(() => { const balanceData = React.useMemo<AccountBalanceRow[]>(() => {
const accountDeposits = props.data?.deposits ?? [] const accountDeposits = props.account?.deposits ?? []
const accountLends = props.data?.lends ?? [] const accountLends = props.account?.lends ?? []
const accountDebts = props.account?.debts ?? []
const deposits = accountDeposits.map((deposit) => { const deposits = accountDeposits.map((deposit) => {
const asset = ASSETS.find((asset) => asset.denom === deposit.denom) ?? ASSETS[0] const asset = ASSETS.find((asset) => asset.denom === deposit.denom) ?? ASSETS[0]
const apy = 0 const apy = 0
return { return calculatePositionValues('deposits', asset, prices, displayCurrency, deposit, apy)
type: 'deposit',
symbol: asset.symbol,
denom: deposit.denom,
amount: deposit.amount,
size: demagnify(deposit.amount, asset),
value: convertToDisplayAmount(
new BNCoin({ amount: deposit.amount, denom: deposit.denom }),
displayCurrency,
prices,
).toString(),
apy,
}
})
const lends = accountLends.map((lending) => {
const asset = ASSETS.find((asset) => asset.denom === lending.denom) ?? ASSETS[0]
const apy = 0
return {
type: 'lending',
symbol: asset.symbol,
denom: lending.denom,
amount: lending.amount,
size: demagnify(lending.amount, asset),
value: convertToDisplayAmount(
new BNCoin({ amount: lending.amount, denom: lending.denom }),
displayCurrency,
prices,
).toString(),
apy,
}
}) })
return [...deposits, ...lends] const lends = accountLends.map((lending) => {
}, [displayCurrency, prices, props.data?.deposits, props.data?.lends]) const asset = ASSETS.find((asset) => asset.denom === lending.denom) ?? ASSETS[0]
const apr = convertLiquidityRateToAPR(
props.lendingData.find((market) => market.asset.denom === lending.denom)
?.marketLiquidityRate ?? 0,
)
const apy = convertAprToApy(apr, 365)
return calculatePositionValues('lending', asset, prices, displayCurrency, lending, apy)
})
const debts = accountDebts.map((debt) => {
const asset = ASSETS.find(byDenom(debt.denom)) ?? ASSETS[0]
const apy =
props.borrowingData.find((market) => market.asset.denom === debt.denom)?.borrowRate ?? 0
return calculatePositionValues('borrowing', asset, prices, displayCurrency, debt, apy * -100)
})
return [...deposits, ...lends, ...debts]
}, [displayCurrency, prices, props.account, props.borrowingData, props.lendingData])
const columns = React.useMemo<ColumnDef<AccountBalanceRow>[]>( const columns = React.useMemo<ColumnDef<AccountBalanceRow>[]>(
() => [ () => [
@ -88,7 +103,7 @@ export const AccountBalancesTable = (props: Props) => {
return ( return (
<Text size='xs'> <Text size='xs'>
{row.original.symbol} {row.original.symbol}
{row.original.type === 'lending' && <span className='text-profit'>(Lent)</span>} {row.original.type === 'lending' && <span className='ml-1 text-profit'>(lent)</span>}
</Text> </Text>
) )
}, },
@ -98,8 +113,11 @@ export const AccountBalancesTable = (props: Props) => {
accessorKey: 'value', accessorKey: 'value',
id: 'value', id: 'value',
cell: ({ row }) => { cell: ({ row }) => {
const coin = new BNCoin({ denom: row.original.denom, amount: row.original.amount }) const coin = new BNCoin({
return <DisplayCurrency coin={coin} className='text-right text-xs' /> denom: row.original.denom,
amount: row.original.amount.toString(),
})
return <DisplayCurrency coin={coin} className='text-xs text-right' />
}, },
}, },
{ {
@ -113,8 +131,8 @@ export const AccountBalancesTable = (props: Props) => {
) )
return ( return (
<FormattedNumber <FormattedNumber
className='text-right text-xs' className='text-xs text-right'
amount={Number(BN(amount).toPrecision(2))} amount={Number(BN(amount).abs().toPrecision(2))}
options={{ maxDecimals: 2, abbreviated: true }} options={{ maxDecimals: 2, abbreviated: true }}
animate animate
/> />
@ -174,7 +192,7 @@ export const AccountBalancesTable = (props: Props) => {
'align-center', 'align-center',
)} )}
> >
<span className='h-6 w-6 text-white'> <span className='w-6 h-6 text-white'>
{header.column.getCanSort() {header.column.getCanSort()
? { ? {
asc: <SortAsc />, asc: <SortAsc />,
@ -203,7 +221,7 @@ export const AccountBalancesTable = (props: Props) => {
<tr key={row.id} className=' text-white/60'> <tr key={row.id} className=' text-white/60'>
{row.getVisibleCells().map((cell) => { {row.getVisibleCells().map((cell) => {
const borderClass = const borderClass =
cell.row.original.type === 'deposit' ? 'border-profit' : 'border-loss' cell.row.original.type === 'borrowing' ? 'border-loss' : 'border-profit'
return ( return (
<td <td
key={cell.id} key={cell.id}

View File

@ -11,6 +11,7 @@ import usePrices from 'hooks/usePrices'
import { BNCoin } from 'types/classes/BNCoin' import { BNCoin } from 'types/classes/BNCoin'
import { import {
calculateAccountApr, calculateAccountApr,
calculateAccountBalanceValue,
calculateAccountBorrowRate, calculateAccountBorrowRate,
calculateAccountDebtValue, calculateAccountDebtValue,
calculateAccountDepositsValue, calculateAccountDepositsValue,
@ -37,8 +38,10 @@ export default function AccountComposition(props: Props) {
const balanceChange = props.change ? calculateAccountDepositsValue(props.change, prices) : BN_ZERO const balanceChange = props.change ? calculateAccountDepositsValue(props.change, prices) : BN_ZERO
const debtBalance = calculateAccountDebtValue(props.account, prices) const debtBalance = calculateAccountDebtValue(props.account, prices)
const debtBalanceChange = props.change ? calculateAccountDebtValue(props.change, prices) : BN_ZERO const debtBalanceChange = props.change ? calculateAccountDebtValue(props.change, prices) : BN_ZERO
const pnL = calculateAccountPnL(props.account, prices) const totalBalance = calculateAccountBalanceValue(props.account, prices)
const pnLChange = props.change ? calculateAccountPnL(props.change, prices) : BN_ZERO const totalBalanceChange = props.change
? calculateAccountBalanceValue(props.change, prices)
: BN_ZERO
const apr = calculateAccountApr(props.account, prices) const apr = calculateAccountApr(props.account, prices)
const aprChange = props.change ? calculateAccountPnL(props.change, prices) : BN_ZERO const aprChange = props.change ? calculateAccountPnL(props.change, prices) : BN_ZERO
const borrowRate = calculateAccountBorrowRate(props.account, prices) const borrowRate = calculateAccountBorrowRate(props.account, prices)
@ -60,10 +63,10 @@ export default function AccountComposition(props: Props) {
isBadIncrease isBadIncrease
/> />
<Item <Item
title='Unrealized PnL' title='Total Balance'
current={pnL} current={totalBalance}
change={pnL.plus(pnLChange)} change={totalBalance.plus(totalBalanceChange)}
className='border border-transparent border-y-white/20 py-3' className='border border-transparent border-y-white/20 py-3 font-bold'
/> />
<Item title='APR' current={apr} change={apr.plus(aprChange)} className='py-3' isPercentage /> <Item title='APR' current={apr} change={apr.plus(aprChange)} className='py-3' isPercentage />
<Item <Item

View File

@ -1,17 +1,25 @@
import classNames from 'classnames' import classNames from 'classnames'
import { Suspense } from 'react' import { Suspense } from 'react'
import { useParams } from 'react-router-dom'
import { AccountBalancesTable } from 'components/Account/AccountBalancesTable' import AccountBalancesTable from 'components/Account/AccountBalancesTable'
import AccountComposition from 'components/Account/AccountComposition' import AccountComposition from 'components/Account/AccountComposition'
import Card from 'components/Card' import Card from 'components/Card'
import Loading from 'components/Loading' import Loading from 'components/Loading'
import Text from 'components/Text' import Text from 'components/Text'
import useAccounts from 'hooks/useAccounts' import useAccounts from 'hooks/useAccounts'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
import useStore from 'store'
function Content() { function Content() {
const address = useParams().address || '' const address = useStore((s) => s.address)
const { data: account } = useAccounts(address) const { data: account } = useAccounts(address)
const { availableAssets: borrowAvailableAssets, accountBorrowedAssets } =
useBorrowMarketAssetsTableData()
const { availableAssets: lendingAvailableAssets, accountLentAssets } =
useLendingMarketAssetsTableData()
const borrowAssetsData = [...borrowAvailableAssets, ...accountBorrowedAssets]
const lendingAssetsData = [...lendingAvailableAssets, ...accountLentAssets]
if (!address) { if (!address) {
return ( return (
@ -35,7 +43,11 @@ function Content() {
<Card className='h-fit w-full bg-white/5' title={`Account ${account.id}`} key={index}> <Card className='h-fit w-full bg-white/5' title={`Account ${account.id}`} key={index}>
<AccountComposition account={account} /> <AccountComposition account={account} />
<Text className='mt-3 w-full bg-white/10 px-4 py-2 text-white/40'>Balances</Text> <Text className='mt-3 w-full bg-white/10 px-4 py-2 text-white/40'>Balances</Text>
<AccountBalancesTable data={account} /> <AccountBalancesTable
account={account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
/>
</Card> </Card>
))} ))}
</div> </div>

View File

@ -1,5 +1,5 @@
import Accordion from 'components/Accordion' import Accordion from 'components/Accordion'
import { AccountBalancesTable } from 'components/Account/AccountBalancesTable' import AccountBalancesTable from 'components/Account/AccountBalancesTable'
import AccountComposition from 'components/Account/AccountComposition' import AccountComposition from 'components/Account/AccountComposition'
import AccountHealth from 'components/Account/AccountHealth' import AccountHealth from 'components/Account/AccountHealth'
import Card from 'components/Card' import Card from 'components/Card'
@ -8,7 +8,9 @@ import { ArrowChartLineUp } from 'components/Icons'
import Text from 'components/Text' import Text from 'components/Text'
import { BN_ZERO } from 'constants/math' import { BN_ZERO } from 'constants/math'
import { ORACLE_DENOM } from 'constants/oracle' import { ORACLE_DENOM } from 'constants/oracle'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useIsOpenArray from 'hooks/useIsOpenArray' import useIsOpenArray from 'hooks/useIsOpenArray'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
import usePrices from 'hooks/usePrices' import usePrices from 'hooks/usePrices'
import { BNCoin } from 'types/classes/BNCoin' import { BNCoin } from 'types/classes/BNCoin'
import { calculateAccountDepositsValue } from 'utils/accounts' import { calculateAccountDepositsValue } from 'utils/accounts'
@ -24,6 +26,12 @@ export default function AccountSummary(props: Props) {
const accountBalance = props.account const accountBalance = props.account
? calculateAccountDepositsValue(props.account, prices) ? calculateAccountDepositsValue(props.account, prices)
: BN_ZERO : BN_ZERO
const { availableAssets: borrowAvailableAssets, accountBorrowedAssets } =
useBorrowMarketAssetsTableData()
const { availableAssets: lendingAvailableAssets, accountLentAssets } =
useLendingMarketAssetsTableData()
const borrowAssetsData = [...borrowAvailableAssets, ...accountBorrowedAssets]
const lendingAssetsData = [...lendingAvailableAssets, ...accountLentAssets]
if (!props.account) return null if (!props.account) return null
return ( return (
@ -60,7 +68,13 @@ export default function AccountSummary(props: Props) {
{ {
title: 'Balances', title: 'Balances',
renderContent: () => renderContent: () =>
props.account ? <AccountBalancesTable data={props.account} /> : null, props.account ? (
<AccountBalancesTable
account={props.account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
/>
) : null,
isOpen: isOpen[1], isOpen: isOpen[1],
toggleOpen: (index: number) => toggleOpen(index), toggleOpen: (index: number) => toggleOpen(index),
renderSubTitle: () => <></>, renderSubTitle: () => <></>,

View File

@ -17,7 +17,7 @@ interface AccountBalanceRow {
type: string type: string
symbol: string symbol: string
denom: string denom: string
amount: string amount: BigNumber
value: string | number value: string | number
size: number size: number
apy: number apy: number