diff --git a/web/cashtab/src/components/Common/Ticker.js b/web/cashtab/src/components/Common/Ticker.js --- a/web/cashtab/src/components/Common/Ticker.js +++ b/web/cashtab/src/components/Common/Ticker.js @@ -11,7 +11,7 @@ prefixes: ['bitcoincash', 'ecash'], coingeckoId: 'bitcoin-cash-abc-2', defaultFee: 5.01, - dust: 0.00001, // The minimum amount of BCHA that can be sent by the app + dust: '0.00000546', // The minimum amount of BCHA that can be sent by the app blockExplorerUrl: 'https://explorer.bitcoinabc.org', blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org', tokenName: 'Bitcoin ABC SLP', 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 @@ -4,6 +4,7 @@ import { Form, notification, message, Spin, Modal, Alert } from 'antd'; import { CashLoader, CashLoadingIcon } from '@components/Common/CustomIcons'; import { Row, Col } from 'antd'; +import BigNumber from 'bignumber.js'; import Paragraph from 'antd/lib/typography/Paragraph'; import PrimaryButton, { SecondaryButton, @@ -344,7 +345,7 @@ error = 'Amount must be a number'; } else if (bchValue <= 0) { error = 'Amount must be greater than 0'; - } else if (bchValue < currency.dust) { + } else if (new BigNumber(bchValue).lt(new BigNumber(currency.dust))) { error = `Send amount must be at least ${currency.dust} ${currency.ticker}`; } else if (bchValue > balances.totalBalance) { error = `Amount cannot exceed your ${currency.ticker} balance`; diff --git a/web/cashtab/src/hooks/__tests__/useBCH.test.js b/web/cashtab/src/hooks/__tests__/useBCH.test.js --- a/web/cashtab/src/hooks/__tests__/useBCH.test.js +++ b/web/cashtab/src/hooks/__tests__/useBCH.test.js @@ -150,6 +150,25 @@ expect(nullValuesSendBch).toBe(null); }); + it('Throws error on attempt to send less than dust limit', async () => { + const { sendBch } = useBCH(); + const BCH = new BCHJS(); + const { expectedTxId, utxos, wallet, addresses } = sendBCHMock; + BCH.RawTransactions.sendRawTransaction = jest + .fn() + .mockResolvedValue(expectedTxId); + const failedSendBch = sendBch(BCH, wallet, utxos, { + addresses, + values: ['0.00000545'], + }); + expect(failedSendBch).rejects.toThrow(new Error('dust')); + const nullValuesSendBch = await sendBch(BCH, wallet, utxos, { + addresses, + values: null, + }); + expect(nullValuesSendBch).toBe(null); + }); + it('receives errors from the network and parses it', async () => { const { sendBch } = useBCH(); const BCH = new BCHJS(); diff --git a/web/cashtab/src/hooks/useBCH.js b/web/cashtab/src/hooks/useBCH.js --- a/web/cashtab/src/hooks/useBCH.js +++ b/web/cashtab/src/hooks/useBCH.js @@ -425,6 +425,9 @@ (previous, current) => new BigNumber(current).plus(previous), new BigNumber(0), ); + if (value.lt(new BigNumber(currency.dust))) { + throw new Error('dust'); + } const REMAINDER_ADDR = wallet.Path1899.cashAddress; const inputUtxos = []; let transactionBuilder;