refactor trade history to use the mango store
reduces rerenders update usePerpPosition with tradeHistory
This commit is contained in:
parent
4548fd0cb9
commit
4c0eb2114e
|
@ -1,6 +1,5 @@
|
|||
import { ArrowSmDownIcon } from '@heroicons/react/solid'
|
||||
import BN from 'bn.js'
|
||||
import useTradeHistory from '../hooks/useTradeHistory'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import SideBadge from './SideBadge'
|
||||
|
@ -15,6 +14,7 @@ import { useTranslation } from 'next-i18next'
|
|||
import Pagination from './Pagination'
|
||||
import usePagination from '../hooks/usePagination'
|
||||
import { useEffect } from 'react'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
|
||||
const renderTradeDateTime = (timestamp: BN | string) => {
|
||||
let date
|
||||
|
@ -37,8 +37,13 @@ const renderTradeDateTime = (timestamp: BN | string) => {
|
|||
const TradeHistoryTable = ({ numTrades }: { numTrades?: number }) => {
|
||||
const { t } = useTranslation('common')
|
||||
const { asPath } = useRouter()
|
||||
const tradeHistory = useTradeHistory({ excludePerpLiquidations: true })
|
||||
const { width } = useViewport()
|
||||
const tradeHistoryAndLiquidations = useMangoStore(
|
||||
(state) => state.tradeHistory.parsed
|
||||
)
|
||||
const tradeHistory = tradeHistoryAndLiquidations.filter(
|
||||
(t) => !('liqor' in t)
|
||||
)
|
||||
const isMobile = width ? width < breakpoints.md : false
|
||||
|
||||
const {
|
||||
|
|
|
@ -15,7 +15,6 @@ import { useSortableData } from '../../hooks/useSortableData'
|
|||
import { formatUsdValue } from '../../utils'
|
||||
import { exportDataToCSV } from '../../utils/export'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import useTradeHistory from '../../hooks/useTradeHistory'
|
||||
import Button from '../Button'
|
||||
import Loading from '../Loading'
|
||||
import { fetchHourlyPerformanceStats } from './AccountOverview'
|
||||
|
@ -35,7 +34,6 @@ export default function AccountHistory() {
|
|||
|
||||
const wallet = useMangoStore((s) => s.wallet.current)
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const tradeHistory = useTradeHistory({ excludePerpLiquidations: true })
|
||||
|
||||
const mangoAccountPk = useMemo(() => {
|
||||
console.log('new mango account')
|
||||
|
@ -86,6 +84,11 @@ export default function AccountHistory() {
|
|||
let headers
|
||||
|
||||
if (view == 'Trades') {
|
||||
// filter liquidations from history
|
||||
const tradeHistory = useMangoStore
|
||||
.getState()
|
||||
.tradeHistory.parsed.filter((t) => !('liqor' in t))
|
||||
|
||||
dataToExport = tradeHistory.map((trade) => {
|
||||
const timestamp = new Date(trade.loadTimestamp)
|
||||
return {
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
PerpMarket,
|
||||
PerpMarketConfig,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import useTradeHistory from './useTradeHistory'
|
||||
import {
|
||||
mangoCacheSelector,
|
||||
mangoGroupConfigSelector,
|
||||
|
@ -92,7 +91,7 @@ const usePerpPositions = () => {
|
|||
const mangoGroup = useMangoStore(mangoGroupSelector)
|
||||
const mangoCache = useMangoStore(mangoCacheSelector)
|
||||
const allMarkets = useMangoStore(marketsSelector)
|
||||
const tradeHistory = useTradeHistory()
|
||||
const tradeHistory = useMangoStore.getState().tradeHistory.parsed
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { getMarketByPublicKey } from '@blockworks-foundation/mango-client'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { useEffect } from 'react'
|
||||
import {
|
||||
fillsSelector,
|
||||
mangoAccountSelector,
|
||||
mangoGroupSelector,
|
||||
marketConfigSelector,
|
||||
tradeHistorySelector,
|
||||
} from '../stores/selectors'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { roundPerpSize } from '../utils'
|
||||
|
@ -92,63 +92,68 @@ const formatTradeHistory = (mangoAccountPk: PublicKey, newTradeHistory) => {
|
|||
.sort(byTimestamp)
|
||||
}
|
||||
|
||||
export const useTradeHistory = (
|
||||
opts: { excludePerpLiquidations?: boolean } = {}
|
||||
) => {
|
||||
export const useTradeHistory = () => {
|
||||
const marketConfig = useMangoStore(marketConfigSelector)
|
||||
const fills = useMangoStore(fillsSelector)
|
||||
const mangoAccount = useMangoStore(mangoAccountSelector)
|
||||
const selectedMangoGroup = useMangoStore(mangoGroupSelector)
|
||||
const tradeHistory = useMangoStore(tradeHistorySelector)
|
||||
const spotTradeHistory = useMangoStore((s) => s.tradeHistory.spot)
|
||||
const perpTradeHistory = useMangoStore((s) => s.tradeHistory.perp)
|
||||
const setMangoStore = useMangoStore.getState().set
|
||||
|
||||
if (!mangoAccount || !selectedMangoGroup) return null
|
||||
useEffect(() => {
|
||||
if (!mangoAccount || !selectedMangoGroup) return null
|
||||
const previousTradeHistory = useMangoStore.getState().tradeHistory.parsed
|
||||
|
||||
let combinedTradeHistory = [...tradeHistory.spot, ...tradeHistory.perp]
|
||||
// combine the trade histories loaded from the DB
|
||||
let tradeHistory = spotTradeHistory.concat(perpTradeHistory)
|
||||
|
||||
const openOrdersAccount =
|
||||
mangoAccount.spotOpenOrdersAccounts[marketConfig.marketIndex]
|
||||
const openOrdersAccount =
|
||||
mangoAccount.spotOpenOrdersAccounts[marketConfig.marketIndex]
|
||||
|
||||
const mangoAccountFills = fills
|
||||
.filter((fill) => {
|
||||
if (fill.openOrders) {
|
||||
return openOrdersAccount?.publicKey
|
||||
? fill.openOrders.equals(openOrdersAccount?.publicKey)
|
||||
: false
|
||||
} else {
|
||||
return (
|
||||
fill.taker.equals(mangoAccount.publicKey) ||
|
||||
fill.maker.equals(mangoAccount.publicKey)
|
||||
)
|
||||
}
|
||||
})
|
||||
.map((fill) => ({ ...fill, marketName: marketConfig.name }))
|
||||
// Look through the loaded fills from the event queue to see if
|
||||
// there are any that match the user's open orders account
|
||||
const tradeHistoryFromEventQueue = fills
|
||||
.filter((fill) => {
|
||||
if (fill.openOrders) {
|
||||
return openOrdersAccount?.publicKey
|
||||
? fill.openOrders.equals(openOrdersAccount?.publicKey)
|
||||
: false
|
||||
} else {
|
||||
return (
|
||||
fill.taker.equals(mangoAccount.publicKey) ||
|
||||
fill.maker.equals(mangoAccount.publicKey)
|
||||
)
|
||||
}
|
||||
})
|
||||
.map((fill) => ({ ...fill, marketName: marketConfig.name }))
|
||||
|
||||
const allTrades = []
|
||||
if (mangoAccountFills && mangoAccountFills.length > 0) {
|
||||
const newFills = mangoAccountFills.filter(
|
||||
(fill) =>
|
||||
!combinedTradeHistory.flat().find((t) => {
|
||||
if (t.orderId) {
|
||||
return t.orderId === fill.orderId?.toString()
|
||||
} else {
|
||||
return t.seqNum === fill.seqNum?.toString()
|
||||
}
|
||||
})
|
||||
)
|
||||
const newTradeHistory = [...newFills, ...combinedTradeHistory]
|
||||
if (newFills.length > 0 && newTradeHistory.length !== allTrades.length) {
|
||||
combinedTradeHistory = newTradeHistory
|
||||
// filters the trades from tradeHistoryFromEventQueue to find the ones we don't already have in the DB
|
||||
if (tradeHistoryFromEventQueue?.length) {
|
||||
const newFills = tradeHistoryFromEventQueue.filter(
|
||||
(fill) =>
|
||||
!tradeHistory.find((t) => {
|
||||
if (t.orderId) {
|
||||
return t.orderId === fill.orderId?.toString()
|
||||
} else {
|
||||
return t.seqNum === fill.seqNum?.toString()
|
||||
}
|
||||
})
|
||||
)
|
||||
tradeHistory = [...newFills, ...tradeHistory]
|
||||
}
|
||||
}
|
||||
|
||||
const formattedTradeHistory = formatTradeHistory(
|
||||
mangoAccount.publicKey,
|
||||
combinedTradeHistory
|
||||
)
|
||||
if (opts.excludePerpLiquidations) {
|
||||
return formattedTradeHistory.filter((t) => !('liqor' in t))
|
||||
}
|
||||
return formattedTradeHistory
|
||||
if (previousTradeHistory.length !== tradeHistory.length) {
|
||||
const formattedTradeHistory = formatTradeHistory(
|
||||
mangoAccount.publicKey,
|
||||
tradeHistory
|
||||
)
|
||||
|
||||
setMangoStore((state) => {
|
||||
state.tradeHistory.parsed = formattedTradeHistory
|
||||
})
|
||||
}
|
||||
}, [spotTradeHistory, perpTradeHistory, fills, mangoAccount])
|
||||
}
|
||||
|
||||
export default useTradeHistory
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
ReferrerIdRecordLayout,
|
||||
ReferrerIdRecord,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import useTradeHistory from '../hooks/useTradeHistory'
|
||||
|
||||
const MangoStoreUpdater = () => {
|
||||
useHydrateStore()
|
||||
|
@ -46,6 +47,11 @@ const PerpPositionsStoreUpdater = () => {
|
|||
return null
|
||||
}
|
||||
|
||||
const TradeHistoryStoreUpdater = () => {
|
||||
useTradeHistory()
|
||||
return null
|
||||
}
|
||||
|
||||
const FetchReferrer = () => {
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const mangoGroup = useMangoStore(mangoGroupSelector)
|
||||
|
@ -156,6 +162,7 @@ function App({ Component, pageProps }) {
|
|||
<WalletStoreUpdater />
|
||||
<OpenOrdersStoreUpdater />
|
||||
<PerpPositionsStoreUpdater />
|
||||
<TradeHistoryStoreUpdater />
|
||||
<FetchReferrer />
|
||||
</ErrorBoundary>
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ export type MangoStore = {
|
|||
tradeHistory: {
|
||||
spot: any[]
|
||||
perp: any[]
|
||||
parsed: any[]
|
||||
}
|
||||
set: (x: (x: MangoStore) => void) => void
|
||||
actions: {
|
||||
|
@ -330,6 +331,7 @@ const useMangoStore = create<
|
|||
tradeHistory: {
|
||||
spot: [],
|
||||
perp: [],
|
||||
parsed: [],
|
||||
},
|
||||
set: (fn) => set(produce(fn)),
|
||||
actions: {
|
||||
|
|
Loading…
Reference in New Issue