import useMangoGroup from 'hooks/useMangoGroup'
import { useMemo } from 'react'
import { SHOW_INACTIVE_POSITIONS_KEY } from 'utils/constants'
import TokenLogo from './shared/TokenLogo'
import Button from './shared/Button'
import { formatTokenSymbol } from 'utils/tokens'
import mangoStore, { ActiveTab } from '@store/mangoStore'
import Switch from './forms/Switch'
import useLocalStorageState from 'hooks/useLocalStorageState'
import FormatNumericValue from './shared/FormatNumericValue'
import {
Bank,
MangoAccount,
toUiDecimalsForQuote,
} from '@blockworks-foundation/mango-v4'
import useBankRates from 'hooks/useBankRates'
import usePositions from 'hooks/usePositions'
const set = mangoStore.getState().set
type Position = {
borrowBalance: number
stakeBalance: number
pnl: number
bank: Bank
acct: MangoAccount | undefined
}
const getLiquidationRatio = (
borrowBalance: number,
stakeBalance: number,
stakeBank: Bank,
borrowBank: Bank,
) => {
return (
(Math.abs(borrowBalance) * borrowBank.maintLiabWeight.toNumber()) /
(stakeBalance * stakeBank.maintAssetWeight.toNumber())
).toFixed(2)
}
const Positions = ({
setActiveTab,
}: {
setActiveTab: (tab: ActiveTab) => void
}) => {
const [showInactivePositions, setShowInactivePositions] =
useLocalStorageState(SHOW_INACTIVE_POSITIONS_KEY, true)
const { borrowBank, positions } = usePositions(showInactivePositions)
const numberOfPositions = useMemo(() => {
if (!positions.length) return 0
return positions.filter((pos) => pos.stakeBalance > 0).length
}, [positions])
return (
<>
{`You have ${numberOfPositions} active position${
numberOfPositions !== 1 ? 's' : ''
}`}
setShowInactivePositions(checked)}
>
Show Inactive
{positions.length ? (
positions.map((position) => {
return position.bank ? (
) : null
})
) : (
Nothing to see here...
)}
>
)
}
const PositionItem = ({
position,
setActiveTab,
borrowBank,
}: {
position: Position
setActiveTab: (v: ActiveTab) => void
borrowBank: Bank | undefined
}) => {
const { group } = useMangoGroup()
const { stakeBalance, borrowBalance, bank, pnl, acct } = position
const handleAddOrManagePosition = (token: string) => {
setActiveTab('Boost!')
set((state) => {
state.selectedToken = token
})
}
const leverage = useMemo(() => {
if (!group || !acct) return 1
const accountValue = toUiDecimalsForQuote(acct.getEquity(group).toNumber())
const assetsValue = toUiDecimalsForQuote(
acct.getAssetsValue(group).toNumber(),
)
if (isNaN(assetsValue / accountValue)) {
return 0
} else {
return Math.abs(1 - assetsValue / accountValue) + 1
}
}, [group, acct])
const [liqRatio, liqPriceChangePercentage] = useMemo(() => {
if (!borrowBalance || !borrowBank) return ['0.00', '']
const liqRatio = getLiquidationRatio(
borrowBalance,
stakeBalance,
bank,
borrowBank,
)
const currentPriceRatio = bank.uiPrice / borrowBank.uiPrice
const liqPriceChangePercentage =
((parseFloat(liqRatio) - currentPriceRatio) / currentPriceRatio) * 100
return [liqRatio, liqPriceChangePercentage.toFixed(2)]
}, [bank, borrowBalance, borrowBank, stakeBalance])
console.log('liq price change percentage', liqPriceChangePercentage)
const { estimatedNetAPY, stakeBankDepositRate } = useBankRates(
bank.name,
leverage,
)
const uiRate = bank.name == 'USDC' ? stakeBankDepositRate : estimatedNetAPY
return (
{formatTokenSymbol(bank.name)}
${bank.uiPrice.toFixed(2)}
Position Size
{' '}
{'USDC'}
{bank.name !== 'USDC' ? (
{' '}
{formatTokenSymbol(bank.name)}
) : null}
Total Earned
= 0
? 'text-th-success'
: 'text-th-error'
}`}
>
{stakeBalance || pnl ? (
) : (
'–'
)}
{position.bank.name == 'USDC' ? null : (
<>
Leverage
{leverage ? leverage.toFixed(2) : 0.0}x
Est. Liquidation Price
${liqRatio}
{/* {liqPriceChangePercentage ? (
{liqPriceChangePercentage}%
) : null} */}
>
)}
)
}
export default Positions