MP-2803: created fund already funded account flow (#350)
This commit is contained in:
parent
d43437e440
commit
f4fc2dcfcc
@ -5,13 +5,12 @@ import Button from 'components/Button'
|
|||||||
import Card from 'components/Card'
|
import Card from 'components/Card'
|
||||||
import FullOverlayContent from 'components/FullOverlayContent'
|
import FullOverlayContent from 'components/FullOverlayContent'
|
||||||
import { Plus } from 'components/Icons'
|
import { Plus } from 'components/Icons'
|
||||||
import SwitchWithLabel from 'components/SwitchWithLabel'
|
import SwitchAutoLend from 'components/Switch/SwitchAutoLend'
|
||||||
import Text from 'components/Text'
|
import Text from 'components/Text'
|
||||||
import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
|
import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
|
||||||
import WalletBridges from 'components/Wallet/WalletBridges'
|
import WalletBridges from 'components/Wallet/WalletBridges'
|
||||||
import { BN_ZERO } from 'constants/math'
|
import { BN_ZERO } from 'constants/math'
|
||||||
import useAccounts from 'hooks/useAccounts'
|
import useAccounts from 'hooks/useAccounts'
|
||||||
import useAutoLendEnabledAccountIds from 'hooks/useAutoLendEnabledAccountIds'
|
|
||||||
import useCurrentAccount from 'hooks/useCurrentAccount'
|
import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||||
import useToggle from 'hooks/useToggle'
|
import useToggle from 'hooks/useToggle'
|
||||||
import useWalletBalances from 'hooks/useWalletBalances'
|
import useWalletBalances from 'hooks/useWalletBalances'
|
||||||
@ -34,8 +33,6 @@ export default function AccountFund() {
|
|||||||
const [fundingAssets, setFundingAssets] = useState<BNCoin[]>([])
|
const [fundingAssets, setFundingAssets] = useState<BNCoin[]>([])
|
||||||
const { data: walletBalances } = useWalletBalances(address)
|
const { data: walletBalances } = useWalletBalances(address)
|
||||||
const baseAsset = getBaseAsset()
|
const baseAsset = getBaseAsset()
|
||||||
const { autoLendEnabledAccountIds, toggleAutoLend } = useAutoLendEnabledAccountIds()
|
|
||||||
const isAutoLendEnabled = autoLendEnabledAccountIds.includes(accountId ?? '0')
|
|
||||||
const hasAssetSelected = fundingAssets.length > 0
|
const hasAssetSelected = fundingAssets.length > 0
|
||||||
const hasFundingAssets =
|
const hasFundingAssets =
|
||||||
fundingAssets.length > 0 && fundingAssets.every((a) => a.toCoin().amount !== '0')
|
fundingAssets.length > 0 && fundingAssets.every((a) => a.toCoin().amount !== '0')
|
||||||
@ -88,7 +85,7 @@ export default function AccountFund() {
|
|||||||
|
|
||||||
const updateFundingAssets = useCallback(
|
const updateFundingAssets = useCallback(
|
||||||
(amount: BigNumber, denom: string) => {
|
(amount: BigNumber, denom: string) => {
|
||||||
const assetToUpdate = fundingAssets.find((asset) => asset.denom === denom)
|
const assetToUpdate = fundingAssets.find(byDenom(denom))
|
||||||
if (assetToUpdate) {
|
if (assetToUpdate) {
|
||||||
assetToUpdate.amount = amount
|
assetToUpdate.amount = amount
|
||||||
setFundingAssets([...fundingAssets.filter((a) => a.denom !== denom), assetToUpdate])
|
setFundingAssets([...fundingAssets.filter((a) => a.denom !== denom), assetToUpdate])
|
||||||
@ -116,21 +113,21 @@ export default function AccountFund() {
|
|||||||
copy='In order to start trading with this account, you need to deposit funds.'
|
copy='In order to start trading with this account, you need to deposit funds.'
|
||||||
docs='fund'
|
docs='fund'
|
||||||
>
|
>
|
||||||
<Card className='w-full bg-white/5 p-6'>
|
<Card className='w-full p-6 bg-white/5'>
|
||||||
{!hasAssetSelected && <Text>Please select an asset.</Text>}
|
{!hasAssetSelected && <Text>Please select an asset.</Text>}
|
||||||
{selectedDenoms.map((denom) => {
|
{fundingAssets.map((coin) => {
|
||||||
const asset = getAssetByDenom(denom) as Asset
|
const asset = getAssetByDenom(coin.denom) as Asset
|
||||||
|
|
||||||
const balance = walletBalances.find(byDenom(asset.denom))?.amount ?? '0'
|
const balance = walletBalances.find(byDenom(coin.denom))?.amount ?? '0'
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={asset.symbol}
|
key={asset.symbol}
|
||||||
className='w-full rounded-base border border-white/20 bg-white/5 p-4'
|
className='w-full p-4 border rounded-base border-white/20 bg-white/5'
|
||||||
>
|
>
|
||||||
<TokenInputWithSlider
|
<TokenInputWithSlider
|
||||||
asset={asset}
|
asset={asset}
|
||||||
onChange={(amount) => updateFundingAssets(amount, asset.denom)}
|
onChange={(amount) => updateFundingAssets(amount, asset.denom)}
|
||||||
amount={BN_ZERO}
|
amount={coin.amount ?? BN_ZERO}
|
||||||
max={BN(balance)}
|
max={BN(balance)}
|
||||||
balances={walletBalances}
|
balances={walletBalances}
|
||||||
maxText='Max'
|
maxText='Max'
|
||||||
@ -140,24 +137,19 @@ export default function AccountFund() {
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className='mt-4 w-full'
|
className='w-full mt-4'
|
||||||
text='Select assets'
|
text='Select assets'
|
||||||
color='tertiary'
|
color='tertiary'
|
||||||
rightIcon={<Plus />}
|
rightIcon={<Plus />}
|
||||||
iconClassName='w-3'
|
iconClassName='w-3'
|
||||||
onClick={handleSelectAssetsClick}
|
onClick={handleSelectAssetsClick}
|
||||||
/>
|
/>
|
||||||
<div className='mt-4 border border-transparent border-t-white/10 pt-4'>
|
<SwitchAutoLend
|
||||||
<SwitchWithLabel
|
className='pt-4 mt-4 border border-transparent border-t-white/10'
|
||||||
name='isLending'
|
accountId={selectedAccountId}
|
||||||
label='Lend assets to earn yield'
|
|
||||||
value={isAutoLendEnabled}
|
|
||||||
onChange={() => toggleAutoLend(selectedAccountId)}
|
|
||||||
tooltip={`Fund your account and lend assets effortlessly! By lending, you'll earn attractive interest (APY) without impacting your LTV. It's a win-win situation - don't miss out on this easy opportunity to grow your holdings!`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<Button
|
<Button
|
||||||
className='mt-4 w-full'
|
className='w-full mt-4'
|
||||||
text='Fund account'
|
text='Fund account'
|
||||||
color='tertiary'
|
color='tertiary'
|
||||||
disabled={!hasFundingAssets}
|
disabled={!hasFundingAssets}
|
||||||
|
@ -8,9 +8,8 @@ import Button from 'components/Button'
|
|||||||
import Card from 'components/Card'
|
import Card from 'components/Card'
|
||||||
import { ArrowCircledTopRight, ArrowDownLine, ArrowUpLine, TrashBin } from 'components/Icons'
|
import { ArrowCircledTopRight, ArrowDownLine, ArrowUpLine, TrashBin } from 'components/Icons'
|
||||||
import Radio from 'components/Radio'
|
import Radio from 'components/Radio'
|
||||||
import SwitchWithLabel from 'components/SwitchWithLabel'
|
import SwitchAutoLend from 'components/Switch/SwitchAutoLend'
|
||||||
import Text from 'components/Text'
|
import Text from 'components/Text'
|
||||||
import useAutoLendEnabledAccountIds from 'hooks/useAutoLendEnabledAccountIds'
|
|
||||||
import useCurrentAccount from 'hooks/useCurrentAccount'
|
import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||||
import usePrices from 'hooks/usePrices'
|
import usePrices from 'hooks/usePrices'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
@ -32,7 +31,6 @@ export default function AccountList(props: Props) {
|
|||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const { address } = useParams()
|
const { address } = useParams()
|
||||||
const { data: prices } = usePrices()
|
const { data: prices } = usePrices()
|
||||||
const { autoLendEnabledAccountIds, toggleAutoLend } = useAutoLendEnabledAccountIds()
|
|
||||||
const account = useCurrentAccount()
|
const account = useCurrentAccount()
|
||||||
const accountId = account?.id
|
const accountId = account?.id
|
||||||
|
|
||||||
@ -52,11 +50,10 @@ export default function AccountList(props: Props) {
|
|||||||
if (!props.accounts?.length) return null
|
if (!props.accounts?.length) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex w-full flex-wrap p-4'>
|
<div className='flex flex-wrap w-full p-4'>
|
||||||
{props.accounts.map((account) => {
|
{props.accounts.map((account) => {
|
||||||
const positionBalance = calculateAccountValue('deposits', account, prices)
|
const positionBalance = calculateAccountValue('deposits', account, prices)
|
||||||
const isActive = accountId === account.id
|
const isActive = accountId === account.id
|
||||||
const isAutoLendEnabled = autoLendEnabledAccountIds.includes(account.id)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={account.id} id={`account-${account.id}`} className='w-full pt-4'>
|
<div key={account.id} id={`account-${account.id}`} className='w-full pt-4'>
|
||||||
@ -81,7 +78,7 @@ export default function AccountList(props: Props) {
|
|||||||
>
|
>
|
||||||
{isActive ? (
|
{isActive ? (
|
||||||
<>
|
<>
|
||||||
<div className='w-full border border-transparent border-b-white/20 p-4'>
|
<div className='w-full p-4 border border-transparent border-b-white/20'>
|
||||||
<AccountStats account={account} />
|
<AccountStats account={account} />
|
||||||
</div>
|
</div>
|
||||||
<div className='grid grid-flow-row grid-cols-2 gap-4 p-4'>
|
<div className='grid grid-flow-row grid-cols-2 gap-4 p-4'>
|
||||||
@ -122,16 +119,11 @@ export default function AccountList(props: Props) {
|
|||||||
text='Transfer'
|
text='Transfer'
|
||||||
onClick={() => {}}
|
onClick={() => {}}
|
||||||
/>
|
/>
|
||||||
<div className='col-span-2 border border-transparent border-t-white/10 pt-4'>
|
<SwitchAutoLend
|
||||||
<SwitchWithLabel
|
className='col-span-2 pt-4 border border-transparent border-t-white/10'
|
||||||
name='isLending'
|
accountId={account.id}
|
||||||
label='Lend assets to earn yield'
|
|
||||||
value={isAutoLendEnabled}
|
|
||||||
onChange={() => toggleAutoLend(account.id)}
|
|
||||||
tooltip={`Fund your account and lend assets effortlessly! By lending, you'll earn attractive interest (APY) without impacting your LTV. It's a win-win situation - don't miss out on this easy opportunity to grow your holdings!`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className='w-full p-4'>
|
<div className='w-full p-4'>
|
||||||
|
@ -4,16 +4,17 @@ import AccountComposition from 'components/Account/AccountComposition'
|
|||||||
import AccountHealth from 'components/Account/AccountHealth'
|
import AccountHealth from 'components/Account/AccountHealth'
|
||||||
import Card from 'components/Card'
|
import Card from 'components/Card'
|
||||||
import DisplayCurrency from 'components/DisplayCurrency'
|
import DisplayCurrency from 'components/DisplayCurrency'
|
||||||
import { ArrowChartLineUp } from 'components/Icons'
|
|
||||||
import Text from 'components/Text'
|
|
||||||
import { BN_ZERO } from 'constants/math'
|
import { BN_ZERO } from 'constants/math'
|
||||||
import { ORACLE_DENOM } from 'constants/oracle'
|
import { ORACLE_DENOM } from 'constants/oracle'
|
||||||
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
|
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
|
||||||
|
import useHealthComputer from 'hooks/useHealthComputer'
|
||||||
import useIsOpenArray from 'hooks/useIsOpenArray'
|
import useIsOpenArray from 'hooks/useIsOpenArray'
|
||||||
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
|
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
|
||||||
import usePrices from 'hooks/usePrices'
|
import usePrices from 'hooks/usePrices'
|
||||||
import { BNCoin } from 'types/classes/BNCoin'
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
import { calculateAccountValue } from 'utils/accounts'
|
import { calculateAccountValue } from 'utils/accounts'
|
||||||
|
import { formatHealth } from 'utils/formatters'
|
||||||
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
account?: Account
|
account?: Account
|
||||||
@ -32,6 +33,9 @@ export default function AccountSummary(props: Props) {
|
|||||||
useLendingMarketAssetsTableData()
|
useLendingMarketAssetsTableData()
|
||||||
const borrowAssetsData = [...borrowAvailableAssets, ...accountBorrowedAssets]
|
const borrowAssetsData = [...borrowAvailableAssets, ...accountBorrowedAssets]
|
||||||
const lendingAssetsData = [...lendingAvailableAssets, ...accountLentAssets]
|
const lendingAssetsData = [...lendingAvailableAssets, ...accountLentAssets]
|
||||||
|
|
||||||
|
const { health } = useHealthComputer(props.account)
|
||||||
|
const healthFactor = BN(100).minus(formatHealth(health)).toNumber()
|
||||||
if (!props.account) return null
|
if (!props.account) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -44,13 +48,7 @@ export default function AccountSummary(props: Props) {
|
|||||||
/>
|
/>
|
||||||
</Item>
|
</Item>
|
||||||
<Item>
|
<Item>
|
||||||
<span className='flex h-4 w-4 items-center'>
|
<AccountHealth health={healthFactor} />
|
||||||
<ArrowChartLineUp />
|
|
||||||
</span>
|
|
||||||
<Text size='sm'>4.5x</Text>
|
|
||||||
</Item>
|
|
||||||
<Item>
|
|
||||||
<AccountHealth health={80} />
|
|
||||||
</Item>
|
</Item>
|
||||||
</Card>
|
</Card>
|
||||||
<Accordion
|
<Accordion
|
||||||
@ -89,7 +87,7 @@ export default function AccountSummary(props: Props) {
|
|||||||
function Item(props: React.HTMLAttributes<HTMLDivElement>) {
|
function Item(props: React.HTMLAttributes<HTMLDivElement>) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='flex flex-1 items-center justify-center gap-1 border-r border-r-white/10 px-2 py-2'
|
className='flex items-center justify-center flex-1 gap-1 px-2 py-2 border-r border-r-white/10'
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
@ -24,12 +24,15 @@ interface Props {
|
|||||||
export default function AssetSelectTable(props: Props) {
|
export default function AssetSelectTable(props: Props) {
|
||||||
const defaultSelected = useMemo(() => {
|
const defaultSelected = useMemo(() => {
|
||||||
const assets = props.assets as BorrowAsset[]
|
const assets = props.assets as BorrowAsset[]
|
||||||
return assets.reduce((acc, asset, index) => {
|
return assets.reduce(
|
||||||
|
(acc, asset, index) => {
|
||||||
if (props.selectedDenoms?.includes(asset.denom)) {
|
if (props.selectedDenoms?.includes(asset.denom)) {
|
||||||
acc[index] = true
|
acc[index] = true
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
}, {} as { [key: number]: boolean })
|
},
|
||||||
|
{} as { [key: number]: boolean },
|
||||||
|
)
|
||||||
}, [props.selectedDenoms, props.assets])
|
}, [props.selectedDenoms, props.assets])
|
||||||
const [sorting, setSorting] = useState<SortingState>([{ id: 'symbol', desc: false }])
|
const [sorting, setSorting] = useState<SortingState>([{ id: 'symbol', desc: false }])
|
||||||
const [selected, setSelected] = useState<RowSelectionState>(defaultSelected)
|
const [selected, setSelected] = useState<RowSelectionState>(defaultSelected)
|
||||||
|
@ -154,7 +154,7 @@ function BorrowModal(props: Props) {
|
|||||||
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
|
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
|
||||||
contentClassName='flex flex-col'
|
contentClassName='flex flex-col'
|
||||||
>
|
>
|
||||||
<div className='flex gap-3 border-b border-white/5 px-6 py-4 gradient-header'>
|
<div className='flex gap-3 px-6 py-4 border-b border-white/5 gradient-header'>
|
||||||
<TitleAndSubCell
|
<TitleAndSubCell
|
||||||
title={formatPercent(modal?.marketData.borrowRate || '0')}
|
title={formatPercent(modal?.marketData.borrowRate || '0')}
|
||||||
sub={'Borrow rate'}
|
sub={'Borrow rate'}
|
||||||
@ -173,12 +173,12 @@ function BorrowModal(props: Props) {
|
|||||||
sub={'Liquidity available'}
|
sub={'Liquidity available'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-1 items-start gap-6 p-6'>
|
<div className='flex items-start flex-1 gap-6 p-6'>
|
||||||
<Card
|
<Card
|
||||||
className='flex flex-1 bg-white/5 p-4'
|
className='flex flex-1 p-4 bg-white/5'
|
||||||
contentClassName='gap-6 flex flex-col justify-between h-full min-h-[380px]'
|
contentClassName='gap-6 flex flex-col justify-between h-full min-h-[380px]'
|
||||||
>
|
>
|
||||||
<div className='flex w-full flex-wrap'>
|
<div className='flex flex-wrap w-full'>
|
||||||
<TokenInputWithSlider
|
<TokenInputWithSlider
|
||||||
asset={asset}
|
asset={asset}
|
||||||
onChange={setAmount}
|
onChange={setAmount}
|
||||||
@ -189,8 +189,8 @@ function BorrowModal(props: Props) {
|
|||||||
disabled={isConfirming}
|
disabled={isConfirming}
|
||||||
/>
|
/>
|
||||||
<Divider className='my-6' />
|
<Divider className='my-6' />
|
||||||
<div className='flex flex-1 flex-wrap'>
|
<div className='flex flex-wrap flex-1'>
|
||||||
<Text className='mb-1 w-full'>Receive funds to Wallet</Text>
|
<Text className='w-full mb-1'>Receive funds to Wallet</Text>
|
||||||
<Text size='xs' className='text-white/50'>
|
<Text size='xs' className='text-white/50'>
|
||||||
Your borrowed funds will directly go to your wallet
|
Your borrowed funds will directly go to your wallet
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
import BigNumber from 'bignumber.js'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
import Button from 'components/Button'
|
import Button from 'components/Button'
|
||||||
import { ArrowRight } from 'components/Icons'
|
import { ArrowRight, Plus } from 'components/Icons'
|
||||||
|
import SwitchAutoLend from 'components/Switch/SwitchAutoLend'
|
||||||
|
import Text from 'components/Text'
|
||||||
import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
|
import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
|
||||||
import { ASSETS } from 'constants/assets'
|
import WalletBridges from 'components/Wallet/WalletBridges'
|
||||||
import { BN_ZERO } from 'constants/math'
|
import { BN_ZERO } from 'constants/math'
|
||||||
import useToggle from 'hooks/useToggle'
|
import useToggle from 'hooks/useToggle'
|
||||||
|
import useWalletBalances from 'hooks/useWalletBalances'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { BNCoin } from 'types/classes/BNCoin'
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
import { getAmount } from 'utils/accounts'
|
|
||||||
import { byDenom } from 'utils/array'
|
import { byDenom } from 'utils/array'
|
||||||
|
import { getAssetByDenom, getBaseAsset } from 'utils/assets'
|
||||||
import { hardcodedFee } from 'utils/constants'
|
import { hardcodedFee } from 'utils/constants'
|
||||||
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
account: Account
|
account: Account
|
||||||
@ -20,68 +23,123 @@ interface Props {
|
|||||||
|
|
||||||
export default function FundAccount(props: Props) {
|
export default function FundAccount(props: Props) {
|
||||||
const { account, setChange } = props
|
const { account, setChange } = props
|
||||||
|
const accountId = account.id
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
const deposit = useStore((s) => s.deposit)
|
const deposit = useStore((s) => s.deposit)
|
||||||
const balances = useStore((s) => s.balances)
|
const walletAssetModal = useStore((s) => s.walletAssetsModal)
|
||||||
const defaultAsset = ASSETS.find(byDenom(balances[0].denom)) ?? ASSETS[0]
|
const [isFunding, setIsFunding] = useToggle(false)
|
||||||
const [isConfirming, setIsConfirming] = useToggle()
|
const [fundingAssets, setFundingAssets] = useState<BNCoin[]>([])
|
||||||
const [currentAsset, setCurrentAsset] = useState(defaultAsset)
|
const { data: walletBalances } = useWalletBalances(address)
|
||||||
const [amount, setAmount] = useState(BN_ZERO)
|
const baseAsset = getBaseAsset()
|
||||||
const depositAmount = BN_ZERO.plus(amount)
|
const hasAssetSelected = fundingAssets.length > 0
|
||||||
const max = getAmount(currentAsset.denom, balances ?? [])
|
const hasFundingAssets =
|
||||||
|
fundingAssets.length > 0 && fundingAssets.every((a) => a.toCoin().amount !== '0')
|
||||||
|
|
||||||
function onChangeAmount(val: BigNumber) {
|
const baseBalance = useMemo(
|
||||||
setAmount(val)
|
() => walletBalances.find(byDenom(baseAsset.denom))?.amount ?? '0',
|
||||||
setChange({
|
[walletBalances, baseAsset],
|
||||||
deposits: [
|
)
|
||||||
{
|
|
||||||
amount: depositAmount.toString(),
|
|
||||||
denom: currentAsset.denom,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetState() {
|
const selectedDenoms = useMemo(() => {
|
||||||
setCurrentAsset(defaultAsset)
|
return walletAssetModal?.selectedDenoms ?? []
|
||||||
setAmount(BN_ZERO)
|
}, [walletAssetModal?.selectedDenoms])
|
||||||
setChange(undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onConfirm() {
|
const handleClick = useCallback(async () => {
|
||||||
setIsConfirming(true)
|
setIsFunding(true)
|
||||||
|
if (!accountId) return
|
||||||
const result = await deposit({
|
const result = await deposit({
|
||||||
fee: hardcodedFee,
|
fee: hardcodedFee,
|
||||||
accountId: account.id,
|
accountId,
|
||||||
coins: [BNCoin.fromDenomAndBigNumber(currentAsset.denom, amount)],
|
coins: fundingAssets,
|
||||||
})
|
})
|
||||||
|
setIsFunding(false)
|
||||||
|
if (result) useStore.setState({ focusComponent: null, walletAssetsModal: null })
|
||||||
|
}, [fundingAssets, accountId, setIsFunding, deposit])
|
||||||
|
|
||||||
setIsConfirming(false)
|
const handleSelectAssetsClick = useCallback(() => {
|
||||||
if (result) {
|
useStore.setState({
|
||||||
resetState()
|
walletAssetsModal: {
|
||||||
useStore.setState({ fundAndWithdrawModal: null })
|
isOpen: true,
|
||||||
|
selectedDenoms,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [selectedDenoms])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const currentSelectedDenom = fundingAssets.map((asset) => asset.denom)
|
||||||
|
|
||||||
|
if (
|
||||||
|
selectedDenoms.every((denom) => currentSelectedDenom.includes(denom)) &&
|
||||||
|
selectedDenoms.length === currentSelectedDenom.length
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
const newFundingAssets = selectedDenoms.map((denom) =>
|
||||||
|
BNCoin.fromDenomAndBigNumber(denom, BN(fundingAssets.find(byDenom(denom))?.amount ?? '0')),
|
||||||
|
)
|
||||||
|
|
||||||
|
setFundingAssets(newFundingAssets)
|
||||||
|
}, [selectedDenoms, fundingAssets])
|
||||||
|
|
||||||
|
const updateFundingAssets = useCallback(
|
||||||
|
(amount: BigNumber, denom: string) => {
|
||||||
|
const assetToUpdate = fundingAssets.find(byDenom(denom))
|
||||||
|
if (assetToUpdate) {
|
||||||
|
assetToUpdate.amount = amount
|
||||||
|
setFundingAssets([...fundingAssets.filter((a) => a.denom !== denom), assetToUpdate])
|
||||||
}
|
}
|
||||||
|
setChange({ deposits: fundingAssets })
|
||||||
|
},
|
||||||
|
[fundingAssets, setChange],
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (BN(baseBalance).isLessThan(hardcodedFee.amount[0].amount)) {
|
||||||
|
useStore.setState({ focusComponent: <WalletBridges /> })
|
||||||
}
|
}
|
||||||
|
}, [baseBalance])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div className='flex flex-wrap items-start'>
|
||||||
|
{!hasAssetSelected && <Text>Please select an asset.</Text>}
|
||||||
|
{fundingAssets.map((coin) => {
|
||||||
|
const asset = getAssetByDenom(coin.denom) as Asset
|
||||||
|
|
||||||
|
const balance = walletBalances.find(byDenom(coin.denom))?.amount ?? '0'
|
||||||
|
return (
|
||||||
<TokenInputWithSlider
|
<TokenInputWithSlider
|
||||||
asset={currentAsset}
|
key={coin.denom}
|
||||||
onChange={onChangeAmount}
|
asset={asset}
|
||||||
onChangeAsset={setCurrentAsset}
|
onChange={(amount) => updateFundingAssets(amount, asset.denom)}
|
||||||
amount={amount}
|
amount={coin.amount ?? BN_ZERO}
|
||||||
max={max}
|
max={BN(balance)}
|
||||||
className='w-full'
|
balances={walletBalances}
|
||||||
balances={balances}
|
|
||||||
hasSelect
|
|
||||||
maxText='Max'
|
maxText='Max'
|
||||||
disabled={isConfirming}
|
className='w-full mb-4'
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
<Button
|
<Button
|
||||||
onClick={onConfirm}
|
className='w-full mt-4'
|
||||||
showProgressIndicator={isConfirming}
|
text='Select assets'
|
||||||
className='w-full'
|
color='tertiary'
|
||||||
text={'Fund'}
|
rightIcon={<Plus />}
|
||||||
|
iconClassName='w-3'
|
||||||
|
onClick={handleSelectAssetsClick}
|
||||||
|
/>
|
||||||
|
<SwitchAutoLend
|
||||||
|
className='pt-4 mt-4 border border-transparent border-t-white/10'
|
||||||
|
accountId={accountId}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
className='w-full mt-4'
|
||||||
|
text='Fund account'
|
||||||
rightIcon={<ArrowRight />}
|
rightIcon={<ArrowRight />}
|
||||||
|
disabled={!hasFundingAssets}
|
||||||
|
showProgressIndicator={isFunding}
|
||||||
|
onClick={handleClick}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -9,14 +9,15 @@ import Slider from 'components/Slider'
|
|||||||
import Text from 'components/Text'
|
import Text from 'components/Text'
|
||||||
import TokenInput from 'components/TokenInput'
|
import TokenInput from 'components/TokenInput'
|
||||||
import { BN_ZERO } from 'constants/math'
|
import { BN_ZERO } from 'constants/math'
|
||||||
|
import useHealthComputer from 'hooks/useHealthComputer'
|
||||||
import useMarketAssets from 'hooks/useMarketAssets'
|
import useMarketAssets from 'hooks/useMarketAssets'
|
||||||
import usePrices from 'hooks/usePrices'
|
import usePrices from 'hooks/usePrices'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { BNCoin } from 'types/classes/BNCoin'
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
import { Action } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
import { Action } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
|
import { byDenom } from 'utils/array'
|
||||||
import { findCoinByDenom, getAssetByDenom } from 'utils/assets'
|
import { findCoinByDenom, getAssetByDenom } from 'utils/assets'
|
||||||
import { formatPercent } from 'utils/formatters'
|
import { formatPercent } from 'utils/formatters'
|
||||||
import useHealthComputer from 'hooks/useHealthComputer'
|
|
||||||
|
|
||||||
export interface VaultBorrowingsProps {
|
export interface VaultBorrowingsProps {
|
||||||
updatedAccount: Account
|
updatedAccount: Account
|
||||||
@ -154,12 +155,10 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-1 flex-col gap-4 p-4'>
|
<div className='flex flex-col flex-1 gap-4 p-4'>
|
||||||
{props.borrowings.map((coin) => {
|
{props.borrowings.map((coin) => {
|
||||||
const asset = getAssetByDenom(coin.denom)
|
const asset = getAssetByDenom(coin.denom)
|
||||||
const maxAmount = maxBorrowAmounts.find(
|
const maxAmount = maxBorrowAmounts.find(byDenom(coin.denom))?.amount
|
||||||
(maxAmount) => maxAmount.denom === coin.denom,
|
|
||||||
)?.amount
|
|
||||||
if (!asset || !maxAmount)
|
if (!asset || !maxAmount)
|
||||||
return <React.Fragment key={`input-${coin.denom}`}></React.Fragment>
|
return <React.Fragment key={`input-${coin.denom}`}></React.Fragment>
|
||||||
return (
|
return (
|
||||||
|
@ -10,13 +10,13 @@ import Slider from 'components/Slider'
|
|||||||
import Switch from 'components/Switch'
|
import Switch from 'components/Switch'
|
||||||
import Text from 'components/Text'
|
import Text from 'components/Text'
|
||||||
import TokenInput from 'components/TokenInput'
|
import TokenInput from 'components/TokenInput'
|
||||||
|
import { BN_ZERO } from 'constants/math'
|
||||||
import usePrice from 'hooks/usePrice'
|
import usePrice from 'hooks/usePrice'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { BNCoin } from 'types/classes/BNCoin'
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
import { getAmount } from 'utils/accounts'
|
import { getAmount } from 'utils/accounts'
|
||||||
import { BN } from 'utils/helpers'
|
|
||||||
import { findCoinByDenom } from 'utils/assets'
|
import { findCoinByDenom } from 'utils/assets'
|
||||||
import { BN_ZERO } from 'constants/math'
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
deposits: BNCoin[]
|
deposits: BNCoin[]
|
||||||
|
@ -34,9 +34,9 @@ export default function WalletAssetsModalContent(props: Props) {
|
|||||||
)
|
)
|
||||||
}, [assets, searchString])
|
}, [assets, searchString])
|
||||||
|
|
||||||
const currentSelectedDenom = useStore((s) => s.walletAssetsModal?.selectedDenoms)
|
const currentSelectedDenom = useStore((s) => s.walletAssetsModal?.selectedDenoms ?? [])
|
||||||
const [selectedDenoms, setSelectedDenoms] = useState<string[]>(
|
const [selectedDenoms, setSelectedDenoms] = useState<string[]>(
|
||||||
currentSelectedDenom?.filter((denom) => filteredAssets.findIndex(byDenom(denom))) || [],
|
currentSelectedDenom.filter((denom) => filteredAssets.findIndex(byDenom(denom)) || []),
|
||||||
)
|
)
|
||||||
|
|
||||||
const onChangeSelect = useCallback(
|
const onChangeSelect = useCallback(
|
||||||
@ -49,7 +49,7 @@ export default function WalletAssetsModalContent(props: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='border-b border-white/5 bg-white/10 px-4 py-3'>
|
<div className='px-4 py-3 border-b border-white/5 bg-white/10'>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
value={searchString}
|
value={searchString}
|
||||||
placeholder={`Search for e.g. "ETH" or "Ethereum"`}
|
placeholder={`Search for e.g. "ETH" or "Ethereum"`}
|
||||||
|
27
src/components/Switch/SwitchAutoLend.tsx
Normal file
27
src/components/Switch/SwitchAutoLend.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
import SwitchWithLabel from 'components/Switch/SwitchWithLabel'
|
||||||
|
import useAutoLendEnabledAccountIds from 'hooks/useAutoLendEnabledAccountIds'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
accountId: string
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SwitchAutoLend(props: Props) {
|
||||||
|
const { accountId, className } = props
|
||||||
|
const { autoLendEnabledAccountIds, toggleAutoLend } = useAutoLendEnabledAccountIds()
|
||||||
|
const isAutoLendEnabled = autoLendEnabledAccountIds.includes(accountId)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames('w-full', className)}>
|
||||||
|
<SwitchWithLabel
|
||||||
|
name='isLending'
|
||||||
|
label='Lend assets to earn yield'
|
||||||
|
value={isAutoLendEnabled}
|
||||||
|
onChange={() => toggleAutoLend(accountId)}
|
||||||
|
tooltip={`Fund your account and lend assets effortlessly! By lending, you'll earn attractive interest (APY) without impacting your LTV. It's a win-win situation - don't miss out on this easy opportunity to grow your holdings!`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Inter;
|
font-family: Inter;
|
||||||
src: url('../fonts/Inter-ExtraLight.woff2') format('woff2'),
|
src:
|
||||||
|
url('../fonts/Inter-ExtraLight.woff2') format('woff2'),
|
||||||
url('../fonts/Inter-ExtraLight.woff') format('woff');
|
url('../fonts/Inter-ExtraLight.woff') format('woff');
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@ -13,7 +14,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Inter;
|
font-family: Inter;
|
||||||
src: url('../fonts/Inter-Regular.woff2') format('woff2'),
|
src:
|
||||||
|
url('../fonts/Inter-Regular.woff2') format('woff2'),
|
||||||
url('../fonts/Inter-Regular.woff') format('woff');
|
url('../fonts/Inter-Regular.woff') format('woff');
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@ -22,7 +24,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Inter;
|
font-family: Inter;
|
||||||
src: url('../fonts/Inter-SemiBold.woff2') format('woff2'),
|
src:
|
||||||
|
url('../fonts/Inter-SemiBold.woff2') format('woff2'),
|
||||||
url('../fonts/Inter-SemiBold.woff') format('woff');
|
url('../fonts/Inter-SemiBold.woff') format('woff');
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
Loading…
Reference in New Issue
Block a user