fix: withdrawal max threshold (#830)
* chore: fix remaning text for large number * feat: make use max only use account balance, add custom max messages * fix: withdraw threshold limit display * fix: assertions in deposit withdrawy e2e tests
This commit is contained in:
parent
0964d6dee5
commit
065b48535b
@ -53,6 +53,6 @@ describe('deposit form validation', () => {
|
|||||||
.clear()
|
.clear()
|
||||||
.type('100')
|
.type('100')
|
||||||
.next(`[data-testid="${formFieldError}"]`)
|
.next(`[data-testid="${formFieldError}"]`)
|
||||||
.should('have.text', 'Amount is above approved amount');
|
.should('have.text', 'Insufficient amount in Ethereum wallet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -58,7 +58,7 @@ describe('withdraw', () => {
|
|||||||
.clear()
|
.clear()
|
||||||
.type('1') // Will be above maximum because the vega wallet doesnt have any collateral
|
.type('1') // Will be above maximum because the vega wallet doesnt have any collateral
|
||||||
.next('[data-testid="input-error-text"]')
|
.next('[data-testid="input-error-text"]')
|
||||||
.should('contain.text', 'Value is above maximum');
|
.should('contain.text', 'Insufficient amount in account');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can set amount using use maximum button', () => {
|
it('can set amount using use maximum button', () => {
|
||||||
|
@ -33,7 +33,7 @@ beforeEach(() => {
|
|||||||
assets: [asset],
|
assets: [asset],
|
||||||
selectedAsset: undefined,
|
selectedAsset: undefined,
|
||||||
onSelectAsset: jest.fn(),
|
onSelectAsset: jest.fn(),
|
||||||
available: new BigNumber(5),
|
balance: new BigNumber(5),
|
||||||
submitApprove: jest.fn(),
|
submitApprove: jest.fn(),
|
||||||
submitDeposit: jest.fn(),
|
submitDeposit: jest.fn(),
|
||||||
requestFaucet: jest.fn(),
|
requestFaucet: jest.fn(),
|
||||||
@ -125,7 +125,7 @@ describe('Deposit form', () => {
|
|||||||
fireEvent.submit(screen.getByTestId('deposit-form'));
|
fireEvent.submit(screen.getByTestId('deposit-form'));
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
await screen.findByText('Amount is above permitted maximum')
|
await screen.findByText('Insufficient amount in Ethereum wallet')
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -133,6 +133,7 @@ describe('Deposit form', () => {
|
|||||||
render(
|
render(
|
||||||
<DepositForm
|
<DepositForm
|
||||||
{...props}
|
{...props}
|
||||||
|
balance={new BigNumber(100)}
|
||||||
limits={{ max: new BigNumber(100), deposited: new BigNumber(10) }}
|
limits={{ max: new BigNumber(100), deposited: new BigNumber(10) }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -216,12 +217,13 @@ describe('Deposit form', () => {
|
|||||||
max: new BigNumber(20),
|
max: new BigNumber(20),
|
||||||
deposited: new BigNumber(10),
|
deposited: new BigNumber(10),
|
||||||
};
|
};
|
||||||
|
const balance = new BigNumber(50);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<DepositForm
|
<DepositForm
|
||||||
{...props}
|
{...props}
|
||||||
allowance={new BigNumber(100)}
|
allowance={new BigNumber(100)}
|
||||||
available={new BigNumber(50)}
|
balance={balance}
|
||||||
limits={limits}
|
limits={limits}
|
||||||
selectedAsset={asset}
|
selectedAsset={asset}
|
||||||
/>
|
/>
|
||||||
@ -229,12 +231,18 @@ describe('Deposit form', () => {
|
|||||||
|
|
||||||
// Check deposit limit is displayed
|
// Check deposit limit is displayed
|
||||||
expect(
|
expect(
|
||||||
screen.getByText('Max deposit total', { selector: 'th' })
|
screen.getByText('Balance available', { selector: 'th' })
|
||||||
|
.nextElementSibling
|
||||||
|
).toHaveTextContent(balance.toString());
|
||||||
|
expect(
|
||||||
|
screen.getByText('Maximum total deposit amount', { selector: 'th' })
|
||||||
.nextElementSibling
|
.nextElementSibling
|
||||||
).toHaveTextContent(limits.max.toString());
|
).toHaveTextContent(limits.max.toString());
|
||||||
expect(
|
expect(
|
||||||
screen.getByText('Remaining available', { selector: 'th' })
|
screen.getByText('Deposited', { selector: 'th' }).nextElementSibling
|
||||||
.nextElementSibling
|
).toHaveTextContent(limits.deposited.toString());
|
||||||
|
expect(
|
||||||
|
screen.getByText('Remaining', { selector: 'th' }).nextElementSibling
|
||||||
).toHaveTextContent(limits.max.minus(limits.deposited).toString());
|
).toHaveTextContent(limits.max.minus(limits.deposited).toString());
|
||||||
|
|
||||||
fireEvent.change(screen.getByLabelText('Amount'), {
|
fireEvent.change(screen.getByLabelText('Amount'), {
|
||||||
|
@ -37,7 +37,7 @@ export interface DepositFormProps {
|
|||||||
assets: Asset[];
|
assets: Asset[];
|
||||||
selectedAsset?: Asset;
|
selectedAsset?: Asset;
|
||||||
onSelectAsset: (assetId: string) => void;
|
onSelectAsset: (assetId: string) => void;
|
||||||
available: BigNumber | undefined;
|
balance: BigNumber | undefined;
|
||||||
submitApprove: () => Promise<void>;
|
submitApprove: () => Promise<void>;
|
||||||
submitDeposit: (args: {
|
submitDeposit: (args: {
|
||||||
assetSource: string;
|
assetSource: string;
|
||||||
@ -57,7 +57,7 @@ export const DepositForm = ({
|
|||||||
assets,
|
assets,
|
||||||
selectedAsset,
|
selectedAsset,
|
||||||
onSelectAsset,
|
onSelectAsset,
|
||||||
available,
|
balance,
|
||||||
submitApprove,
|
submitApprove,
|
||||||
submitDeposit,
|
submitDeposit,
|
||||||
requestFaucet,
|
requestFaucet,
|
||||||
@ -99,7 +99,7 @@ export const DepositForm = ({
|
|||||||
|
|
||||||
const max = useMemo(() => {
|
const max = useMemo(() => {
|
||||||
const maxApproved = allowance ? allowance : new BigNumber(0);
|
const maxApproved = allowance ? allowance : new BigNumber(0);
|
||||||
const maxAvailable = available ? available : new BigNumber(0);
|
const maxAvailable = balance ? balance : new BigNumber(0);
|
||||||
|
|
||||||
// limits.max is a lifetime deposit limit, so the actual max value for form
|
// limits.max is a lifetime deposit limit, so the actual max value for form
|
||||||
// input is the max minus whats already been deposited
|
// input is the max minus whats already been deposited
|
||||||
@ -116,7 +116,7 @@ export const DepositForm = ({
|
|||||||
limit: maxLimit,
|
limit: maxLimit,
|
||||||
amount: BigNumber.minimum(maxLimit, maxApproved, maxAvailable),
|
amount: BigNumber.minimum(maxLimit, maxApproved, maxAvailable),
|
||||||
};
|
};
|
||||||
}, [limits, allowance, available]);
|
}, [limits, allowance, balance]);
|
||||||
|
|
||||||
const min = useMemo(() => {
|
const min = useMemo(() => {
|
||||||
// Min viable amount given asset decimals EG for WEI 0.000000000000000001
|
// Min viable amount given asset decimals EG for WEI 0.000000000000000001
|
||||||
@ -198,7 +198,7 @@ export const DepositForm = ({
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
{selectedAsset && limits && (
|
{selectedAsset && limits && (
|
||||||
<div className="mb-20">
|
<div className="mb-20">
|
||||||
<DepositLimits limits={limits} />
|
<DepositLimits limits={limits} balance={balance} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<FormGroup label={t('Amount')} labelFor="amount" className="relative">
|
<FormGroup label={t('Amount')} labelFor="amount" className="relative">
|
||||||
@ -212,12 +212,12 @@ export const DepositForm = ({
|
|||||||
minSafe: (value) => minSafe(new BigNumber(min))(value),
|
minSafe: (value) => minSafe(new BigNumber(min))(value),
|
||||||
maxSafe: (v) => {
|
maxSafe: (v) => {
|
||||||
const value = new BigNumber(v);
|
const value = new BigNumber(v);
|
||||||
if (value.isGreaterThan(max.approved)) {
|
if (value.isGreaterThan(max.available)) {
|
||||||
return t('Amount is above approved amount');
|
|
||||||
} else if (value.isGreaterThan(max.limit)) {
|
|
||||||
return t('Amount is above permitted maximum');
|
|
||||||
} else if (value.isGreaterThan(max.available)) {
|
|
||||||
return t('Insufficient amount in Ethereum wallet');
|
return t('Insufficient amount in Ethereum wallet');
|
||||||
|
} else if (value.isGreaterThan(max.limit)) {
|
||||||
|
return t('Amount is above temporary deposit limit');
|
||||||
|
} else if (value.isGreaterThan(max.approved)) {
|
||||||
|
return t('Amount is above approved amount');
|
||||||
}
|
}
|
||||||
return maxSafe(max.amount)(v);
|
return maxSafe(max.amount)(v);
|
||||||
},
|
},
|
||||||
@ -229,10 +229,10 @@ export const DepositForm = ({
|
|||||||
{errors.amount.message}
|
{errors.amount.message}
|
||||||
</InputError>
|
</InputError>
|
||||||
)}
|
)}
|
||||||
{account && selectedAsset && available && (
|
{selectedAsset && balance && (
|
||||||
<UseButton
|
<UseButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValue('amount', max.amount.toFixed(selectedAsset.decimals));
|
setValue('amount', balance.toFixed(selectedAsset.decimals));
|
||||||
clearErrors('amount');
|
clearErrors('amount');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -6,11 +6,11 @@ interface DepositLimitsProps {
|
|||||||
max: BigNumber;
|
max: BigNumber;
|
||||||
deposited: BigNumber;
|
deposited: BigNumber;
|
||||||
};
|
};
|
||||||
|
balance?: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DepositLimits = ({ limits }: DepositLimitsProps) => {
|
export const DepositLimits = ({ limits, balance }: DepositLimitsProps) => {
|
||||||
let maxLimit = '';
|
let maxLimit = '';
|
||||||
|
|
||||||
if (limits.max.isEqualTo(Infinity)) {
|
if (limits.max.isEqualTo(Infinity)) {
|
||||||
maxLimit = t('No limit');
|
maxLimit = t('No limit');
|
||||||
} else if (limits.max.isGreaterThan(1_000_000)) {
|
} else if (limits.max.isGreaterThan(1_000_000)) {
|
||||||
@ -19,29 +19,35 @@ export const DepositLimits = ({ limits }: DepositLimitsProps) => {
|
|||||||
maxLimit = limits.max.toString();
|
maxLimit = limits.max.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remaining = '';
|
||||||
|
if (limits.deposited.isEqualTo(0)) {
|
||||||
|
remaining = maxLimit;
|
||||||
|
} else {
|
||||||
|
remaining = limits.max.minus(limits.deposited).toString();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<table className="w-full text-ui">
|
||||||
<p className="text-ui font-bold">{t('Deposit limits')}</p>
|
<tbody>
|
||||||
<table className="w-full text-ui">
|
<tr>
|
||||||
<tbody>
|
<th className="text-left font-normal">{t('Balance available')}</th>
|
||||||
<tr>
|
<td className="text-right">{balance ? balance.toString() : 0}</td>
|
||||||
<th className="text-left font-normal">{t('Max deposit total')}</th>
|
</tr>
|
||||||
<td className="text-right">{maxLimit}</td>
|
<tr>
|
||||||
</tr>
|
<th className="text-left font-normal">
|
||||||
<tr>
|
{t('Maximum total deposit amount')}
|
||||||
<th className="text-left font-normal">{t('Deposited')}</th>
|
</th>
|
||||||
<td className="text-right">{limits.deposited.toString()}</td>
|
<td className="text-right">{maxLimit}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="text-left font-normal">
|
<th className="text-left font-normal">{t('Deposited')}</th>
|
||||||
{t('Remaining available')}
|
<td className="text-right">{limits.deposited.toString()}</td>
|
||||||
</th>
|
</tr>
|
||||||
<td className="text-right">
|
<tr>
|
||||||
{limits.max.minus(limits.deposited).toString()}
|
<th className="text-left font-normal">{t('Remaining')}</th>
|
||||||
</td>
|
<td className="text-right">{remaining}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -105,7 +105,7 @@ export const DepositManager = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DepositForm
|
<DepositForm
|
||||||
available={balance}
|
balance={balance}
|
||||||
selectedAsset={asset}
|
selectedAsset={asset}
|
||||||
onSelectAsset={(id) => setAssetId(id)}
|
onSelectAsset={(id) => setAssetId(id)}
|
||||||
assets={sortBy(assets, 'name')}
|
assets={sortBy(assets, 'name')}
|
||||||
|
@ -20,9 +20,11 @@ export const useGetWithdrawLimits = (asset?: Asset) => {
|
|||||||
|
|
||||||
if (!data || !asset) return null;
|
if (!data || !asset) return null;
|
||||||
|
|
||||||
const max = new BigNumber(addDecimal(data.toString(), asset.decimals));
|
const value = new BigNumber(addDecimal(data.toString(), asset.decimals));
|
||||||
|
const max = value.isEqualTo(0)
|
||||||
|
? new BigNumber(Infinity)
|
||||||
|
: value.minus(new BigNumber(addDecimal('1', asset.decimals)));
|
||||||
return {
|
return {
|
||||||
max: max.isEqualTo(0) ? new BigNumber(Infinity) : max,
|
max,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,10 @@ beforeEach(() => {
|
|||||||
props = {
|
props = {
|
||||||
assets,
|
assets,
|
||||||
min: new BigNumber(0.00001),
|
min: new BigNumber(0.00001),
|
||||||
max: new BigNumber(100),
|
max: {
|
||||||
|
balance: new BigNumber(100),
|
||||||
|
threshold: new BigNumber(200),
|
||||||
|
},
|
||||||
limits: {
|
limits: {
|
||||||
max: new BigNumber(200),
|
max: new BigNumber(200),
|
||||||
},
|
},
|
||||||
@ -75,7 +78,9 @@ describe('Withdrawal form', () => {
|
|||||||
expect(
|
expect(
|
||||||
await screen.findByText('Invalid Ethereum address')
|
await screen.findByText('Invalid Ethereum address')
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(screen.getByText('Value is above maximum')).toBeInTheDocument();
|
expect(
|
||||||
|
screen.getByText('Insufficient amount in account')
|
||||||
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails when submitted amount is less than the minimum limit', async () => {
|
it('fails when submitted amount is less than the minimum limit', async () => {
|
||||||
@ -111,14 +116,14 @@ describe('Withdrawal form', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('populates amount field with maximum value when clicking the "use maximum" button', () => {
|
it('populates amount field with balance value when clicking the "use maximum" button', () => {
|
||||||
const asset = props.assets[0];
|
const asset = props.assets[0];
|
||||||
render(<WithdrawForm {...props} selectedAsset={asset} />);
|
render(<WithdrawForm {...props} selectedAsset={asset} />);
|
||||||
|
|
||||||
fireEvent.click(screen.getByText('Use maximum'));
|
fireEvent.click(screen.getByText('Use maximum'));
|
||||||
|
|
||||||
expect(screen.getByLabelText('Amount')).toHaveValue(
|
expect(screen.getByLabelText('Amount')).toHaveValue(
|
||||||
Number(props.max.toFixed(asset.decimals))
|
Number(props.max.balance.toFixed(asset.decimals))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
ethereumAddress,
|
ethereumAddress,
|
||||||
maxSafe,
|
|
||||||
minSafe,
|
minSafe,
|
||||||
t,
|
t,
|
||||||
removeDecimal,
|
removeDecimal,
|
||||||
required,
|
required,
|
||||||
|
maxSafe,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { Web3WalletInput } from '@vegaprotocol/web3';
|
import { Web3WalletInput } from '@vegaprotocol/web3';
|
||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import type BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import type { WithdrawalFields } from './use-withdraw';
|
import type { WithdrawalFields } from './use-withdraw';
|
||||||
@ -30,7 +30,10 @@ interface FormFields {
|
|||||||
|
|
||||||
export interface WithdrawFormProps {
|
export interface WithdrawFormProps {
|
||||||
assets: Asset[];
|
assets: Asset[];
|
||||||
max: BigNumber;
|
max: {
|
||||||
|
balance: BigNumber;
|
||||||
|
threshold: BigNumber;
|
||||||
|
};
|
||||||
min: BigNumber;
|
min: BigNumber;
|
||||||
selectedAsset?: Asset;
|
selectedAsset?: Asset;
|
||||||
limits: {
|
limits: {
|
||||||
@ -49,7 +52,7 @@ export const WithdrawForm = ({
|
|||||||
onSelectAsset,
|
onSelectAsset,
|
||||||
submitWithdraw,
|
submitWithdraw,
|
||||||
}: WithdrawFormProps) => {
|
}: WithdrawFormProps) => {
|
||||||
const { account } = useWeb3React();
|
const { account: address } = useWeb3React();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -60,7 +63,7 @@ export const WithdrawForm = ({
|
|||||||
} = useForm<FormFields>({
|
} = useForm<FormFields>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
asset: selectedAsset?.id,
|
asset: selectedAsset?.id,
|
||||||
to: account,
|
to: address,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const onSubmit = async (fields: FormFields) => {
|
const onSubmit = async (fields: FormFields) => {
|
||||||
@ -106,7 +109,6 @@ export const WithdrawForm = ({
|
|||||||
</Select>
|
</Select>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{errors.asset?.message && (
|
{errors.asset?.message && (
|
||||||
<InputError intent="danger" className="mt-4">
|
<InputError intent="danger" className="mt-4">
|
||||||
{errors.asset.message}
|
{errors.asset.message}
|
||||||
@ -132,7 +134,7 @@ export const WithdrawForm = ({
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
{selectedAsset && limits && (
|
{selectedAsset && limits && (
|
||||||
<div className="mb-20">
|
<div className="mb-20">
|
||||||
<WithdrawLimits limits={limits} />
|
<WithdrawLimits limits={limits} balance={max.balance} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<FormGroup label={t('Amount')} labelFor="amount" className="relative">
|
<FormGroup label={t('Amount')} labelFor="amount" className="relative">
|
||||||
@ -143,7 +145,17 @@ export const WithdrawForm = ({
|
|||||||
{...register('amount', {
|
{...register('amount', {
|
||||||
validate: {
|
validate: {
|
||||||
required,
|
required,
|
||||||
maxSafe: (value) => maxSafe(max)(value),
|
maxSafe: (v) => {
|
||||||
|
const value = new BigNumber(v);
|
||||||
|
if (value.isGreaterThan(max.balance)) {
|
||||||
|
return t('Insufficient amount in account');
|
||||||
|
} else if (value.isGreaterThan(max.threshold)) {
|
||||||
|
return t('Amount is above temporary withdrawal limit');
|
||||||
|
}
|
||||||
|
return maxSafe(BigNumber.minimum(max.balance, max.threshold))(
|
||||||
|
v
|
||||||
|
);
|
||||||
|
},
|
||||||
minSafe: (value) => minSafe(min)(value),
|
minSafe: (value) => minSafe(min)(value),
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
@ -157,7 +169,7 @@ export const WithdrawForm = ({
|
|||||||
<UseButton
|
<UseButton
|
||||||
data-testid="use-maximum"
|
data-testid="use-maximum"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValue('amount', max.toFixed(selectedAsset.decimals));
|
setValue('amount', max.balance.toFixed(selectedAsset.decimals));
|
||||||
clearErrors('amount');
|
clearErrors('amount');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -5,9 +5,10 @@ interface WithdrawLimitsProps {
|
|||||||
limits: {
|
limits: {
|
||||||
max: BigNumber;
|
max: BigNumber;
|
||||||
};
|
};
|
||||||
|
balance: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WithdrawLimits = ({ limits }: WithdrawLimitsProps) => {
|
export const WithdrawLimits = ({ limits, balance }: WithdrawLimitsProps) => {
|
||||||
let maxLimit = '';
|
let maxLimit = '';
|
||||||
|
|
||||||
if (limits.max.isEqualTo(Infinity)) {
|
if (limits.max.isEqualTo(Infinity)) {
|
||||||
@ -19,16 +20,17 @@ export const WithdrawLimits = ({ limits }: WithdrawLimitsProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<table className="w-full text-ui">
|
||||||
<p className="text-ui font-bold">{t('Withdraw limits')}</p>
|
<tbody>
|
||||||
<table className="w-full text-ui">
|
<tr>
|
||||||
<tbody>
|
<th className="text-left font-normal">{t('Balance available')}</th>
|
||||||
<tr>
|
<td className="text-right">{balance.toString()}</td>
|
||||||
<th className="text-left font-normal">{t('Maximum')}</th>
|
</tr>
|
||||||
<td className="text-right">{maxLimit}</td>
|
<tr>
|
||||||
</tr>
|
<th className="text-left font-normal">{t('Maximum withdrawal')}</th>
|
||||||
</tbody>
|
<td className="text-right">{maxLimit}</td>
|
||||||
</table>
|
</tr>
|
||||||
</>
|
</tbody>
|
||||||
|
</table>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -111,7 +111,9 @@ it('Correct min max values provided to form', async () => {
|
|||||||
target: { value: '2' },
|
target: { value: '2' },
|
||||||
});
|
});
|
||||||
fireEvent.submit(screen.getByTestId('withdraw-form'));
|
fireEvent.submit(screen.getByTestId('withdraw-form'));
|
||||||
expect(await screen.findByText('Value is above maximum')).toBeInTheDocument();
|
expect(
|
||||||
|
await screen.findByText('Insufficient amount in account')
|
||||||
|
).toBeInTheDocument();
|
||||||
expect(mockSubmit).not.toBeCalled();
|
expect(mockSubmit).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,22 +38,31 @@ export const WithdrawManager = ({
|
|||||||
return assets?.find((a) => a.id === assetId);
|
return assets?.find((a) => a.id === assetId);
|
||||||
}, [assets, assetId]);
|
}, [assets, assetId]);
|
||||||
|
|
||||||
|
const account = useMemo(() => {
|
||||||
|
return accounts.find(
|
||||||
|
(a) => a.type === AccountType.General && a.asset.id === asset?.id
|
||||||
|
);
|
||||||
|
}, [asset, accounts]);
|
||||||
|
|
||||||
const limits = useGetWithdrawLimits(asset);
|
const limits = useGetWithdrawLimits(asset);
|
||||||
|
|
||||||
const max = useMemo(() => {
|
const max = useMemo(() => {
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
return new BigNumber(0);
|
return {
|
||||||
|
balance: new BigNumber(0),
|
||||||
|
threshold: new BigNumber(0),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const account = accounts.find(
|
const balance = account
|
||||||
(a) => a.type === AccountType.General && a.asset.id === asset.id
|
|
||||||
);
|
|
||||||
|
|
||||||
const v = account
|
|
||||||
? new BigNumber(addDecimal(account.balance, asset.decimals))
|
? new BigNumber(addDecimal(account.balance, asset.decimals))
|
||||||
: new BigNumber(0);
|
: new BigNumber(0);
|
||||||
return BigNumber.minimum(v, limits ? limits.max : new BigNumber(Infinity));
|
|
||||||
}, [asset, accounts, limits]);
|
return {
|
||||||
|
balance,
|
||||||
|
threshold: limits ? limits.max : new BigNumber(Infinity),
|
||||||
|
};
|
||||||
|
}, [asset, account, limits]);
|
||||||
|
|
||||||
const min = useMemo(() => {
|
const min = useMemo(() => {
|
||||||
return asset
|
return asset
|
||||||
|
Loading…
Reference in New Issue
Block a user