diff --git a/apps/web/src/state/info/api/client.ts b/apps/web/src/state/info/api/client.ts index e3c28b7fe3a8b..3e40f3a7f8d83 100644 --- a/apps/web/src/state/info/api/client.ts +++ b/apps/web/src/state/info/api/client.ts @@ -84,11 +84,8 @@ export function createExplorerQuery< } export const chartPeriodRange = ['1H', '1D', '1W', '1M', '1Y'] as const -export type ChartPeriod = (typeof chartPeriodRange)[number] - -export const chartGroupBy = ['1D', '1W', '1M'] as const -export type ChartGroupBy = (typeof chartGroupBy)[number] +export type ChartPeriod = (typeof chartPeriodRange)[number] export const chainIdToExplorerInfoChainName = { [ChainId.BSC]: 'bsc', diff --git a/apps/web/src/state/info/constant.ts b/apps/web/src/state/info/constant.ts index 9e5c4a3d2b88f..583ea8e7f09ff 100644 --- a/apps/web/src/state/info/constant.ts +++ b/apps/web/src/state/info/constant.ts @@ -44,17 +44,6 @@ export const multiChainQueryMainToken: Record = { OPBNB: 'ETH', } -export const multiChainStartTime = { - BSC: PCS_V2_START, - ETH: PCS_ETH_START, - POLYGON_ZKEVM: 1686236845, - ZKSYNC: 1690462800, // Thu Jul 27 2023 13:00:00 UTC+0000 - ARB: 1686732526, - LINEA: 1692878400, - BASE: 1693483200, - OPBNB: 1695945600, -} - export const multiChainId: Record = { BSC: ChainId.BSC, ETH: ChainId.ETHEREUM, diff --git a/apps/web/src/state/info/hooks.ts b/apps/web/src/state/info/hooks.ts index bdd6f2b216206..3d805dc1787bb 100644 --- a/apps/web/src/state/info/hooks.ts +++ b/apps/web/src/state/info/hooks.ts @@ -11,7 +11,7 @@ import { getAprsForStableFarm } from 'utils/getAprsForStableFarm' import { getDeltaTimestamps } from 'utils/getDeltaTimestamps' import { getLpFeesAndApr } from 'utils/getLpFeesAndApr' import { getPercentChange } from 'utils/infoDataHelpers' -import { useBlockFromTimeStampQuery } from 'views/Info/hooks/useBlocksFromTimestamps' +import { useBlocksFromTimestamps } from 'views/Info/hooks/useBlocksFromTimestamps' import { explorerApiClient } from './api/client' import { useExplorerChainNameByQuery } from './api/hooks' import { MultiChainName, MultiChainNameExtend, checkIsStableSwap, multiChainId } from './constant' @@ -555,7 +555,7 @@ export const useAllTokenHighLight = ({ const chainNameByQuery = useChainNameByQuery() const chainName = targetChainName ?? chainNameByQuery const [t24h, t48h, t7d, t14d] = getDeltaTimestamps() - const { blocks } = useBlockFromTimeStampQuery([t24h, t48h, t7d, t14d], undefined, undefined, chainName) + const { blocks } = useBlocksFromTimestamps([t24h, t48h, t7d, t14d], undefined, chainName) const type = checkIsStableSwap() ? 'stableSwap' : 'swap' const { data, isPending } = useQuery({ queryKey: [`info/token/data/${type}`, chainName], @@ -667,7 +667,7 @@ export const useTokenDatasQuery = (addresses?: string[], withSettings = true): T const name = addresses?.join('') const chainName = useChainNameByQuery() const [t24h, t48h, t7d, t14d] = getDeltaTimestamps() - const { blocks } = useBlockFromTimeStampQuery([t24h, t48h, t7d, t14d]) + const { blocks } = useBlocksFromTimestamps([t24h, t48h, t7d, t14d]) const type = checkIsStableSwap() ? 'stableSwap' : 'swap' const { data, isPending } = useQuery({ queryKey: [`info/token/data/${name}/${type}`, chainName], diff --git a/apps/web/src/state/info/queries/helpers.ts b/apps/web/src/state/info/queries/helpers.ts deleted file mode 100644 index 124b25088ef4a..0000000000000 --- a/apps/web/src/state/info/queries/helpers.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { ONE_DAY_UNIX } from 'config/constants/info' -import fromPairs from 'lodash/fromPairs' - -import dayjs from 'dayjs' -import { TransactionType } from 'state/info/types' -import { MultiChainName, multiChainStartTime } from '../constant' -import { ChartEntry } from '../types' -import { BurnResponse, MintResponse, PairDayData, PancakeDayData, SwapResponse, TokenDayData } from './types' - -export const mapMints = (mint: MintResponse) => { - return { - type: TransactionType.MINT, - hash: mint.id.split('-')[0], - timestamp: mint.timestamp, - sender: mint.to, - token0Symbol: mint.pair?.token0.symbol, - token1Symbol: mint.pair?.token1.symbol, - token0Address: mint.pair?.token0.id, - token1Address: mint.pair?.token1.id, - amountUSD: parseFloat(mint.amountUSD), - amountToken0: parseFloat(mint.amount0), - amountToken1: parseFloat(mint.amount1), - } -} - -export const mapBurns = (burn: BurnResponse) => { - return { - type: TransactionType.BURN, - hash: burn.id.split('-')[0], - timestamp: burn.timestamp, - sender: burn.sender, - token0Symbol: burn.pair?.token0.symbol, - token1Symbol: burn.pair?.token1.symbol, - token0Address: burn.pair?.token0.id, - token1Address: burn.pair?.token1.id, - amountUSD: parseFloat(burn.amountUSD), - amountToken0: parseFloat(burn.amount0), - amountToken1: parseFloat(burn.amount1), - } -} - -export const mapSwaps = (swap: SwapResponse) => { - return { - type: TransactionType.SWAP, - hash: swap.id.split('-')[0], - timestamp: swap.timestamp, - sender: swap.from, - token0Symbol: swap.pair?.token0.symbol, - token1Symbol: swap.pair?.token1.symbol, - token0Address: swap.pair?.token0.id, - token1Address: swap.pair?.token1.id, - amountUSD: parseFloat(swap.amountUSD), - amountToken0: parseFloat(swap.amount0In) - parseFloat(swap.amount0Out), - amountToken1: parseFloat(swap.amount1In) - parseFloat(swap.amount1Out), - } -} - -export const mapDayData = (tokenDayData: TokenDayData | PancakeDayData): ChartEntry => ({ - date: tokenDayData.date, - volumeUSD: parseFloat(tokenDayData.dailyVolumeUSD), - liquidityUSD: parseFloat(tokenDayData.totalLiquidityUSD), -}) - -export const mapPairDayData = (pairDayData: PairDayData): ChartEntry => ({ - date: pairDayData.date, - volumeUSD: parseFloat(pairDayData.dailyVolumeUSD), - liquidityUSD: parseFloat(pairDayData.reserveUSD), -}) - -type PoolOrTokenFetchFn = ( - chainName: MultiChainName, - skip: number, - address: string, -) => Promise<{ data?: ChartEntry[]; error: boolean }> - -type OverviewFetchFn = (chianName: MultiChainName, skip: number) => Promise<{ data?: ChartEntry[]; error: boolean }> - -// Common helper function to retrieve chart data -// Used for both Pool and Token charts -export const fetchChartData = async ( - chainName: MultiChainName, - getEntityDayDatas: OverviewFetchFn, -): Promise<{ data?: ChartEntry[]; error: boolean }> => { - let chartEntries: ChartEntry[] = [] - let error = false - let skip = 0 - let allFound = false - - while (!allFound && !error) { - // eslint-disable-next-line no-await-in-loop - const { data, error: fetchError } = await getEntityDayDatas(chainName, skip) - const length = data?.length || 0 - skip += 1000 - allFound = length < 1000 || skip > 2000 - error = fetchError - if (data) { - chartEntries = chartEntries.concat(data) - } - } - - if (error || chartEntries.length === 0) { - return { - error: true, - } - } - - const formattedDayDatas = fromPairs( - chartEntries.map((dayData) => { - // At this stage we track unix day ordinal for each data point to check for empty days later - const dayOrdinal = parseInt((dayData.date / ONE_DAY_UNIX).toFixed(0)) - return [dayOrdinal, dayData] - }), - ) - - const availableDays = Object.keys(formattedDayDatas).map((dayOrdinal) => parseInt(dayOrdinal, 10)) - - const firstAvailableDayData = formattedDayDatas[availableDays[0]] - // fill in empty days ( there will be no day datas if no trades made that day ) - let timestamp = firstAvailableDayData?.date ?? multiChainStartTime[chainName] - let latestLiquidityUSD = firstAvailableDayData?.liquidityUSD ?? 0 - const endTimestamp = dayjs().unix() - while (timestamp < endTimestamp - ONE_DAY_UNIX) { - timestamp += ONE_DAY_UNIX - const dayOrdinal = parseInt((timestamp / ONE_DAY_UNIX).toFixed(0), 10) - if (!Object.keys(formattedDayDatas).includes(dayOrdinal.toString())) { - formattedDayDatas[dayOrdinal] = { - date: timestamp, - volumeUSD: 0, - liquidityUSD: latestLiquidityUSD, - } - } else { - latestLiquidityUSD = formattedDayDatas[dayOrdinal].liquidityUSD - } - } - - return { - data: Object.values(formattedDayDatas), - error: false, - } -} - -export const fetchChartDataWithAddress = async ( - chainName: MultiChainName, - getEntityDayDatas: PoolOrTokenFetchFn, - address: string, -): Promise<{ data?: ChartEntry[]; error: boolean }> => { - let chartEntries: ChartEntry[] = [] - let error = false - let skip = 0 - let allFound = false - - while (!allFound && !error) { - // eslint-disable-next-line no-await-in-loop - const { data, error: fetchError } = await getEntityDayDatas(chainName, skip, address) - skip += 1000 - const length = data?.length || 0 - allFound = length < 1000 || skip > 2000 - error = fetchError - if (data) { - chartEntries = chartEntries.concat(data) - } - } - - if (error || chartEntries.length === 0) { - return { - error: true, - } - } - - const formattedDayDatas = fromPairs( - chartEntries.map((dayData) => { - // At this stage we track unix day ordinal for each data point to check for empty days later - const dayOrdinal = parseInt((dayData.date / ONE_DAY_UNIX).toFixed(0)) - return [dayOrdinal, dayData] - }), - ) - - const availableDays = Object.keys(formattedDayDatas).map((dayOrdinal) => parseInt(dayOrdinal, 10)) - - const firstAvailableDayData = formattedDayDatas[availableDays[0]] - // fill in empty days ( there will be no day datas if no trades made that day ) - let timestamp = firstAvailableDayData?.date ?? multiChainStartTime[chainName] - let latestLiquidityUSD = firstAvailableDayData?.liquidityUSD ?? 0 - const endTimestamp = dayjs().unix() - while (timestamp < endTimestamp - ONE_DAY_UNIX) { - timestamp += ONE_DAY_UNIX - const dayOrdinal = parseInt((timestamp / ONE_DAY_UNIX).toFixed(0), 10) - if (!Object.keys(formattedDayDatas).includes(dayOrdinal.toString())) { - formattedDayDatas[dayOrdinal] = { - date: timestamp, - volumeUSD: 0, - liquidityUSD: latestLiquidityUSD, - } - } else { - latestLiquidityUSD = formattedDayDatas[dayOrdinal].liquidityUSD - } - } - - return { - data: Object.values(formattedDayDatas), - error: false, - } -} diff --git a/apps/web/src/state/info/queries/types.ts b/apps/web/src/state/info/queries/types.ts deleted file mode 100644 index 3d5657915bc88..0000000000000 --- a/apps/web/src/state/info/queries/types.ts +++ /dev/null @@ -1,68 +0,0 @@ -interface PairResponse { - token0: { - id: string - symbol: string - } - token1: { - id: string - symbol: string - } -} - -export interface MintResponse { - id: string - timestamp: string - pair?: PairResponse - to: string - amount0: string - amount1: string - amountUSD: string -} - -export interface SwapResponse { - id: string - timestamp: string - pair?: PairResponse - from: string - amount0In: string - amount1In: string - amount0Out: string - amount1Out: string - amountUSD: string -} - -export interface BurnResponse { - id: string - timestamp: string - pair?: PairResponse - sender: string - amount0: string - amount1: string - amountUSD: string -} -export interface TokenDayData { - date: number // UNIX timestamp in seconds - dailyVolumeUSD: string - totalLiquidityUSD: string -} - -export interface TokenDayDatasResponse { - tokenDayDatas: TokenDayData[] -} - -// Footprint is the same, declared just for better readability -export type PancakeDayData = TokenDayData - -export interface PancakeDayDatasResponse { - pancakeDayDatas: PancakeDayData[] -} - -export interface PairDayData { - date: number // UNIX timestamp in seconds - dailyVolumeUSD: string - reserveUSD: string -} - -export interface PairDayDatasResponse { - pairDayDatas: PairDayData[] -} diff --git a/apps/web/src/state/info/types.ts b/apps/web/src/state/info/types.ts index e16c2c210095b..50b2569c121b7 100644 --- a/apps/web/src/state/info/types.ts +++ b/apps/web/src/state/info/types.ts @@ -5,12 +5,6 @@ export interface Block { timestamp: string } -export interface ChartEntry { - date: number - volumeUSD: number - liquidityUSD: number -} - export interface TvlChartEntry { date: number liquidityUSD: number @@ -62,15 +56,6 @@ export interface ProtocolData { txCount: number txCountChange: number } - -export interface ProtocolState { - readonly overview?: ProtocolData - - readonly chartData?: ChartEntry[] - - readonly transactions?: Transaction[] -} - // POOLS export interface PoolData { @@ -112,17 +97,6 @@ export interface PoolData { liquidityToken0: number liquidityToken1: number } - -export interface PoolsState { - byAddress: { - [address: string]: { - data?: PoolData - chartData?: ChartEntry[] - transactions?: Transaction[] - } - } -} - // TOKENS export type TokenData = { @@ -149,29 +123,6 @@ export type TokenData = { campaignId?: string pairs?: ComputedFarmConfigV3[] } - -export interface TokensState { - byAddress: { - [address: string]: { - data?: TokenData - poolAddresses?: string[] - chartData?: ChartEntry[] - priceData: { - oldestFetchedTimestamp?: number - [secondsInterval: number]: PriceChartEntry[] | undefined - } - transactions?: Transaction[] - } - } -} - -// Info redux state -export interface InfoState { - protocol: ProtocolState - pools: PoolsState - tokens: TokensState -} - export enum InfoDataSource { V3, V2, diff --git a/apps/web/src/views/Info/hooks/useBlocksFromTimestamps.ts b/apps/web/src/views/Info/hooks/useBlocksFromTimestamps.ts index b68c9929198d7..a20dd7209e298 100644 --- a/apps/web/src/views/Info/hooks/useBlocksFromTimestamps.ts +++ b/apps/web/src/views/Info/hooks/useBlocksFromTimestamps.ts @@ -1,57 +1,11 @@ import { useQuery } from '@tanstack/react-query' -import { useEffect, useState } from 'react' import { MultiChainNameExtend, multiChainId, multiChainName } from 'state/info/constant' import { useChainNameByQuery } from 'state/info/hooks' -import { Block } from 'state/info/types' import { getBlocksFromTimestamps } from 'utils/getBlocksFromTimestamps' -/** - * for a given array of timestamps, returns block entities - * @param timestamps - * @param sortDirection - * @param skipCount - */ export const useBlocksFromTimestamps = ( - timestamps: number[], - sortDirection: 'asc' | 'desc' = 'desc', - skipCount = 1000, -): { - blocks?: Block[] - error: boolean -} => { - const [blocks, setBlocks] = useState() - const [error, setError] = useState(false) - - const timestampsString = JSON.stringify(timestamps) - const blocksString = blocks ? JSON.stringify(blocks) : undefined - const chainName = useChainNameByQuery() - - useEffect(() => { - const fetchData = async () => { - const timestampsArray = JSON.parse(timestampsString) - const result = await getBlocksFromTimestamps(timestampsArray, sortDirection, chainName) - if (result.length === 0) { - setError(true) - } else { - setBlocks(result) - } - } - const blocksArray = blocksString ? JSON.parse(blocksString) : undefined - if (!blocksArray && !error && chainName) { - fetchData() - } - }, [blocksString, error, skipCount, sortDirection, timestampsString, chainName]) - - return { - blocks, - error, - } -} - -export const useBlockFromTimeStampQuery = ( timestamps: number[], sortDirection: 'asc' | 'desc' | undefined = 'desc', - skipCount: number | undefined = 1000, targetChainName?: MultiChainNameExtend, ) => { const chainNameByQuery = useChainNameByQuery() diff --git a/apps/web/src/views/V3Info/hooks/index.ts b/apps/web/src/views/V3Info/hooks/index.ts index 12b3b332efdc4..a30ddb893a606 100644 --- a/apps/web/src/views/V3Info/hooks/index.ts +++ b/apps/web/src/views/V3Info/hooks/index.ts @@ -7,7 +7,7 @@ import { Block } from 'state/info/types' import { getChainName } from 'state/info/utils' import { getDeltaTimestamps } from 'utils/getDeltaTimestamps' import { v3InfoClients } from 'utils/graphql' -import { useBlockFromTimeStampQuery } from 'views/Info/hooks/useBlocksFromTimestamps' +import { useBlocksFromTimestamps } from 'views/Info/hooks/useBlocksFromTimestamps' import { useQuery } from '@tanstack/react-query' import { chainIdToExplorerInfoChainName, explorerApiClient } from 'state/info/api/client' @@ -215,7 +215,7 @@ export const useTokensData = (addresses: string[], targetChainId?: ChainId): Tok const chainName = useChainNameByQuery() const chainId = targetChainId ?? multiChainId[chainName] const [t24, t48, t7d] = getDeltaTimestamps() - const { blocks } = useBlockFromTimeStampQuery([t24, t48, t7d], undefined, undefined, getChainName(chainId)) + const { blocks } = useBlocksFromTimestamps([t24, t48, t7d], undefined, getChainName(chainId)) const { data } = useQuery({ queryKey: [`v3/info/token/tokensData/${targetChainId}/${addresses?.join()}`, chainId],