From 7564e249d1d6f255860c8fe06220ef29bdd8c720 Mon Sep 17 00:00:00 2001 From: DenysKarmazynDFINITY Date: Fri, 15 Nov 2024 13:46:43 +0100 Subject: [PATCH] feat(frontend): validateConvertAmount util --- src/frontend/src/lib/utils/convert.utils.ts | 41 ++++++++++++++ .../src/tests/lib/utils/convert.utils.spec.ts | 53 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 src/frontend/src/lib/utils/convert.utils.ts create mode 100644 src/frontend/src/tests/lib/utils/convert.utils.spec.ts diff --git a/src/frontend/src/lib/utils/convert.utils.ts b/src/frontend/src/lib/utils/convert.utils.ts new file mode 100644 index 0000000000..2abd3b3550 --- /dev/null +++ b/src/frontend/src/lib/utils/convert.utils.ts @@ -0,0 +1,41 @@ +import { ZERO } from '$lib/constants/app.constants'; +import type { ConvertAmountErrorType } from '$lib/types/convert'; +import { formatToken } from '$lib/utils/format.utils'; +import { isNullish, nonNullish } from '@dfinity/utils'; +import { BigNumber } from '@ethersproject/bignumber'; +import { Utils } from 'alchemy-sdk'; + +export const validateConvertAmount = ({ + userAmount, + decimals, + balance, + totalFee +}: { + userAmount: BigNumber; + decimals: number; + balance?: BigNumber; + totalFee?: bigint; +}): ConvertAmountErrorType => { + if (isNullish(totalFee)) { + return; + } + // We should align balance and userAmount to avoid issues caused by comparing formatted and unformatted BN + const parsedSendBalance = nonNullish(balance) + ? Utils.parseUnits( + formatToken({ + value: balance, + unitName: decimals, + displayDecimals: decimals + }), + decimals + ) + : ZERO; + + if (userAmount.gt(parsedSendBalance)) { + return 'insufficient-funds'; + } + + if (nonNullish(totalFee) && userAmount.add(totalFee).gt(parsedSendBalance)) { + return 'insufficient-funds-for-fee'; + } +}; diff --git a/src/frontend/src/tests/lib/utils/convert.utils.spec.ts b/src/frontend/src/tests/lib/utils/convert.utils.spec.ts new file mode 100644 index 0000000000..aa1a6e1ca3 --- /dev/null +++ b/src/frontend/src/tests/lib/utils/convert.utils.spec.ts @@ -0,0 +1,53 @@ +import { validateConvertAmount } from '$lib/utils/convert.utils'; +import { BigNumber } from 'alchemy-sdk'; +import { describe } from 'vitest'; + +describe('validateConvertAmount', () => { + const userAmount = BigNumber.from(200000n); + const decimals = 8; + const balance = BigNumber.from(9000000n); + const totalFee = 10000n; + + it('should return undefined if all data satisfies the conditions', () => { + expect( + validateConvertAmount({ + userAmount, + decimals, + balance, + totalFee + }) + ).toBeUndefined(); + }); + + it('should return undefined if totalFee is undefined', () => { + expect( + validateConvertAmount({ + userAmount, + decimals, + balance + }) + ).toBeUndefined(); + }); + + it('should return insufficient funds error', () => { + expect( + validateConvertAmount({ + userAmount: balance.add(userAmount), + decimals, + balance, + totalFee + }) + ).toBe('insufficient-funds'); + }); + + it('should return insufficient funds for fee error', () => { + expect( + validateConvertAmount({ + userAmount: balance.sub(BigNumber.from(totalFee).div(2)), + decimals, + balance, + totalFee + }) + ).toBe('insufficient-funds-for-fee'); + }); +});