feat(accounts): get trasfer fee from estimateTransferFee API

This commit is contained in:
Bartłomiej Głownia 2024-02-05 11:40:46 +01:00
parent 575897d94f
commit 8cfcb8ef79
No known key found for this signature in database
GPG Key ID: A622E438A7075295
5 changed files with 99 additions and 86 deletions

View File

@ -25,7 +25,6 @@ export const TransferContainer = ({ assetId }: { assetId?: string }) => {
const t = useT();
const { pubKey, pubKeys, isReadOnly } = useVegaWallet();
const { params } = useNetworkParams([
NetworkParams.transfer_fee_factor,
NetworkParams.transfer_minTransferQuantumMultiple,
]);

View File

@ -15,6 +15,30 @@ import {
} from './transfer-form';
import { AccountType, AccountTypeMapping } from '@vegaprotocol/types';
import { removeDecimal } from '@vegaprotocol/utils';
import type { TransferFeeQuery } from './__generated__/TransferFee';
const feeFactor = 0.001;
const mockUseTransferFeeQuery = jest.fn(
({
variables: { amount },
}: {
variables: { amount: string };
}): { data: TransferFeeQuery } => {
return {
data: {
estimateTransferFee: {
discount: '0',
fee: (Number(amount) * feeFactor).toFixed(),
},
},
};
}
);
jest.mock('./__generated__/TransferFee', () => ({
useTransferFeeQuery: (props: { variables: { amount: string } }) =>
mockUseTransferFeeQuery(props),
}));
describe('TransferForm', () => {
const renderComponent = (props: TransferFormProps) => {
@ -56,7 +80,6 @@ describe('TransferForm', () => {
const props = {
pubKey,
pubKeys: [pubKey, '2'.repeat(64)],
feeFactor: '0.001',
submitTransfer: jest.fn(),
accounts: [
{
@ -79,7 +102,6 @@ describe('TransferForm', () => {
pubKey,
'a4b6e3de5d7ef4e31ae1b090be49d1a2ef7bcefff60cccf7658a0d4922651cce',
],
feeFactor: '0.001',
submitTransfer: jest.fn(),
accounts: [],
minQuantumMultiple: '1',
@ -96,10 +118,6 @@ describe('TransferForm', () => {
});
it.each([
{
targetText: 'Transfer fee',
tooltipText: /transfer\.fee\.factor/,
},
{
targetText: 'Amount to be transferred',
tooltipText: /without the fee/,
@ -109,9 +127,6 @@ describe('TransferForm', () => {
tooltipText: /total amount taken from your account/,
},
])('Tooltip for "$targetText" shows', async (o) => {
// 1003-TRAN-015
// 1003-TRAN-016
// 1003-TRAN-017
// 1003-TRAN-018
// 1003-TRAN-019
renderComponent(props);
@ -124,6 +139,10 @@ describe('TransferForm', () => {
// Select asset
await selectAsset(asset);
await userEvent.selectOptions(
screen.getByLabelText('From account'),
`${AccountType.ACCOUNT_TYPE_GENERAL}-${asset.id}`
);
// set valid amount
const amountInput = screen.getByLabelText('Amount');
await userEvent.type(amountInput, amount);
@ -214,9 +233,7 @@ describe('TransferForm', () => {
// set valid amount
await userEvent.clear(amountInput);
await userEvent.type(amountInput, amount);
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(
new BigNumber(props.feeFactor).times(amount).toFixed()
);
expect(screen.getByTestId('transfer-fee')).toHaveTextContent('1');
await submit();
@ -385,47 +402,44 @@ describe('TransferForm', () => {
});
});
});
describe('IncludeFeesCheckbox', () => {
it('validates fields when checkbox is not checked', async () => {
renderComponent(props);
// check current pubkey not shown
const keySelect: HTMLSelectElement = screen.getByLabelText('To Vega key');
const pubKeyOptions = ['', pubKey, props.pubKeys[1]];
expect(keySelect.children).toHaveLength(pubKeyOptions.length);
expect(Array.from(keySelect.options).map((o) => o.value)).toEqual(
pubKeyOptions
);
it('validates fields', async () => {
renderComponent(props);
await submit();
expect(await screen.findAllByText('Required')).toHaveLength(2); // pubkey set as default value
// check current pubkey not shown
const keySelect: HTMLSelectElement = screen.getByLabelText('To Vega key');
const pubKeyOptions = ['', pubKey, props.pubKeys[1]];
expect(keySelect.children).toHaveLength(pubKeyOptions.length);
expect(Array.from(keySelect.options).map((o) => o.value)).toEqual(
pubKeyOptions
);
// Select a pubkey
await userEvent.selectOptions(
screen.getByLabelText('To Vega key'),
props.pubKeys[1]
);
await submit();
expect(await screen.findAllByText('Required')).toHaveLength(2); // pubkey set as default value
// Select asset
await selectAsset(asset);
// Select a pubkey
await userEvent.selectOptions(
screen.getByLabelText('To Vega key'),
props.pubKeys[1]
);
await userEvent.selectOptions(
screen.getByLabelText('From account'),
`${AccountType.ACCOUNT_TYPE_GENERAL}-${asset.id}`
);
// Select asset
await selectAsset(asset);
const amountInput = screen.getByLabelText('Amount');
await userEvent.selectOptions(
screen.getByLabelText('From account'),
`${AccountType.ACCOUNT_TYPE_GENERAL}-${asset.id}`
);
await userEvent.type(amountInput, amount);
const expectedFee = new BigNumber(amount)
.times(props.feeFactor)
.toFixed();
const total = new BigNumber(amount).plus(expectedFee).toFixed();
// 1003-TRAN-021
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expectedFee);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(amount);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(total);
});
const amountInput = screen.getByLabelText('Amount');
await userEvent.type(amountInput, amount);
const expectedFee = new BigNumber(amount).times(feeFactor).toFixed();
const total = new BigNumber(amount).plus(expectedFee).toFixed();
// 1003-TRAN-021
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expectedFee);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(amount);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(total);
});
describe('AddressField', () => {
@ -457,24 +471,29 @@ describe('TransferForm', () => {
describe('TransferFee', () => {
const props = {
amount: '200',
feeFactor: '0.001',
fee: '0.2',
transferAmount: '200',
decimals: 8,
amount: '20000',
discount: '0',
fee: '20',
decimals: 2,
};
it('calculates and renders the transfer fee', () => {
it('calculates and renders amounts and fee', () => {
render(<TransferFee {...props} />);
const expected = new BigNumber(props.amount)
.times(props.feeFactor)
.toFixed();
const total = new BigNumber(props.amount).plus(expected).toFixed();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expected);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(
props.amount
expect(screen.queryByTestId('discount')).not.toBeInTheDocument();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent('0.2');
expect(screen.getByTestId('transfer-amount')).toHaveTextContent('200.00');
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(
'200.20'
);
});
it('calculates and renders amounts, fee and discount', () => {
render(<TransferFee {...props} discount="10" />);
expect(screen.getByTestId('discount')).toHaveTextContent('0.1');
expect(screen.getByTestId('transfer-fee')).toHaveTextContent('0.2');
expect(screen.getByTestId('transfer-amount')).toHaveTextContent('200.00');
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(
'200.10'
);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(total);
});
});
});

View File

@ -4,9 +4,9 @@ import {
useRequired,
useVegaPublicKey,
addDecimal,
formatNumber,
toBigNum,
removeDecimal,
addDecimalsFormatNumber,
} from '@vegaprotocol/utils';
import { useT } from './use-t';
import {
@ -136,12 +136,14 @@ export const TransferForm = ({
// Max amount given selected asset and from account
const max = accountBalance ? new BigNumber(accountBalance) : new BigNumber(0);
const normalizedAmount =
(amount && asset && removeDecimal(amount, asset.decimals)) || '0';
const transferFeeQuery = useTransferFeeQuery({
variables: {
fromAccount: pubKey || '',
fromAccountType: accountType || AccountType.ACCOUNT_TYPE_GENERAL,
amount: (amount && asset && removeDecimal(amount, asset.decimals)) || '0',
amount: normalizedAmount,
assetId: asset?.id || '',
toAccount: selectedPubKey,
},
@ -441,14 +443,15 @@ export const TransferForm = ({
</TradingInputError>
)}
</TradingFormGroup>
{(transferFee?.estimateTransferFee || fromVested) && amount && (
{JSON.stringify(transferFee)}
{(transferFee?.estimateTransferFee || fromVested) && amount && asset && (
<TransferFee
amount={amount}
amount={normalizedAmount}
fee={fromVested ? '0' : transferFee?.estimateTransferFee?.fee}
discount={
fromVested ? '0' : transferFee?.estimateTransferFee?.discount
}
decimals={asset?.decimals}
decimals={asset.decimals}
/>
)}
<TradingButton type="submit" fill={true} disabled={isReadOnly}>
@ -467,7 +470,7 @@ export const TransferFee = ({
amount: string;
fee?: string;
discount?: string;
decimals?: number;
decimals: number;
}) => {
const t = useT();
if (!amount || !fee) return null;
@ -475,30 +478,25 @@ export const TransferFee = ({
return null;
}
const totalValue = new BigNumber(amount).plus(fee).toString();
const feeFactor = new BigNumber(fee).dividedBy(amount).toFixed(2);
const totalValue = (
BigInt(amount) +
BigInt(fee) -
BigInt(discount || '0')
).toString();
return (
<div className="mb-4 flex flex-col gap-2 text-xs">
<div className="flex flex-wrap items-center justify-between gap-1">
<Tooltip
description={t(
`The transfer fee is set by the network parameter transfer.fee.factor, currently set to {{feeFactor}}`,
{ feeFactor }
)}
>
<div>{t('Transfer fee')}</div>
</Tooltip>
<div>{t('Transfer fee')}</div>
<div data-testid="transfer-fee" className="text-muted">
{formatNumber(fee, decimals)}
{addDecimalsFormatNumber(fee, decimals)}
</div>
</div>
{discount && discount !== '0' && (
<div className="flex flex-wrap items-center justify-between gap-1">
<div>{t('Discount')}</div>
<div data-testid="discount" className="text-muted">
{formatNumber(discount, decimals)}
{addDecimalsFormatNumber(discount, decimals)}
</div>
</div>
)}
@ -513,7 +511,7 @@ export const TransferFee = ({
</Tooltip>
<div data-testid="transfer-amount" className="text-muted">
{formatNumber(amount, decimals)}
{addDecimalsFormatNumber(amount, decimals)}
</div>
</div>
<div className="flex flex-wrap items-center justify-between gap-1">
@ -526,7 +524,7 @@ export const TransferFee = ({
</Tooltip>
<div data-testid="total-transfer-fee" className="text-muted">
{formatNumber(totalValue, decimals)}
{addDecimalsFormatNumber(totalValue, decimals)}
</div>
</div>
</div>

View File

@ -35,7 +35,6 @@
"The total amount of each asset on this key. Includes used and available collateral.": "The total amount of each asset on this key. Includes used and available collateral.",
"The total amount taken from your account. The amount to be transferred plus the fee.": "The total amount taken from your account. The amount to be transferred plus the fee.",
"The total amount to be transferred (without the fee)": "The total amount to be transferred (without the fee)",
"The transfer fee is set by the network parameter transfer.fee.factor, currently set to {{feeFactor}}": "The transfer fee is set by the network parameter transfer.fee.factor, currently set to {{feeFactor}}",
"To account": "To account",
"To Vega key": "To Vega key",
"Total": "Total",

View File

@ -40,8 +40,6 @@
## Transfer
- **Must** display tooltip for "Transfer fee when hovered over.(<a name="1003-TRAN-017" href="#1003-TRAN-017">1003-TRAN-017</a>)
- **Must** display tooltip for "Amount to be transferred" when hovered over.(<a name="1003-TRAN-018" href="#1003-TRAN-018">1003-TRAN-018</a>)
- **Must** display tooltip for "Total amount (with fee)" when hovered over.(<a name="1003-TRAN-019" href="#1003-TRAN-019">1003-TRAN-019</a>)