diff --git a/components/TokenList.tsx b/components/TokenList.tsx index ad7d3bab..c1f90be9 100644 --- a/components/TokenList.tsx +++ b/components/TokenList.tsx @@ -32,6 +32,7 @@ import useBanksWithBalances, { import useUnownedAccount from 'hooks/useUnownedAccount' import useLocalStorageState from 'hooks/useLocalStorageState' import TokenLogo from './shared/TokenLogo' +import useHealthContributions from 'hooks/useHealthContributions' const TokenList = () => { const { t } = useTranslation(['common', 'token', 'trade']) @@ -40,6 +41,7 @@ const TokenList = () => { true ) const { mangoAccount, mangoAccountAddress } = useMangoAccount() + const { initContributions } = useHealthContributions() const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances) const totalInterestData = mangoStore( (s) => s.mangoAccount.interestTotals.data @@ -48,14 +50,26 @@ const TokenList = () => { const showTableView = width ? width > breakpoints.md : false const banks = useBanksWithBalances('balance') + // const filteredBanks = useMemo(() => { + // if (banks.length) { + // return showZeroBalances || !mangoAccountAddress + // ? banks + // : banks.filter((b) => Math.abs(b.balance) > 0) + // } + // return [] + // }, [banks, mangoAccountAddress, showZeroBalances]) + const filteredBanks = useMemo(() => { - if (banks.length) { - return showZeroBalances || !mangoAccountAddress - ? banks - : banks.filter((b) => Math.abs(b.balance) > 0) - } - return [] - }, [banks, mangoAccountAddress, showZeroBalances]) + if (!banks.length) return [] + if (showZeroBalances || !mangoAccountAddress) return banks + const filtered = banks.filter((b) => { + const contribution = + initContributions.find((cont) => cont.asset === b.bank.name) + ?.contribution || 0 + return Math.abs(contribution) > 0 + }) + return filtered + }, [banks, mangoAccountAddress, showZeroBalances, initContributions]) return ( @@ -66,141 +80,181 @@ const TokenList = () => { disabled={!mangoAccount} onChange={() => setShowZeroBalances(!showZeroBalances)} > - {t('show-zero-balances')} + {t('account:zero-collateral')} ) : null} {showTableView ? ( - - - - - + + + + + + ) + })} + +
{t('token')} -
- - {t('balance')} +
+ + + + + + + + + - - - - - - - - - {filteredBanks.map((b) => { - const bank = b.bank + + + + + + + {filteredBanks.map((b) => { + const bank = b.bank - const tokenBalance = b.balance - const symbol = bank.name === 'MSOL' ? 'mSOL' : bank.name + const tokenBalance = b.balance + const symbol = bank.name === 'MSOL' ? 'mSOL' : bank.name - const hasInterestEarned = totalInterestData.find( - (d) => - d.symbol.toLowerCase() === symbol.toLowerCase() || - (symbol === 'ETH (Portal)' && d.symbol === 'ETH') - ) + const hasInterestEarned = totalInterestData.find( + (d) => + d.symbol.toLowerCase() === symbol.toLowerCase() || + (symbol === 'ETH (Portal)' && d.symbol === 'ETH') + ) - const interestAmount = hasInterestEarned - ? hasInterestEarned.borrow_interest * -1 + - hasInterestEarned.deposit_interest - : 0 + const interestAmount = hasInterestEarned + ? hasInterestEarned.borrow_interest * -1 + + hasInterestEarned.deposit_interest + : 0 - const interestValue = hasInterestEarned - ? hasInterestEarned.borrow_interest_usd * -1 + - hasInterestEarned.deposit_interest_usd - : 0.0 + const interestValue = hasInterestEarned + ? hasInterestEarned.borrow_interest_usd * -1 + + hasInterestEarned.deposit_interest_usd + : 0.0 - const inOrders = spotBalances[bank.mint.toString()]?.inOrders || 0 + const inOrders = + spotBalances[bank.mint.toString()]?.inOrders || 0 - const unsettled = - spotBalances[bank.mint.toString()]?.unsettled || 0 + const unsettled = + spotBalances[bank.mint.toString()]?.unsettled || 0 - return ( - - - - - - + - + - - - ) - })} - -
{t('token')} +
+ + {t('balance')} + +
+
+
+ + + {t('account:collateral-value')} + + +
+
{t('trade:in-orders')}{t('trade:unsettled')} + + + {t('interest-earned-paid')} + - - {t('trade:in-orders')}{t('trade:unsettled')} - - - {t('interest-earned-paid')} - - - -
- - {t('rates')} - -
-
- {t('actions')} -
+
+ + {t('rates')} + +
+
+ {t('actions')} +
-
-
- + const collateralValue = + initContributions.find((val) => val.asset === bank.name) + ?.contribution || 0 + + const assetWeight = bank + .scaledInitAssetWeight(bank.price) + .toFixed(2) + const liabWeight = bank + .scaledInitLiabWeight(bank.price) + .toFixed(2) + + return ( + +
+
+
+ +
+

{symbol}

-

{symbol}

- -
- - - - - - -
+
- - -
-

+

+

- %

- | -

+

- % + x

- -
-
- -
-
+ +
+ + + + +
+ +
+
+
+

+ + % +

+ | +

+ + % +

+
+
+
+ +
+
+ ) : (
{filteredBanks.map((b) => { @@ -218,6 +272,7 @@ const MobileTokenListItem = ({ bank }: { bank: BankWithBalance }) => { const { t } = useTranslation(['common', 'token']) const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances) const { mangoAccount } = useMangoAccount() + const { initContributions } = useHealthContributions() const totalInterestData = mangoStore( (s) => s.mangoAccount.interestTotals.data ) @@ -247,6 +302,15 @@ const MobileTokenListItem = ({ bank }: { bank: BankWithBalance }) => { const unsettled = spotBalances[mint.toString()]?.unsettled || 0 + const collateralValue = + initContributions.find((val) => val.asset === tokenBank.name) + ?.contribution || 0 + + const assetWeight = tokenBank + .scaledInitAssetWeight(tokenBank.price) + .toFixed(2) + const liabWeight = tokenBank.scaledInitLiabWeight(tokenBank.price).toFixed(2) + return ( {({ open }) => ( @@ -296,6 +360,29 @@ const MobileTokenListItem = ({ bank }: { bank: BankWithBalance }) => { >
+
+ +

+ {t('account:collateral-value')} +

+
+

+ + + {' '} + + x + +

+

{t('trade:in-orders')} diff --git a/components/shared/BalancesTable.tsx b/components/shared/BalancesTable.tsx index 20d46207..cfaf6e21 100644 --- a/components/shared/BalancesTable.tsx +++ b/components/shared/BalancesTable.tsx @@ -22,18 +22,21 @@ import useBanksWithBalances, { import useUnownedAccount from 'hooks/useUnownedAccount' import { Disclosure, Transition } from '@headlessui/react' import TokenLogo from './TokenLogo' +import useHealthContributions from 'hooks/useHealthContributions' +import Tooltip from './Tooltip' import { PublicKey } from '@solana/web3.js' import { USDC_MINT } from 'utils/constants' import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions' const BalancesTable = () => { - const { t } = useTranslation(['common', 'trade']) + const { t } = useTranslation(['common', 'account', 'trade']) const { mangoAccount, mangoAccountAddress } = useMangoAccount() const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances) const { width } = useViewport() const { connected } = useWallet() const showTableView = width ? width > breakpoints.md : false const banks = useBanksWithBalances('balance') + const { initContributions } = useHealthContributions() const filteredBanks = useMemo(() => { if (banks.length) { @@ -56,6 +59,15 @@ const BalancesTable = () => { {t('token')} {t('balance')} + +

+ + + {t('account:collateral-value')} + + +
+ {t('trade:in-orders')} {t('trade:unsettled')} @@ -70,6 +82,15 @@ const BalancesTable = () => { const inOrders = spotBalances[bank.mint.toString()]?.inOrders || 0 const unsettled = spotBalances[bank.mint.toString()]?.unsettled || 0 + const collateralValue = + initContributions.find((val) => val.asset === bank.name) + ?.contribution || 0 + + const assetWeight = bank + .scaledInitAssetWeight(bank.price) + .toFixed(2) + const liabWeight = bank.scaledInitLiabWeight(bank.price).toFixed(2) + return ( @@ -89,6 +110,23 @@ const BalancesTable = () => { />

+ +

+ +

+

+ + x +

+ @@ -109,6 +147,13 @@ const BalancesTable = () => { const inOrders = spotBalances[bank.mint.toString()]?.inOrders || 0 const unsettled = spotBalances[bank.mint.toString()]?.unsettled || 0 + const collateralValue = + initContributions.find((val) => val.asset === bank.name) + ?.contribution || 0 + + const assetWeight = bank.scaledInitAssetWeight(bank.price).toFixed(2) + const liabWeight = bank.scaledInitLiabWeight(bank.price).toFixed(2) + return ( {({ open }) => ( @@ -152,6 +197,33 @@ const BalancesTable = () => { >
+
+ +

+ {t('account:collateral-value')} +

+
+

+ + + {' '} + + x + +

+

{t('trade:in-orders')} diff --git a/hooks/useHealthContributions.ts b/hooks/useHealthContributions.ts new file mode 100644 index 00000000..6845fa78 --- /dev/null +++ b/hooks/useHealthContributions.ts @@ -0,0 +1,24 @@ +import { HealthType } from '@blockworks-foundation/mango-v4' +import mangoStore from '@store/mangoStore' +import { useMemo } from 'react' +import useMangoAccount from './useMangoAccount' + +export default function useHealthContributions() { + const { mangoAccount } = useMangoAccount() + + const [initContributions, maintContributions] = useMemo(() => { + const group = mangoStore.getState().group + if (!mangoAccount || !group) return [[], []] + const init = mangoAccount.getHealthContributionPerAssetUi( + group, + HealthType.init + ) + const maint = mangoAccount.getHealthContributionPerAssetUi( + group, + HealthType.maint + ) + return [init, maint] + }, [mangoAccount]) + + return { initContributions, maintContributions } +} diff --git a/public/locales/en/account.json b/public/locales/en/account.json index 8fb3b404..71df1eeb 100644 --- a/public/locales/en/account.json +++ b/public/locales/en/account.json @@ -1,6 +1,7 @@ { "assets": "Assets", "assets-liabilities": "Assets & Liabilities", + "collateral-value": "Collateral Value", "cumulative-interest-chart": "Cumulative Interst Chart", "daily-volume": "24h Volume", "export": "Export {{dataType}}", @@ -16,6 +17,7 @@ "no-pnl-history": "No PnL History", "pnl-chart": "PnL Chart", "pnl-history": "PnL History", + "tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.", "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", "tooltip-init-health": "The contribution an asset gives to your initial account health. Initial health affects your ability to open new positions and withdraw collateral from your account. The sum of these values is equal to your account's free collateral.", "tooltip-leverage": "Total assets value divided by account equity value", @@ -26,5 +28,6 @@ "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", "total-funding-earned": "Total Funding Earned", "volume-chart": "Volume Chart", - "week-starting": "Week starting {{week}}" + "week-starting": "Week starting {{week}}", + "zero-collateral": "Zero Collateral" } \ No newline at end of file diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 5b29c39f..63e60f25 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -142,7 +142,6 @@ "sell": "Sell", "settings": "Settings", "show-more": "Show More", - "show-zero-balances": "Show Zero Balances", "solana-tps": "Solana TPS", "soon": "Soon", "spot": "Spot", diff --git a/public/locales/es/account.json b/public/locales/es/account.json index 8fb3b404..71df1eeb 100644 --- a/public/locales/es/account.json +++ b/public/locales/es/account.json @@ -1,6 +1,7 @@ { "assets": "Assets", "assets-liabilities": "Assets & Liabilities", + "collateral-value": "Collateral Value", "cumulative-interest-chart": "Cumulative Interst Chart", "daily-volume": "24h Volume", "export": "Export {{dataType}}", @@ -16,6 +17,7 @@ "no-pnl-history": "No PnL History", "pnl-chart": "PnL Chart", "pnl-history": "PnL History", + "tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.", "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", "tooltip-init-health": "The contribution an asset gives to your initial account health. Initial health affects your ability to open new positions and withdraw collateral from your account. The sum of these values is equal to your account's free collateral.", "tooltip-leverage": "Total assets value divided by account equity value", @@ -26,5 +28,6 @@ "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", "total-funding-earned": "Total Funding Earned", "volume-chart": "Volume Chart", - "week-starting": "Week starting {{week}}" + "week-starting": "Week starting {{week}}", + "zero-collateral": "Zero Collateral" } \ No newline at end of file diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 31adca8b..96f00a91 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -141,7 +141,6 @@ "sell": "Sell", "settings": "Settings", "show-more": "Show More", - "show-zero-balances": "Show Zero Balances", "solana-tps": "Solana TPS", "soon": "Soon", "spot": "Spot", diff --git a/public/locales/ru/account.json b/public/locales/ru/account.json index 8fb3b404..71df1eeb 100644 --- a/public/locales/ru/account.json +++ b/public/locales/ru/account.json @@ -1,6 +1,7 @@ { "assets": "Assets", "assets-liabilities": "Assets & Liabilities", + "collateral-value": "Collateral Value", "cumulative-interest-chart": "Cumulative Interst Chart", "daily-volume": "24h Volume", "export": "Export {{dataType}}", @@ -16,6 +17,7 @@ "no-pnl-history": "No PnL History", "pnl-chart": "PnL Chart", "pnl-history": "PnL History", + "tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.", "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", "tooltip-init-health": "The contribution an asset gives to your initial account health. Initial health affects your ability to open new positions and withdraw collateral from your account. The sum of these values is equal to your account's free collateral.", "tooltip-leverage": "Total assets value divided by account equity value", @@ -26,5 +28,6 @@ "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", "total-funding-earned": "Total Funding Earned", "volume-chart": "Volume Chart", - "week-starting": "Week starting {{week}}" + "week-starting": "Week starting {{week}}", + "zero-collateral": "Zero Collateral" } \ No newline at end of file diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 31adca8b..96f00a91 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -141,7 +141,6 @@ "sell": "Sell", "settings": "Settings", "show-more": "Show More", - "show-zero-balances": "Show Zero Balances", "solana-tps": "Solana TPS", "soon": "Soon", "spot": "Spot", diff --git a/public/locales/zh/account.json b/public/locales/zh/account.json index 8fb3b404..71df1eeb 100644 --- a/public/locales/zh/account.json +++ b/public/locales/zh/account.json @@ -1,6 +1,7 @@ { "assets": "Assets", "assets-liabilities": "Assets & Liabilities", + "collateral-value": "Collateral Value", "cumulative-interest-chart": "Cumulative Interst Chart", "daily-volume": "24h Volume", "export": "Export {{dataType}}", @@ -16,6 +17,7 @@ "no-pnl-history": "No PnL History", "pnl-chart": "PnL Chart", "pnl-history": "PnL History", + "tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.", "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", "tooltip-init-health": "The contribution an asset gives to your initial account health. Initial health affects your ability to open new positions and withdraw collateral from your account. The sum of these values is equal to your account's free collateral.", "tooltip-leverage": "Total assets value divided by account equity value", @@ -26,5 +28,6 @@ "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", "total-funding-earned": "Total Funding Earned", "volume-chart": "Volume Chart", - "week-starting": "Week starting {{week}}" + "week-starting": "Week starting {{week}}", + "zero-collateral": "Zero Collateral" } \ No newline at end of file diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 4d29b366..de46da28 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -141,7 +141,6 @@ "sell": "卖", "settings": "设置", "show-more": "显示更多", - "show-zero-balances": "显示零余额", "solana-tps": "Solana TPS", "soon": "Soon", "spot": "现货", diff --git a/public/locales/zh_tw/account.json b/public/locales/zh_tw/account.json index 8fb3b404..71df1eeb 100644 --- a/public/locales/zh_tw/account.json +++ b/public/locales/zh_tw/account.json @@ -1,6 +1,7 @@ { "assets": "Assets", "assets-liabilities": "Assets & Liabilities", + "collateral-value": "Collateral Value", "cumulative-interest-chart": "Cumulative Interst Chart", "daily-volume": "24h Volume", "export": "Export {{dataType}}", @@ -16,6 +17,7 @@ "no-pnl-history": "No PnL History", "pnl-chart": "PnL Chart", "pnl-history": "PnL History", + "tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.", "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", "tooltip-init-health": "The contribution an asset gives to your initial account health. Initial health affects your ability to open new positions and withdraw collateral from your account. The sum of these values is equal to your account's free collateral.", "tooltip-leverage": "Total assets value divided by account equity value", @@ -26,5 +28,6 @@ "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", "total-funding-earned": "Total Funding Earned", "volume-chart": "Volume Chart", - "week-starting": "Week starting {{week}}" + "week-starting": "Week starting {{week}}", + "zero-collateral": "Zero Collateral" } \ No newline at end of file diff --git a/public/locales/zh_tw/common.json b/public/locales/zh_tw/common.json index 03cc864d..235ea30b 100644 --- a/public/locales/zh_tw/common.json +++ b/public/locales/zh_tw/common.json @@ -141,7 +141,6 @@ "sell": "賣", "settings": "設置", "show-more": "顯示更多", - "show-zero-balances": "顯示零餘額", "solana-tps": "Solana TPS", "soon": "Soon", "spot": "現貨",