From 8cfcb8ef7967edb044fc4fc5a5982d053048bb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Mon, 5 Feb 2024 11:40:46 +0100 Subject: [PATCH] feat(accounts): get trasfer fee from estimateTransferFee API --- libs/accounts/src/lib/transfer-container.tsx | 1 - libs/accounts/src/lib/transfer-form.spec.tsx | 141 +++++++++++-------- libs/accounts/src/lib/transfer-form.tsx | 40 +++--- libs/i18n/src/locales/en/accounts.json | 1 - specs/1003-TRAN-transfer.md | 2 - 5 files changed, 99 insertions(+), 86 deletions(-) diff --git a/libs/accounts/src/lib/transfer-container.tsx b/libs/accounts/src/lib/transfer-container.tsx index 306aa2147..84ab0d1d1 100644 --- a/libs/accounts/src/lib/transfer-container.tsx +++ b/libs/accounts/src/lib/transfer-container.tsx @@ -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, ]); diff --git a/libs/accounts/src/lib/transfer-form.spec.tsx b/libs/accounts/src/lib/transfer-form.spec.tsx index 369e52ced..d1eb6d738 100644 --- a/libs/accounts/src/lib/transfer-form.spec.tsx +++ b/libs/accounts/src/lib/transfer-form.spec.tsx @@ -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(); - - 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(); + 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); }); }); }); diff --git a/libs/accounts/src/lib/transfer-form.tsx b/libs/accounts/src/lib/transfer-form.tsx index f6e689e60..11622259e 100644 --- a/libs/accounts/src/lib/transfer-form.tsx +++ b/libs/accounts/src/lib/transfer-form.tsx @@ -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 = ({ )} - {(transferFee?.estimateTransferFee || fromVested) && amount && ( + {JSON.stringify(transferFee)} + {(transferFee?.estimateTransferFee || fromVested) && amount && asset && ( )} @@ -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 (
- -
{t('Transfer fee')}
-
- +
{t('Transfer fee')}
- {formatNumber(fee, decimals)} + {addDecimalsFormatNumber(fee, decimals)}
{discount && discount !== '0' && (
{t('Discount')}
- {formatNumber(discount, decimals)} + {addDecimalsFormatNumber(discount, decimals)}
)} @@ -513,7 +511,7 @@ export const TransferFee = ({
- {formatNumber(amount, decimals)} + {addDecimalsFormatNumber(amount, decimals)}
@@ -526,7 +524,7 @@ export const TransferFee = ({
- {formatNumber(totalValue, decimals)} + {addDecimalsFormatNumber(totalValue, decimals)}
diff --git a/libs/i18n/src/locales/en/accounts.json b/libs/i18n/src/locales/en/accounts.json index cface53cb..8f5259e75 100644 --- a/libs/i18n/src/locales/en/accounts.json +++ b/libs/i18n/src/locales/en/accounts.json @@ -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", diff --git a/specs/1003-TRAN-transfer.md b/specs/1003-TRAN-transfer.md index b6d08f33f..9f014c3de 100644 --- a/specs/1003-TRAN-transfer.md +++ b/specs/1003-TRAN-transfer.md @@ -40,8 +40,6 @@ ## Transfer -- **Must** display tooltip for "Transfer fee when hovered over.(1003-TRAN-017) - - **Must** display tooltip for "Amount to be transferred" when hovered over.(1003-TRAN-018) - **Must** display tooltip for "Total amount (with fee)" when hovered over.(1003-TRAN-019)