Mp 2681 interact with credit account modal (#189)

* MP-2681: fixed and simplified fund and withdraw
;.
:

* MP-2352: created the CreditAccountComposition

* fix: adjusted according to feedback

* fix: fixed funding account max

* fix: fix portfolio
This commit is contained in:
Linkie Link 2023-05-09 17:22:11 +02:00 committed by GitHub
parent 78aa6b3089
commit 5c01ec6872
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 392 additions and 151 deletions

View File

@ -11,13 +11,18 @@ interface Props {
interface Item {
title: string
content: React.ReactNode
open?: boolean
}
export default function Accordion(props: Props) {
return (
<Card>
<Card className='w-full'>
{props.items.map((item) => (
<details key={item.title} className='group border-b-white/10 [&:not(:last-child)]:border-b'>
<details
key={item.title}
open={item.open}
className='group border-b-white/10 [&:not(:last-child)]:border-b'
>
<summary
className={classNames(
'mb-0 flex cursor-pointer items-center justify-between border-t border-white/10 bg-white/10 p-4 text-white',

View File

@ -0,0 +1,98 @@
'use client'
import BigNumber from 'bignumber.js'
import classNames from 'classnames'
import DisplayCurrency from 'components/DisplayCurrency'
import { ArrowRight } from 'components/Icons'
import Text from 'components/Text'
import useStore from 'store'
import {
calculateAccountApr,
calculateAccountBalance,
calculateAccountBorrowRate,
calculateAccountDebt,
calculateAccountPnL,
} from 'utils/accounts'
import { BN } from 'utils/helpers'
interface Props {
account: Account
change?: AccountChange
}
interface ItemProps {
title: string
current: BigNumber
change: BigNumber
className?: string
}
export default function AccountComposition(props: Props) {
const prices = useStore((s) => s.prices)
const balance = calculateAccountBalance(props.account, prices)
const balanceChange = props.change ? calculateAccountBalance(props.change, prices) : BN(0)
const debtBalance = calculateAccountDebt(props.account, prices)
const debtBalanceChange = props.change ? calculateAccountDebt(props.change, prices) : BN(0)
const pnL = calculateAccountPnL(props.account, prices)
const pnLChange = props.change ? calculateAccountPnL(props.change, prices) : BN(0)
const apr = calculateAccountApr(props.account, prices)
const aprChange = props.change ? calculateAccountPnL(props.change, prices) : BN(0)
const borrowRate = calculateAccountBorrowRate(props.account, prices)
const borrowRateChange = props.change ? calculateAccountPnL(props.change, prices) : BN(0)
return (
<div className='w-full flex-wrap'>
<Item
title='Total Position Value'
current={balance}
change={balance.plus(balanceChange)}
className='pb-3'
/>
<Item
title='Total Liabilities'
current={debtBalance}
change={debtBalance.plus(debtBalanceChange)}
className='pb-3'
/>
<Item
title='Unrealized PnL'
current={pnL}
change={pnL.plus(pnLChange)}
className='border border-transparent border-y-white/20 py-3'
/>
<Item title='APR' current={apr} change={apr.plus(aprChange)} className='py-3' />
<Item title='Borrow Rate' current={borrowRate} change={borrowRate.plus(borrowRateChange)} />
</div>
)
}
function Item(props: ItemProps) {
const baseCurrency = useStore((s) => s.baseCurrency)
const increase = props.current.isLessThan(props.change)
return (
<div className={classNames('flex w-full flex-nowrap', props.className)}>
<div className='flex flex-shrink items-center'>
<Text size='sm' className='text-white/60'>
{props.title}
</Text>
</div>
<div className='flex flex-grow items-center justify-end gap-2'>
<DisplayCurrency
coin={{ amount: props.current.toString(), denom: baseCurrency.denom }}
className='text-sm'
/>
{!props.current.isEqualTo(props.change) && (
<>
<span className={classNames('w-3', increase ? 'text-profit' : 'text-loss')}>
<ArrowRight />
</span>
<DisplayCurrency
coin={{ amount: props.change.toString(), denom: baseCurrency.denom }}
className={classNames('text-sm', increase ? 'text-profit' : 'text-loss')}
/>
</>
)}
</div>
</div>
)
}

View File

@ -15,6 +15,7 @@ import useToggle from 'hooks/useToggle'
import useStore from 'store'
import { calculateAccountBalance } from 'utils/accounts'
import { hardcodedFee } from 'utils/contants'
import { BN } from 'utils/helpers'
import useParams, { getRoute } from 'utils/route'
interface Props {
@ -41,7 +42,7 @@ export default function AccountList(props: Props) {
const selectedAccountDetails = props.accounts.find((account) => account.id === selectedAccount)
const selectedAccountBalance = selectedAccountDetails
? calculateAccountBalance(selectedAccountDetails, prices)
: 0
: BN(0)
async function deleteAccountHandler() {
if (!accountSelected) return
@ -107,7 +108,9 @@ export default function AccountList(props: Props) {
text='Fund'
color='tertiary'
leftIcon={<ArrowUpLine />}
onClick={() => props.setShowFundAccount(true)}
onClick={() => {
useStore.setState({ fundAndWithdrawModal: 'fund' })
}}
/>
<Button
className='w-full'
@ -115,9 +118,9 @@ export default function AccountList(props: Props) {
leftIcon={<ArrowDownLine />}
text='Withdraw'
onClick={() => {
useStore.setState({ withdrawModal: true })
useStore.setState({ fundAndWithdrawModal: 'withdraw' })
}}
disabled={positionBalance <= 0}
disabled={positionBalance.isLessThanOrEqualTo(0)}
/>
<Button
className='w-full'

View File

@ -2,7 +2,7 @@
import classNames from 'classnames'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import AccountList from 'components/Account/AccountList'
import CreateAccount from 'components/Account/CreateAccount'
@ -52,6 +52,10 @@ export default function AccountMenuContent(props: Props) {
router.push(`/wallets/${params.address}/accounts/${accountId}`)
}
useEffect(() => {
useStore.setState({ accounts: props.accounts })
}, [props.accounts])
if (!params.address) return null
return (

View File

@ -1,11 +1,12 @@
'use client'
import BigNumber from 'bignumber.js'
import AccountHealth from 'components/Account/AccountHealth'
import DisplayCurrency from 'components/DisplayCurrency'
import useStore from 'store'
import AccountHealth from './AccountHealth'
interface Props {
balance: number
balance: BigNumber
risk: number
health: number
}

View File

@ -1,18 +1,35 @@
'use client'
import Accordion from 'components/Accordion'
import AccountComposition from 'components/Account/AccountComposition'
import AccountHealth from 'components/Account/AccountHealth'
import Card from 'components/Card'
import DisplayCurrency from 'components/DisplayCurrency'
import { ArrowChartLineUp } from 'components/Icons'
import Text from 'components/Text'
import useParams from 'utils/route'
import useStore from 'store'
import { calculateAccountBalance } from 'utils/accounts'
import { BN } from 'utils/helpers'
export default function AccountSummary() {
const params = useParams()
interface Props {
account?: Account
change?: AccountChange
}
export default function AccountSummary(props: Props) {
const prices = useStore((s) => s.prices)
const baseCurrency = useStore((s) => s.baseCurrency)
const accountBalance = props.account ? calculateAccountBalance(props.account, prices) : BN(0)
if (!props.account) return null
return (
<div className='flex min-w-[320px] flex-col'>
<div className='flex basis-[345px] flex-wrap'>
<Card className='mb-4 min-w-fit bg-white/10' contentClassName='flex'>
<Item>
<Text size='sm'>$90,000</Text>
<DisplayCurrency
coin={{ amount: accountBalance.toString(), denom: baseCurrency.denom }}
className='text-sm'
/>
</Item>
<Item>
<span className='flex h-4 w-4 items-center'>
@ -26,8 +43,11 @@ export default function AccountSummary() {
</Card>
<Accordion
items={[
{ title: `Subaccount ${params.accountId} Composition`, content: <p>My content</p> },
{ title: 'Risk Score: 60/100', content: <p>My content</p> },
{
title: `Subaccount ${props.account.id} Composition`,
content: <AccountComposition account={props.account} change={props.change} />,
open: true,
},
{ title: 'Balances', content: <p>My content</p> },
]}
/>

View File

@ -1,7 +1,7 @@
'use client'
import { useCallback, useState } from 'react'
import BigNumber from 'bignumber.js'
import { useCallback, useState } from 'react'
import { Button } from 'components/Button'
import { ArrowRight, Cross } from 'components/Icons'
@ -11,6 +11,7 @@ import TokenInputWithSlider from 'components/TokenInputWithSlider'
import { ASSETS } from 'constants/assets'
import useToggle from 'hooks/useToggle'
import useStore from 'store'
import { getAmount } from 'utils/accounts'
import { hardcodedFee } from 'utils/contants'
import { BN } from 'utils/helpers'
import useParams from 'utils/route'
@ -23,12 +24,15 @@ interface Props {
export default function FundAccount(props: Props) {
const params = useParams()
const deposit = useStore((s) => s.deposit)
const balances = useStore((s) => s.balances)
const [amount, setAmount] = useState(BN(0))
const [asset, setAsset] = useState<Asset>(ASSETS[0])
const [isLending, setIsLending] = useToggle()
const [isFunding, setIsFunding] = useToggle()
const max = getAmount(asset.denom, balances ?? [])
const onChangeAmount = useCallback((amount: BigNumber) => {
setAmount(amount)
}, [])
@ -85,10 +89,11 @@ export default function FundAccount(props: Props) {
onChange={onChangeAmount}
onChangeAsset={onChangeAsset}
amount={amount}
max={BN(1).shiftedBy(ASSETS[0].decimals)}
max={max}
className='mb-4'
disabled={isFunding}
hasSelect
balances={balances}
/>
<div className='mb-4 w-full border-b border-white/10' />
<SwitchWithLabel

View File

@ -53,7 +53,7 @@ export default function Modal(props: Props) {
>
<Card
className={classNames(
'relative w-full max-w-full bg-white/5 backdrop-blur-3xl',
'relative flex max-w-full flex-grow bg-white/5 backdrop-blur-3xl',
props.className,
)}
>

View File

@ -11,6 +11,7 @@ import Text from 'components/Text'
import TitleAndSubCell from 'components/TitleAndSubCell'
import TokenInputWithSlider from 'components/TokenInputWithSlider'
import { ASSETS } from 'constants/assets'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useStore from 'store'
import { hardcodedFee } from 'utils/contants'
import { formatPercent, formatValue } from 'utils/formatters'
@ -29,6 +30,7 @@ function getAssetLogo(modal: BorrowModal | null) {
export default function BorrowModal() {
const params = useParams()
const currentAccount = useCurrentAccount()
const [percentage, setPercentage] = useState(0)
const [amount, setAmount] = useState(BN(0))
const [selectedAccount, setSelectedAccount] = useState(params.accountId)
@ -149,7 +151,7 @@ export default function BorrowModal() {
rightIcon={<ArrowRight />}
/>
</Card>
<AccountSummary />
<AccountSummary account={currentAccount} />
</div>
</Modal>
)

View File

@ -0,0 +1,140 @@
'use client'
import { useEffect, useState } from 'react'
import AccountSummary from 'components/Account/AccountSummary'
import { Button } from 'components/Button'
import Card from 'components/Card'
import Divider from 'components/Divider'
import { ArrowRight } from 'components/Icons'
import Modal from 'components/Modal'
import Text from 'components/Text'
import TokenInputWithSlider from 'components/TokenInputWithSlider'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useToggle from 'hooks/useToggle'
import useStore from 'store'
import { getAmount } from 'utils/accounts'
import { hardcodedFee } from 'utils/contants'
import { BN } from 'utils/helpers'
export default function FundAndWithdrawModal() {
const currentAccount = useCurrentAccount()
const modal = useStore((s) => s.fundAndWithdrawModal)
const baseCurrency = useStore((s) => s.baseCurrency)
const withdraw = useStore((s) => s.withdraw)
const deposit = useStore((s) => s.deposit)
const [amount, setAmount] = useState(BN(0))
const [currentAsset, setCurrentAsset] = useState(baseCurrency)
const [change, setChange] = useState<AccountChange | undefined>()
const [isConfirming, setIsConfirming] = useToggle()
const balances = useStore((s) => s.balances)
const isFunding = modal === 'fund'
function resetState() {
setCurrentAsset(baseCurrency)
setAmount(BN(0))
setChange(undefined)
}
function onClose() {
resetState()
useStore.setState({ fundAndWithdrawModal: null })
}
async function onConfirm() {
if (!currentAccount) return
setIsConfirming(true)
let result
if (isFunding) {
result = await deposit({
fee: hardcodedFee,
accountId: currentAccount.id,
coin: {
denom: currentAsset.denom,
amount: amount.toString(),
},
})
} else {
result = await withdraw({
fee: hardcodedFee,
accountId: currentAccount.id,
coin: {
denom: currentAsset.denom,
amount: amount.toString(),
},
})
}
setIsConfirming(false)
if (result) {
resetState()
useStore.setState({ fundAndWithdrawModal: null })
}
}
const max = isFunding
? getAmount(currentAsset.denom, balances ?? [])
: currentAccount
? getAmount(currentAsset.denom, currentAccount.deposits)
: BN(0)
useEffect(() => {
setChange({
deposits: [
{
amount: isFunding ? BN(0).plus(amount).toString() : BN(0).minus(amount).toString(),
denom: currentAsset.denom,
},
],
})
}, [amount, currentAsset, currentAccount, isFunding])
return (
<Modal
open={!!modal}
onClose={onClose}
header={
<span className='flex items-center gap-4 px-4'>
<Text>
{isFunding
? `Fund Account ${currentAccount?.id ?? '0'}`
: `Withdraw from Account ${currentAccount?.id ?? '0'}`}
</Text>
</span>
}
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
contentClassName='flex flex-col min-h-[400px]'
>
<div className='flex flex-grow items-start gap-6 p-6'>
<Card
className='flex flex-grow bg-white/5 p-4'
contentClassName='gap-6 flex flex-col justify-between h-full'
>
<TokenInputWithSlider
asset={currentAsset}
onChange={(val) => {
setAmount(val)
}}
onChangeAsset={(asset) => {
setCurrentAsset(asset)
}}
amount={amount}
max={max}
hasSelect
balances={isFunding ? balances : currentAccount?.deposits ?? []}
accountId={!isFunding ? currentAccount?.id ?? '0' : undefined}
/>
<Divider />
<Button
onClick={onConfirm}
showProgressIndicator={isConfirming}
className='w-full'
text={isFunding ? 'Fund' : 'Withdraw'}
rightIcon={<ArrowRight />}
/>
</Card>
<AccountSummary account={currentAccount} change={change} />
</div>
</Modal>
)
}

View File

@ -1,14 +1,14 @@
'use client'
import WithdrawModal from 'components/Modals//WithdrawModal'
import BorrowModal from 'components/Modals/BorrowModal'
import FundAndWithdrawModal from 'components/Modals/FundAndWithdrawModal'
import VaultModal from 'components/Modals/VaultModal'
export default function ModalsContainer() {
return (
<>
<BorrowModal />
<WithdrawModal />
<FundAndWithdrawModal />
<VaultModal />
</>
)

View File

@ -22,11 +22,11 @@ import { formatValue } from 'utils/formatters'
import { BN } from 'utils/helpers'
export default function VaultModal() {
const currentAccount = useCurrentAccount()
const modal = useStore((s) => s.vaultModal)
const [amount, setAmount] = useState(BN(0))
const [percentage, setPercentage] = useState(0)
const [isCustomAmount, setIsCustomAmount] = useState(false)
const currentAccount = useCurrentAccount()
function handleSwitch() {
setIsCustomAmount(() => !isCustomAmount)
@ -80,7 +80,7 @@ export default function VaultModal() {
</div>
<div className='flex flex-grow items-start gap-6 p-6'>
<Card
className='w-full bg-white/5 p-4'
className='flex flex-grow bg-white/5 p-4'
contentClassName='gap-6 flex flex-col justify-between h-full'
>
<TokenInput
@ -112,7 +112,7 @@ export default function VaultModal() {
rightIcon={<ArrowRight />}
/>
</Card>
<AccountSummary />
<AccountSummary account={currentAccount} />
</div>
</Modal>
)

View File

@ -1,96 +0,0 @@
import { useState } from 'react'
import AccountSummary from 'components/Account/AccountSummary'
import { Button } from 'components/Button'
import Card from 'components/Card'
import Divider from 'components/Divider'
import { ArrowRight } from 'components/Icons'
import Modal from 'components/Modal'
import Text from 'components/Text'
import TokenInputWithSlider from 'components/TokenInputWithSlider'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useToggle from 'hooks/useToggle'
import useStore from 'store'
import { getAmount } from 'utils/accounts'
import { hardcodedFee } from 'utils/contants'
import { BN } from 'utils/helpers'
export default function WithdrawModal() {
const currentAccount = useCurrentAccount()
const modal = useStore((s) => s.withdrawModal)
const baseCurrency = useStore((s) => s.baseCurrency)
const withdraw = useStore((s) => s.withdraw)
const [amount, setAmount] = useState(BN(0))
const [currentAsset, setCurrentAsset] = useState(baseCurrency)
const [isWithdrawing, setIsWithdrawing] = useToggle()
function onClose() {
useStore.setState({ withdrawModal: false })
setAmount(BN(0))
}
async function onWithdraw() {
if (!currentAccount) return
setIsWithdrawing(true)
const result = await withdraw({
fee: hardcodedFee,
accountId: currentAccount.id,
coin: {
denom: currentAsset.denom,
amount: amount.toString(),
},
})
setIsWithdrawing(false)
if (result) {
useStore.setState({ withdrawModal: false })
}
}
const maxWithdraw = currentAccount
? getAmount(currentAsset.denom, currentAccount.deposits)
: BN(0)
return (
<Modal
open={modal}
onClose={onClose}
header={
<span className='flex items-center gap-4 px-4'>
<Text>{`Withdraw from Account ${currentAccount?.id ?? '0'}`}</Text>
</span>
}
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
contentClassName='flex flex-col min-h-[400px]'
>
<div className='flex flex-grow items-start gap-6 p-6'>
<Card
className='w-full bg-white/5 p-4'
contentClassName='gap-6 flex flex-col justify-between h-full'
>
<TokenInputWithSlider
asset={currentAsset}
onChange={(val) => {
setAmount(val)
}}
onChangeAsset={(asset) => {
setCurrentAsset(asset)
}}
amount={amount}
max={maxWithdraw}
hasSelect
currentAccount={currentAccount}
/>
<Divider />
<Button
onClick={onWithdraw}
showProgressIndicator={isWithdrawing}
className='w-full'
text='Withdraw'
rightIcon={<ArrowRight />}
/>
</Card>
<AccountSummary />
</div>
</Modal>
)
}

View File

@ -31,7 +31,7 @@ async function Content(props: PageProps) {
{account.map((account: Account, index: number) => (
<Card
className='h-fit w-full bg-white/5'
title={`Account ${account}`}
title={`Account ${account.id}`}
key={index}
contentClassName='px-4 py-6'
>

View File

@ -1,3 +1,5 @@
'use client'
import classNames from 'classnames'
import { ChangeEvent, useRef, useState } from 'react'
import Draggable from 'react-draggable'

View File

@ -19,7 +19,8 @@ interface Props {
onChange: (amount: BigNumber) => void
className?: string
disabled?: boolean
currentAccount?: Account
balances?: Coin[] | null
accountId?: string
}
interface SingleProps extends Props {
@ -37,7 +38,6 @@ interface SelectProps extends Props {
}
export default function TokenInput(props: SingleProps | SelectProps) {
const balances = useStore((s) => s.balances)
const baseCurrency = useStore((s) => s.baseCurrency)
const [asset, setAsset] = useState<Asset>(props.asset ? props.asset : baseCurrency)
const [coin, setCoin] = useState<Coin>({
@ -45,26 +45,24 @@ export default function TokenInput(props: SingleProps | SelectProps) {
amount: '0',
})
const selectableBalances = props.currentAccount?.deposits ?? balances
const selectedAssetDenom = props.asset ? props.asset.denom : baseCurrency.denom
const updateAsset = useCallback(
(coinDenom: string) => {
const newAsset = ASSETS.find((asset) => asset.denom === coinDenom) ?? baseCurrency
const newCoin = selectableBalances?.find((coin) => coin.denom === coinDenom)
const newCoin = props.balances?.find((coin) => coin.denom === coinDenom)
setAsset(newAsset)
setCoin(newCoin ?? { denom: coinDenom, amount: '0' })
},
[selectableBalances, baseCurrency],
[props.balances, baseCurrency],
)
function setDefaultAsset() {
if (!selectableBalances || selectableBalances?.length === 0) return setAsset(baseCurrency)
if (selectableBalances.length === 1)
return setAsset(
ASSETS.find((asset) => asset.denom === selectableBalances[0].denom) ?? baseCurrency,
)
if (!props.balances || props.balances?.length === 0) return setAsset(baseCurrency)
if (props.balances.length === 1) {
const balances = props.balances ?? []
return setAsset(ASSETS.find((asset) => asset.denom === balances[0].denom) ?? baseCurrency)
}
return setAsset(ASSETS.find((asset) => asset.denom === selectedAssetDenom) ?? baseCurrency)
}
@ -91,12 +89,12 @@ export default function TokenInput(props: SingleProps | SelectProps) {
)}
>
<div className='relative isolate z-40 box-content flex h-11 w-full rounded-sm border border-white/20 bg-white/5'>
{props.hasSelect && selectableBalances ? (
{props.hasSelect && props.balances ? (
<Select
options={selectableBalances}
options={props.balances}
defaultValue={coin.denom}
onChange={(value) => updateAsset(value)}
title={props.currentAccount ? `Account ${props.currentAccount.id}` : 'Your Wallet'}
title={props.accountId ? `Account ${props.accountId}` : 'Your Wallet'}
className='border-r border-white/20 bg-white/5'
/>
) : (

View File

@ -1,5 +1,7 @@
'use client'
import BigNumber from 'bignumber.js'
import { useCallback, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import Slider from 'components/Slider'
import TokenInput from 'components/TokenInput'
@ -11,7 +13,8 @@ interface Props {
onChange: (amount: BigNumber) => void
className?: string
disabled?: boolean
currentAccount?: Account
balances?: Coin[] | null
accountId?: string
}
interface SingleProps extends Props {
@ -64,6 +67,15 @@ export default function TokenInputWithSlider(props: SingleProps | SelectProps) {
[props],
)
useEffect(() => {
if (props.max?.isEqualTo(max)) return
setMax(props.max ?? BN(0))
setPercentage(0)
setAmount(BN(0))
setAsset(props.asset ?? ASSETS[0])
}, [props.max, props.asset, max])
return (
<div className={props.className}>
<TokenInput
@ -75,7 +87,8 @@ export default function TokenInputWithSlider(props: SingleProps | SelectProps) {
className='mb-4'
disabled={props.disabled}
hasSelect={props.hasSelect}
currentAccount={props.currentAccount}
balances={props.balances}
accountId={props.accountId}
/>
<Slider
value={percentage}

View File

@ -6,7 +6,7 @@ export default function createModalSlice(set: SetState<ModalSlice>, get: GetStat
createAccountModal: false,
deleteAccountModal: false,
fundAccountModal: false,
withdrawModal: false,
fundAndWithdrawModal: null,
vaultModal: null,
}
}

View File

@ -5,3 +5,10 @@ interface Account {
lends: Coin[]
vaults: import('types/generated/mars-mock-credit-manager/MarsMockCreditManager.types').ArrayOfVaultInfoResponse
}
interface AccountChange {
deposits?: Coin[]
debts?: Coin[]
lends?: Coin[]
vaults?: import('types/generated/mars-mock-credit-manager/MarsMockCreditManager.types').ArrayOfVaultInfoResponse
}

View File

@ -3,7 +3,7 @@ interface ModalSlice {
createAccountModal: boolean
deleteAccountModal: boolean
fundAccountModal: boolean
withdrawModal: boolean
fundAndWithdrawModal: 'fund' | 'withdraw' | null
vaultModal: {
vault: Vault
} | null

View File

@ -1,21 +1,61 @@
import BigNumber from 'bignumber.js'
import { BN } from 'utils/helpers'
export const calculateAccountBalance = (account: Account, prices: Coin[]) => {
const totalDepositValue = account.deposits.reduce((acc, deposit) => {
export const calculateAccountBalance = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
const totalDepositValue = calculateAccountDeposits(account, prices)
const totalDebtValue = calculateAccountDebt(account, prices)
return totalDepositValue.minus(totalDebtValue)
}
export const calculateAccountDeposits = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
if (!account.deposits) return BN(0)
return account.deposits.reduce((acc, deposit) => {
const price = prices.find((price) => price.denom === deposit.denom)?.amount ?? 0
const depositValue = BN(deposit.amount).multipliedBy(price)
return acc.plus(depositValue)
}, BN(0))
const totalDebtValue = account.debts.reduce((acc, debt) => {
}
export const calculateAccountDebt = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
if (!account.debts) return BN(0)
return account.debts.reduce((acc, debt) => {
const price = prices.find((price) => price.denom === debt.denom)?.amount ?? 0
const debtValue = BN(debt.amount).multipliedBy(price)
return acc.plus(debtValue)
}, BN(0))
return totalDepositValue.minus(totalDebtValue).toNumber()
}
export function getAmount(denom: string, coins: Coin[]) {
export const calculateAccountPnL = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
return BN(0)
}
export const calculateAccountApr = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
return BN(0)
}
export const calculateAccountBorrowRate = (
account: Account | AccountChange,
prices: Coin[],
): BigNumber => {
return BN(0)
}
export function getAmount(denom: string, coins: Coin[]): BigNumber {
return BN(coins.find((asset) => asset.denom === denom)?.amount ?? 0)
}

View File

@ -2,8 +2,7 @@ import { usePathname } from 'next/navigation'
export default function useParams() {
const pathname = usePathname()
return getParamsFromUrl(pathname || '')
return getParamsFromUrl(pathname ?? '')
}
export function getRouteParams(url: string | null): PageParams {