89 lines
2.8 KiB
TypeScript
89 lines
2.8 KiB
TypeScript
import { Group, Serum3Market } from '@blockworks-foundation/mango-v4'
|
|
import mangoStore from '@store/mangoStore'
|
|
import { useQuery } from '@tanstack/react-query'
|
|
import { makeApiRequest } from 'apis/birdeye/helpers'
|
|
import useMangoGroup from './useMangoGroup'
|
|
import { DAILY_SECONDS } from 'utils/constants'
|
|
|
|
const fetchBirdeye24hrPrices = async (
|
|
group: Group | undefined,
|
|
spotMarkets: Serum3Market[],
|
|
) => {
|
|
if (!group) return []
|
|
|
|
try {
|
|
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 baseResponse = await makeApiRequest(baseQuery)
|
|
|
|
return {
|
|
base: baseResponse?.data?.items?.length ? baseResponse.data.items : [],
|
|
quote: quoteItemsMap.get(quoteBank?.mint) || [],
|
|
marketIndex: market.marketIndex,
|
|
}
|
|
})
|
|
|
|
const responses = await Promise.all(promises)
|
|
|
|
return responses
|
|
} catch (e) {
|
|
console.error('error fetching 24-hour price data from birdeye', e)
|
|
return []
|
|
}
|
|
}
|
|
|
|
export const useBirdeye24hrPrices = () => {
|
|
const spotMarkets = mangoStore((s) => s.serumMarkets)
|
|
const { group } = useMangoGroup()
|
|
return useQuery(
|
|
['birdeye-daily-prices'],
|
|
() => fetchBirdeye24hrPrices(group, spotMarkets),
|
|
{
|
|
cacheTime: 1000 * 60 * 15,
|
|
staleTime: 1000 * 60 * 10,
|
|
retry: 3,
|
|
enabled: !!(group && spotMarkets?.length),
|
|
refetchOnWindowFocus: false,
|
|
},
|
|
)
|
|
}
|