import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4' import { IconButton } from '@components/shared/Button' import Change from '@components/shared/Change' import { getOneDayPerpStats } from '@components/stats/PerpMarketsTable' import { ChartBarIcon } from '@heroicons/react/20/solid' import { Market } from '@project-serum/serum' import mangoStore from '@store/mangoStore' import { useQuery } from '@tanstack/react-query' import useJupiterMints from 'hooks/useJupiterMints' import useSelectedMarket from 'hooks/useSelectedMarket' import { useTranslation } from 'next-i18next' import { useEffect, useMemo } from 'react' import { Token } from 'types/jupiter' import { getDecimalCount } from 'utils/numbers' import MarketSelectDropdown from './MarketSelectDropdown' import PerpFundingRate from './PerpFundingRate' type ResponseType = { prices: [number, number][] market_caps: [number, number][] total_volumes: [number, number][] } const fetchTokenChange = async ( mangoTokens: Token[], baseAddress: string ): Promise => { let coingeckoId = mangoTokens.find((t) => t.address === baseAddress) ?.extensions?.coingeckoId if (baseAddress === '3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh') { coingeckoId = 'bitcoin' } const response = await fetch( `https://api.coingecko.com/api/v3/coins/${coingeckoId}/market_chart?vs_currency=usd&days=1` ) const data = await response.json() return data } const AdvancedMarketHeader = ({ showChart, setShowChart, }: { showChart?: boolean setShowChart?: (x: boolean) => void }) => { const { t } = useTranslation(['common', 'trade']) const perpStats = mangoStore((s) => s.perpStats.data) const { serumOrPerpMarket, price, selectedMarket } = useSelectedMarket() const selectedMarketName = mangoStore((s) => s.selectedMarket.name) const { mangoTokens } = useJupiterMints() useEffect(() => { if (serumOrPerpMarket instanceof PerpMarket) { const actions = mangoStore.getState().actions actions.fetchPerpStats() } }, [serumOrPerpMarket]) const spotBaseAddress = useMemo(() => { const group = mangoStore.getState().group if (group && selectedMarket && selectedMarket instanceof Serum3Market) { return group .getFirstBankByTokenIndex(selectedMarket.baseTokenIndex) .mint.toString() } }, [selectedMarket]) const spotChangeResponse = useQuery( ['coingecko-tokens', spotBaseAddress], () => fetchTokenChange(mangoTokens, spotBaseAddress!), { cacheTime: 1000 * 60 * 15, staleTime: 1000 * 60 * 10, retry: 3, enabled: !!spotBaseAddress && serumOrPerpMarket instanceof Market && mangoTokens.length > 0, refetchOnWindowFocus: false, } ) const change = useMemo(() => { if (!price || !serumOrPerpMarket) return 0 if (serumOrPerpMarket instanceof PerpMarket) { const changeData = getOneDayPerpStats(perpStats, selectedMarketName) return changeData.length ? ((price - changeData[0].price) / changeData[0].price) * 100 : 0 } else { if (!spotChangeResponse.data) return 0 return ( ((price - spotChangeResponse.data.prices?.[0][1]) / spotChangeResponse.data.prices?.[0][1]) * 100 ) } }, [ spotChangeResponse, price, serumOrPerpMarket, perpStats, selectedMarketName, ]) return (
{t('trade:oracle-price')}
{price ? ( `$${price.toFixed( getDecimalCount(serumOrPerpMarket?.tickSize || 0.01) )}` ) : ( )}
{t('rolling-change')}
{serumOrPerpMarket instanceof PerpMarket ? (
{t('trade:funding-rate')}
) : null}
{setShowChart ? ( setShowChart(!showChart)} hideBg > ) : null}
) } export default AdvancedMarketHeader