diff --git a/web/cashtab/src/components/Send/Send.js b/web/cashtab/src/components/Send/Send.js --- a/web/cashtab/src/components/Send/Send.js +++ b/web/cashtab/src/components/Send/Send.js @@ -22,7 +22,7 @@ toLegacy, } from '@components/Common/Ticker.js'; import { Event } from '@utils/GoogleAnalytics'; -import { shouldRejectAmountInput } from '@utils/validation'; +import { fiatToCrypto, shouldRejectAmountInput } from '@utils/validation'; export const BalanceHeader = styled.div` p { color: #777; @@ -209,7 +209,7 @@ let bchValue = value; if (selectedCurrency === 'USD') { - bchValue = (value / fiatPrice).toFixed(8); + bchValue = fiatToCrypto(value, fiatPrice); } try { @@ -379,9 +379,9 @@ 2, )} USD`; } else { - fiatPriceString = `${(Number(formData.value) / fiatPrice).toFixed( - 8, - )} ${currency.ticker}`; + fiatPriceString = `${ + formData.value ? fiatToCrypto(formData.value, fiatPrice) : '0' + } ${currency.ticker}`; } } diff --git a/web/cashtab/src/utils/__tests__/validation.test.js b/web/cashtab/src/utils/__tests__/validation.test.js --- a/web/cashtab/src/utils/__tests__/validation.test.js +++ b/web/cashtab/src/utils/__tests__/validation.test.js @@ -1,5 +1,6 @@ -import { shouldRejectAmountInput } from '../validation'; +import { shouldRejectAmountInput, fiatToCrypto } from '../validation'; import { currency } from '@components/Common/Ticker.js'; +import BigNumber from 'bignumber.js'; describe('Validation utils', () => { it(`Returns 'false' if ${currency.ticker} send amount is a valid send amount`, () => { @@ -71,4 +72,13 @@ shouldRejectAmountInput('17.123456789', currency.ticker, 20.0, 35), ).toBe(expectedValidationError); }); + it(`Returns a crypto amount with 8 decimals of precision`, () => { + let testConvertedCryptoAmount = fiatToCrypto( + '10.97231694823432', + 20.3231342349234234, + ); + expect( + testConvertedCryptoAmount.toString().split('.')[1].length === 8, + ).toBe(true); + }); }); diff --git a/web/cashtab/src/utils/validation.js b/web/cashtab/src/utils/validation.js --- a/web/cashtab/src/utils/validation.js +++ b/web/cashtab/src/utils/validation.js @@ -1,3 +1,4 @@ +import BigNumber from 'bignumber.js'; import { currency } from '@components/Common/Ticker.js'; // Validate cash amount @@ -9,20 +10,21 @@ ) => { // Take cashAmount as input, a string from form input let error = false; - let testedAmount = cashAmount; + let testedAmount = new BigNumber(cashAmount); if (selectedCurrency === 'USD') { - testedAmount = (cashAmount / fiatPrice).toFixed(8); + // Ensure no more than 8 decimal places + testedAmount = fiatToCrypto(cashAmount, fiatPrice); } // Validate value for > 0 if (isNaN(testedAmount)) { error = 'Amount must be a number'; - } else if (testedAmount <= 0) { + } else if (testedAmount.lte(0)) { error = 'Amount must be greater than 0'; - } else if (testedAmount < currency.dust) { + } else if (testedAmount.lt(currency.dust)) { error = `Send amount must be at least ${currency.dust} ${currency.ticker}`; - } else if (testedAmount > totalCashBalance) { + } else if (testedAmount.gt(totalCashBalance)) { error = `Amount cannot exceed your ${currency.ticker} balance`; } else if (!isNaN(testedAmount) && testedAmount.toString().includes('.')) { if (testedAmount.toString().split('.')[1].length > 8) { @@ -32,3 +34,11 @@ // return false if no error, or string error msg if error return error; }; + +export const fiatToCrypto = (fiatAmount, fiatPrice) => { + // Ensure no more than 8 decimal places + let cryptoAmount = new BigNumber( + new BigNumber(fiatAmount).div(new BigNumber(fiatPrice)).toFixed(8), + ); + return cryptoAmount; +};