diff --git a/src/api/prices/getOraclePrices.ts b/src/api/prices/getOraclePrices.ts index ec3d52ef..a927efb0 100644 --- a/src/api/prices/getOraclePrices.ts +++ b/src/api/prices/getOraclePrices.ts @@ -1,5 +1,6 @@ import { cacheFn, oraclePriceCache } from 'api/cache' import { getOracleQueryClient } from 'api/cosmwasm-client' +import { BN_ZERO } from 'constants/math' import { PRICE_ORACLE_DECIMALS } from 'constants/query' import { BNCoin } from 'types/classes/BNCoin' import { PriceResponse } from 'types/generated/mars-oracle-osmosis/MarsOracleOsmosis.types' @@ -27,7 +28,7 @@ export default async function getOraclePrices( const decimalDiff = asset.decimals - PRICE_ORACLE_DECIMALS return BNCoin.fromDenomAndBigNumber( asset.denom, - BN(priceResponse.price).shiftedBy(decimalDiff), + BN(priceResponse?.price ?? BN_ZERO).shiftedBy(decimalDiff), ) }) } catch (ex) { diff --git a/src/components/DisplayCurrency.tsx b/src/components/DisplayCurrency.tsx index 165b3dd6..fcd89566 100644 --- a/src/components/DisplayCurrency.tsx +++ b/src/components/DisplayCurrency.tsx @@ -18,6 +18,7 @@ interface Props { parentheses?: boolean showZero?: boolean options?: FormatOptions + isProfitOrLoss?: boolean } export default function DisplayCurrency(props: Props) { @@ -34,10 +35,10 @@ export default function DisplayCurrency(props: Props) { const isUSD = displayCurrencyAsset.id === 'USD' - const amount = useMemo(() => { + const [amount, absoluteAmount] = useMemo(() => { const coinValue = getCoinValue(props.coin, prices, assets) - if (displayCurrency === ORACLE_DENOM) return coinValue.toNumber() + if (displayCurrency === ORACLE_DENOM) return [coinValue.toNumber(), coinValue.abs().toNumber()] const displayDecimals = displayCurrencyAsset.decimals const displayPrice = getCoinValue( @@ -46,10 +47,14 @@ export default function DisplayCurrency(props: Props) { assets, ) - return coinValue.div(displayPrice).toNumber() + const amount = coinValue.div(displayPrice).toNumber() + + return [amount, Math.abs(amount)] }, [assets, displayCurrency, displayCurrencyAsset.decimals, prices, props.coin]) - const isLessThanACent = (isUSD && amount < 0.01 && amount > 0) || (amount === 0 && props.showZero) + const isLessThanACent = + (isUSD && absoluteAmount < 0.01 && absoluteAmount > 0) || + (absoluteAmount === 0 && props.showZero) const smallerThanPrefix = isLessThanACent ? '< ' : '' const prefix = isUSD @@ -64,8 +69,10 @@ export default function DisplayCurrency(props: Props) { className={classNames( props.className, props.parentheses && 'before:content-["("] after:content-[")"]', + props.isProfitOrLoss && (amount < 0 ? 'text-error' : amount === 0 ? '' : 'text-success'), + props.isProfitOrLoss && amount < 0 && 'before:content-["-"]', )} - amount={isLessThanACent ? 0.01 : amount} + amount={isLessThanACent ? 0.01 : absoluteAmount} options={{ minDecimals: isUSD ? 2 : 0, maxDecimals: 2, diff --git a/src/components/Header/ChainSelect.tsx b/src/components/Header/ChainSelect.tsx index 957e9752..15ef5931 100644 --- a/src/components/Header/ChainSelect.tsx +++ b/src/components/Header/ChainSelect.tsx @@ -35,7 +35,6 @@ export default function ChainSelect() { client: undefined, address: undefined, userDomain: undefined, - accounts: null, balances: [], }) navigate(getRoute(getPage(pathname), searchParams)) diff --git a/src/components/Perps/BalancesTable/Columns/Leverage.tsx b/src/components/Perps/BalancesTable/Columns/Leverage.tsx new file mode 100644 index 00000000..db402e24 --- /dev/null +++ b/src/components/Perps/BalancesTable/Columns/Leverage.tsx @@ -0,0 +1,31 @@ +import { FormattedNumber } from 'components/FormattedNumber' +import Text from 'components/Text' +import TitleAndSubCell from 'components/TitleAndSubCell' + +export const LEVERAGE_META = { + accessorKey: 'leverage', + header: () => ( +
+ Liquidation Price + + Leverage + +
+ ), +} + +type Props = { + liquidationPrice: BigNumber + leverage: number +} + +export default function Leverage(props: Props) { + return ( + + } + sub={} + /> + ) +} diff --git a/src/components/Perps/BalancesTable/Columns/PerpType.tsx b/src/components/Perps/BalancesTable/Columns/PerpType.tsx deleted file mode 100644 index 55288a8a..00000000 --- a/src/components/Perps/BalancesTable/Columns/PerpType.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import classNames from 'classnames' - -import Text from 'components/Text' - -export const PERP_TYPE_META = { accessorKey: 'type', header: 'Side' } - -type Props = { - type: PerpsType -} - -export default function PerpType(props: Props) { - return ( - - {props.type} - - ) -} diff --git a/src/components/Perps/BalancesTable/Columns/PnL.tsx b/src/components/Perps/BalancesTable/Columns/PnL.tsx index f4b928b2..c8ea7db6 100644 --- a/src/components/Perps/BalancesTable/Columns/PnL.tsx +++ b/src/components/Perps/BalancesTable/Columns/PnL.tsx @@ -1,6 +1,7 @@ -import classNames from 'classnames' - import DisplayCurrency from 'components/DisplayCurrency' +import Text from 'components/Text' +import { Tooltip } from 'components/Tooltip' +import { BN_ZERO } from 'constants/math' import { BNCoin } from 'types/classes/BNCoin' export const PNL_META = { accessorKey: 'pnl', header: 'Total PnL', id: 'pnl' } @@ -10,19 +11,38 @@ type Props = { } export default function PnL(props: Props) { - const isNegative = props.pnl.amount.isNegative() return ( - + } + type='info' + underline > - {isNegative ? '-' : props.pnl.amount.isZero() ? '' : '+'} - - + + + ) +} + +type PnLTooltipProps = { + realized: BNCoin + unrealized: BNCoin +} + +function PnLTooltip(props: PnLTooltipProps) { + return ( +
+ {[props.realized, props.unrealized].map((coin, i) => ( +
+ + {i === 0 ? 'Realized' : 'Unrealized'} PnL + + +
+ ))} +
) } diff --git a/src/components/Perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/Perps/BalancesTable/Columns/TradeDirection.tsx new file mode 100644 index 00000000..e11c5f00 --- /dev/null +++ b/src/components/Perps/BalancesTable/Columns/TradeDirection.tsx @@ -0,0 +1,25 @@ +import classNames from 'classnames' + +import Text from 'components/Text' + +export const PERP_TYPE_META = { accessorKey: 'tradeDirection', header: 'Side' } + +type Props = { + tradeDirection: TradeDirection +} + +export default function TradeDirection(props: Props) { + const { tradeDirection } = props + return ( + + {tradeDirection} + + ) +} diff --git a/src/components/Perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx b/src/components/Perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx index 4602a2b6..1bb97e9f 100644 --- a/src/components/Perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx +++ b/src/components/Perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx @@ -2,11 +2,14 @@ import { ColumnDef } from '@tanstack/react-table' import { useMemo } from 'react' import EntryPrice, { ENTRY_PRICE_META } from 'components/Perps/BalancesTable/Columns/EntryPrice' +import Leverage, { LEVERAGE_META } from 'components/Perps/BalancesTable/Columns/Leverage' import Manage, { MANAGE_META } from 'components/Perps/BalancesTable/Columns/Manage' import { PERP_NAME_META, PerpName } from 'components/Perps/BalancesTable/Columns/PerpName' -import PerpType, { PERP_TYPE_META } from 'components/Perps/BalancesTable/Columns/PerpType' import PnL, { PNL_META } from 'components/Perps/BalancesTable/Columns/PnL' import Size, { SIZE_META } from 'components/Perps/BalancesTable/Columns/Size' +import TradeDirection, { + PERP_TYPE_META, +} from 'components/Perps/BalancesTable/Columns/TradeDirection' import { PerpPositionRow } from 'components/Perps/BalancesTable/usePerpsBalancesData' export default function usePerpsBalancesTable() { @@ -18,12 +21,21 @@ export default function usePerpsBalancesTable() { }, { ...PERP_TYPE_META, - cell: ({ row }) => , + cell: ({ row }) => , }, { ...SIZE_META, cell: ({ row }) => , }, + { + ...LEVERAGE_META, + cell: ({ row }) => ( + + ), + }, { ...ENTRY_PRICE_META, cell: ({ row }) => ( diff --git a/src/components/Perps/BalancesTable/usePerpsBalancesData.ts b/src/components/Perps/BalancesTable/usePerpsBalancesData.ts index f018c598..43b1a807 100644 --- a/src/components/Perps/BalancesTable/usePerpsBalancesData.ts +++ b/src/components/Perps/BalancesTable/usePerpsBalancesData.ts @@ -1,34 +1,48 @@ import { useMemo } from 'react' +import { BN_ZERO } from 'constants/math' +import useAllAssets from 'hooks/assets/useAllAssets' import usePerpsEnabledAssets from 'hooks/assets/usePerpsEnabledAssets' import useCurrentAccount from 'hooks/useCurrentAccount' +import usePrices from 'hooks/usePrices' import { BNCoin } from 'types/classes/BNCoin' +import { getAccountNetValue } from 'utils/accounts' import { byDenom } from 'utils/array' +import { demagnify } from 'utils/formatters' export default function usePerpsBalancesTable() { const currentAccount = useCurrentAccount() const perpAssets = usePerpsEnabledAssets() + const allAssets = useAllAssets() + const { data: prices } = usePrices() return useMemo(() => { if (!currentAccount) return [] + const netValue = getAccountNetValue(currentAccount, prices, allAssets) + return currentAccount.perps.map((position) => { - const asset = perpAssets.find(byDenom(position.denom)) + const price = prices.find(byDenom(position.denom))?.amount ?? BN_ZERO + const asset = perpAssets.find(byDenom(position.denom))! return { asset, - type: position.type, + tradeDirection: position.tradeDirection, size: position.size, pnl: position.pnl, entryPrice: position.entryPrice, + liquidationPrice: position.entryPrice, // TODO: 📈 Get actual liquidation price from HC + leverage: price.times(demagnify(position.size, asset)).div(netValue).plus(1).toNumber(), } as PerpPositionRow }) - }, [currentAccount, perpAssets]) + }, [allAssets, currentAccount, perpAssets, prices]) } export type PerpPositionRow = { asset: Asset - type: 'long' | 'short' + tradeDirection: TradeDirection size: BigNumber pnl: BNCoin entryPrice: BigNumber + liquidationPrice: BigNumber + leverage: number } diff --git a/src/components/Perps/Module/LeverageButtons.tsx b/src/components/Perps/Module/LeverageButtons.tsx index 66a61bb9..e1df98f7 100644 --- a/src/components/Perps/Module/LeverageButtons.tsx +++ b/src/components/Perps/Module/LeverageButtons.tsx @@ -1,14 +1,15 @@ -import Button from 'components/Button' - const LEVERAGE_PRESETS = [1, 2, 3, 5, 10] export function LeverageButtons() { return (
{LEVERAGE_PRESETS.map((leverage) => ( - + ))}
) diff --git a/src/components/Perps/Module/PerpsModule.tsx b/src/components/Perps/Module/PerpsModule.tsx index bb1acb8f..a9510f9e 100644 --- a/src/components/Perps/Module/PerpsModule.tsx +++ b/src/components/Perps/Module/PerpsModule.tsx @@ -1,10 +1,9 @@ -import { useCallback, useState } from 'react' +import { useState } from 'react' -import Button from 'components/Button' import Card from 'components/Card' -import { DirectionSelect } from 'components/DirectionSelect' import { LeverageButtons } from 'components/Perps/Module/LeverageButtons' import { Or } from 'components/Perps/Module/Or' +import PerpsSummary from 'components/Perps/Module/Summary' import RangeInput from 'components/RangeInput' import { Spacer } from 'components/Spacer' import Text from 'components/Text' @@ -12,50 +11,35 @@ import AssetSelectorPerps from 'components/Trade/TradeModule/AssetSelector/Asset import AssetAmountInput from 'components/Trade/TradeModule/SwapForm/AssetAmountInput' import OrderTypeSelector from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector' import { AvailableOrderType } from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector/types' +import { TradeDirectionSelector } from 'components/TradeDirectionSelector' import { BN_ZERO } from 'constants/math' -import useBaseAsset from 'hooks/assets/useBasetAsset' import usePerpsAsset from 'hooks/perps/usePerpsAsset' -import useCurrentAccount from 'hooks/useCurrentAccount' -import useStore from 'store' -import { BNCoin } from 'types/classes/BNCoin' import { BN } from 'utils/helpers' export function PerpsModule() { const [selectedOrderType, setSelectedOrderType] = useState('Market') - const [selectedOrderDirection, setSelectedOrderDirection] = useState('long') - const baseAsset = useBaseAsset() + const [tradeDirection, setTradeDirection] = useState('long') const { perpsAsset } = usePerpsAsset() - const openPerpPosition = useStore((s) => s.openPerpPosition) - const currentAccount = useCurrentAccount() - const onConfirm = useCallback(async () => { - if (!currentAccount) return - await openPerpPosition({ - accountId: currentAccount.id, - coin: BNCoin.fromDenomAndBigNumber(perpsAsset.denom, BN(1000)), - }) - }, [currentAccount, openPerpPosition, perpsAsset.denom]) + const [amount, setAmount] = useState(BN_ZERO) if (!perpsAsset) return null return ( } - className='mb-4' + className='mb-4 h-full' > - + {}} - asset={baseAsset} + max={BN(1000)} // TODO: Implement max calculation + amount={amount} + setAmount={setAmount} + asset={perpsAsset} maxButtonLabel='Max:' disabled={false} /> @@ -64,7 +48,7 @@ export function PerpsModule() { {}} /> - + ) } diff --git a/src/components/Perps/Module/Summary.tsx b/src/components/Perps/Module/Summary.tsx new file mode 100644 index 00000000..6b0f5f5d --- /dev/null +++ b/src/components/Perps/Module/Summary.tsx @@ -0,0 +1,47 @@ +import { useCallback } from 'react' + +import ActionButton from 'components/Button/ActionButton' +import SummaryLine from 'components/SummaryLine' +import Text from 'components/Text' +import useCurrentAccount from 'hooks/useCurrentAccount' +import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' + +type Props = { + amount: BigNumber + tradeDirection: TradeDirection + asset: Asset +} + +export default function PerpsSummary(props: Props) { + const openPerpPosition = useStore((s) => s.openPerpPosition) + const currentAccount = useCurrentAccount() + + const onConfirm = useCallback(async () => { + if (!currentAccount) return + await openPerpPosition({ + accountId: currentAccount.id, + coin: BNCoin.fromDenomAndBigNumber( + props.asset.denom, + props.amount.times(props.tradeDirection === 'short' ? -1 : 1), + ), + }) + }, [currentAccount, openPerpPosition, props.amount, props.asset.denom, props.tradeDirection]) + + return ( +
+
+ + Summary + + Something + Something + Something +
+ + {props.tradeDirection} + {props.asset.symbol} + +
+ ) +} diff --git a/src/components/SummaryLine.tsx b/src/components/SummaryLine.tsx new file mode 100644 index 00000000..594246a1 --- /dev/null +++ b/src/components/SummaryLine.tsx @@ -0,0 +1,18 @@ +import classNames from 'classnames' +import React from 'react' + +const infoLineClasses = 'flex flex-row justify-between flex-1 mb-1 text-xs text-white' + +interface SummaryLineProps { + children: React.ReactNode + className?: string + label: string +} +export default function SummaryLine(props: SummaryLineProps) { + return ( +
+ {props.label} + {props.children} +
+ ) +} diff --git a/src/components/Tooltip/TooltipContent.tsx b/src/components/Tooltip/TooltipContent.tsx index b2832bc8..22014581 100644 --- a/src/components/Tooltip/TooltipContent.tsx +++ b/src/components/Tooltip/TooltipContent.tsx @@ -16,7 +16,7 @@ export default function TooltipContent(props: Props) {
{ { - if (!isAdvanced && direction === 'sell') return `Sell ${sellAsset.symbol}` + if (!isAdvanced && direction === 'short') return `Sell ${sellAsset.symbol}` return route.length ? `Buy ${buyAsset.symbol}` : 'No route found' }, [buyAsset.symbol, route, sellAsset.symbol, isAdvanced, direction]) @@ -189,17 +188,3 @@ export default function TradeSummary(props: Props) {
) } - -interface SummaryLineProps { - children: React.ReactNode - label: string - className?: string -} -function SummaryLine(props: SummaryLineProps) { - return ( -
- {props.label} - {props.children} -
- ) -} diff --git a/src/components/Trade/TradeModule/SwapForm/index.tsx b/src/components/Trade/TradeModule/SwapForm/index.tsx index 391cc74f..b6fd395e 100644 --- a/src/components/Trade/TradeModule/SwapForm/index.tsx +++ b/src/components/Trade/TradeModule/SwapForm/index.tsx @@ -4,7 +4,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react' import estimateExactIn from 'api/swap/estimateExactIn' import AvailableLiquidityMessage from 'components/AvailableLiquidityMessage' import DepositCapMessage from 'components/DepositCapMessage' -import { DirectionSelect } from 'components/DirectionSelect' import Divider from 'components/Divider' import RangeInput from 'components/RangeInput' import Text from 'components/Text' @@ -16,6 +15,7 @@ import MarginToggle from 'components/Trade/TradeModule/SwapForm/MarginToggle' import OrderTypeSelector from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector' import { AvailableOrderType } from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector/types' import TradeSummary from 'components/Trade/TradeModule/SwapForm/TradeSummary' +import { TradeDirectionSelector } from 'components/TradeDirectionSelector' import { DEFAULT_SETTINGS } from 'constants/defaultSettings' import { LocalStorageKeys } from 'constants/localStorageKeys' import { BN_ZERO } from 'constants/math' @@ -52,14 +52,15 @@ export default function SwapForm(props: Props) { const swap = useStore((s) => s.swap) const [slippage] = useLocalStorage(LocalStorageKeys.SLIPPAGE, DEFAULT_SETTINGS.slippage) const { computeMaxSwapAmount } = useHealthComputer(account) - const [orderDirection, setOrderDirection] = useState('buy') + const [tradeDirection, setTradeDirection] = useState('long') const { data: borrowAssets } = useMarketBorrowings() const { data: marketAssets } = useMarketAssets() + const [inputAsset, outputAsset] = useMemo(() => { if (isAdvanced) return [sellAsset, buyAsset] - if (orderDirection === 'buy') return [sellAsset, buyAsset] + if (tradeDirection === 'long') return [sellAsset, buyAsset] return [buyAsset, sellAsset] - }, [buyAsset, sellAsset, orderDirection, isAdvanced]) + }, [buyAsset, sellAsset, tradeDirection, isAdvanced]) const { data: route, isLoading: isRouteLoading } = useSwapRoute( inputAsset.denom, outputAsset.denom, @@ -246,7 +247,7 @@ export default function SwapForm(props: Props) { useEffect(() => { onChangeOutputAmount(BN_ZERO) onChangeInputAmount(BN_ZERO) - }, [orderDirection, onChangeOutputAmount, onChangeInputAmount]) + }, [tradeDirection, onChangeOutputAmount, onChangeInputAmount]) useEffect(() => { setOutputAssetAmount(BN_ZERO) @@ -375,9 +376,9 @@ export default function SwapForm(props: Props) { /> ) : ( <> -
diff --git a/src/components/DirectionSelect.tsx b/src/components/TradeDirectionSelector.tsx similarity index 51% rename from src/components/DirectionSelect.tsx rename to src/components/TradeDirectionSelector.tsx index e94da6ed..e5f783e4 100644 --- a/src/components/DirectionSelect.tsx +++ b/src/components/TradeDirectionSelector.tsx @@ -1,28 +1,27 @@ import classNames from 'classnames' +import { useMemo } from 'react' import Text from 'components/Text' interface Props { - direction: OrderDirection - onChangeDirection: (direction: OrderDirection) => void + direction: TradeDirection + onChangeDirection: (direction: TradeDirection) => void asset?: Asset } -export function DirectionSelect(props: Props) { - const hasAsset = props.asset - const directions: OrderDirection[] = hasAsset ? ['buy', 'sell'] : ['long', 'short'] +export function TradeDirectionSelector(props: Props) { return (
props.onChangeDirection(directions[0])} - direction={directions[0]} - isActive={props.direction === directions[0]} + onClick={() => props.onChangeDirection('long')} + direction={'long'} + isActive={props.direction === 'long'} asset={props.asset} /> props.onChangeDirection(directions[1])} - direction={directions[1]} - isActive={props.direction === directions[1]} + onClick={() => props.onChangeDirection('short')} + direction={'short'} + isActive={props.direction === 'short'} asset={props.asset} />
@@ -30,13 +29,22 @@ export function DirectionSelect(props: Props) { } interface DirectionProps { - direction: 'long' | 'short' | 'buy' | 'sell' + direction: TradeDirection isActive: boolean onClick: () => void asset?: Asset } function Direction(props: DirectionProps) { - const classString = props.direction === 'long' || props.direction === 'buy' ? 'success' : 'error' + const classString = props.direction === 'long' ? 'success' : 'error' + + const label = useMemo(() => { + if (props.asset) { + return props.direction === 'long' ? `Buy ${props.asset.symbol}` : `Sell ${props.asset.symbol}` + } else { + return props.direction === 'long' ? 'Long' : 'Short' + } + }, [props.asset, props.direction]) + return ( ) diff --git a/src/components/Wallet/WalletConnectedButton.tsx b/src/components/Wallet/WalletConnectedButton.tsx index 0d070306..9afb70f0 100644 --- a/src/components/Wallet/WalletConnectedButton.tsx +++ b/src/components/Wallet/WalletConnectedButton.tsx @@ -74,7 +74,6 @@ export default function WalletConnectedButton() { client: undefined, address: undefined, userDomain: undefined, - accounts: null, balances: [], focusComponent: null, }) diff --git a/src/components/Wallet/WalletConnecting.tsx b/src/components/Wallet/WalletConnecting.tsx index 75531157..8bc0511d 100644 --- a/src/components/Wallet/WalletConnecting.tsx +++ b/src/components/Wallet/WalletConnecting.tsx @@ -72,7 +72,6 @@ export default function WalletConnecting(props: Props) { client: undefined, address: undefined, userDomain: undefined, - accounts: null, focusComponent: { component: ( , }, @@ -137,7 +135,6 @@ export default function WalletConnecting(props: Props) { client: undefined, address: undefined, userDomain: undefined, - accounts: null, focusComponent: { component: ( , }, diff --git a/src/components/Wallet/index.tsx b/src/components/Wallet/index.tsx index 15a11678..7b70ca62 100644 --- a/src/components/Wallet/index.tsx +++ b/src/components/Wallet/index.tsx @@ -27,7 +27,6 @@ export default function Wallet() { client: undefined, address: undefined, userDomain: undefined, - accounts: null, balances: [], focusComponent: null, }) diff --git a/src/hooks/accounts/useAccount.tsx b/src/hooks/accounts/useAccount.tsx index 2a070cd4..980cc590 100644 --- a/src/hooks/accounts/useAccount.tsx +++ b/src/hooks/accounts/useAccount.tsx @@ -7,7 +7,7 @@ export default function useAccount(accountId?: string, suspense?: boolean) { const chainConfig = useChainConfig() return useSWR( - `chains/${chainConfig.id}/accounts/${accountId}`, + accountId && `chains/${chainConfig.id}/accounts/${accountId}`, () => getAccount(chainConfig, accountId), { suspense: suspense, diff --git a/src/hooks/accounts/useAccounts.tsx b/src/hooks/accounts/useAccounts.tsx index 3e051443..21027704 100644 --- a/src/hooks/accounts/useAccounts.tsx +++ b/src/hooks/accounts/useAccounts.tsx @@ -2,7 +2,6 @@ import useSWR from 'swr' import getAccounts from 'api/wallets/getAccounts' import useChainConfig from 'hooks/useChainConfig' -import useStore from 'store' import { AccountKind } from 'types/generated/mars-rover-health-computer/MarsRoverHealthComputer.types' export default function useAccounts(kind: AccountKind, address?: string, suspense = true) { @@ -15,13 +14,6 @@ export default function useAccounts(kind: AccountKind, address?: string, suspens suspense: suspense, fallbackData: [], revalidateOnFocus: false, - onSuccess: (accounts) => { - if (kind === 'high_levered_strategy') { - useStore.setState({ hlsAccounts: accounts }) - return - } - useStore.setState({ accounts: accounts }) - }, }, ) } diff --git a/src/hooks/useAutoLend.ts b/src/hooks/useAutoLend.ts index 1d6f6592..3406419e 100644 --- a/src/hooks/useAutoLend.ts +++ b/src/hooks/useAutoLend.ts @@ -1,6 +1,6 @@ +import useAccounts from 'hooks/accounts/useAccounts' import useAutoLendEnabledAccountIds from 'hooks/localStorage/useAutoLendEnabledAccountIds' import useCurrentAccount from 'hooks/useCurrentAccount' -import useStore from 'store' export default function useAutoLend(): { autoLendEnabledAccountIds: string[] @@ -10,7 +10,7 @@ export default function useAutoLend(): { setAutoLendOnAllAccounts: (lendAssets: boolean) => void enableAutoLendAccountId: (accountId: string) => void } { - const accounts = useStore((s) => s.accounts) + const { data: accounts } = useAccounts('default', undefined, false) const currentAccount = useCurrentAccount() const [autoLendEnabledAccountIds, setAutoLendEnabledAccountIds] = useAutoLendEnabledAccountIds() diff --git a/src/hooks/useCurrentAccount.tsx b/src/hooks/useCurrentAccount.tsx index 0d747ec8..c69dde15 100644 --- a/src/hooks/useCurrentAccount.tsx +++ b/src/hooks/useCurrentAccount.tsx @@ -1,9 +1,9 @@ +import useAccounts from 'hooks/accounts/useAccounts' import useAccountId from 'hooks/useAccountId' -import useStore from 'store' export default function useCurrentAccount(): Account | undefined { const accountId = useAccountId() + const { data: accounts } = useAccounts('default', undefined, false) - const accounts = useStore((s) => s.accounts) return accounts?.find((account) => account.id === accountId) } diff --git a/src/pages/PerpsPage.tsx b/src/pages/PerpsPage.tsx index 6df46f7c..23ec7eb3 100644 --- a/src/pages/PerpsPage.tsx +++ b/src/pages/PerpsPage.tsx @@ -5,15 +5,13 @@ import { PerpsPositions } from 'components/Perps/PerpsPositions' export default function PerpsPage() { return ( -
-
-
- - -
+
+ +
-
+ +
) } diff --git a/src/store/slices/broadcast.ts b/src/store/slices/broadcast.ts index 1287fd19..a35d2978 100644 --- a/src/store/slices/broadcast.ts +++ b/src/store/slices/broadcast.ts @@ -120,7 +120,7 @@ export default function createBroadcastSlice( case 'open-perp': toast.content.push({ coins: changes.deposits?.map((deposit) => deposit.toCoin()) ?? [], - text: 'Opened perp position', + text: 'Market order executed', }) break case 'close-perp': diff --git a/src/types/interfaces/perps.d.ts b/src/types/interfaces/perps.d.ts index 480a9e67..5d1cc462 100644 --- a/src/types/interfaces/perps.d.ts +++ b/src/types/interfaces/perps.d.ts @@ -1,8 +1,6 @@ const BNCoin = import('types/classes/BNCoin').BNCoin -type OrderDirection = PerpsType | ('buy' | 'sell') - -type PerpsType = 'long' | 'short' +type TradeDirection = 'long' | 'short' // TODO: 📈Remove this type when healthcomputer is implemented type PositionsWithoutPerps = Omit< @@ -13,7 +11,6 @@ type PositionsWithoutPerps = Omit< type PerpsPosition = { denom: string baseDenom: string - type: PerpsType + tradeDirection: TradeDirection size: BigNumber - // closingFee: BNCoin } diff --git a/src/types/interfaces/store/common.d.ts b/src/types/interfaces/store/common.d.ts index 550e14cb..93d61291 100644 --- a/src/types/interfaces/store/common.d.ts +++ b/src/types/interfaces/store/common.d.ts @@ -1,5 +1,4 @@ interface CommonSlice { - accounts: Account[] | null address?: string chainConfig: ChainConfig userDomain?: { @@ -7,7 +6,6 @@ interface CommonSlice { domain_full: string } balances: Coin[] - hlsAccounts: Account[] | null client?: WalletClient isOpen: boolean selectedAccount: string | null diff --git a/src/utils/accounts.ts b/src/utils/accounts.ts index 8b2f761c..fb0b5ca1 100644 --- a/src/utils/accounts.ts +++ b/src/utils/accounts.ts @@ -331,3 +331,8 @@ export function isAccountEmpty(account: Account) { account.deposits.length === 0 ) } + +export function getAccountNetValue(account: Account, prices: BNCoin[], assets: Asset[]) { + const [deposits, lends, debts, vaults] = getAccountPositionValues(account, prices, assets) + return deposits.plus(lends).plus(vaults).minus(debts) +} diff --git a/src/utils/resolvers.ts b/src/utils/resolvers.ts index 1db0209b..cced04ca 100644 --- a/src/utils/resolvers.ts +++ b/src/utils/resolvers.ts @@ -82,8 +82,8 @@ export function resolvePerpsPositions(perpPositions: Positions['perps']): PerpsP return { denom: position.denom, baseDenom: position.base_denom, - size: BN(position.size as any), - type: BN(position.size as any).isNegative() ? 'short' : 'long', + size: BN(position.size as any).abs(), + tradeDirection: BN(position.size as any).isNegative() ? 'short' : 'long', closingFee: BNCoin.fromCoin(position.pnl.coins.closing_fee), pnl: getPnlCoin(position.pnl.coins.pnl, position.base_denom), entryPrice: BN(position.entry_price), @@ -94,7 +94,9 @@ export function resolvePerpsPositions(perpPositions: Positions['perps']): PerpsP function getPnlCoin(pnl: PnL, denom: string): BNCoin { let amount = BN_ZERO - if ('loss' in (pnl as { loss: Coin })) { + if (pnl === 'break_even') return BNCoin.fromDenomAndBigNumber(denom, amount) + + if ('loss' in (pnl as any)) { amount = BN((pnl as any).loss.amount).times(-1) } else if ('profit' in (pnl as { profit: Coin })) { amount = BN((pnl as any).profit.amount)