mango-ui-v3/hooks/useHydrateStore.tsx

110 lines
3.1 KiB
TypeScript
Raw Normal View History

2021-07-24 11:29:24 -07:00
import { useCallback, useEffect } from 'react'
import { AccountInfo } from '@solana/web3.js'
import useMangoStore, {
DEFAULT_CONNECTION,
WEBSOCKET_CONNECTION,
} from '../stores/useMangoStore'
2021-04-12 21:40:26 -07:00
import useInterval from './useInterval'
import useOrderbook from './useOrderbook'
2021-04-12 21:40:26 -07:00
const SECONDS = 1000
2021-07-19 14:28:30 -07:00
const _SLOW_REFRESH_INTERVAL = 10 * SECONDS
2021-04-07 08:44:22 -07:00
2021-04-06 15:11:42 -07:00
const useHydrateStore = () => {
const setMangoStore = useMangoStore((s) => s.set)
2021-04-14 23:16:36 -07:00
const actions = useMangoStore((s) => s.actions)
2021-06-18 20:07:57 -07:00
const markets = useMangoStore((s) => s.selectedMangoGroup.markets)
2021-06-17 14:07:10 -07:00
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
2021-06-18 16:56:53 -07:00
const selectedMarket = useMangoStore((s) => s.selectedMarket.current)
useOrderbook()
2021-04-06 15:11:42 -07:00
2021-04-14 23:16:36 -07:00
useEffect(() => {
actions.fetchMangoGroup()
}, [actions])
useInterval(() => {
actions.fetchMangoGroup()
2021-04-29 08:08:36 -07:00
}, 60 * SECONDS)
2021-04-07 08:44:22 -07:00
2021-05-01 13:30:05 -07:00
useEffect(() => {
setMangoStore((state) => {
state.selectedMarket.current = markets[marketConfig.publicKey.toString()]
})
2021-07-19 14:28:30 -07:00
}, [marketConfig, markets, setMangoStore])
2021-06-18 16:56:53 -07:00
// hydrate orderbook with all markets in mango group
useEffect(() => {
let previousBidInfo: AccountInfo<Buffer> | null = null
let previousAskInfo: AccountInfo<Buffer> | null = null
if (!marketConfig) return
2021-06-18 16:56:53 -07:00
const bidSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange(
marketConfig.bidsKey,
(info, context) => {
const lastSlot = useMangoStore.getState().connection.slot
2021-06-18 16:56:53 -07:00
if (
!previousBidInfo ||
!previousBidInfo.data.equals(info.data) ||
(previousBidInfo.lamports !== info.lamports &&
context.slot > lastSlot)
2021-06-18 16:56:53 -07:00
) {
previousBidInfo = info
setMangoStore((state) => {
state.accountInfos[marketConfig.bidsKey.toString()] =
previousBidInfo
2021-06-18 16:56:53 -07:00
})
}
}
)
const askSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange(
marketConfig.asksKey,
2021-06-18 16:56:53 -07:00
(info) => {
if (
!previousAskInfo ||
!previousAskInfo.data.equals(info.data) ||
previousAskInfo.lamports !== info.lamports
) {
previousAskInfo = info
setMangoStore((state) => {
state.accountInfos[marketConfig.asksKey.toString()] =
previousAskInfo
2021-06-18 16:56:53 -07:00
})
}
}
)
2021-06-18 16:56:53 -07:00
return () => {
WEBSOCKET_CONNECTION.removeAccountChangeListener(bidSubscriptionId)
WEBSOCKET_CONNECTION.removeAccountChangeListener(askSubscriptionId)
}
}, [selectedMarket])
2021-04-12 21:40:26 -07:00
// fetch filled trades for selected market
2021-07-24 11:29:24 -07:00
const fetchFills = useCallback(async () => {
if (!selectedMarket) {
return null
}
try {
const loadedFills = await selectedMarket.loadFills(
DEFAULT_CONNECTION,
10000
)
setMangoStore((state) => {
state.selectedMarket.fills = loadedFills
})
} catch (err) {
console.log('Error fetching fills:', err)
}
2021-07-24 11:29:24 -07:00
}, [selectedMarket, setMangoStore])
2021-07-24 11:29:24 -07:00
useInterval(() => {
fetchFills()
}, _SLOW_REFRESH_INTERVAL)
2021-07-24 11:29:24 -07:00
useEffect(() => {
fetchFills()
}, [fetchFills])
2021-04-06 15:11:42 -07:00
}
export default useHydrateStore