import { HealthType, toUiDecimalsForQuote, } from '@blockworks-foundation/mango-v4' import { useTranslation } from 'next-i18next' import { useEffect, useMemo, useState } from 'react' import AccountActions from './AccountActions' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' import { formatNumericValue } from '../../utils/numbers' import FlipNumbers from 'react-flip-numbers' import dynamic from 'next/dynamic' const SimpleAreaChart = dynamic( () => import('@components/shared/SimpleAreaChart'), { ssr: false } ) import { COLORS } from '../../styles/colors' import { useTheme } from 'next-themes' import { IconButton } from '../shared/Button' import { ArrowsPointingOutIcon, ChartBarIcon, ClockIcon, } from '@heroicons/react/20/solid' import { Transition } from '@headlessui/react' import AccountTabs from './AccountTabs' import SheenLoader from '../shared/SheenLoader' import AccountChart from './AccountChart' import useMangoAccount from '../../hooks/useMangoAccount' import Change from '../shared/Change' import Tooltip from '@components/shared/Tooltip' import { ANIMATION_SETTINGS_KEY, // IS_ONBOARDED_KEY } from 'utils/constants' // import { useWallet } from '@solana/wallet-adapter-react' import useLocalStorageState from 'hooks/useLocalStorageState' // import AccountOnboardingTour from '@components/tours/AccountOnboardingTour' import dayjs from 'dayjs' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' import { useViewport } from 'hooks/useViewport' import { breakpoints } from 'utils/theme' import useMangoGroup from 'hooks/useMangoGroup' import PnlHistoryModal from '@components/modals/PnlHistoryModal' import FormatNumericValue from '@components/shared/FormatNumericValue' const AccountPage = () => { const { t } = useTranslation(['common', 'account']) // const { connected } = useWallet() const { group } = useMangoGroup() const { mangoAccount, mangoAccountAddress, initialLoad } = useMangoAccount() const actions = mangoStore.getState().actions const performanceInitialLoad = mangoStore( (s) => s.mangoAccount.performance.initialLoad ) const performanceData = mangoStore((s) => s.mangoAccount.performance.data) const totalInterestData = mangoStore( (s) => s.mangoAccount.interestTotals.data ) const [chartToShow, setChartToShow] = useState< 'account-value' | 'cumulative-interest-value' | 'pnl' | '' >('') const [oneDayPerformanceData, setOneDayPerformanceData] = useState< PerformanceDataItem[] >([]) const [showExpandChart, setShowExpandChart] = useState(false) const [showPnlHistory, setShowPnlHistory] = useState(false) const { theme } = useTheme() const { width } = useViewport() const isMobile = width ? width < breakpoints.md : false // const tourSettings = mangoStore((s) => s.settings.tours) // const [isOnBoarded] = useLocalStorageState(IS_ONBOARDED_KEY) const [animationSettings] = useLocalStorageState( ANIMATION_SETTINGS_KEY, INITIAL_ANIMATION_SETTINGS ) useEffect(() => { if (mangoAccountAddress || (!initialLoad && !mangoAccountAddress)) { const set = mangoStore.getState().set set((s) => { s.mangoAccount.performance.initialLoad = false }) setOneDayPerformanceData([]) actions.fetchAccountPerformance(mangoAccountAddress, 1) actions.fetchAccountInterestTotals(mangoAccountAddress) } }, [actions, initialLoad, mangoAccountAddress]) useEffect(() => { if ( performanceData.length && performanceInitialLoad && !oneDayPerformanceData.length ) { setOneDayPerformanceData(performanceData) } }, [performanceInitialLoad, oneDayPerformanceData, performanceData]) const onHoverMenu = (open: boolean, action: string) => { if ( (!open && action === 'onMouseEnter') || (open && action === 'onMouseLeave') ) { setShowExpandChart(!open) } } const handleShowAccountValueChart = () => { setChartToShow('account-value') setShowExpandChart(false) } const handleHideChart = () => { const set = mangoStore.getState().set set((s) => { s.mangoAccount.performance.data = oneDayPerformanceData }) setChartToShow('') } const handleCloseDailyPnlModal = () => { const set = mangoStore.getState().set set((s) => { s.mangoAccount.performance.data = oneDayPerformanceData }) setShowPnlHistory(false) } const accountValue = useMemo(() => { if (!group || !mangoAccount) return 0.0 return toUiDecimalsForQuote(mangoAccount.getEquity(group).toNumber()) }, [group, mangoAccount]) const leverage = useMemo(() => { if (!group || !mangoAccount) return 0 const assetsValue = toUiDecimalsForQuote( mangoAccount.getAssetsValue(group).toNumber() ) if (isNaN(assetsValue / accountValue)) { return 0 } else { return Math.abs(1 - assetsValue / accountValue) } }, [mangoAccount, group, accountValue]) const [accountPnl, accountValueChange, oneDayPnlChange] = useMemo(() => { if ( accountValue && oneDayPerformanceData.length && performanceData.length ) { const accountPnl = performanceData[performanceData.length - 1].pnl const accountValueChange = accountValue - oneDayPerformanceData[0].account_equity const startDayPnl = oneDayPerformanceData[0].pnl const endDayPnl = oneDayPerformanceData[oneDayPerformanceData.length - 1].pnl const oneDayPnlChange = endDayPnl - startDayPnl return [accountPnl, accountValueChange, oneDayPnlChange] } return [0, 0, 0] }, [accountValue, oneDayPerformanceData, performanceData]) const interestTotalValue = useMemo(() => { if (totalInterestData.length) { return totalInterestData.reduce( (a, c) => a + c.borrow_interest_usd + c.deposit_interest_usd, 0 ) } return 0.0 }, [totalInterestData]) const oneDayInterestChange = useMemo(() => { if (oneDayPerformanceData.length) { const startDayInterest = oneDayPerformanceData[0].borrow_interest_cumulative_usd + oneDayPerformanceData[0].deposit_interest_cumulative_usd const latest = oneDayPerformanceData.length - 1 const endDayInterest = oneDayPerformanceData[latest].borrow_interest_cumulative_usd + oneDayPerformanceData[latest].deposit_interest_cumulative_usd return endDayInterest - startDayInterest } return 0.0 }, [oneDayPerformanceData]) const maintHealth = useMemo(() => { return group && mangoAccount ? mangoAccount.getHealthRatioUi(group, HealthType.maint) : 0 }, [mangoAccount, group]) const handleChartToShow = ( chartName: 'pnl' | 'cumulative-interest-value' ) => { if ( (chartName === 'cumulative-interest-value' && interestTotalValue > 1) || interestTotalValue < -1 ) { setChartToShow(chartName) } if (chartName === 'pnl' && performanceData.length > 4) { setChartToShow(chartName) } } const latestAccountData = useMemo(() => { if (!accountValue || !performanceData.length) return [] const latestIndex = performanceData.length - 1 return [ { account_equity: accountValue, time: dayjs(Date.now()).toISOString(), borrow_interest_cumulative_usd: performanceData[latestIndex].borrow_interest_cumulative_usd, deposit_interest_cumulative_usd: performanceData[latestIndex].deposit_interest_cumulative_usd, pnl: performanceData[latestIndex].pnl, spot_value: performanceData[latestIndex].spot_value, transfer_balance: performanceData[latestIndex].transfer_balance, }, ] }, [accountValue, performanceData]) return !chartToShow ? ( <>

{t('account-value')}

{animationSettings['number-scroll'] ? ( group && mangoAccount ? ( ) : ( ) ) : ( )}

{t('today')}

{performanceInitialLoad ? ( oneDayPerformanceData.length ? (
onHoverMenu(showExpandChart, 'onMouseEnter') } onMouseLeave={() => onHoverMenu(showExpandChart, 'onMouseLeave') } > = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } data={oneDayPerformanceData.concat(latestAccountData)} name="accountValue" xKey="time" yKey="account_equity" /> handleShowAccountValueChart()} >
) : null ) : mangoAccountAddress ? (
) : null}

