mango-v4-ui/hooks/useOpenPerpPositions.ts

79 lines
2.4 KiB
TypeScript
Raw Normal View History

2023-01-31 20:49:37 -08:00
import mangoStore from '@store/mangoStore'
import { useMemo } from 'react'
import useMangoAccount from './useMangoAccount'
2024-03-26 09:49:20 -07:00
import { sleep } from 'utils'
2023-01-31 20:49:37 -08:00
const useOpenPerpPositions = () => {
2024-01-06 06:47:49 -08:00
const { mangoAccountAddress, mangoAccountPk } = useMangoAccount()
const client = mangoStore((s) => s.client)
2023-01-31 20:49:37 -08:00
const perpPositions = mangoStore((s) => s.mangoAccount.perpPositions)
2024-01-06 06:47:49 -08:00
const poolIsPerpReadyForRefresh = async (
successCallback: () => void,
timeoutCallback?: () => void,
): Promise<'ready' | 'timeout'> => {
2024-03-26 09:37:46 -07:00
const timeout = 25000
2024-01-06 06:47:49 -08:00
let interval: NodeJS.Timeout
let isTimeout = false
const checkPerps = async (): Promise<boolean> => {
2024-03-26 09:49:20 -07:00
await sleep(200)
2024-01-06 06:47:49 -08:00
const newMangoAccount = await client.getMangoAccount(mangoAccountPk!)
return newMangoAccount.perps.every((x) => x.takerBaseLots.isZero())
}
const poll = async (
resolve: (value: 'ready') => void,
reject: (reason: 'timeout') => void,
): Promise<void> => {
if (await checkPerps()) {
clearInterval(interval)
resolve('ready')
} else if (isTimeout) {
clearInterval(interval)
reject('timeout')
}
}
const pollPromise = new Promise<'ready' | 'timeout'>((resolve, reject) => {
interval = setInterval(() => poll(resolve, reject), 700)
setTimeout(() => {
isTimeout = true
}, timeout)
})
try {
const resp = await pollPromise
successCallback()
return resp
} catch (error) {
console.error(error)
if (timeoutCallback) {
timeoutCallback()
}
return 'timeout'
}
}
const openPerpPositions = useMemo(() => {
const group = mangoStore.getState().group
if (!mangoAccountAddress || !group) return []
return Object.values(perpPositions)
.filter((p) => p.basePositionLots.toNumber())
.sort((a, b) => {
const aMarket = group.getPerpMarketByMarketIndex(a.marketIndex)
const bMarket = group.getPerpMarketByMarketIndex(b.marketIndex)
const aBasePosition = a.getBasePositionUi(aMarket)
const bBasePosition = b.getBasePositionUi(bMarket)
const aNotional = aBasePosition * aMarket._uiPrice
const bNotional = bBasePosition * bMarket._uiPrice
return Math.abs(bNotional) - Math.abs(aNotional)
})
2023-02-08 17:23:21 -08:00
}, [mangoAccountAddress, perpPositions])
2023-01-31 20:49:37 -08:00
2024-01-06 06:47:49 -08:00
return { openPerpPositions, poolIsPerpReadyForRefresh }
2023-01-31 20:49:37 -08:00
}
export default useOpenPerpPositions