Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

[Batch Viewer] Avoid multiple requests to Tenderly API #128

Merged
merged 5 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from 'apps/explorer/components/SummaryCardsWidget/VolumeChart/VolumeChartWidget'
import { numberFormatter } from 'apps/explorer/components/SummaryCardsWidget/utils'
import { useNetworkId } from 'state/network'
import { usePrevious } from 'hooks/usePrevious'

const DEFAULT_CHART_HEIGHT = 214 // px

Expand Down Expand Up @@ -64,20 +65,6 @@ function _formatAmount(amount: string): string {
return formatSmart({ amount, precision: 0, decimals: 0 })
}

/* Store an ID to check if there is new data that
* requires the graph to be rendered.
* example: <lastRecordId>-<volumePeriodSelected>
* */
function usePreviousLastValueData<T>(value: T): T | undefined {
const ref = useRef<T>()

useEffect(() => {
ref.current = value
}, [value])

return ref.current
}

function _buildChart(
chartContainer: HTMLDivElement,
width: number | undefined,
Expand Down Expand Up @@ -209,8 +196,8 @@ export function VolumeChart({
const captionNameColor = getColorBySign(diffPercentageVolume || 0)
const [crossHairData, setCrossHairData] = useState<CrossHairData | null>(null)
const network = useNetworkId()
const previousPeriod = usePreviousLastValueData(period)
const previousNetwork = usePreviousLastValueData(network)
const previousPeriod = usePrevious(period)
const previousNetwork = usePrevious(network)
const periodTitle = period && volumePeriodTitle.get(period)

// reset the chart when the volume/network period is changed
Expand Down
11 changes: 11 additions & 0 deletions src/hooks/usePrevious.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useEffect, useRef } from 'react'

export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>()

useEffect(() => {
ref.current = value
}, [value])

return ref.current
}
71 changes: 34 additions & 37 deletions src/hooks/useTxBatchTrades.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getTradesAccount, getTradesAndTransfers, Trade, Transfer, Account } fro
import { useMultipleErc20 } from './useErc20'
import { SingleErc20State } from 'state/erc20'
import { Order } from 'api/operator'
import { usePrevious } from './usePrevious'

interface TxBatchTrades {
trades: Trade[]
Expand Down Expand Up @@ -37,53 +38,49 @@ export function useTxBatchTrades(
const [error, setError] = useState('')
const [txBatchTrades, setTxBatchTrades] = useState<TxBatchTrades>({ trades: [], transfers: [] })
const [accounts, setAccounts] = useState<Accounts>()
const txOrders = usePrevious(JSON.stringify(orders?.map((o) => ({ owner: o.owner, kind: o.kind })))) // We need to do a deep comparison here to avoid useEffect to be called twice (Orders array is populated partially from different places)
const [erc20Addresses, setErc20Addresses] = useState<string[]>([])
const { value: valueErc20s, isLoading: areErc20Loading } = useMultipleErc20({ networkId, addresses: erc20Addresses })
const ordersFoundInTx = orders?.length

const _fetchTxTrades = useCallback(
async (network: Network, _txHash: string): Promise<void> => {
setIsLoading(true)
setError('')
const _fetchTxTrades = useCallback(async (network: Network, _txHash: string, orders: Order[]): Promise<void> => {
setIsLoading(true)
setError('')

try {
const { transfers, trades } = await getTradesAndTransfers(network, _txHash)
const _accounts = Object.fromEntries(await getTradesAccount(network, _txHash, trades, transfers))
const orderIds = orders?.map((order) => order.owner) || []
const transfersWithKind: Transfer[] = transfers.reduce(
(acc, transfer) =>
!orderIds.includes(transfer.from) && !orderIds.includes(transfer.to) ? [...acc, transfer] : acc,
[],
)

orders?.forEach((order) => {
const { owner, kind } = order
transfersWithKind.push(
...transfers.filter((t) => [t.from, t.to].includes(owner)).map((transfer) => ({ ...transfer, kind })),
)
})
try {
const { transfers, trades } = await getTradesAndTransfers(network, _txHash)
const _accounts = Object.fromEntries(await getTradesAccount(network, _txHash, trades, transfers))
const orderIds = orders.map((order) => order.owner) || []
const transfersWithKind: Transfer[] = transfers.reduce(
(acc, transfer) =>
!orderIds.includes(transfer.from) && !orderIds.includes(transfer.to) ? [...acc, transfer] : acc,
[],
)

setErc20Addresses(transfers.map((transfer: Transfer): string => transfer.token))
setTxBatchTrades({ trades, transfers: transfersWithKind })
setAccounts(_accounts)
} catch (e) {
const msg = `Failed to fetch tx batch trades`
console.error(msg, e)
setError(msg)
} finally {
setIsLoading(false)
}
},
[orders],
)
orders.forEach((order) => {
const { owner, kind } = order
transfersWithKind.push(
...transfers.filter((t) => [t.from, t.to].includes(owner)).map((transfer) => ({ ...transfer, kind })),
)
})
setErc20Addresses(transfers.map((transfer: Transfer): string => transfer.token))
setTxBatchTrades({ trades, transfers })
setAccounts(_accounts)
} catch (e) {
const msg = `Failed to fetch tx batch trades`
console.error(msg, e)
setError(msg)
} finally {
setIsLoading(false)
}
}, [])

useEffect(() => {
if (!networkId || !ordersFoundInTx) {
if (!networkId || !txOrders) {
return
}

_fetchTxTrades(networkId, txHash)
}, [_fetchTxTrades, networkId, ordersFoundInTx, txHash])
_fetchTxTrades(networkId, txHash, JSON.parse(txOrders))
}, [_fetchTxTrades, networkId, txHash, txOrders])

return {
txSettlement: { ...txBatchTrades, tokens: valueErc20s, accounts },
Expand Down