import { useEffect, useState } from 'react' import SwapHistoryTable from '../swap/SwapHistoryTable' import TradeHistory from '@components/trade/TradeHistory' import mangoStore from '@store/mangoStore' import useMangoAccount from 'hooks/useMangoAccount' import ActivityFeedTable, { getCreditAndDebit, getFee, getValue, } from './ActivityFeedTable' import { handleExport } from 'utils/export' import { LinkButton } from '@components/shared/Button' import Loading from '@components/shared/Loading' import { ArrowDownTrayIcon } from '@heroicons/react/20/solid' import { countLeadingZeros, floorToDecimal, formatCurrencyValue, formatNumericValue, } from 'utils/numbers' import { formatTokenSymbol } from 'utils/tokens' import { fetchTradeHistory, parseApiTradeHistory } from 'hooks/useTradeHistory' import { PublicKey } from '@solana/web3.js' import { PerpMarket } from '@blockworks-foundation/mango-v4' import useUnownedAccount from 'hooks/useUnownedAccount' import SecondaryTabBar from '@components/shared/SecondaryTabBar' import ActivityFilters from './ActivityFilters' import { useTranslation } from 'react-i18next' const TABS = ['activity:activity-feed', 'activity:swaps', 'activity:trades'] const HistoryTabs = () => { const { t } = useTranslation(['common', 'account', 'activity', 'trade']) const [activeTab, setActiveTab] = useState('activity:activity-feed') const actions = mangoStore((s) => s.actions) const { mangoAccountAddress } = useMangoAccount() const { isUnownedAccount } = useUnownedAccount() const [loadExportData, setLoadExportData] = useState(false) useEffect(() => { if (actions && mangoAccountAddress) { actions.fetchActivityFeed(mangoAccountAddress) } }, [actions, mangoAccountAddress]) const exportActivityDataToCSV = async () => { setLoadExportData(true) await actions.fetchActivityFeed(mangoAccountAddress, 0, '', 10000) const activityFeed = mangoStore.getState().activityFeed.feed const dataToExport = activityFeed.map((row) => { const { activity_type, block_datetime } = row const { signature } = row.activity_details const amounts = getCreditAndDebit(row, mangoAccountAddress) const value = getValue(row, mangoAccountAddress) const fee = getFee(row, mangoAccountAddress) const timestamp = new Date(block_datetime) return { date: `${timestamp.toLocaleDateString()} ${timestamp.toLocaleTimeString()}`, activity: t(`activity:${activity_type}`), credit: `${amounts.credit.value} ${amounts.credit.symbol}`, debit: `${amounts.debit.value} ${amounts.debit.symbol}`, fee: `${fee.value} ${fee.symbol}`, value: value.toFixed(3), signature, } }) const title = `${mangoAccountAddress}-Activity-${new Date().toLocaleDateString()}` handleExport(dataToExport, title) setLoadExportData(false) } const exportSwapsDataToCSV = async () => { setLoadExportData(true) await actions.fetchSwapHistory(mangoAccountAddress, 0, 0, 10000) const swapHistory = mangoStore.getState().mangoAccount.swapHistory.data const dataToExport = swapHistory.map((row) => { const { block_datetime, signature, swap_in_amount, swap_in_loan_origination_fee, swap_in_symbol, swap_out_amount, loan, loan_origination_fee, swap_out_price_usd, swap_out_symbol, } = row const borrowAmount = loan > 0 ? `${floorToDecimal(loan, countLeadingZeros(loan) + 2)}` : 0 const borrowFee = swap_in_loan_origination_fee > 0 ? swap_in_loan_origination_fee.toFixed(4) : loan_origination_fee > 0 ? loan_origination_fee.toFixed(4) : 0 const inSymbol = formatTokenSymbol(swap_in_symbol) const outSymbol = formatTokenSymbol(swap_out_symbol) const inDecimals = countLeadingZeros(swap_in_amount) + 2 const outDecimals = countLeadingZeros(swap_out_amount) + 2 const timestamp = new Date(block_datetime) return { date: `${timestamp.toLocaleDateString()} ${timestamp.toLocaleTimeString()}`, paid: `${formatNumericValue(swap_in_amount, inDecimals)} ${inSymbol}`, received: `${formatNumericValue( swap_out_amount, outDecimals )} ${outSymbol}`, value: formatCurrencyValue(swap_out_price_usd * swap_out_amount), borrow: `${borrowAmount} ${inSymbol}`, ['borrow fee']: `${borrowFee} ${inSymbol}`, signature, } }) const title = `${mangoAccountAddress}-Swaps-${new Date().toLocaleDateString()}` handleExport(dataToExport, title) setLoadExportData(false) } const exportTradesDataToCSV = async () => { setLoadExportData(true) const group = mangoStore.getState().group if (!group) return const tradeHistory = await fetchTradeHistory(mangoAccountAddress, 0, 10000) const dataToExport = tradeHistory.map((row) => { const trade = parseApiTradeHistory(mangoAccountAddress, row) const timestamp = new Date(trade.block_datetime) let market if ('market' in trade) { market = group.getSerum3MarketByExternalMarket( new PublicKey(trade.market) ) } else if ('perp_market' in trade) { market = group.getPerpMarketByMarketIndex(trade.market_index) } const { side, price, size, feeCost, liquidity, signature } = trade return { date: `${timestamp.toLocaleDateString()} ${timestamp.toLocaleTimeString()}`, market: market?.name, side: market instanceof PerpMarket ? side === 'buy' ? t('trade:long') : t('trade:short') : t(side), size: size, price: price, value: (price * size).toFixed(2), fee: formatNumericValue(feeCost), type: liquidity, signature, } }) const title = `${mangoAccountAddress}-Trades-${new Date().toLocaleDateString()}` handleExport(dataToExport, title) setLoadExportData(false) } const handleExportData = (dataType: string) => { if (dataType === 'activity:activity-feed') { exportActivityDataToCSV() } else if (dataType === 'activity:swaps') { exportSwapsDataToCSV() } else { exportTradesDataToCSV() } } return ( <>
{!isUnownedAccount ? ( handleExportData(activeTab)} > {t('account:export', { dataType: t(activeTab) })} {loadExportData ? ( ) : ( )} ) : null} {activeTab === 'activity:activity-feed' ? : null}
) } const TabContent = ({ activeTab }: { activeTab: string }) => { switch (activeTab) { case 'activity:activity-feed': return case 'activity:swaps': return case 'activity:trades': return default: return } } export default HistoryTabs