Merge branch 'main' into pan/fix-trade-history
This commit is contained in:
commit
ac2a50c1fc
|
@ -46,7 +46,7 @@ const TokenList = () => {
|
||||||
const { group } = useMangoGroup()
|
const { group } = useMangoGroup()
|
||||||
const { mangoTokens } = useJupiterMints()
|
const { mangoTokens } = useJupiterMints()
|
||||||
const totalInterestData = mangoStore(
|
const totalInterestData = mangoStore(
|
||||||
(s) => s.mangoAccount.stats.interestTotals.data
|
(s) => s.mangoAccount.interestTotals.data
|
||||||
)
|
)
|
||||||
const { width } = useViewport()
|
const { width } = useViewport()
|
||||||
const showTableView = width ? width > breakpoints.md : false
|
const showTableView = width ? width > breakpoints.md : false
|
||||||
|
@ -304,7 +304,7 @@ const MobileTokenListItem = ({ bank }: { bank: Bank }) => {
|
||||||
const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances)
|
const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances)
|
||||||
const { mangoAccount } = useMangoAccount()
|
const { mangoAccount } = useMangoAccount()
|
||||||
const totalInterestData = mangoStore(
|
const totalInterestData = mangoStore(
|
||||||
(s) => s.mangoAccount.stats.interestTotals.data
|
(s) => s.mangoAccount.interestTotals.data
|
||||||
)
|
)
|
||||||
const symbol = bank.name
|
const symbol = bank.name
|
||||||
const oraclePrice = bank.uiPrice
|
const oraclePrice = bank.uiPrice
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
|
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import mangoStore from '@store/mangoStore'
|
import mangoStore from '@store/mangoStore'
|
||||||
import dynamic from 'next/dynamic'
|
import dynamic from 'next/dynamic'
|
||||||
import { numberCompacter } from 'utils/numbers'
|
import { numberCompacter } from 'utils/numbers'
|
||||||
|
@ -11,19 +11,38 @@ const DetailedAreaChart = dynamic(
|
||||||
|
|
||||||
const AccountChart = ({
|
const AccountChart = ({
|
||||||
chartToShow,
|
chartToShow,
|
||||||
data,
|
|
||||||
hideChart,
|
hideChart,
|
||||||
|
mangoAccountAddress,
|
||||||
yKey,
|
yKey,
|
||||||
}: {
|
}: {
|
||||||
chartToShow: string
|
chartToShow: string
|
||||||
data: Array<any>
|
|
||||||
hideChart: () => void
|
hideChart: () => void
|
||||||
|
mangoAccountAddress: string
|
||||||
yKey: string
|
yKey: string
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
const actions = mangoStore.getState().actions
|
const actions = mangoStore.getState().actions
|
||||||
const [daysToShow, setDaysToShow] = useState<string>('1')
|
const [daysToShow, setDaysToShow] = useState<string>('1')
|
||||||
const loading = mangoStore((s) => s.mangoAccount.stats.performance.loading)
|
const loading = mangoStore((s) => s.mangoAccount.performance.loading)
|
||||||
|
const performanceData = mangoStore((s) => s.mangoAccount.performance.data)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (mangoAccountAddress) {
|
||||||
|
actions.fetchAccountPerformance(mangoAccountAddress, 1)
|
||||||
|
}
|
||||||
|
}, [actions, mangoAccountAddress])
|
||||||
|
|
||||||
|
const data: any = useMemo(() => {
|
||||||
|
if (!performanceData.length) return []
|
||||||
|
if (chartToShow === 'cumulative-interest-value') {
|
||||||
|
performanceData.map((d) => ({
|
||||||
|
interest_value:
|
||||||
|
d.borrow_interest_cumulative_usd + d.deposit_interest_cumulative_usd,
|
||||||
|
time: d.time,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return performanceData
|
||||||
|
}, [performanceData])
|
||||||
|
|
||||||
const handleDaysToShow = async (days: string) => {
|
const handleDaysToShow = async (days: string) => {
|
||||||
const mangoAccount = mangoStore.getState().mangoAccount.current
|
const mangoAccount = mangoStore.getState().mangoAccount.current
|
||||||
|
|
|
@ -3,7 +3,6 @@ import {
|
||||||
toUiDecimalsForQuote,
|
toUiDecimalsForQuote,
|
||||||
} from '@blockworks-foundation/mango-v4'
|
} from '@blockworks-foundation/mango-v4'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import AccountActions from './AccountActions'
|
import AccountActions from './AccountActions'
|
||||||
import mangoStore, { PerformanceDataItem } from '@store/mangoStore'
|
import mangoStore, { PerformanceDataItem } from '@store/mangoStore'
|
||||||
|
@ -19,7 +18,8 @@ import { useTheme } from 'next-themes'
|
||||||
import { IconButton } from '../shared/Button'
|
import { IconButton } from '../shared/Button'
|
||||||
import {
|
import {
|
||||||
ArrowsPointingOutIcon,
|
ArrowsPointingOutIcon,
|
||||||
ChevronRightIcon,
|
ChartBarIcon,
|
||||||
|
ClockIcon,
|
||||||
} from '@heroicons/react/20/solid'
|
} from '@heroicons/react/20/solid'
|
||||||
import { Transition } from '@headlessui/react'
|
import { Transition } from '@headlessui/react'
|
||||||
import AccountTabs from './AccountTabs'
|
import AccountTabs from './AccountTabs'
|
||||||
|
@ -40,33 +40,20 @@ import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettin
|
||||||
import { useViewport } from 'hooks/useViewport'
|
import { useViewport } from 'hooks/useViewport'
|
||||||
import { breakpoints } from 'utils/theme'
|
import { breakpoints } from 'utils/theme'
|
||||||
import useMangoGroup from 'hooks/useMangoGroup'
|
import useMangoGroup from 'hooks/useMangoGroup'
|
||||||
|
import PnlHistoryModal from '@components/modals/PnlHistoryModal'
|
||||||
export async function getStaticProps({ locale }: { locale: string }) {
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
...(await serverSideTranslations(locale, [
|
|
||||||
'common',
|
|
||||||
'close-account',
|
|
||||||
'trade',
|
|
||||||
])),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const AccountPage = () => {
|
const AccountPage = () => {
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation(['common', 'account'])
|
||||||
// const { connected } = useWallet()
|
// const { connected } = useWallet()
|
||||||
const { group } = useMangoGroup()
|
const { group } = useMangoGroup()
|
||||||
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
|
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
|
||||||
const actions = mangoStore.getState().actions
|
const actions = mangoStore.getState().actions
|
||||||
const loadPerformanceData = mangoStore(
|
const performanceInitialLoad = mangoStore(
|
||||||
(s) => s.mangoAccount.stats.performance.loading
|
(s) => s.mangoAccount.performance.initialLoad
|
||||||
)
|
|
||||||
const performanceData = mangoStore(
|
|
||||||
(s) => s.mangoAccount.stats.performance.data
|
|
||||||
)
|
)
|
||||||
|
const performanceData = mangoStore((s) => s.mangoAccount.performance.data)
|
||||||
const totalInterestData = mangoStore(
|
const totalInterestData = mangoStore(
|
||||||
(s) => s.mangoAccount.stats.interestTotals.data
|
(s) => s.mangoAccount.interestTotals.data
|
||||||
)
|
)
|
||||||
const [chartToShow, setChartToShow] = useState<
|
const [chartToShow, setChartToShow] = useState<
|
||||||
'account-value' | 'cumulative-interest-value' | 'pnl' | ''
|
'account-value' | 'cumulative-interest-value' | 'pnl' | ''
|
||||||
|
@ -75,6 +62,7 @@ const AccountPage = () => {
|
||||||
PerformanceDataItem[]
|
PerformanceDataItem[]
|
||||||
>([])
|
>([])
|
||||||
const [showExpandChart, setShowExpandChart] = useState<boolean>(false)
|
const [showExpandChart, setShowExpandChart] = useState<boolean>(false)
|
||||||
|
const [showPnlHistory, setShowPnlHistory] = useState<boolean>(false)
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { width } = useViewport()
|
const { width } = useViewport()
|
||||||
const isMobile = width ? width < breakpoints.md : false
|
const isMobile = width ? width < breakpoints.md : false
|
||||||
|
@ -93,10 +81,10 @@ const AccountPage = () => {
|
||||||
}, [actions, mangoAccountAddress])
|
}, [actions, mangoAccountAddress])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mangoAccount && performanceData.length && !chartToShow) {
|
if (performanceInitialLoad && !oneDayPerformanceData.length) {
|
||||||
setOneDayPerformanceData(performanceData)
|
setOneDayPerformanceData(performanceData)
|
||||||
}
|
}
|
||||||
}, [mangoAccount, performanceData, chartToShow])
|
}, [performanceInitialLoad, oneDayPerformanceData])
|
||||||
|
|
||||||
const onHoverMenu = (open: boolean, action: string) => {
|
const onHoverMenu = (open: boolean, action: string) => {
|
||||||
if (
|
if (
|
||||||
|
@ -115,11 +103,19 @@ const AccountPage = () => {
|
||||||
const handleHideChart = () => {
|
const handleHideChart = () => {
|
||||||
const set = mangoStore.getState().set
|
const set = mangoStore.getState().set
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.mangoAccount.stats.performance.data = oneDayPerformanceData
|
s.mangoAccount.performance.data = oneDayPerformanceData
|
||||||
})
|
})
|
||||||
setChartToShow('')
|
setChartToShow('')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleCloseDailyPnlModal = () => {
|
||||||
|
const set = mangoStore.getState().set
|
||||||
|
set((s) => {
|
||||||
|
s.mangoAccount.performance.data = oneDayPerformanceData
|
||||||
|
})
|
||||||
|
setShowPnlHistory(false)
|
||||||
|
}
|
||||||
|
|
||||||
const accountValue = useMemo(() => {
|
const accountValue = useMemo(() => {
|
||||||
if (!group || !mangoAccount) return 0.0
|
if (!group || !mangoAccount) return 0.0
|
||||||
return toUiDecimalsForQuote(mangoAccount.getEquity(group).toNumber())
|
return toUiDecimalsForQuote(mangoAccount.getEquity(group).toNumber())
|
||||||
|
@ -139,19 +135,26 @@ const AccountPage = () => {
|
||||||
}, [mangoAccount, group, accountValue])
|
}, [mangoAccount, group, accountValue])
|
||||||
|
|
||||||
const { accountPnl, accountValueChange } = useMemo(() => {
|
const { accountPnl, accountValueChange } = useMemo(() => {
|
||||||
if (accountValue && performanceData.length) {
|
if (
|
||||||
|
accountValue &&
|
||||||
|
oneDayPerformanceData.length &&
|
||||||
|
performanceData.length
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
accountPnl: performanceData[performanceData.length - 1].pnl,
|
accountPnl: performanceData[performanceData.length - 1].pnl,
|
||||||
accountValueChange: accountValue - performanceData[0].account_equity,
|
accountValueChange:
|
||||||
|
accountValue - oneDayPerformanceData[0].account_equity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { accountPnl: 0, accountValueChange: 0 }
|
return { accountPnl: 0, accountValueChange: 0 }
|
||||||
}, [accountValue, performanceData])
|
}, [accountValue, oneDayPerformanceData, performanceData])
|
||||||
|
|
||||||
const oneDayPnlChange = useMemo(() => {
|
const oneDayPnlChange = useMemo(() => {
|
||||||
if (accountPnl && oneDayPerformanceData.length) {
|
if (accountPnl && oneDayPerformanceData.length) {
|
||||||
const startDayPnl = oneDayPerformanceData[0].pnl
|
const startDayPnl = oneDayPerformanceData[0].pnl
|
||||||
return accountPnl - startDayPnl
|
const endDayPnl =
|
||||||
|
oneDayPerformanceData[oneDayPerformanceData.length - 1].pnl
|
||||||
|
return endDayPnl - startDayPnl
|
||||||
}
|
}
|
||||||
return 0.0
|
return 0.0
|
||||||
}, [accountPnl, oneDayPerformanceData])
|
}, [accountPnl, oneDayPerformanceData])
|
||||||
|
@ -266,8 +269,8 @@ const AccountPage = () => {
|
||||||
<p className="text-th-fgd-4">{t('today')}</p>
|
<p className="text-th-fgd-4">{t('today')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!loadPerformanceData ? (
|
{performanceInitialLoad ? (
|
||||||
mangoAccount && performanceData.length ? (
|
oneDayPerformanceData.length ? (
|
||||||
<div
|
<div
|
||||||
className="relative mt-4 flex h-44 items-end md:mt-0 md:h-24 md:w-48"
|
className="relative mt-4 flex h-44 items-end md:mt-0 md:h-24 md:w-48"
|
||||||
onMouseEnter={() =>
|
onMouseEnter={() =>
|
||||||
|
@ -283,7 +286,7 @@ const AccountPage = () => {
|
||||||
? COLORS.UP[theme]
|
? COLORS.UP[theme]
|
||||||
: COLORS.DOWN[theme]
|
: COLORS.DOWN[theme]
|
||||||
}
|
}
|
||||||
data={performanceData.concat(latestAccountData)}
|
data={oneDayPerformanceData.concat(latestAccountData)}
|
||||||
name="accountValue"
|
name="accountValue"
|
||||||
xKey="time"
|
xKey="time"
|
||||||
yKey="account_equity"
|
yKey="account_equity"
|
||||||
|
@ -309,11 +312,11 @@ const AccountPage = () => {
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
) : (
|
) : mangoAccountAddress ? (
|
||||||
<SheenLoader className="mt-4 flex flex-1 md:mt-0">
|
<SheenLoader className="mt-4 flex flex-1 md:mt-0">
|
||||||
<div className="h-40 w-full rounded-md bg-th-bkg-2 md:h-24 md:w-48" />
|
<div className="h-40 w-full rounded-md bg-th-bkg-2 md:h-24 md:w-48" />
|
||||||
</SheenLoader>
|
</SheenLoader>
|
||||||
)}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6 mb-1 lg:mt-0 lg:mb-0">
|
<div className="mt-6 mb-1 lg:mt-0 lg:mb-0">
|
||||||
<AccountActions />
|
<AccountActions />
|
||||||
|
@ -369,7 +372,7 @@ const AccountPage = () => {
|
||||||
<div className="col-span-5 flex border-t border-th-bkg-3 py-3 pl-6 lg:col-span-1 lg:border-l lg:border-t-0">
|
<div className="col-span-5 flex border-t border-th-bkg-3 py-3 pl-6 lg:col-span-1 lg:border-l lg:border-t-0">
|
||||||
<div id="account-step-five">
|
<div id="account-step-five">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content="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."
|
content={t('account:tooltip-free-collateral')}
|
||||||
maxWidth="20rem"
|
maxWidth="20rem"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
delay={250}
|
delay={250}
|
||||||
|
@ -391,12 +394,12 @@ const AccountPage = () => {
|
||||||
</p>
|
</p>
|
||||||
<span className="text-xs font-normal text-th-fgd-4">
|
<span className="text-xs font-normal text-th-fgd-4">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content="Total value of collateral for trading and borrowing (including unsettled PnL)."
|
content={t('account:tooltip-total-collateral')}
|
||||||
maxWidth="20rem"
|
maxWidth="20rem"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
delay={250}
|
delay={250}
|
||||||
>
|
>
|
||||||
<span className="tooltip-underline">Total</span>:
|
<span className="tooltip-underline">{t('total')}</span>:
|
||||||
<span className="ml-1 font-mono text-th-fgd-2">
|
<span className="ml-1 font-mono text-th-fgd-2">
|
||||||
{group && mangoAccount
|
{group && mangoAccount
|
||||||
? formatFixedDecimals(
|
? formatFixedDecimals(
|
||||||
|
@ -417,7 +420,7 @@ const AccountPage = () => {
|
||||||
<div className="col-span-5 flex border-t border-th-bkg-3 py-3 pl-6 lg:col-span-1 lg:border-l lg:border-t-0">
|
<div className="col-span-5 flex border-t border-th-bkg-3 py-3 pl-6 lg:col-span-1 lg:border-l lg:border-t-0">
|
||||||
<div id="account-step-six">
|
<div id="account-step-six">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content="Total assets value divided by account equity value."
|
content={t('account:tooltip-leverage')}
|
||||||
maxWidth="20rem"
|
maxWidth="20rem"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
delay={250}
|
delay={250}
|
||||||
|
@ -431,24 +434,43 @@ const AccountPage = () => {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="col-span-5 border-t border-th-bkg-3 py-3 pl-6 pr-4 lg:col-span-1 lg:border-l lg:border-t-0">
|
||||||
className={`col-span-5 flex items-center justify-between border-t border-th-bkg-3 py-3 pl-6 pr-4 lg:col-span-1 lg:border-l lg:border-t-0 ${
|
|
||||||
performanceData.length > 4
|
|
||||||
? 'default-transition cursor-pointer md:hover:bg-th-bkg-2'
|
|
||||||
: 'cursor-default'
|
|
||||||
}`}
|
|
||||||
onClick={() => handleChartToShow('pnl')}
|
|
||||||
>
|
|
||||||
<div id="account-step-seven" className="flex flex-col items-start">
|
<div id="account-step-seven" className="flex flex-col items-start">
|
||||||
<Tooltip
|
<div className="flex w-full items-center justify-between">
|
||||||
content="The amount your account has made or lost."
|
<Tooltip
|
||||||
placement="bottom"
|
content={t('account:tooltip-pnl')}
|
||||||
delay={250}
|
placement="bottom"
|
||||||
>
|
delay={250}
|
||||||
<p className="tooltip-underline inline text-sm text-th-fgd-3 xl:text-base">
|
>
|
||||||
{t('pnl')}
|
<p className="tooltip-underline inline text-sm text-th-fgd-3 xl:text-base">
|
||||||
</p>
|
{t('pnl')}
|
||||||
</Tooltip>
|
</p>
|
||||||
|
</Tooltip>
|
||||||
|
{mangoAccountAddress ? (
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
{performanceData.length > 4 ? (
|
||||||
|
<Tooltip content={t('account:pnl-chart')} delay={250}>
|
||||||
|
<IconButton
|
||||||
|
className="text-th-fgd-3"
|
||||||
|
hideBg
|
||||||
|
onClick={() => handleChartToShow('pnl')}
|
||||||
|
>
|
||||||
|
<ChartBarIcon className="h-5 w-5" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
) : null}
|
||||||
|
<Tooltip content={t('account:pnl-history')} delay={250}>
|
||||||
|
<IconButton
|
||||||
|
className="text-th-fgd-3"
|
||||||
|
hideBg
|
||||||
|
onClick={() => setShowPnlHistory(true)}
|
||||||
|
>
|
||||||
|
<ClockIcon className="h-5 w-5" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
<p className="mt-1 mb-0.5 text-left text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
<p className="mt-1 mb-0.5 text-left text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
||||||
{formatFixedDecimals(accountPnl, true, true)}
|
{formatFixedDecimals(accountPnl, true, true)}
|
||||||
</p>
|
</p>
|
||||||
|
@ -457,29 +479,34 @@ const AccountPage = () => {
|
||||||
<p className="text-xs text-th-fgd-4">{t('today')}</p>
|
<p className="text-xs text-th-fgd-4">{t('today')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{performanceData.length > 4 ? (
|
</div>
|
||||||
<ChevronRightIcon className="h-6 w-6" />
|
<div className="col-span-5 border-t border-th-bkg-3 py-3 pl-6 pr-4 text-left lg:col-span-1 lg:border-l lg:border-t-0">
|
||||||
) : null}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`col-span-5 flex items-center justify-between border-t border-th-bkg-3 py-3 pl-6 pr-4 text-left lg:col-span-1 lg:border-l lg:border-t-0 ${
|
|
||||||
interestTotalValue > 1 || interestTotalValue < -1
|
|
||||||
? 'default-transition cursor-pointer md:hover:bg-th-bkg-2'
|
|
||||||
: 'cursor-default'
|
|
||||||
}`}
|
|
||||||
onClick={() => handleChartToShow('cumulative-interest-value')}
|
|
||||||
>
|
|
||||||
<div id="account-step-eight">
|
<div id="account-step-eight">
|
||||||
<Tooltip
|
<div className="flex w-full items-center justify-between">
|
||||||
content="The value of interest earned (deposits) minus interest paid (borrows)."
|
<Tooltip
|
||||||
maxWidth="20rem"
|
content={t('account:tooltip-total-interest')}
|
||||||
placement="bottom-end"
|
maxWidth="20rem"
|
||||||
delay={250}
|
placement="bottom-end"
|
||||||
>
|
delay={250}
|
||||||
<p className="tooltip-underline text-sm text-th-fgd-3 xl:text-base">
|
>
|
||||||
{t('total-interest-earned')}
|
<p className="tooltip-underline text-sm text-th-fgd-3 xl:text-base">
|
||||||
</p>
|
{t('total-interest-earned')}
|
||||||
</Tooltip>
|
</p>
|
||||||
|
</Tooltip>
|
||||||
|
{interestTotalValue > 1 || interestTotalValue < -1 ? (
|
||||||
|
<Tooltip content="Cumulative Interest Chart" delay={250}>
|
||||||
|
<IconButton
|
||||||
|
className="text-th-fgd-3"
|
||||||
|
hideBg
|
||||||
|
onClick={() =>
|
||||||
|
handleChartToShow('cumulative-interest-value')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ChartBarIcon className="h-5 w-5" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
<p className="mt-1 mb-0.5 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
<p className="mt-1 mb-0.5 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
||||||
{formatFixedDecimals(interestTotalValue, true, true)}
|
{formatFixedDecimals(interestTotalValue, true, true)}
|
||||||
</p>
|
</p>
|
||||||
|
@ -488,42 +515,41 @@ const AccountPage = () => {
|
||||||
<p className="text-xs text-th-fgd-4">{t('today')}</p>
|
<p className="text-xs text-th-fgd-4">{t('today')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{interestTotalValue > 1 || interestTotalValue < -1 ? (
|
</div>
|
||||||
<ChevronRightIcon className="-mt-0.5 h-6 w-6" />
|
|
||||||
) : null}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<AccountTabs />
|
<AccountTabs />
|
||||||
{/* {!tourSettings?.account_tour_seen && isOnBoarded && connected ? (
|
{/* {!tourSettings?.account_tour_seen && isOnBoarded && connected ? (
|
||||||
<AccountOnboardingTour />
|
<AccountOnboardingTour />
|
||||||
) : null} */}
|
) : null} */}
|
||||||
|
{showPnlHistory ? (
|
||||||
|
<PnlHistoryModal
|
||||||
|
pnlChangeToday={oneDayPnlChange}
|
||||||
|
isOpen={showPnlHistory}
|
||||||
|
onClose={handleCloseDailyPnlModal}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="p-6 pb-0">
|
<div className="p-6 pb-0">
|
||||||
{chartToShow === 'account-value' ? (
|
{chartToShow === 'account-value' ? (
|
||||||
<AccountChart
|
<AccountChart
|
||||||
chartToShow="account-value"
|
chartToShow="account-value"
|
||||||
data={performanceData}
|
|
||||||
hideChart={handleHideChart}
|
hideChart={handleHideChart}
|
||||||
|
mangoAccountAddress={mangoAccountAddress}
|
||||||
yKey="account_equity"
|
yKey="account_equity"
|
||||||
/>
|
/>
|
||||||
) : chartToShow === 'pnl' ? (
|
) : chartToShow === 'pnl' ? (
|
||||||
<AccountChart
|
<AccountChart
|
||||||
chartToShow="pnl"
|
chartToShow="pnl"
|
||||||
data={performanceData}
|
|
||||||
hideChart={handleHideChart}
|
hideChart={handleHideChart}
|
||||||
|
mangoAccountAddress={mangoAccountAddress}
|
||||||
yKey="pnl"
|
yKey="pnl"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<AccountChart
|
<AccountChart
|
||||||
chartToShow="cumulative-interest-value"
|
chartToShow="cumulative-interest-value"
|
||||||
data={performanceData.map((d) => ({
|
|
||||||
interest_value:
|
|
||||||
d.borrow_interest_cumulative_usd +
|
|
||||||
d.deposit_interest_cumulative_usd,
|
|
||||||
time: d.time,
|
|
||||||
}))}
|
|
||||||
hideChart={handleHideChart}
|
hideChart={handleHideChart}
|
||||||
|
mangoAccountAddress={mangoAccountAddress}
|
||||||
yKey="interest_value"
|
yKey="interest_value"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { useUnsettledSpotBalances } from 'hooks/useUnsettledSpotBalances'
|
||||||
import { useViewport } from 'hooks/useViewport'
|
import { useViewport } from 'hooks/useViewport'
|
||||||
import { breakpoints } from 'utils/theme'
|
import { breakpoints } from 'utils/theme'
|
||||||
import useUnsettledPerpPositions from 'hooks/useUnsettledPerpPositions'
|
import useUnsettledPerpPositions from 'hooks/useUnsettledPerpPositions'
|
||||||
|
import TradeHistory from '@components/trade/TradeHistory'
|
||||||
|
|
||||||
const AccountTabs = () => {
|
const AccountTabs = () => {
|
||||||
const [activeTab, setActiveTab] = useState('balances')
|
const [activeTab, setActiveTab] = useState('balances')
|
||||||
|
@ -23,15 +24,16 @@ const AccountTabs = () => {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['balances', 0],
|
['balances', 0],
|
||||||
|
['trade:unsettled', unsettledTradeCount],
|
||||||
['activity:activity', 0],
|
['activity:activity', 0],
|
||||||
['swap:swap-history', 0],
|
['swap:swap-history', 0],
|
||||||
['trade:unsettled', unsettledTradeCount],
|
['trade-history', 0],
|
||||||
]
|
]
|
||||||
}, [unsettledPerpPositions, unsettledSpotBalances])
|
}, [unsettledPerpPositions, unsettledSpotBalances])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="border-b border-th-bkg-3">
|
<div className="hide-scroll overflow-x-auto border-b border-th-bkg-3">
|
||||||
<TabButtons
|
<TabButtons
|
||||||
activeValue={activeTab}
|
activeValue={activeTab}
|
||||||
onChange={(v) => setActiveTab(v)}
|
onChange={(v) => setActiveTab(v)}
|
||||||
|
@ -51,10 +53,6 @@ const TabContent = ({ activeTab }: { activeTab: string }) => {
|
||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
case 'balances':
|
case 'balances':
|
||||||
return <TokenList />
|
return <TokenList />
|
||||||
case 'activity:activity':
|
|
||||||
return <ActivityFeed />
|
|
||||||
case 'swap:swap-history':
|
|
||||||
return <SwapHistoryTable />
|
|
||||||
case 'trade:unsettled':
|
case 'trade:unsettled':
|
||||||
return (
|
return (
|
||||||
<UnsettledTrades
|
<UnsettledTrades
|
||||||
|
@ -62,6 +60,12 @@ const TabContent = ({ activeTab }: { activeTab: string }) => {
|
||||||
unsettledPerpPositions={unsettledPerpPositions}
|
unsettledPerpPositions={unsettledPerpPositions}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
case 'activity:activity':
|
||||||
|
return <ActivityFeed />
|
||||||
|
case 'swap:swap-history':
|
||||||
|
return <SwapHistoryTable />
|
||||||
|
case 'trade-history':
|
||||||
|
return <TradeHistory />
|
||||||
default:
|
default:
|
||||||
return <TokenList />
|
return <TokenList />
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { useViewport } from 'hooks/useViewport'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import Image from 'next/legacy/image'
|
import Image from 'next/legacy/image'
|
||||||
import { Fragment, useCallback, useState } from 'react'
|
import { Fragment, useCallback, useState } from 'react'
|
||||||
import { PREFERRED_EXPLORER_KEY } from 'utils/constants'
|
import { PAGINATION_PAGE_LENGTH, PREFERRED_EXPLORER_KEY } from 'utils/constants'
|
||||||
import { formatDecimal, formatFixedDecimals } from 'utils/numbers'
|
import { formatDecimal, formatFixedDecimals } from 'utils/numbers'
|
||||||
import { breakpoints } from 'utils/theme'
|
import { breakpoints } from 'utils/theme'
|
||||||
|
|
||||||
|
@ -55,8 +55,12 @@ const ActivityFeedTable = ({
|
||||||
s.activityFeed.loading = true
|
s.activityFeed.loading = true
|
||||||
})
|
})
|
||||||
if (!mangoAccountAddress) return
|
if (!mangoAccountAddress) return
|
||||||
setOffset(offset + 25)
|
setOffset(offset + PAGINATION_PAGE_LENGTH)
|
||||||
actions.fetchActivityFeed(mangoAccountAddress, offset + 25, params)
|
actions.fetchActivityFeed(
|
||||||
|
mangoAccountAddress,
|
||||||
|
offset + PAGINATION_PAGE_LENGTH,
|
||||||
|
params
|
||||||
|
)
|
||||||
}, [actions, offset, params, mangoAccountAddress])
|
}, [actions, offset, params, mangoAccountAddress])
|
||||||
|
|
||||||
const getCreditAndDebit = (activity: any) => {
|
const getCreditAndDebit = (activity: any) => {
|
||||||
|
@ -316,7 +320,8 @@ const ActivityFeedTable = ({
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{activityFeed.length && activityFeed.length % 25 === 0 ? (
|
{activityFeed.length &&
|
||||||
|
activityFeed.length % PAGINATION_PAGE_LENGTH === 0 ? (
|
||||||
<div className="flex justify-center py-6">
|
<div className="flex justify-center py-6">
|
||||||
<LinkButton onClick={handleShowMore}>Show More</LinkButton>
|
<LinkButton onClick={handleShowMore}>Show More</LinkButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
import { ModalProps } from '../../types/modal'
|
||||||
|
import Modal from '../shared/Modal'
|
||||||
|
import mangoStore, { PerformanceDataItem } from '@store/mangoStore'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import { useEffect, useMemo } from 'react'
|
||||||
|
import useMangoAccount from 'hooks/useMangoAccount'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import Change from '@components/shared/Change'
|
||||||
|
import SheenLoader from '@components/shared/SheenLoader'
|
||||||
|
import { NoSymbolIcon } from '@heroicons/react/20/solid'
|
||||||
|
|
||||||
|
interface PnlChange {
|
||||||
|
time: string
|
||||||
|
pnlChange: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PnlHistoryModalProps {
|
||||||
|
pnlChangeToday: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModalCombinedProps = PnlHistoryModalProps & ModalProps
|
||||||
|
|
||||||
|
const PnlHistoryModal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
pnlChangeToday,
|
||||||
|
}: ModalCombinedProps) => {
|
||||||
|
const { t } = useTranslation('account')
|
||||||
|
const { mangoAccountAddress } = useMangoAccount()
|
||||||
|
const actions = mangoStore.getState().actions
|
||||||
|
const loading = mangoStore((s) => s.mangoAccount.performance.loading)
|
||||||
|
const performanceData = mangoStore((s) => s.mangoAccount.performance.data)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (mangoAccountAddress) {
|
||||||
|
actions.fetchAccountPerformance(mangoAccountAddress, 30)
|
||||||
|
}
|
||||||
|
}, [actions, mangoAccountAddress])
|
||||||
|
|
||||||
|
const dailyValues: PnlChange[] = useMemo(() => {
|
||||||
|
if (!performanceData.length) return []
|
||||||
|
|
||||||
|
const dailyPnl = performanceData.filter((d: PerformanceDataItem) => {
|
||||||
|
const date = new Date(d.time)
|
||||||
|
return date.getHours() === 0
|
||||||
|
})
|
||||||
|
|
||||||
|
return dailyPnl.length
|
||||||
|
? dailyPnl
|
||||||
|
.map((d: PerformanceDataItem, index: number) => {
|
||||||
|
if (index < dailyPnl.length - 1) {
|
||||||
|
return {
|
||||||
|
time: d.time,
|
||||||
|
pnlChange: dailyPnl[index + 1].pnl - d.pnl,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
time: performanceData[performanceData.length - 1].time,
|
||||||
|
pnlChange: pnlChangeToday,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.reverse()
|
||||||
|
: []
|
||||||
|
}, [performanceData])
|
||||||
|
|
||||||
|
const pnlThisWeek = useMemo(() => {
|
||||||
|
if (dailyValues.length) {
|
||||||
|
const saturdayIndex = dailyValues.findIndex((d) => {
|
||||||
|
const day = new Date(d.time).getDay()
|
||||||
|
return day === 6
|
||||||
|
})
|
||||||
|
if (saturdayIndex !== -1) {
|
||||||
|
return dailyValues
|
||||||
|
.slice(0, saturdayIndex)
|
||||||
|
.reduce((a, c) => a + c.pnlChange, 0)
|
||||||
|
} else {
|
||||||
|
return dailyValues.reduce((a, c) => a + c.pnlChange, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}, [dailyValues])
|
||||||
|
|
||||||
|
const getLastSunday = (d: Date) => {
|
||||||
|
return d.setDate(d.getDate() - d.getDay())
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<div className="h-96">
|
||||||
|
<div className="flex h-full flex-col">
|
||||||
|
<h2 className="mb-4">{t('pnl-history')}</h2>
|
||||||
|
{loading ? (
|
||||||
|
<div className="space-y-1.5">
|
||||||
|
{[...Array(4)].map((x, i) => (
|
||||||
|
<SheenLoader className="flex flex-1" key={i}>
|
||||||
|
<div className="h-12 w-full bg-th-bkg-2" />
|
||||||
|
</SheenLoader>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : dailyValues?.length ? (
|
||||||
|
<>
|
||||||
|
<div className="thin-scroll overflow-auto pr-1">
|
||||||
|
<div className="border-b border-th-bkg-3">
|
||||||
|
{dailyValues.map((v: any) => (
|
||||||
|
<div
|
||||||
|
className="flex items-center justify-between border-t border-th-bkg-3 p-3"
|
||||||
|
key={v.time + v.pnlChange}
|
||||||
|
>
|
||||||
|
<p>{dayjs(v.time).format('YYYY-MM-DD')}</p>
|
||||||
|
<Change change={v.pnlChange} prefix="$" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-4 flex justify-between rounded-md bg-th-bkg-2 p-3">
|
||||||
|
<p>
|
||||||
|
{t('week-starting', {
|
||||||
|
week: dayjs(getLastSunday(new Date())).format('MM-DD'),
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<Change change={pnlThisWeek} prefix="$" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-full flex-col items-center justify-center pb-12">
|
||||||
|
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-3" />
|
||||||
|
<p>{t('no-pnl-history')}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PnlHistoryModal
|
|
@ -3,7 +3,7 @@ export const UpTriangle = ({ size }: { size?: 'small' }) => (
|
||||||
className={`h-0 w-0 ${
|
className={`h-0 w-0 ${
|
||||||
size === 'small'
|
size === 'small'
|
||||||
? 'border-l-[4px] border-r-[4px] border-b-[6.92px]'
|
? 'border-l-[4px] border-r-[4px] border-b-[6.92px]'
|
||||||
: 'border-l-[6px] border-r-[6px] border-b-[10.39px]'
|
: 'border-l-[5px] border-r-[5px] border-b-[8.65px]'
|
||||||
} border-b-th-up border-l-transparent border-r-transparent`}
|
} border-b-th-up border-l-transparent border-r-transparent`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ export const DownTriangle = ({ size }: { size?: 'small' }) => (
|
||||||
className={`h-0 w-0 ${
|
className={`h-0 w-0 ${
|
||||||
size === 'small'
|
size === 'small'
|
||||||
? 'border-l-[4px] border-r-[4px] border-t-[6.92px]'
|
? 'border-l-[4px] border-r-[4px] border-t-[6.92px]'
|
||||||
: 'border-l-[6px] border-r-[6px] border-t-[10.39px]'
|
: 'border-l-[5px] border-r-[5px] border-t-[8.65px]'
|
||||||
} border-l-transparent border-r-transparent border-t-th-down`}
|
} border-l-transparent border-r-transparent border-t-th-down`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,11 @@ export const Table = ({
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
}) => <table className={`m-0 min-w-full p-0 ${className}`}>{children}</table>
|
}) => (
|
||||||
|
<div className="thin-scroll overflow-x-auto">
|
||||||
|
<table className={`m-0 min-w-full p-0 ${className}`}>{children}</table>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
export const TrHead = ({
|
export const TrHead = ({
|
||||||
children,
|
children,
|
||||||
|
|
|
@ -31,10 +31,8 @@ import { useWallet } from '@solana/wallet-adapter-react'
|
||||||
|
|
||||||
const SwapHistoryTable = () => {
|
const SwapHistoryTable = () => {
|
||||||
const { t } = useTranslation(['common', 'settings', 'swap'])
|
const { t } = useTranslation(['common', 'settings', 'swap'])
|
||||||
const swapHistory = mangoStore((s) => s.mangoAccount.stats.swapHistory.data)
|
const swapHistory = mangoStore((s) => s.mangoAccount.swapHistory.data)
|
||||||
const initialLoad = mangoStore(
|
const initialLoad = mangoStore((s) => s.mangoAccount.swapHistory.initialLoad)
|
||||||
(s) => s.mangoAccount.stats.swapHistory.initialLoad
|
|
||||||
)
|
|
||||||
const { connected } = useWallet()
|
const { connected } = useWallet()
|
||||||
const { mangoTokens } = useJupiterMints()
|
const { mangoTokens } = useJupiterMints()
|
||||||
const [showSwapDetails, setSwapDetails] = useState('')
|
const [showSwapDetails, setSwapDetails] = useState('')
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { I80F48, PerpMarket } from '@blockworks-foundation/mango-v4'
|
import { I80F48, PerpMarket } from '@blockworks-foundation/mango-v4'
|
||||||
|
import { LinkButton } from '@components/shared/Button'
|
||||||
|
import SheenLoader from '@components/shared/SheenLoader'
|
||||||
import SideBadge from '@components/shared/SideBadge'
|
import SideBadge from '@components/shared/SideBadge'
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
@ -14,7 +16,9 @@ import mangoStore from '@store/mangoStore'
|
||||||
import useMangoAccount from 'hooks/useMangoAccount'
|
import useMangoAccount from 'hooks/useMangoAccount'
|
||||||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||||
import { useViewport } from 'hooks/useViewport'
|
import { useViewport } from 'hooks/useViewport'
|
||||||
import { useMemo } from 'react'
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import { useCallback, useMemo, useState } from 'react'
|
||||||
|
import { PAGINATION_PAGE_LENGTH } from 'utils/constants'
|
||||||
import { formatDecimal, formatFixedDecimals } from 'utils/numbers'
|
import { formatDecimal, formatFixedDecimals } from 'utils/numbers'
|
||||||
import { breakpoints } from 'utils/theme'
|
import { breakpoints } from 'utils/theme'
|
||||||
import TableMarketName from './TableMarketName'
|
import TableMarketName from './TableMarketName'
|
||||||
|
@ -86,11 +90,17 @@ const formatTradeHistory = (
|
||||||
}
|
}
|
||||||
|
|
||||||
const TradeHistory = () => {
|
const TradeHistory = () => {
|
||||||
|
const { t } = useTranslation(['common', 'trade'])
|
||||||
const group = mangoStore.getState().group
|
const group = mangoStore.getState().group
|
||||||
const { selectedMarket } = useSelectedMarket()
|
const { selectedMarket } = useSelectedMarket()
|
||||||
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
|
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
|
||||||
|
const actions = mangoStore((s) => s.actions)
|
||||||
const fills = mangoStore((s) => s.selectedMarket.fills)
|
const fills = mangoStore((s) => s.selectedMarket.fills)
|
||||||
const tradeHistory = mangoStore((s) => s.mangoAccount.tradeHistory)
|
const tradeHistory = mangoStore((s) => s.mangoAccount.tradeHistory.data)
|
||||||
|
const loadingTradeHistory = mangoStore(
|
||||||
|
(s) => s.mangoAccount.tradeHistory.loading
|
||||||
|
)
|
||||||
|
const [offset, setOffset] = useState(0)
|
||||||
const { width } = useViewport()
|
const { width } = useViewport()
|
||||||
const showTableView = width ? width > breakpoints.md : false
|
const showTableView = width ? width > breakpoints.md : false
|
||||||
|
|
||||||
|
@ -151,27 +161,35 @@ const TradeHistory = () => {
|
||||||
return [...newFills, ...tradeHistory]
|
return [...newFills, ...tradeHistory]
|
||||||
}, [eventQueueFillsForAccount, tradeHistory])
|
}, [eventQueueFillsForAccount, tradeHistory])
|
||||||
|
|
||||||
console.log('trade history', tradeHistory)
|
const handleShowMore = useCallback(() => {
|
||||||
|
const set = mangoStore.getState().set
|
||||||
|
set((s) => {
|
||||||
|
s.mangoAccount.tradeHistory.loading = true
|
||||||
|
})
|
||||||
|
setOffset(offset + PAGINATION_PAGE_LENGTH)
|
||||||
|
actions.fetchTradeHistory(offset + PAGINATION_PAGE_LENGTH)
|
||||||
|
}, [actions, offset])
|
||||||
|
|
||||||
if (!selectedMarket || !group) return null
|
if (!selectedMarket || !group) return null
|
||||||
|
|
||||||
return mangoAccount && combinedTradeHistory.length ? (
|
return mangoAccount &&
|
||||||
showTableView ? (
|
(combinedTradeHistory.length || loadingTradeHistory) ? (
|
||||||
<div>
|
<>
|
||||||
|
{showTableView ? (
|
||||||
<Table>
|
<Table>
|
||||||
<thead>
|
<thead>
|
||||||
<TrHead>
|
<TrHead>
|
||||||
<Th className="text-left">Market</Th>
|
<Th className="text-left">{t('market')}</Th>
|
||||||
<Th className="text-right">Side</Th>
|
<Th className="text-right">{t('trade:side')}</Th>
|
||||||
<Th className="text-right">Size</Th>
|
<Th className="text-right">{t('trade:size')}</Th>
|
||||||
<Th className="text-right">Price</Th>
|
<Th className="text-right">{t('price')}</Th>
|
||||||
<Th className="text-right">Value</Th>
|
<Th className="text-right">{t('value')}</Th>
|
||||||
<Th className="text-right">Fee</Th>
|
<Th className="text-right">{t('fee')}</Th>
|
||||||
<Th className="text-right">Time</Th>
|
<Th className="text-right">{t('date')}</Th>
|
||||||
</TrHead>
|
</TrHead>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{combinedTradeHistory.map((trade: any) => {
|
{combinedTradeHistory.map((trade: any, index: number) => {
|
||||||
let market
|
let market
|
||||||
if ('market' in trade) {
|
if ('market' in trade) {
|
||||||
market = group.getSerum3MarketByExternalMarket(
|
market = group.getSerum3MarketByExternalMarket(
|
||||||
|
@ -213,7 +231,7 @@ const TradeHistory = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TrBody
|
<TrBody
|
||||||
key={`${trade.signature || trade.marketIndex}${size}`}
|
key={`${trade.signature || trade.marketIndex}${index}`}
|
||||||
className="my-1 p-2"
|
className="my-1 p-2"
|
||||||
>
|
>
|
||||||
<Td className="">
|
<Td className="">
|
||||||
|
@ -227,7 +245,7 @@ const TradeHistory = () => {
|
||||||
{formatDecimal(trade.price)}
|
{formatDecimal(trade.price)}
|
||||||
</Td>
|
</Td>
|
||||||
<Td className="text-right font-mono">
|
<Td className="text-right font-mono">
|
||||||
${formatFixedDecimals(trade.price * size)}
|
${formatFixedDecimals(trade.price * size, true)}
|
||||||
</Td>
|
</Td>
|
||||||
<Td className="text-right">
|
<Td className="text-right">
|
||||||
<span className="font-mono">{formatDecimal(fee)}</span>
|
<span className="font-mono">{formatDecimal(fee)}</span>
|
||||||
|
@ -251,36 +269,64 @@ const TradeHistory = () => {
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
) : (
|
||||||
) : (
|
<div>
|
||||||
<div>
|
{combinedTradeHistory.map((trade: any, index: number) => {
|
||||||
{eventQueueFillsForAccount.map((trade: any) => {
|
const size = trade.size || trade.quantity
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex items-center justify-between border-b border-th-bkg-3 p-4"
|
className="flex items-center justify-between border-b border-th-bkg-3 p-4"
|
||||||
key={`${trade.marketIndex}`}
|
key={`${trade.marketIndex}${index}`}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<TableMarketName market={selectedMarket} />
|
<TableMarketName market={selectedMarket} />
|
||||||
<div className="mt-1 flex items-center space-x-1">
|
<div className="mt-1 flex items-center space-x-1">
|
||||||
<SideBadge side={trade.side} />
|
<SideBadge side={trade.side} />
|
||||||
<p className="text-th-fgd-4">
|
<p className="text-th-fgd-4">
|
||||||
<span className="font-mono text-th-fgd-3">
|
<span className="font-mono text-th-fgd-2">{size}</span>
|
||||||
{trade.size}
|
{' for '}
|
||||||
</span>
|
<span className="font-mono text-th-fgd-2">
|
||||||
{' for '}
|
{formatDecimal(trade.price)}
|
||||||
<span className="font-mono text-th-fgd-3">
|
</span>
|
||||||
{formatDecimal(trade.price)}
|
</p>
|
||||||
</span>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-end">
|
||||||
|
<span className="mb-0.5 flex items-center space-x-1.5">
|
||||||
|
{trade.block_datetime ? (
|
||||||
|
<TableDateDisplay
|
||||||
|
date={trade.block_datetime}
|
||||||
|
showSeconds
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
'Recent'
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<p className="font-mono text-th-fgd-2">
|
||||||
|
{formatFixedDecimals(trade.price * size, true, true)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="font-mono">${trade.value.toFixed(2)}</p>
|
)
|
||||||
</div>
|
})}
|
||||||
)
|
</div>
|
||||||
})}
|
)}
|
||||||
</div>
|
{loadingTradeHistory ? (
|
||||||
)
|
<div className="mt-4 space-y-1.5">
|
||||||
|
{[...Array(4)].map((x, i) => (
|
||||||
|
<SheenLoader className="mx-4 flex flex-1 md:mx-6" key={i}>
|
||||||
|
<div className="h-16 w-full bg-th-bkg-2" />
|
||||||
|
</SheenLoader>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{combinedTradeHistory.length &&
|
||||||
|
combinedTradeHistory.length % PAGINATION_PAGE_LENGTH === 0 ? (
|
||||||
|
<div className="flex justify-center py-6">
|
||||||
|
<LinkButton onClick={handleShowMore}>Show More</LinkButton>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center p-8">
|
<div className="flex flex-col items-center p-8">
|
||||||
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
|
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
|
||||||
|
|
|
@ -29,24 +29,28 @@ export const ConnectWalletButton: React.FC = () => {
|
||||||
>
|
>
|
||||||
<div className="relative flex h-16 w-44 bg-th-bkg-2 py-2 before:absolute before:inset-0 before:bg-gradient-to-r before:from-transparent before:via-th-bkg-4 before:to-transparent before:opacity-0 hover:overflow-hidden hover:before:-translate-x-full hover:before:animate-[shimmer_0.75s_normal] hover:before:opacity-100">
|
<div className="relative flex h-16 w-44 bg-th-bkg-2 py-2 before:absolute before:inset-0 before:bg-gradient-to-r before:from-transparent before:via-th-bkg-4 before:to-transparent before:opacity-0 hover:overflow-hidden hover:before:-translate-x-full hover:before:animate-[shimmer_0.75s_normal] hover:before:opacity-100">
|
||||||
<div className="default-transition relative z-10 flex h-full items-center justify-center space-x-3 px-4">
|
<div className="default-transition relative z-10 flex h-full items-center justify-center space-x-3 px-4">
|
||||||
<div
|
{connecting ? (
|
||||||
className={`flex h-[28px] w-[28px] items-center justify-center rounded-full ${
|
<Loading className="h-[28px] w-[28px]" />
|
||||||
wallet?.adapter.name === 'Solflare' ? 'bg-black' : ''
|
) : (
|
||||||
}`}
|
<div
|
||||||
>
|
className={`flex h-[28px] w-[28px] items-center justify-center rounded-full ${
|
||||||
<img
|
wallet?.adapter.name === 'Solflare' ? 'bg-black' : ''
|
||||||
src={wallet?.adapter.icon || selectedWallet?.adapter.icon}
|
}`}
|
||||||
className={
|
>
|
||||||
wallet?.adapter.name === 'Solflare'
|
<img
|
||||||
? 'h-auto w-[20px]'
|
src={wallet?.adapter.icon || selectedWallet?.adapter.icon}
|
||||||
: 'h-auto w-[28px]'
|
className={
|
||||||
}
|
wallet?.adapter.name === 'Solflare'
|
||||||
alt={`${wallet?.adapter.name} icon`}
|
? 'h-auto w-[20px]'
|
||||||
/>
|
: 'h-auto w-[28px]'
|
||||||
</div>
|
}
|
||||||
|
alt={`${wallet?.adapter.name} icon`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="mb-1.5 flex justify-center font-display text-base leading-none text-th-fgd-1">
|
<div className="mb-1.5 flex font-display text-base leading-none text-th-fgd-1">
|
||||||
{connecting ? <Loading className="h-4 w-4" /> : t('connect')}
|
{t('connect')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-xxs font-normal leading-3 text-th-fgd-3">
|
<div className="text-xxs font-normal leading-3 text-th-fgd-3">
|
||||||
|
|
|
@ -46,8 +46,12 @@ const ConnectedMenu = () => {
|
||||||
state.mangoAccount.current = undefined
|
state.mangoAccount.current = undefined
|
||||||
state.mangoAccounts = []
|
state.mangoAccounts = []
|
||||||
state.mangoAccount.openOrders = {}
|
state.mangoAccount.openOrders = {}
|
||||||
state.mangoAccount.stats.interestTotals = { data: [], loading: false }
|
state.mangoAccount.interestTotals = { data: [], loading: false }
|
||||||
state.mangoAccount.stats.performance = { data: [], loading: false }
|
state.mangoAccount.performance = {
|
||||||
|
data: [],
|
||||||
|
loading: false,
|
||||||
|
initialLoad: false,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
disconnect()
|
disconnect()
|
||||||
wallet?.adapter.disconnect()
|
wallet?.adapter.disconnect()
|
||||||
|
|
|
@ -6,6 +6,7 @@ export async function getStaticProps({ locale }: { locale: string }) {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
...(await serverSideTranslations(locale, [
|
...(await serverSideTranslations(locale, [
|
||||||
|
'account',
|
||||||
'activity',
|
'activity',
|
||||||
'common',
|
'common',
|
||||||
'onboarding',
|
'onboarding',
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"no-pnl-history": "No PnL History",
|
||||||
|
"pnl-chart": "PnL Chart",
|
||||||
|
"pnl-history": "PnL History",
|
||||||
|
"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-leverage": "Total assets value divided by account equity value",
|
||||||
|
"tooltip-pnl": "The amount your account has profited or lost",
|
||||||
|
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||||
|
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||||
|
"week-starting": "Week starting {{week}}"
|
||||||
|
}
|
|
@ -121,6 +121,7 @@
|
||||||
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
||||||
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
||||||
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
||||||
|
"total": "Total",
|
||||||
"total-borrows": "Total Borrows",
|
"total-borrows": "Total Borrows",
|
||||||
"total-borrow-value": "Total Borrow Value",
|
"total-borrow-value": "Total Borrow Value",
|
||||||
"total-collateral": "Total Collateral",
|
"total-collateral": "Total Collateral",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"no-pnl-history": "No PnL History",
|
||||||
|
"pnl-chart": "PnL Chart",
|
||||||
|
"pnl-history": "PnL History",
|
||||||
|
"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-leverage": "Total assets value divided by account equity value",
|
||||||
|
"tooltip-pnl": "The amount your account has profited or lost",
|
||||||
|
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||||
|
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||||
|
"week-starting": "Week starting {{week}}"
|
||||||
|
}
|
|
@ -121,6 +121,7 @@
|
||||||
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
||||||
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
||||||
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
||||||
|
"total": "Total",
|
||||||
"total-borrows": "Total Borrows",
|
"total-borrows": "Total Borrows",
|
||||||
"total-borrow-value": "Total Borrow Value",
|
"total-borrow-value": "Total Borrow Value",
|
||||||
"total-collateral": "Total Collateral",
|
"total-collateral": "Total Collateral",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"no-pnl-history": "No PnL History",
|
||||||
|
"pnl-chart": "PnL Chart",
|
||||||
|
"pnl-history": "PnL History",
|
||||||
|
"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-leverage": "Total assets value divided by account equity value",
|
||||||
|
"tooltip-pnl": "The amount your account has profited or lost",
|
||||||
|
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||||
|
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||||
|
"week-starting": "Week starting {{week}}"
|
||||||
|
}
|
|
@ -121,6 +121,7 @@
|
||||||
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
||||||
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
||||||
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
||||||
|
"total": "Total",
|
||||||
"total-borrows": "Total Borrows",
|
"total-borrows": "Total Borrows",
|
||||||
"total-borrow-value": "Total Borrow Value",
|
"total-borrow-value": "Total Borrow Value",
|
||||||
"total-collateral": "Total Collateral",
|
"total-collateral": "Total Collateral",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"no-pnl-history": "No PnL History",
|
||||||
|
"pnl-chart": "PnL Chart",
|
||||||
|
"pnl-history": "PnL History",
|
||||||
|
"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-leverage": "Total assets value divided by account equity value",
|
||||||
|
"tooltip-pnl": "The amount your account has profited or lost",
|
||||||
|
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||||
|
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||||
|
"week-starting": "Week starting {{week}}"
|
||||||
|
}
|
|
@ -121,6 +121,7 @@
|
||||||
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
||||||
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
||||||
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
||||||
|
"total": "Total",
|
||||||
"total-borrows": "Total Borrows",
|
"total-borrows": "Total Borrows",
|
||||||
"total-borrow-value": "Total Borrow Value",
|
"total-borrow-value": "Total Borrow Value",
|
||||||
"total-collateral": "Total Collateral",
|
"total-collateral": "Total Collateral",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"no-pnl-history": "No PnL History",
|
||||||
|
"pnl-chart": "PnL Chart",
|
||||||
|
"pnl-history": "PnL History",
|
||||||
|
"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-leverage": "Total assets value divided by account equity value",
|
||||||
|
"tooltip-pnl": "The amount your account has profited or lost",
|
||||||
|
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||||
|
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||||
|
"week-starting": "Week starting {{week}}"
|
||||||
|
}
|
|
@ -121,6 +121,7 @@
|
||||||
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
"token-collateral-multiplier": "{{token}} Collateral Multiplier",
|
||||||
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
"tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance",
|
||||||
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
"tooltip-collateral-value": "The USD amount you can trade or borrow against",
|
||||||
|
"total": "Total",
|
||||||
"total-borrows": "Total Borrows",
|
"total-borrows": "Total Borrows",
|
||||||
"total-borrow-value": "Total Borrow Value",
|
"total-borrow-value": "Total Borrow Value",
|
||||||
"total-collateral": "Total Collateral",
|
"total-collateral": "Total Collateral",
|
||||||
|
|
|
@ -34,6 +34,7 @@ import {
|
||||||
INPUT_TOKEN_DEFAULT,
|
INPUT_TOKEN_DEFAULT,
|
||||||
LAST_ACCOUNT_KEY,
|
LAST_ACCOUNT_KEY,
|
||||||
OUTPUT_TOKEN_DEFAULT,
|
OUTPUT_TOKEN_DEFAULT,
|
||||||
|
PAGINATION_PAGE_LENGTH,
|
||||||
RPC_PROVIDER_KEY,
|
RPC_PROVIDER_KEY,
|
||||||
} from '../utils/constants'
|
} from '../utils/constants'
|
||||||
import { OrderbookL2, SpotBalances, SpotTradeHistory } from 'types'
|
import { OrderbookL2, SpotBalances, SpotTradeHistory } from 'types'
|
||||||
|
@ -240,15 +241,17 @@ export type MangoStore = {
|
||||||
openOrders: Record<string, Order[] | PerpOrder[]>
|
openOrders: Record<string, Order[] | PerpOrder[]>
|
||||||
perpPositions: PerpPosition[]
|
perpPositions: PerpPosition[]
|
||||||
spotBalances: SpotBalances
|
spotBalances: SpotBalances
|
||||||
stats: {
|
interestTotals: { data: TotalInterestDataItem[]; loading: boolean }
|
||||||
interestTotals: { data: TotalInterestDataItem[]; loading: boolean }
|
performance: {
|
||||||
performance: { data: PerformanceDataItem[]; loading: boolean }
|
data: PerformanceDataItem[]
|
||||||
swapHistory: {
|
loading: boolean
|
||||||
data: SwapHistoryItem[]
|
initialLoad: boolean
|
||||||
initialLoad: boolean
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tradeHistory: SpotTradeHistory[]
|
swapHistory: {
|
||||||
|
data: SwapHistoryItem[]
|
||||||
|
initialLoad: boolean
|
||||||
|
}
|
||||||
|
tradeHistory: { data: SpotTradeHistory[]; loading: boolean }
|
||||||
}
|
}
|
||||||
mangoAccounts: MangoAccount[]
|
mangoAccounts: MangoAccount[]
|
||||||
markets: Serum3Market[] | undefined
|
markets: Serum3Market[] | undefined
|
||||||
|
@ -332,7 +335,7 @@ export type MangoStore = {
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
fetchTokenStats: () => void
|
fetchTokenStats: () => void
|
||||||
fetchTourSettings: (walletPk: string) => void
|
fetchTourSettings: (walletPk: string) => void
|
||||||
fetchTradeHistory: () => Promise<void>
|
fetchTradeHistory: (offset?: number) => Promise<void>
|
||||||
fetchWalletTokens: (walletPk: PublicKey) => Promise<void>
|
fetchWalletTokens: (walletPk: PublicKey) => Promise<void>
|
||||||
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
|
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
|
||||||
loadMarketFills: () => Promise<void>
|
loadMarketFills: () => Promise<void>
|
||||||
|
@ -385,7 +388,7 @@ const mangoStore = create<MangoStore>()(
|
||||||
performance: { data: [], loading: false },
|
performance: { data: [], loading: false },
|
||||||
swapHistory: { data: [], initialLoad: false },
|
swapHistory: { data: [], initialLoad: false },
|
||||||
},
|
},
|
||||||
tradeHistory: [],
|
tradeHistory: { data: [], loading: true },
|
||||||
},
|
},
|
||||||
mangoAccounts: [],
|
mangoAccounts: [],
|
||||||
markets: undefined,
|
markets: undefined,
|
||||||
|
@ -457,7 +460,7 @@ const mangoStore = create<MangoStore>()(
|
||||||
fetchAccountInterestTotals: async (mangoAccountPk: string) => {
|
fetchAccountInterestTotals: async (mangoAccountPk: string) => {
|
||||||
const set = get().set
|
const set = get().set
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.interestTotals.loading = true
|
state.mangoAccount.interestTotals.loading = true
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
@ -475,12 +478,12 @@ const mangoStore = create<MangoStore>()(
|
||||||
.filter((x: string) => x)
|
.filter((x: string) => x)
|
||||||
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.interestTotals.data = stats
|
state.mangoAccount.interestTotals.data = stats
|
||||||
state.mangoAccount.stats.interestTotals.loading = false
|
state.mangoAccount.interestTotals.loading = false
|
||||||
})
|
})
|
||||||
} catch {
|
} catch {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.interestTotals.loading = false
|
state.mangoAccount.interestTotals.loading = false
|
||||||
})
|
})
|
||||||
console.error({
|
console.error({
|
||||||
title: 'Failed to load account interest totals',
|
title: 'Failed to load account interest totals',
|
||||||
|
@ -494,7 +497,7 @@ const mangoStore = create<MangoStore>()(
|
||||||
) => {
|
) => {
|
||||||
const set = get().set
|
const set = get().set
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.performance.loading = true
|
state.mangoAccount.performance.loading = true
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
@ -514,18 +517,19 @@ const mangoStore = create<MangoStore>()(
|
||||||
.filter((x: string) => x)
|
.filter((x: string) => x)
|
||||||
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.performance.data = stats.reverse()
|
state.mangoAccount.performance.data = stats.reverse()
|
||||||
state.mangoAccount.stats.performance.loading = false
|
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
set((state) => {
|
|
||||||
state.mangoAccount.stats.performance.loading = false
|
|
||||||
})
|
|
||||||
console.error('Failed to load account performance data', e)
|
console.error('Failed to load account performance data', e)
|
||||||
// notify({
|
} finally {
|
||||||
// title: 'Failed to load account performance data',
|
const hasLoaded =
|
||||||
// type: 'error',
|
mangoStore.getState().mangoAccount.performance.initialLoad
|
||||||
// })
|
set((state) => {
|
||||||
|
state.mangoAccount.performance.loading = false
|
||||||
|
if (!hasLoaded) {
|
||||||
|
state.mangoAccount.performance.initialLoad = true
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fetchActivityFeed: async (
|
fetchActivityFeed: async (
|
||||||
|
@ -541,7 +545,7 @@ const mangoStore = create<MangoStore>()(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://mango-transaction-log.herokuapp.com/v4/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=25${
|
`https://mango-transaction-log.herokuapp.com/v4/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=${PAGINATION_PAGE_LENGTH}${
|
||||||
params ? params : ''
|
params ? params : ''
|
||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
|
@ -853,12 +857,12 @@ const mangoStore = create<MangoStore>()(
|
||||||
: []
|
: []
|
||||||
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.swapHistory.data = sortedHistory
|
state.mangoAccount.swapHistory.data = sortedHistory
|
||||||
state.mangoAccount.stats.swapHistory.initialLoad = true
|
state.mangoAccount.swapHistory.initialLoad = true
|
||||||
})
|
})
|
||||||
} catch {
|
} catch {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.mangoAccount.stats.swapHistory.initialLoad = true
|
state.mangoAccount.swapHistory.initialLoad = true
|
||||||
})
|
})
|
||||||
notify({
|
notify({
|
||||||
title: 'Failed to load account swap history data',
|
title: 'Failed to load account swap history data',
|
||||||
|
@ -1015,36 +1019,33 @@ const mangoStore = create<MangoStore>()(
|
||||||
console.log('Error fetching fills:', err)
|
console.log('Error fetching fills:', err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetchTradeHistory() {
|
async fetchTradeHistory(offset = 0) {
|
||||||
const set = get().set
|
const set = get().set
|
||||||
const mangoAccount = get().mangoAccount.current
|
const mangoAccountPk =
|
||||||
|
get().mangoAccount?.current?.publicKey.toString()
|
||||||
|
const loadedHistory =
|
||||||
|
mangoStore.getState().mangoAccount.tradeHistory.data
|
||||||
try {
|
try {
|
||||||
const [spotRes, perpRes] = await Promise.all([
|
const response = await fetch(
|
||||||
fetch(
|
`https://mango-transaction-log.herokuapp.com/v4/stats/trade-history?mango-account=${mangoAccountPk}&limit=${PAGINATION_PAGE_LENGTH}&offset=${offset}`
|
||||||
`https://mango-transaction-log.herokuapp.com/v4/stats/openbook-trades?address=${mangoAccount?.publicKey.toString()}&address-type=mango-account`
|
)
|
||||||
),
|
const parsedHistory = await response.json()
|
||||||
fetch(
|
const newHistory = parsedHistory.map((h: any) => h.activity_details)
|
||||||
`https://mango-transaction-log.herokuapp.com/v4/stats/perp-trade-history?mango-account=${mangoAccount?.publicKey.toString()}&limit=1000`
|
|
||||||
),
|
const history =
|
||||||
])
|
offset !== 0 ? loadedHistory.concat(newHistory) : newHistory
|
||||||
const spotHistory = await spotRes.json()
|
|
||||||
const perpHistory = await perpRes.json()
|
|
||||||
console.log('th', spotHistory, perpHistory)
|
|
||||||
let tradeHistory: any[] = []
|
|
||||||
if (spotHistory?.length) {
|
|
||||||
tradeHistory = tradeHistory.concat(spotHistory)
|
|
||||||
}
|
|
||||||
if (perpHistory?.length) {
|
|
||||||
tradeHistory = tradeHistory.concat(perpHistory)
|
|
||||||
}
|
|
||||||
|
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.mangoAccount.tradeHistory = tradeHistory.sort(
|
s.mangoAccount.tradeHistory.data = history?.sort(
|
||||||
(x: any) => x.block_datetime
|
(x: any) => x.block_datetime
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Unable to fetch trade history', e)
|
console.error('Unable to fetch trade history', e)
|
||||||
|
} finally {
|
||||||
|
set((s) => {
|
||||||
|
s.mangoAccount.tradeHistory.loading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateConnection(endpointUrl) {
|
updateConnection(endpointUrl) {
|
||||||
|
|
|
@ -67,3 +67,5 @@ export const MIN_SOL_BALANCE = 0.001
|
||||||
export const ACCOUNT_ACTION_MODAL_HEIGHT = '506px'
|
export const ACCOUNT_ACTION_MODAL_HEIGHT = '506px'
|
||||||
|
|
||||||
export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '444px'
|
export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '444px'
|
||||||
|
|
||||||
|
export const PAGINATION_PAGE_LENGTH = 25
|
||||||
|
|
Loading…
Reference in New Issue