import { useMemo } from 'react' import FloatingElement from './FloatingElement' import { ElementTitle } from './styles' import useMangoStore, { mangoClient } from '../stores/useMangoStore' import { ceilToDecimal, floorToDecimal, i80f48ToPercent, formatUsdValue, } from '../utils/index' import { LinkButton } from './Button' import Tooltip from './Tooltip' import SideBadge from './SideBadge' import { getMarketIndexBySymbol, nativeI80F48ToUi, PerpAccount, PerpMarket, QUOTE_INDEX, ZERO_BN, ZERO_I80F48, } from '@blockworks-foundation/mango-client' import useTradeHistory from '../hooks/useTradeHistory' import { getAvgEntryPrice, getBreakEvenPrice } from './PerpPositionsTable' import { notify } from '../utils/notifications' const handleSettlePnl = async ( perpMarket: PerpMarket, perpAccount: PerpAccount ) => { const mangoAccount = useMangoStore.getState().selectedMangoAccount.current const mangoGroup = useMangoStore.getState().selectedMangoGroup.current const mangoCache = useMangoStore.getState().selectedMangoGroup.cache const wallet = useMangoStore.getState().wallet.current const actions = useMangoStore.getState().actions const marketIndex = mangoGroup.getPerpMarketIndex(perpMarket.publicKey) try { const txid = await mangoClient.settlePnl( mangoGroup, mangoAccount, perpMarket, mangoGroup.rootBankAccounts[QUOTE_INDEX], mangoCache.priceCache[marketIndex].price, wallet ) actions.fetchMangoAccounts() notify({ title: 'Successfully settled PNL', description: '', txid, }) } catch (e) { console.log('Error settling PNL: ', `${e}`, `${perpAccount}`) notify({ title: 'Error settling PNL', description: e.message, txid: e.txid, type: 'error', }) } } export function SettlePnlTooltip() { return (
Settling will update your USDC balance to reflect the PnL amount.{' '} Learn more
) } export default function MarketPosition() { const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const mangoGroupConfig = useMangoStore((s) => s.selectedMangoGroup.config) const mangoGroupCache = useMangoStore((s) => s.selectedMangoGroup.cache) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) const selectedMarket = useMangoStore((s) => s.selectedMarket.current) const marketConfig = useMangoStore((s) => s.selectedMarket.config) const connected = useMangoStore((s) => s.wallet.connected) const baseSymbol = marketConfig.baseSymbol const marketName = marketConfig.name const tradeHistory = useTradeHistory() const perpTradeHistory = tradeHistory?.filter( (t) => t.marketName === marketName ) const marketIndex = useMemo(() => { return getMarketIndexBySymbol(mangoGroupConfig, baseSymbol) }, [mangoGroupConfig, baseSymbol]) const perpAccount = useMemo(() => { if (marketName.includes('PERP') && mangoAccount) { return mangoAccount.perpAccounts[marketIndex] } }, [marketName, mangoAccount, marketIndex]) if (!mangoGroup) return null return selectedMarket instanceof PerpMarket ? (
Position
Side
{perpAccount && !perpAccount.basePosition.eq(ZERO_BN) ? ( ) : ( '-' )}
Position size
{perpAccount ? selectedMarket.baseLotsToNumber(perpAccount.basePosition) : 0}{' '} {baseSymbol}
Notional size
{perpAccount ? formatUsdValue( selectedMarket.baseLotsToNumber(perpAccount.basePosition) * mangoGroup.getPrice(marketIndex, mangoGroupCache).toNumber() ) : 0}
Avg entry price
{perpAccount ? getAvgEntryPrice( mangoAccount, perpAccount, selectedMarket, perpTradeHistory ) : 0}
Break-even price
{perpAccount ? getBreakEvenPrice( mangoAccount, perpAccount, selectedMarket, perpTradeHistory ) : 0}
}> Unsettled PnL
{perpAccount ? formatUsdValue( +nativeI80F48ToUi( perpAccount.getPnl( mangoGroup.perpMarkets[marketIndex], mangoGroupCache.priceCache[marketIndex].price ), marketConfig.quoteDecimals ) ) : '0'} handleSettlePnl(selectedMarket, perpAccount)} className="ml-2 text-th-primary text-xs disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:underline" disabled={ perpAccount ? perpAccount .getPnl( mangoGroup.perpMarkets[marketIndex], mangoGroupCache.priceCache[marketIndex].price ) .eq(ZERO_I80F48) : true } > Settle
) : ( <>
Balance {mangoGroup ? (
{mangoGroupConfig.tokens .filter((t) => t.symbol === baseSymbol || t.symbol === 'USDC') .reverse() .map(({ symbol, mintKey }) => { const tokenIndex = mangoGroup.getTokenIndex(mintKey) return (
{symbol}
Deposits
{mangoAccount ? floorToDecimal( mangoAccount .getUiDeposit( mangoGroupCache.rootBankCache[tokenIndex], mangoGroup, tokenIndex ) .toNumber(), mangoGroup.tokens[tokenIndex].decimals ) : (0).toFixed( mangoGroup.tokens[tokenIndex].decimals )}
Borrows
{mangoAccount ? ceilToDecimal( mangoAccount .getUiBorrow( mangoGroupCache.rootBankCache[tokenIndex], mangoGroup, tokenIndex ) .toNumber(), mangoGroup.tokens[tokenIndex].decimals ) : (0).toFixed( mangoGroup.tokens[tokenIndex].decimals )}
Interest Rates
{i80f48ToPercent( mangoGroup.getDepositRate(tokenIndex) ).toFixed(2)} % {' / '} {i80f48ToPercent( mangoGroup.getBorrowRate(tokenIndex) ).toFixed(2)} %
) })}
) : null}
) }