diff --git a/components/explore/Spot.tsx b/components/explore/Spot.tsx index 17493f06..14a12c65 100644 --- a/components/explore/Spot.tsx +++ b/components/explore/Spot.tsx @@ -17,6 +17,7 @@ import Input from '@components/forms/Input' import EmptyState from '@components/nftMarket/EmptyState' import { Bank } from '@blockworks-foundation/mango-v4' import useBanks from 'hooks/useBanks' +import SheenLoader from '@components/shared/SheenLoader' export type BankWithMarketData = { bank: Bank @@ -91,7 +92,8 @@ const Spot = () => { const { t } = useTranslation(['common', 'explore', 'trade']) const { group } = useMangoGroup() const { banks } = useBanks() - const { serumMarketsWithData } = useListedMarketsWithMarketData() + const { serumMarketsWithData, isLoading: loadingMarketsData } = + useListedMarketsWithMarketData() const [sortByKey, setSortByKey] = useState('quote_volume_24h') const [search, setSearch] = useState('') const [showTableView, setShowTableView] = useState(true) @@ -169,7 +171,15 @@ const Spot = () => { - {sortedTokensToShow.length ? ( + {loadingMarketsData ? ( +
+ {[...Array(4)].map((x, i) => ( + +
+ + ))} +
+ ) : sortedTokensToShow.length ? ( showTableView ? (
diff --git a/hooks/useBirdeye24hrPrices.ts b/hooks/useBirdeye24hrPrices.ts index 87022fea..cf0102fa 100644 --- a/hooks/useBirdeye24hrPrices.ts +++ b/hooks/useBirdeye24hrPrices.ts @@ -15,23 +15,49 @@ const fetchBirdeye24hrPrices = async ( const queryEnd = Math.floor(Date.now() / 1000) const queryStart = queryEnd - DAILY_SECONDS + // collect unique quote tokens + const uniqueQuoteTokens = Array.from( + new Set( + spotMarkets.map((market) => { + const quoteBank = group.getFirstBankByTokenIndex( + market.quoteTokenIndex, + ) + return quoteBank?.mint + }), + ), + ).filter(Boolean) // remove any undefined values + + // fetch responses for unique quote tokens + const quoteResponses = await Promise.all( + uniqueQuoteTokens.map(async (quoteToken) => { + const quoteQuery = `defi/history_price?address=${quoteToken}&address_type=token&type=1H&time_from=${queryStart}&time_to=${queryEnd}` + const quoteResponse = await makeApiRequest(quoteQuery) + return { + quoteToken, + items: quoteResponse?.data?.items?.length + ? quoteResponse.data.items + : [], + } + }), + ) + + // create a map for quick access to quote items based on quoteToken + const quoteItemsMap = new Map( + quoteResponses.map((response) => [response.quoteToken, response.items]), + ) + + // fetch base responses and match them with quote items const promises = spotMarkets.map(async (market) => { const baseBank = group.getFirstBankByTokenIndex(market.baseTokenIndex) const quoteBank = group.getFirstBankByTokenIndex(market.quoteTokenIndex) const baseQuery = `defi/history_price?address=${baseBank?.mint}&address_type=token&type=1H&time_from=${queryStart}&time_to=${queryEnd}` - const quoteQuery = `defi/history_price?address=${quoteBank?.mint}&address_type=token&type=1H&time_from=${queryStart}&time_to=${queryEnd}` - const [baseResponse, quoteResponse] = await Promise.all([ - makeApiRequest(baseQuery), - makeApiRequest(quoteQuery), - ]) + const baseResponse = await makeApiRequest(baseQuery) return { base: baseResponse?.data?.items?.length ? baseResponse.data.items : [], - quote: quoteResponse?.data?.items?.length - ? quoteResponse.data.items - : [], + quote: quoteItemsMap.get(quoteBank?.mint) || [], marketIndex: market.marketIndex, } })