Merge pull request #202 from blockworks-foundation/fix-24h-change

fix 24h spot change
This commit is contained in:
saml33 2023-07-17 08:28:58 +10:00 committed by GitHub
commit 2c3f6208fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 204 additions and 148 deletions

View File

@ -8,7 +8,7 @@ import {
HourlyFundingData,
HourlyFundingStatsData,
} from 'types'
import { MANGO_DATA_API_URL } from 'utils/constants'
import { DAILY_MILLISECONDS, MANGO_DATA_API_URL } from 'utils/constants'
import { formatCurrencyValue } from 'utils/numbers'
import { TooltipProps } from 'recharts/types/component/Tooltip'
import {
@ -191,7 +191,7 @@ const FundingChart = ({ hideChart }: { hideChart: () => void }) => {
const filteredData: HourlyFundingChartData[] = useMemo(() => {
if (!chartData.length) return []
const start = Number(daysToShow) * 86400000
const start = Number(daysToShow) * DAILY_MILLISECONDS
const filtered = chartData.filter((d: HourlyFundingChartData) => {
const date = new Date()
if (daysToShow === '30') {

View File

@ -24,6 +24,7 @@ import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
import { FadeInFadeOut } from '@components/shared/Transitions'
import ContentBox from '@components/shared/ContentBox'
import SheenLoader from '@components/shared/SheenLoader'
import { DAILY_MILLISECONDS } from 'utils/constants'
const VolumeChart = ({
chartData,
@ -123,7 +124,7 @@ const VolumeChart = ({
const filteredData: FormattedHourlyAccountVolumeData[] = useMemo(() => {
if (!chartData || !chartData.length) return []
const start = Number(daysToShow) * 86400000
const start = Number(daysToShow) * DAILY_MILLISECONDS
const filtered = chartData.filter((d: FormattedHourlyAccountVolumeData) => {
const date = new Date()
if (daysToShow === '30') {

View File

@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'
import { Governance, Proposal } from '@solana/spl-governance'
import dayjs from 'dayjs'
import { useTranslation } from 'next-i18next'
import { DAILY_SECONDS } from 'utils/constants'
interface CountdownState {
days: number
@ -53,8 +54,8 @@ export function VoteCountdown({
return ZeroCountdown
}
const days = Math.floor(timeToVoteEnd / 86400)
timeToVoteEnd -= days * 86400
const days = Math.floor(timeToVoteEnd / DAILY_SECONDS)
timeToVoteEnd -= days * DAILY_SECONDS
const hours = Math.floor(timeToVoteEnd / 3600) % 24
timeToVoteEnd -= hours * 3600

View File

@ -8,6 +8,7 @@ import SheenLoader from '@components/shared/SheenLoader'
import { NoSymbolIcon } from '@heroicons/react/20/solid'
import { PerformanceDataItem } from 'types'
import useAccountPerformanceData from 'hooks/useAccountPerformanceData'
import { DAILY_MILLISECONDS } from 'utils/constants'
interface PnlChange {
time: string
@ -33,7 +34,7 @@ const PnlHistoryModal = ({
if (!performanceData || !performanceData.length) return []
const dailyPnl = performanceData.filter((d: PerformanceDataItem) => {
const startTime = new Date().getTime() - 30 * 86400000
const startTime = new Date().getTime() - 30 * DAILY_MILLISECONDS
const dataDate = new Date(d.time)
const dataTime = dataDate.getTime()
return dataTime >= startTime && dataDate.getHours() === 0

View File

@ -25,7 +25,7 @@ import { FadeInFadeOut } from './Transitions'
import ChartRangeButtons from './ChartRangeButtons'
import Change from './Change'
import useLocalStorageState from 'hooks/useLocalStorageState'
import { ANIMATION_SETTINGS_KEY } from 'utils/constants'
import { ANIMATION_SETTINGS_KEY, DAILY_MILLISECONDS } from 'utils/constants'
import { formatNumericValue } from 'utils/numbers'
import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings'
import { AxisDomain } from 'recharts/types/util/types'
@ -120,7 +120,7 @@ const DetailedAreaOrBarChart: FunctionComponent<
const filteredData = useMemo(() => {
if (!data.length) return []
const start = Number(daysToShow) * 86400000
const start = Number(daysToShow) * DAILY_MILLISECONDS
const filtered = data.filter((d: any) => {
const dataTime = new Date(d[xKey]).getTime()
const now = new Date().getTime()

View File

@ -0,0 +1,67 @@
import { MinusSmallIcon } from '@heroicons/react/20/solid'
import { DownTriangle, UpTriangle } from './DirectionTriangles'
import FormatNumericValue from './FormatNumericValue'
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
import use24HourChange from 'hooks/use24HourChange'
import { useMemo } from 'react'
import SheenLoader from './SheenLoader'
const MarketChange = ({
market,
size,
}: {
market: PerpMarket | Serum3Market | undefined
size?: 'small'
}) => {
const { loading, spotChange, perpChange } = use24HourChange(market)
const change = useMemo(() => {
if (!market) return
return market instanceof PerpMarket ? perpChange : spotChange
}, [perpChange, spotChange])
return loading ? (
<SheenLoader className="mt-0.5">
<div className="h-3.5 w-12 bg-th-bkg-2" />
</SheenLoader>
) : change && !isNaN(change) ? (
<div className="flex items-center space-x-1.5">
{change > 0 ? (
<div className="mt-[1px]">
<UpTriangle size={size} />
</div>
) : change < 0 ? (
<div className="mt-[1px]">
<DownTriangle size={size} />
</div>
) : (
<MinusSmallIcon
className={`-mr-1 ${
size === 'small' ? 'h-4 w-4' : 'h-6 w-6'
} text-th-fgd-4`}
/>
)}
<p
className={`font-mono font-normal ${
size === 'small' ? 'text-xs' : 'text-sm'
} ${
change > 0
? 'text-th-up'
: change < 0
? 'text-th-down'
: 'text-th-fgd-4'
}`}
>
<FormatNumericValue
value={isNaN(change) ? '0.00' : Math.abs(change)}
decimals={2}
/>
%
</p>
</div>
) : (
<p></p>
)
}
export default MarketChange

View File

@ -24,6 +24,7 @@ import SimpleAreaChart from '@components/shared/SimpleAreaChart'
import { Disclosure, Transition } from '@headlessui/react'
import { LinkButton } from '@components/shared/Button'
import SoonBadge from '@components/shared/SoonBadge'
import { DAILY_SECONDS } from 'utils/constants'
export const getOneDayPerpStats = (
stats: PerpStatsItem[] | null,
@ -33,7 +34,7 @@ export const getOneDayPerpStats = (
? stats
.filter((s) => s.perp_market === marketName)
.filter((f) => {
const seconds = 86400
const seconds = DAILY_SECONDS
const dataTime = new Date(f.date_hour).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds

View File

@ -20,6 +20,7 @@ import { fetchSpotVolume } from '@components/trade/AdvancedMarketHeader'
import { TickerData } from 'types'
import { Disclosure, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import MarketChange from '@components/shared/MarketChange'
const SpotMarketsTable = () => {
const { t } = useTranslation('common')
@ -87,7 +88,7 @@ const SpotMarketsTable = () => {
(m) => m.mint === mkt.serumMarketExternal.toString()
)
const change =
const birdeyeChange =
birdeyeData && price
? ((price - birdeyeData.data[0].value) /
birdeyeData.data[0].value) *
@ -131,7 +132,7 @@ const SpotMarketsTable = () => {
<div className="h-10 w-24">
<SimpleAreaChart
color={
change >= 0
birdeyeChange >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
@ -153,7 +154,7 @@ const SpotMarketsTable = () => {
</Td>
<Td>
<div className="flex flex-col items-end">
<Change change={change} suffix="%" />
<MarketChange market={mkt} />
</div>
</Td>
<Td>

View File

@ -13,6 +13,7 @@ import parse from 'html-react-parser'
import { useTranslation } from 'next-i18next'
import { useMemo, useState } from 'react'
import PriceChart from '@components/token/PriceChart'
import { DAILY_SECONDS } from 'utils/constants'
dayjs.extend(relativeTime)
const DEFAULT_COINGECKO_VALUES = {
@ -44,7 +45,7 @@ const fetchBirdeyePrices = async (
): Promise<BirdeyePriceResponse[] | []> => {
const interval = daysToShow === '1' ? '30m' : daysToShow === '7' ? '1H' : '4H'
const queryEnd = Math.floor(Date.now() / 1000)
const queryStart = queryEnd - parseInt(daysToShow) * 86400
const queryStart = queryEnd - parseInt(daysToShow) * DAILY_SECONDS
const query = `defi/history_price?address=${mint}&address_type=token&type=${interval}&time_from=${queryStart}&time_to=${queryEnd}`
const response: BirdeyeResponse = await makeApiRequest(query)

View File

@ -1,6 +1,5 @@
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
import { IconButton, LinkButton } from '@components/shared/Button'
import Change from '@components/shared/Change'
import { getOneDayPerpStats } from '@components/stats/PerpMarketsOverviewTable'
import { ChartBarIcon, InformationCircleIcon } from '@heroicons/react/20/solid'
import mangoStore from '@store/mangoStore'
@ -10,9 +9,7 @@ import { useEffect, useMemo, useState } from 'react'
import { numberCompacter } from 'utils/numbers'
import MarketSelectDropdown from './MarketSelectDropdown'
import PerpFundingRate from './PerpFundingRate'
import { useBirdeyeMarketPrices } from 'hooks/useBirdeyeMarketPrices'
import SheenLoader from '@components/shared/SheenLoader'
import usePrevious from '@components/shared/usePrevious'
import PerpMarketDetailsModal from '@components/modals/PerpMarketDetailsModal'
import useMangoGroup from 'hooks/useMangoGroup'
import OraclePrice from './OraclePrice'
@ -23,6 +20,7 @@ import { TickerData } from 'types'
import ManualRefresh from '@components/shared/ManualRefresh'
import { useViewport } from 'hooks/useViewport'
import { breakpoints } from 'utils/theme'
import MarketChange from '@components/shared/MarketChange'
export const fetchSpotVolume = async () => {
try {
@ -43,17 +41,8 @@ const AdvancedMarketHeader = ({
}) => {
const { t } = useTranslation(['common', 'trade'])
const perpStats = mangoStore((s) => s.perpStats.data)
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const {
serumOrPerpMarket,
price: stalePrice,
selectedMarket,
} = useSelectedMarket()
const { serumOrPerpMarket, selectedMarket } = useSelectedMarket()
const selectedMarketName = mangoStore((s) => s.selectedMarket.name)
const [changePrice, setChangePrice] = useState(stalePrice)
const { data: birdeyePrices, isLoading: loadingPrices } =
useBirdeyeMarketPrices()
const previousMarketName = usePrevious(selectedMarketName)
const [showMarketDetails, setShowMarketDetails] = useState(false)
const { group } = useMangoGroup()
const { width } = useViewport()
@ -85,18 +74,6 @@ const AdvancedMarketHeader = ({
}
}, [group])
const birdeyeData = useMemo(() => {
if (
!birdeyePrices?.length ||
!selectedMarket ||
selectedMarket instanceof PerpMarket
)
return
return birdeyePrices.find(
(m) => m.mint === selectedMarket.serumMarketExternal.toString()
)
}, [birdeyePrices, selectedMarket])
const oneDayPerpStats = useMemo(() => {
if (
!perpStats ||
@ -108,36 +85,6 @@ const AdvancedMarketHeader = ({
return getOneDayPerpStats(perpStats, selectedMarketName)
}, [perpStats, selectedMarketName])
const change = useMemo(() => {
if (
!changePrice ||
!serumOrPerpMarket ||
selectedMarketName !== previousMarketName
)
return 0
if (serumOrPerpMarket instanceof PerpMarket) {
return oneDayPerpStats.length
? ((changePrice - oneDayPerpStats[0].price) /
oneDayPerpStats[0].price) *
100
: 0
} else {
if (!birdeyeData) return 0
return (
((changePrice - birdeyeData.data[0].value) /
birdeyeData.data[0].value) *
100
)
}
}, [
birdeyeData,
changePrice,
serumOrPerpMarket,
oneDayPerpStats,
previousMarketName,
selectedMarketName,
])
const perpVolume = useMemo(() => {
if (!oneDayPerpStats.length) return
return (
@ -155,19 +102,13 @@ const AdvancedMarketHeader = ({
<div className="hide-scroll flex w-full items-center justify-between overflow-x-auto border-t border-th-bkg-3 py-2 px-5 md:border-t-0 md:py-0 md:px-0 md:pr-6">
<div className="flex items-center">
<>
<OraclePrice setChangePrice={setChangePrice} />
<OraclePrice />
</>
<div className="ml-6 flex-col whitespace-nowrap">
<div className="mb-0.5 text-xs text-th-fgd-4">
{t('rolling-change')}
</div>
{!loadingPrices && !loadingPerpStats ? (
<Change change={change} size="small" suffix="%" />
) : (
<SheenLoader className="mt-0.5">
<div className="h-3.5 w-12 bg-th-bkg-2" />
</SheenLoader>
)}
<MarketChange market={selectedMarket} size="small" />
</div>
{serumOrPerpMarket instanceof PerpMarket ? (
<>

View File

@ -1,12 +1,7 @@
// import ChartRangeButtons from '@components/shared/ChartRangeButtons'
import Change from '@components/shared/Change'
import FavoriteMarketButton from '@components/shared/FavoriteMarketButton'
import SheenLoader from '@components/shared/SheenLoader'
import { getOneDayPerpStats } from '@components/stats/PerpMarketsOverviewTable'
import { Popover } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import mangoStore from '@store/mangoStore'
import { useBirdeyeMarketPrices } from 'hooks/useBirdeyeMarketPrices'
import useMangoGroup from 'hooks/useMangoGroup'
import useSelectedMarket from 'hooks/useSelectedMarket'
import { useTranslation } from 'next-i18next'
@ -23,6 +18,7 @@ import SoonBadge from '@components/shared/SoonBadge'
import TabButtons from '@components/shared/TabButtons'
import { PerpMarket } from '@blockworks-foundation/mango-v4'
import Loading from '@components/shared/Loading'
import MarketChange from '@components/shared/MarketChange'
const MARKET_LINK_WRAPPER_CLASSES =
'flex items-center justify-between px-4 md:pl-6 md:pr-4'
@ -41,11 +37,7 @@ const MarketSelectDropdown = () => {
)
const serumMarkets = mangoStore((s) => s.serumMarkets)
const allPerpMarkets = mangoStore((s) => s.perpMarkets)
const perpStats = mangoStore((s) => s.perpStats.data)
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const { group } = useMangoGroup()
const { data: birdeyePrices, isLoading: loadingPrices } =
useBirdeyeMarketPrices()
const [spotBaseFilter, setSpotBaseFilter] = useState('All')
const perpMarkets = useMemo(() => {
@ -130,14 +122,7 @@ const MarketSelectDropdown = () => {
<div className="py-3">
{spotOrPerp === 'perp' && perpMarkets?.length
? perpMarkets.map((m) => {
const changeData = getOneDayPerpStats(perpStats, m.name)
const isComingSoon = m.oracleLastUpdatedSlot == 0
const change = changeData.length
? ((m.uiPrice - changeData[0].price) /
changeData[0].price) *
100
: 0
return (
<div
className={MARKET_LINK_WRAPPER_CLASSES}
@ -167,17 +152,7 @@ const MarketSelectDropdown = () => {
getDecimalCount(m.tickSize)
)}
</span>
{!loadingPerpStats ? (
<Change
change={change}
suffix="%"
size="small"
/>
) : (
<SheenLoader className="mt-0.5">
<div className="h-3.5 w-12 bg-th-bkg-2" />
</SheenLoader>
)}
<MarketChange market={m} size="small" />
</div>
</Link>
<FavoriteMarketButton market={m} />
@ -216,12 +191,6 @@ const MarketSelectDropdown = () => {
.map((x) => x)
.sort((a, b) => a.name.localeCompare(b.name))
.map((m) => {
const birdeyeData = birdeyePrices?.length
? birdeyePrices.find(
(market) =>
market.mint === m.serumMarketExternal.toString()
)
: null
const baseBank = group?.getFirstBankByTokenIndex(
m.baseTokenIndex
)
@ -238,12 +207,6 @@ const MarketSelectDropdown = () => {
getDecimalCount(market.tickSize)
).toNumber()
}
const change =
birdeyeData && price
? ((price - birdeyeData.data[0].value) /
birdeyeData.data[0].value) *
100
: 0
return (
<div
className={MARKET_LINK_WRAPPER_CLASSES}
@ -281,21 +244,7 @@ const MarketSelectDropdown = () => {
) : null}
</span>
) : null}
{!loadingPrices ? (
change ? (
<Change
change={change}
suffix="%"
size="small"
/>
) : (
<span className="text-th-fgd-3"></span>
)
) : (
<SheenLoader className="mt-0.5">
<div className="h-3.5 w-12 bg-th-bkg-2" />
</SheenLoader>
)}
<MarketChange market={m} size="small" />
</div>
</Link>
<FavoriteMarketButton market={m} />

View File

@ -17,11 +17,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'
import useOracleProvider from 'hooks/useOracleProvider'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
const OraclePrice = ({
setChangePrice,
}: {
setChangePrice: (price: number) => void
}) => {
const OraclePrice = () => {
const {
serumOrPerpMarket,
price: stalePrice,
@ -96,7 +92,6 @@ const OraclePrice = ({
if (selectedMarket instanceof PerpMarket) {
setPrice(uiPrice)
setChangePrice(uiPrice)
} else {
let price
if (quoteBank && serumOrPerpMarket) {
@ -108,7 +103,6 @@ const OraclePrice = ({
price = 0
}
setPrice(price)
setChangePrice(price)
}
},
'processed'
@ -118,14 +112,7 @@ const OraclePrice = ({
connection.removeAccountChangeListener(subId)
}
}
}, [
connection,
selectedMarket,
serumOrPerpMarket,
setChangePrice,
quoteBank,
stalePrice,
])
}, [connection, selectedMarket, serumOrPerpMarket, quoteBank, stalePrice])
const oracleDecimals = getDecimalCount(serumOrPerpMarket?.tickSize || 0.01)

View File

@ -3,6 +3,7 @@ import NotificationCookieStore from '@store/notificationCookieStore'
import { useWallet } from '@solana/wallet-adapter-react'
import { fetchNotificationSettings } from 'apis/notifications/notificationSettings'
import { useIsAuthorized } from './useIsAuthorized'
import { DAILY_MILLISECONDS } from 'utils/constants'
export function useNotificationSettings() {
const { publicKey } = useWallet()
@ -18,7 +19,7 @@ export function useNotificationSettings() {
{
enabled: !!isAuth,
retry: 1,
staleTime: 86400000,
staleTime: DAILY_MILLISECONDS,
}
)
}

100
hooks/use24HourChange.tsx Normal file
View File

@ -0,0 +1,100 @@
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
import { getOneDayPerpStats } from '@components/stats/PerpMarketsOverviewTable'
import mangoStore from '@store/mangoStore'
import { useQuery } from '@tanstack/react-query'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import { useMemo } from 'react'
import { DAILY_SECONDS, MANGO_DATA_API_URL } from 'utils/constants'
dayjs.extend(utc)
const fetchPrices = async (market: Serum3Market | PerpMarket | undefined) => {
if (!market || market instanceof PerpMarket) return
const { baseTokenIndex, quoteTokenIndex } = market
const nowTimestamp = Date.now() / 1000
const changePriceTimestamp = nowTimestamp - DAILY_SECONDS
const changePriceTime = dayjs
.unix(changePriceTimestamp)
.utc()
.format('YYYY-MM-DDTHH:mm:ss[Z]')
const promises = [
fetch(
`${MANGO_DATA_API_URL}/stats/token-price?token-index=${baseTokenIndex}&price-time=${changePriceTime}`
),
fetch(
`${MANGO_DATA_API_URL}/stats/token-price?token-index=${quoteTokenIndex}&price-time=${changePriceTime}`
),
]
try {
const data = await Promise.all(promises)
const baseTokenPriceData = await data[0].json()
const quoteTokenPriceData = await data[1].json()
const baseTokenPrice = baseTokenPriceData ? baseTokenPriceData.price : 1
const quoteTokenPrice = quoteTokenPriceData ? quoteTokenPriceData.price : 1
return { baseTokenPrice, quoteTokenPrice }
} catch (e) {
console.log('failed to fetch 24hr price data', e)
return { baseTokenPrice: 1, quoteTokenPrice: 1 }
}
}
export default function use24HourChange(
market: Serum3Market | PerpMarket | undefined
) {
const perpStats = mangoStore((s) => s.perpStats.data)
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const {
data: priceData,
isLoading: loadingPriceData,
isFetching: fetchingPriceData,
} = useQuery(['token-prices', market], () => fetchPrices(market), {
cacheTime: 1000 * 60 * 10,
staleTime: 1000 * 60,
retry: 3,
refetchOnWindowFocus: false,
enabled: market && market instanceof Serum3Market,
})
const [currentBasePrice, currentQuotePrice] = useMemo(() => {
const group = mangoStore.getState().group
if (!group || !market || market instanceof PerpMarket)
return [undefined, undefined]
const baseBank = group.getFirstBankByTokenIndex(market.baseTokenIndex)
const quoteBank = group.getFirstBankByTokenIndex(market.quoteTokenIndex)
return [baseBank?.uiPrice, quoteBank?.uiPrice]
}, [market])
const perpChange = useMemo(() => {
if (
!market ||
market instanceof Serum3Market ||
!perpStats ||
!perpStats.length
)
return
const oneDayStats = getOneDayPerpStats(perpStats, market.name)
const currentPrice = market.uiPrice
const change = oneDayStats.length
? ((currentPrice - oneDayStats[0].price) / oneDayStats[0].price) * 100
: undefined
return change
}, [market, perpStats])
const spotChange = useMemo(() => {
if (!market) return
if (!currentBasePrice || !currentQuotePrice || !priceData) return
const currentPrice = currentBasePrice / currentQuotePrice
const oneDayPrice = priceData.baseTokenPrice / priceData.quoteTokenPrice
const change = ((currentPrice - oneDayPrice) / oneDayPrice) * 100
return change
}, [market, priceData])
const loading = useMemo(() => {
if (!market) return false
if (market instanceof PerpMarket) return loadingPerpStats
return loadingPriceData || fetchingPriceData
}, [market, loadingPerpStats, loadingPriceData, fetchingPriceData])
return { loading, perpChange, spotChange }
}

View File

@ -3,6 +3,7 @@ import { fetchAccountPerformance } from 'utils/account'
import useMangoAccount from './useMangoAccount'
import { useMemo } from 'react'
import { PerformanceDataItem } from 'types'
import { DAILY_MILLISECONDS } from 'utils/constants'
export default function useAccountPerformanceData() {
const { mangoAccountAddress } = useMangoAccount()
@ -28,7 +29,7 @@ export default function useAccountPerformanceData() {
const nowDate = new Date()
return performanceData.filter((d) => {
const dataTime = new Date(d.time).getTime()
return dataTime >= nowDate.getTime() - 86400000
return dataTime >= nowDate.getTime() - DAILY_MILLISECONDS
})
}, [performanceData])

View File

@ -2,6 +2,7 @@ import { Serum3Market } from '@blockworks-foundation/mango-v4'
import mangoStore from '@store/mangoStore'
import { useQuery } from '@tanstack/react-query'
import { makeApiRequest } from 'apis/birdeye/helpers'
import { DAILY_SECONDS } from 'utils/constants'
export interface BirdeyePriceResponse {
address: string
@ -18,7 +19,7 @@ const fetchBirdeyePrices = async (
const promises = []
const queryEnd = Math.floor(Date.now() / 1000)
const queryStart = queryEnd - 86400
const queryStart = queryEnd - DAILY_SECONDS
for (const mint of mints) {
const query = `defi/history_price?address=${mint}&address_type=pair&type=30m&time_from=${queryStart}&time_to=${queryEnd}`
promises.push(makeApiRequest(query))

View File

@ -128,3 +128,6 @@ export const CUSTOM_TOKEN_ICONS: { [key: string]: boolean } = {
wbtcpo: true,
'wbtc (portal)': true,
}
export const DAILY_SECONDS = 86400
export const DAILY_MILLISECONDS = 86400000