2021-07-24 11:29:24 -07:00
|
|
|
import { useCallback, useEffect } from 'react'
|
2021-06-18 21:26:47 -07:00
|
|
|
import { AccountInfo } from '@solana/web3.js'
|
2021-06-20 11:08:14 -07:00
|
|
|
import useMangoStore, {
|
|
|
|
DEFAULT_CONNECTION,
|
|
|
|
WEBSOCKET_CONNECTION,
|
|
|
|
} from '../stores/useMangoStore'
|
2021-04-12 21:40:26 -07:00
|
|
|
import useInterval from './useInterval'
|
2021-06-23 12:09:19 -07:00
|
|
|
import useOrderbook from './useOrderbook'
|
2021-04-12 21:40:26 -07:00
|
|
|
|
2021-04-26 12:17:57 -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)
|
2021-06-23 12:09:19 -07:00
|
|
|
useOrderbook()
|
2021-04-06 15:11:42 -07:00
|
|
|
|
2021-04-14 23:16:36 -07:00
|
|
|
useEffect(() => {
|
|
|
|
actions.fetchMangoGroup()
|
|
|
|
}, [actions])
|
|
|
|
|
2021-04-26 12:17:57 -07:00
|
|
|
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(() => {
|
2021-06-20 11:08:14 -07:00
|
|
|
setMangoStore((state) => {
|
|
|
|
state.selectedMarket.current = markets[marketConfig.publicKey.toString()]
|
|
|
|
})
|
2021-07-19 14:28:30 -07:00
|
|
|
}, [marketConfig, markets, setMangoStore])
|
2021-06-18 15:38:09 -07:00
|
|
|
|
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
|
2021-06-23 12:09:19 -07:00
|
|
|
if (!marketConfig) return
|
2021-06-18 16:56:53 -07:00
|
|
|
|
|
|
|
const bidSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange(
|
2021-06-23 12:09:19 -07:00
|
|
|
marketConfig.bidsKey,
|
2021-08-23 10:12:48 -07:00
|
|
|
(info, context) => {
|
|
|
|
const lastSlot = useMangoStore.getState().connection.slot
|
2021-06-18 16:56:53 -07:00
|
|
|
if (
|
|
|
|
!previousBidInfo ||
|
|
|
|
!previousBidInfo.data.equals(info.data) ||
|
2021-08-23 10:12:48 -07:00
|
|
|
(previousBidInfo.lamports !== info.lamports &&
|
|
|
|
context.slot > lastSlot)
|
2021-06-18 16:56:53 -07:00
|
|
|
) {
|
|
|
|
previousBidInfo = info
|
|
|
|
setMangoStore((state) => {
|
2021-06-23 12:09:19 -07:00
|
|
|
state.accountInfos[marketConfig.bidsKey.toString()] =
|
|
|
|
previousBidInfo
|
2021-06-18 16:56:53 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
const askSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange(
|
2021-06-23 12:09:19 -07:00
|
|
|
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) => {
|
2021-06-23 12:09:19 -07:00
|
|
|
state.accountInfos[marketConfig.asksKey.toString()] =
|
|
|
|
previousAskInfo
|
2021-06-18 16:56:53 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2021-06-18 15:38:09 -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
|
|
|
|
2021-06-20 11:08:14 -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-06-20 11:08:14 -07:00
|
|
|
}
|
2021-07-24 11:29:24 -07:00
|
|
|
}, [selectedMarket, setMangoStore])
|
2021-04-15 12:05:48 -07:00
|
|
|
|
2021-07-24 11:29:24 -07:00
|
|
|
useInterval(() => {
|
2021-06-20 11:08:14 -07:00
|
|
|
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
|