fix: updated the account balances and added debts (#325)
This commit is contained in:
parent
fec03d030f
commit
1eec100907
@ -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}
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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: () => <></>,
|
||||||
|
2
src/types/interfaces/account.d.ts
vendored
2
src/types/interfaces/account.d.ts
vendored
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user