Health describes how close your account is to liquidation. The lower your account health is the more likely you are to get liquidated when prices fluctuate.

Your account health is {maintHealth}%

Scenario:{' '} If the prices of all your liabilities increase by{' '} {maintHealth}%, even for just a moment, some of your liabilities will be liquidated.

Scenario:{' '} If the value of your total collateral decreases by{' '} {((1 - 1 / ((maintHealth || 0) / 100 + 1)) * 100).toFixed( 2 )} % , some of your liabilities will be liquidated.

These are examples. A combination of events can also lead to liquidation.

} >

{t('health')}

{maintHealth}%

{t('free-collateral')}

{t('total')}:

{t('leverage')}

x

{t('pnl')}

{mangoAccountAddress ? (
{performanceData.length > 4 ? ( handleChartToShow('pnl')} > ) : null} setShowPnlHistory(true)} >
) : null}

{t('today')}

{t('total-interest-earned')}

{interestTotalValue > 1 || interestTotalValue < -1 ? ( handleChartToShow('cumulative-interest-value') } > ) : null}

{t('today')}

{/* {!tourSettings?.account_tour_seen && isOnBoarded && connected ? ( ) : null} */} {showPnlHistory ? ( ) : null} ) : (
{chartToShow === 'account-value' ? ( ) : chartToShow === 'pnl' ? ( ) : ( )}
) } export default AccountPage