mango-v4-ui/components/MangoProvider.tsx

124 lines
3.5 KiB
TypeScript
Raw Normal View History

import { useEffect } from 'react'
import mangoStore from '@store/mangoStore'
import { PublicKey } from '@solana/web3.js'
import { useRouter } from 'next/router'
2022-10-27 13:58:54 -07:00
import { MangoAccount } from '@blockworks-foundation/mango-v4'
2022-11-18 09:09:39 -08:00
import useMangoAccount from 'hooks/useMangoAccount'
const HydrateStore = () => {
2022-11-01 23:03:50 -07:00
const actions = mangoStore((s) => s.actions)
2022-11-18 09:09:39 -08:00
const { mangoAccount } = useMangoAccount()
useEffect(() => {
2022-11-01 23:03:50 -07:00
const fetchData = async () => {
await actions.fetchGroup()
}
fetchData()
2022-11-18 11:11:06 -08:00
}, [actions])
2022-10-27 13:58:54 -07:00
// watch selected Mango Account for changes
useEffect(() => {
const connection = mangoStore.getState().connection
const client = mangoStore.getState().client
if (!mangoAccount) return
const subscriptionId = connection.onAccountChange(
mangoAccount.publicKey,
2022-10-28 12:24:05 -07:00
async (info, context) => {
2022-10-27 13:58:54 -07:00
if (info?.lamports === 0) return
const lastSeenSlot = mangoStore.getState().mangoAccount.lastSlot
2022-10-27 13:58:54 -07:00
// const mangoAccountLastUpdated = new Date(
// mangoStore.getState().mangoAccount.lastUpdatedAt
// )
const mangoAccount = mangoStore.getState().mangoAccount.current
if (!mangoAccount) return
// const newUpdatedAt = new Date()
// const timeDiff =
// mangoAccountLastUpdated.getTime() - newUpdatedAt.getTime()
// only updated mango account if it's been more than 1 second since last update
// if (Math.abs(timeDiff) >= 500 && context.slot > lastSeenSlot) {
if (context.slot > lastSeenSlot) {
const decodedMangoAccount = client.program.coder.accounts.decode(
'mangoAccount',
info?.data
)
const newMangoAccount = MangoAccount.from(
mangoAccount.publicKey,
decodedMangoAccount
)
await newMangoAccount.reloadAccountData(client)
2022-10-28 12:24:05 -07:00
// newMangoAccount.spotOpenOrdersAccounts =
// mangoAccount.spotOpenOrdersAccounts
// newMangoAccount.advancedOrders = mangoAccount.advancedOrders
mangoStore.setState({
mangoAccount: {
...mangoStore.getState().mangoAccount,
current: newMangoAccount,
lastSlot: context.slot,
},
})
}
2022-10-27 13:58:54 -07:00
}
)
return () => {
connection.removeAccountChangeListener(subscriptionId)
}
}, [mangoAccount])
return null
}
const ReadOnlyMangoAccount = () => {
const router = useRouter()
const groupLoaded = mangoStore((s) => s.groupLoaded)
2022-10-27 13:58:54 -07:00
const ma = router.query?.mangoAccount
useEffect(() => {
if (!groupLoaded) return
const set = mangoStore.getState().set
const group = mangoStore.getState().group
async function loadUnownedMangoAccount() {
try {
if (!ma || !group) return
const client = mangoStore.getState().client
const pk = new PublicKey(ma)
const readOnlyMangoAccount = await client.getMangoAccount(pk)
await readOnlyMangoAccount.reloadAccountData(client)
2022-10-27 13:58:54 -07:00
set((state) => {
state.mangoAccount.current = readOnlyMangoAccount
state.mangoAccount.initialLoad = false
})
} catch (error) {
2022-11-01 11:13:02 -07:00
console.error('error', error)
}
}
if (ma) {
set((state) => {
state.mangoAccount.initialLoad = true
})
loadUnownedMangoAccount()
}
}, [ma, groupLoaded, router])
return null
}
const MangoProvider = () => {
return (
<>
<HydrateStore />
<ReadOnlyMangoAccount />
</>
)
}
export default MangoProvider