mango-ui-v3/hooks/useHydrateStore.tsx

134 lines
4.4 KiB
TypeScript
Raw Normal View History

2021-04-06 15:11:42 -07:00
import { useEffect } from 'react'
import { Market } from '@project-serum/serum'
2021-04-07 08:44:22 -07:00
import { PublicKey, AccountInfo } from '@solana/web3.js'
2021-04-06 15:11:42 -07:00
import useConnection from './useConnection'
import useMangoStore from '../stores/useMangoStore'
2021-04-07 08:44:22 -07:00
import useMarketList from './useMarketList'
2021-04-11 21:17:23 -07:00
import { notify } from '../utils/notifications'
2021-04-07 08:44:22 -07:00
const marketAddressSelector = (s) => s.selectedMarket.address
const mangoGroupMarketsSelector = (s) => s.selectedMangoGroup.markets
2021-04-06 15:11:42 -07:00
const useHydrateStore = () => {
const setMangoStore = useMangoStore((s) => s.set)
2021-04-07 08:44:22 -07:00
const selectedMarketAddress = useMangoStore(marketAddressSelector)
const marketsForSelectedMangoGroup = useMangoStore(mangoGroupMarketsSelector)
2021-04-06 15:11:42 -07:00
const { connection, dexProgramId } = useConnection()
2021-04-07 08:44:22 -07:00
const { marketList } = useMarketList()
2021-04-06 15:11:42 -07:00
2021-04-07 08:44:22 -07:00
// load selected market
2021-04-06 15:11:42 -07:00
useEffect(() => {
2021-04-07 08:44:22 -07:00
console.log('useEffect loading market', selectedMarketAddress, dexProgramId)
2021-04-06 15:11:42 -07:00
Market.load(
connection,
2021-04-07 08:44:22 -07:00
new PublicKey(selectedMarketAddress),
2021-04-06 15:11:42 -07:00
{},
new PublicKey(dexProgramId)
)
2021-04-07 08:44:22 -07:00
.then(async (market) => {
// @ts-ignore
const bidAcccount = market._decoded.bids
const bidInfo = await connection.getAccountInfo(bidAcccount)
// @ts-ignore
const askAccount = market._decoded.asks
const askInfo = await connection.getAccountInfo(askAccount)
2021-04-06 15:11:42 -07:00
setMangoStore((state) => {
state.market.current = market
2021-04-07 08:44:22 -07:00
state.accountInfos[askAccount.toString()] = askInfo
state.accountInfos[bidAcccount.toString()] = bidInfo
2021-04-06 15:11:42 -07:00
})
})
2021-04-11 21:17:23 -07:00
.catch((e) => {
notify({
message: 'Error loading market',
description: e.message,
type: 'error',
})
})
2021-04-07 08:44:22 -07:00
}, [selectedMarketAddress])
// load all markets for mangoGroup
useEffect(() => {
console.log('loading all markets for mangoGroup')
Promise.all(
marketList.map((mkt) => {
return Market.load(connection, mkt.address, {}, mkt.programId)
})
).then((markets) => {
setMangoStore((state) => {
markets.forEach((market) => {
state.selectedMangoGroup.markets[market.publicKey.toString()] = market
// @ts-ignore
const bidAcctAddress = market._decoded.bids.toString()
if (!(bidAcctAddress in state.accountInfos)) {
state.accountInfos[bidAcctAddress] = null
}
2021-04-07 08:44:22 -07:00
// @ts-ignore
const askAcctAddress = market._decoded.asks.toString()
if (!(askAcctAddress in state.accountInfos)) {
state.accountInfos[askAcctAddress] = null
}
2021-04-07 08:44:22 -07:00
})
})
})
}, [marketList])
// hydrate orderbook for all markets in mango group
useEffect(() => {
const subscriptionIds = Object.entries(marketsForSelectedMangoGroup).map(
([, market]) => {
let previousBidInfo: AccountInfo<Buffer> | null = null
let previousAskInfo: AccountInfo<Buffer> | null = null
return [
connection.onAccountChange(
// @ts-ignore
market._decoded.bids,
(info) => {
if (
!previousBidInfo ||
!previousBidInfo.data.equals(info.data) ||
previousBidInfo.lamports !== info.lamports
) {
previousBidInfo = info
setMangoStore((state) => {
// @ts-ignore
const pkString = market._decoded.bids.toString()
state.accountInfos[pkString] = previousBidInfo
})
}
}
),
connection.onAccountChange(
// @ts-ignore
market._decoded.asks,
(info) => {
if (
!previousAskInfo ||
!previousAskInfo.data.equals(info.data) ||
previousAskInfo.lamports !== info.lamports
) {
previousAskInfo = info
setMangoStore((state) => {
// @ts-ignore
const pkString = market._decoded.asks.toString()
2021-04-07 08:44:22 -07:00
state.accountInfos[pkString] = previousAskInfo
})
}
}
),
]
}
)
console.log('subscription ids', subscriptionIds)
2021-04-06 15:11:42 -07:00
2021-04-07 08:44:22 -07:00
return () => {
for (const id of subscriptionIds.flat()) {
connection.removeAccountChangeListener(id)
}
}
}, [marketsForSelectedMangoGroup])
2021-04-06 15:11:42 -07:00
}
export default useHydrateStore