Mp 3004 implement account balance amount when withdrawing 100 of lent asset (#263)
This commit is contained in:
parent
2c399a2f16
commit
7fda98aeea
@ -1,5 +1,4 @@
|
||||
import Image from 'next/image'
|
||||
import { useState } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
import Button from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
@ -24,7 +23,7 @@ interface Props {
|
||||
accountSummaryChange?: AccountChange
|
||||
onClose: () => void
|
||||
onChange: (value: BigNumber) => void
|
||||
onAction: (value: BigNumber) => void
|
||||
onAction: (value: BigNumber, isMax: boolean) => void
|
||||
}
|
||||
|
||||
export default function AssetAmountSelectActionModal(props: Props) {
|
||||
@ -44,14 +43,17 @@ export default function AssetAmountSelectActionModal(props: Props) {
|
||||
const [amount, setAmount] = useState(BN(0))
|
||||
const maxAmount = BN(coinBalances.find(byDenom(asset.denom))?.amount ?? 0)
|
||||
|
||||
const handleAmountChange = (value: BigNumber) => {
|
||||
setAmount(value)
|
||||
onChange(value)
|
||||
}
|
||||
const handleAmountChange = useCallback(
|
||||
(value: BigNumber) => {
|
||||
setAmount(value)
|
||||
onChange(value)
|
||||
},
|
||||
[onChange],
|
||||
)
|
||||
|
||||
const handleActionClick = () => {
|
||||
onAction(amount)
|
||||
}
|
||||
const handleActionClick = useCallback(() => {
|
||||
onAction(amount, amount.eq(maxAmount))
|
||||
}, [amount, maxAmount, onAction])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
@ -9,7 +9,7 @@ interface Props {
|
||||
}
|
||||
|
||||
function DetailsHeader({ data }: Props) {
|
||||
const { asset, marketDepositCap, accountLentAmount: accountLendAmount } = data
|
||||
const { asset, marketDepositCap, accountLentAmount } = data
|
||||
const { data: assetApy } = useAssetIncentivesApy(asset.denom)
|
||||
const balanceInWallet = useCurrentWalletBalance(asset.denom)
|
||||
|
||||
@ -33,10 +33,10 @@ function DetailsHeader({ data }: Props) {
|
||||
<div className='h-100 w-[1px] bg-white/10'></div>
|
||||
</>
|
||||
)}
|
||||
{accountLendAmount && (
|
||||
{accountLentAmount && (
|
||||
<>
|
||||
<TitleAndSubCell
|
||||
title={<DisplayCurrency coin={{ denom: asset.denom, amount: accountLendAmount }} />}
|
||||
title={<DisplayCurrency coin={{ denom: asset.denom, amount: accountLentAmount }} />}
|
||||
sub={'Deposited'}
|
||||
/>
|
||||
<div className='h-100 w-[1px] bg-white/10'></div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
import useStore from 'store'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
@ -7,31 +7,29 @@ import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||
import useLendAndReclaimModal from 'hooks/useLendAndReclaimModal'
|
||||
import DetailsHeader from 'components/Modals/LendAndReclaim/DetailsHeader'
|
||||
import AssetAmountSelectActionModal from 'components/Modals/AssetAmountSelectActionModal'
|
||||
import AccountBalanceSettableCoin from 'types/classes/AccountBalanceSettableCoin'
|
||||
|
||||
const getAccountChange = (isLend: boolean, value: BigNumber, denom: string): AccountChange => {
|
||||
const makeCoin = (denom: string, shouldNegate: boolean) => [
|
||||
{
|
||||
amount: (shouldNegate ? value.negated() : value).toString(),
|
||||
denom,
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
deposits: makeCoin(denom, isLend),
|
||||
lends: makeCoin(denom, !isLend),
|
||||
}
|
||||
}
|
||||
|
||||
function LendAndReclaimModal() {
|
||||
const lend = useStore((s) => s.lend)
|
||||
const reclaim = useStore((s) => s.reclaim)
|
||||
function LendAndReclaimModalController() {
|
||||
const currentAccount = useCurrentAccount()
|
||||
const { config, close } = useLendAndReclaimModal()
|
||||
const [isConfirming, setIsConfirming] = useToggle()
|
||||
const [accountChange, setAccountChange] = useState<AccountChange | undefined>()
|
||||
const { config } = useLendAndReclaimModal()
|
||||
|
||||
if (!config || !currentAccount) return null
|
||||
|
||||
return <LendAndReclaimModal currentAccount={currentAccount} config={config} />
|
||||
}
|
||||
|
||||
interface Props {
|
||||
currentAccount: Account
|
||||
config: LendAndReclaimModalConfig
|
||||
}
|
||||
|
||||
function LendAndReclaimModal({ currentAccount, config }: Props) {
|
||||
const lend = useStore((s) => s.lend)
|
||||
const reclaim = useStore((s) => s.reclaim)
|
||||
const { close } = useLendAndReclaimModal()
|
||||
const [isConfirming, setIsConfirming] = useToggle()
|
||||
const [accountChange, setAccountChange] = useState<AccountChange | undefined>()
|
||||
|
||||
const { data, action } = config
|
||||
const { asset } = data
|
||||
|
||||
@ -39,26 +37,34 @@ function LendAndReclaimModal() {
|
||||
const actionText = isLendAction ? 'Lend' : 'Withdraw'
|
||||
const coinBalances = currentAccount[isLendAction ? 'deposits' : 'lends'] ?? []
|
||||
|
||||
const handleAmountChange = (value: BigNumber) => {
|
||||
setAccountChange(getAccountChange(isLendAction, value, asset.denom))
|
||||
}
|
||||
const handleAmountChange = useCallback(
|
||||
(value: BigNumber) => {
|
||||
setAccountChange(getAccountChange(isLendAction, value, asset.denom))
|
||||
},
|
||||
[asset.denom, isLendAction],
|
||||
)
|
||||
|
||||
const handleAction = async (value: BigNumber) => {
|
||||
setIsConfirming(true)
|
||||
const handleAction = useCallback(
|
||||
async (value: BigNumber, isMax: boolean) => {
|
||||
setIsConfirming(true)
|
||||
|
||||
const options = {
|
||||
fee: hardcodedFee,
|
||||
accountId: currentAccount.id,
|
||||
coin: {
|
||||
denom: asset.denom,
|
||||
amount: value.toString(),
|
||||
},
|
||||
}
|
||||
await (isLendAction ? lend : reclaim)(options)
|
||||
const coin = new AccountBalanceSettableCoin(
|
||||
asset.denom,
|
||||
value.integerValue().toString(),
|
||||
isMax,
|
||||
)
|
||||
const options = {
|
||||
fee: hardcodedFee,
|
||||
accountId: currentAccount.id,
|
||||
coin,
|
||||
}
|
||||
await (isLendAction ? lend : reclaim)(options)
|
||||
|
||||
setIsConfirming(false)
|
||||
close()
|
||||
}
|
||||
setIsConfirming(false)
|
||||
close()
|
||||
},
|
||||
[asset.denom, close, currentAccount.id, isLendAction, lend, reclaim, setIsConfirming],
|
||||
)
|
||||
|
||||
return (
|
||||
<AssetAmountSelectActionModal
|
||||
@ -77,4 +83,18 @@ function LendAndReclaimModal() {
|
||||
)
|
||||
}
|
||||
|
||||
export default LendAndReclaimModal
|
||||
const getAccountChange = (isLend: boolean, value: BigNumber, denom: string): AccountChange => {
|
||||
const makeCoin = (denom: string, shouldNegate: boolean) => [
|
||||
{
|
||||
amount: (shouldNegate ? value.negated() : value).toString(),
|
||||
denom,
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
deposits: makeCoin(denom, isLend),
|
||||
lends: makeCoin(denom, !isLend),
|
||||
}
|
||||
}
|
||||
|
||||
export default LendAndReclaimModalController
|
||||
|
@ -3,7 +3,7 @@ import BorrowModal from 'components/Modals/Borrow/BorrowModal'
|
||||
import FundAndWithdrawModal from 'components/Modals/FundWithdraw/FundAndWithdrawModal'
|
||||
import AddVaultBorrowAssetsModal from 'components/Modals/AddVaultAssets/AddVaultBorrowAssetsModal'
|
||||
import UnlockModal from 'components/Modals/Unlock/UnlockModal'
|
||||
import LendAndReclaimModal from 'components/Modals/LendAndReclaim'
|
||||
import LendAndReclaimModalController from 'components/Modals/LendAndReclaim'
|
||||
|
||||
export default function ModalsContainer() {
|
||||
return (
|
||||
@ -14,7 +14,7 @@ export default function ModalsContainer() {
|
||||
<VaultModal />
|
||||
<AddVaultBorrowAssetsModal />
|
||||
<UnlockModal />
|
||||
<LendAndReclaimModal />
|
||||
<LendAndReclaimModalController />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -43,12 +43,7 @@ export default function Toaster() {
|
||||
{toast.message}
|
||||
</Text>
|
||||
<div className='absolute right-6 top-8 '>
|
||||
<Button
|
||||
leftIcon={<Cross />}
|
||||
variant='transparent'
|
||||
className='w-2'
|
||||
iconClassName={classNames('w-2 h-2', toast.isError ? 'text-error' : 'text-success')}
|
||||
/>
|
||||
<Cross className={classNames('h-2 w-2', toast.isError ? 'text-error' : 'text-success')} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import { ENV } from 'constants/env'
|
||||
import { Store } from 'store'
|
||||
import { getSingleValueFromBroadcastResult } from 'utils/broadcast'
|
||||
import { formatAmountWithSymbol } from 'utils/formatters'
|
||||
import { BN } from 'utils/helpers'
|
||||
import AccountBalanceSettableCoin from 'types/classes/AccountBalanceSettableCoin'
|
||||
|
||||
export default function createBroadcastSlice(
|
||||
set: SetState<Store>,
|
||||
@ -213,7 +213,7 @@ export default function createBroadcastSlice(
|
||||
)
|
||||
return !!response.result
|
||||
},
|
||||
lend: async (options: { fee: StdFee; accountId: string; coin: Coin }) => {
|
||||
lend: async (options: { fee: StdFee; accountId: string; coin: AccountBalanceSettableCoin }) => {
|
||||
const msg = {
|
||||
update_credit_account: {
|
||||
account_id: options.accountId,
|
||||
@ -233,14 +233,17 @@ export default function createBroadcastSlice(
|
||||
)
|
||||
return !!response.result
|
||||
},
|
||||
reclaim: async (options: { fee: StdFee; accountId: string; coin: Coin }) => {
|
||||
const reclaim = { denom: options.coin.denom, amount: { exact: BN(options.coin.amount) } }
|
||||
reclaim: async (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
coin: AccountBalanceSettableCoin
|
||||
}) => {
|
||||
const msg = {
|
||||
update_credit_account: {
|
||||
account_id: options.accountId,
|
||||
actions: [
|
||||
{
|
||||
reclaim,
|
||||
reclaim: options.coin.toActionCoin(),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -250,7 +253,7 @@ export default function createBroadcastSlice(
|
||||
|
||||
handleResponseMessages(
|
||||
response,
|
||||
`Successfully deposited ${formatAmountWithSymbol(options.coin)}`,
|
||||
`Successfully withdrew ${formatAmountWithSymbol(options.coin)}`,
|
||||
)
|
||||
return !!response.result
|
||||
},
|
||||
|
22
src/types/classes/AccountBalanceSettableCoin.ts
Normal file
22
src/types/classes/AccountBalanceSettableCoin.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { ActionCoin } from 'types/generated'
|
||||
|
||||
class AccountBalanceSettableCoin implements Coin {
|
||||
public denom: string
|
||||
public amount: string
|
||||
public setAccountBalance: boolean
|
||||
|
||||
constructor(denom: string, amount: string, setAccountBalance: boolean) {
|
||||
this.denom = denom
|
||||
this.amount = amount
|
||||
this.setAccountBalance = setAccountBalance
|
||||
}
|
||||
|
||||
toActionCoin(): ActionCoin {
|
||||
return {
|
||||
denom: this.denom,
|
||||
amount: this.setAccountBalance ? 'account_balance' : { exact: this.amount },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default AccountBalanceSettableCoin
|
1
src/types/generated.d.ts
vendored
Normal file
1
src/types/generated.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export { ActionCoin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
14
src/types/interfaces/store/broadcast.d.ts
vendored
14
src/types/interfaces/store/broadcast.d.ts
vendored
@ -1,3 +1,5 @@
|
||||
type AccountBalanceSettableCoin = import('types/classes/AccountBalanceSettableCoin')
|
||||
|
||||
interface BroadcastResult {
|
||||
result?: import('@marsprotocol/wallet-connector').TxBroadcastResult
|
||||
error?: string
|
||||
@ -16,8 +18,16 @@ interface BroadcastSlice {
|
||||
deposit: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
unlock: (options: { fee: StdFee; vault: Vault; amount: string }) => Promise<boolean>
|
||||
withdraw: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
lend: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
reclaim: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
lend: (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
coin: AccountBalanceSettableCoin
|
||||
}) => Promise<boolean>
|
||||
reclaim: (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
coin: AccountBalanceSettableCoin
|
||||
}) => Promise<boolean>
|
||||
repay: (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
|
4
src/types/stargate.d.ts
vendored
4
src/types/stargate.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
type Coin = {
|
||||
readonly denom: string
|
||||
readonly amount: string
|
||||
denom: string
|
||||
amount: string
|
||||
}
|
||||
|
||||
type StdFee = {
|
||||
|
Loading…
Reference in New Issue
Block a user