diff --git a/web/cashtab/src/components/Configure/Configure.js b/web/cashtab/src/components/Configure/Configure.js --- a/web/cashtab/src/components/Configure/Configure.js +++ b/web/cashtab/src/components/Configure/Configure.js @@ -57,6 +57,7 @@ import { isValidXecAddress, isValidNewWalletNameLength, + validateMnemonic, } from 'utils/validation'; import { convertToEcashPrefix } from 'utils/cashMethods'; import useWindowDimensions from 'hooks/useWindowDimensions'; @@ -479,7 +480,6 @@ renameSavedWallet, renameActiveWallet, deleteWallet, - validateMnemonic, getSavedWallets, cashtabSettings, changeCashtabSettings, diff --git a/web/cashtab/src/components/OnBoarding/OnBoarding.js b/web/cashtab/src/components/OnBoarding/OnBoarding.js --- a/web/cashtab/src/components/OnBoarding/OnBoarding.js +++ b/web/cashtab/src/components/OnBoarding/OnBoarding.js @@ -15,6 +15,7 @@ } from 'components/Common/PrimaryButton'; import { currency } from 'components/Common/Ticker.js'; import { Event } from 'utils/GoogleAnalytics'; +import { validateMnemonic } from 'utils/validation'; export const WelcomeCtn = styled.div` margin-top: 20px; @@ -43,7 +44,7 @@ const OnBoarding = () => { const ContextValue = React.useContext(WalletContext); - const { createWallet, validateMnemonic } = ContextValue; + const { createWallet } = ContextValue; const [formData, setFormData] = useState({ dirty: true, mnemonic: '', diff --git a/web/cashtab/src/hooks/useWallet.js b/web/cashtab/src/hooks/useWallet.js --- a/web/cashtab/src/hooks/useWallet.js +++ b/web/cashtab/src/hooks/useWallet.js @@ -837,23 +837,6 @@ return wallet; }; - const validateMnemonic = (mnemonic, wordlist = bip39.wordlists.english) => { - try { - if (!mnemonic || !wordlist) return false; - - // Preprocess the words - const words = mnemonic.split(' '); - // Detect blank phrase - if (words.length === 0) return false; - - // Check the words are valid - return bip39.validateMnemonic(mnemonic, wordlist); - } catch (err) { - console.log(err); - return false; - } - }; - // Parse chronik ws message for incoming tx notifications const processChronikWsMsg = async (msg, wallet, fiatPrice) => { // get the message type @@ -1450,7 +1433,6 @@ changeCashtabSettings, getActiveWalletFromLocalForage, getWallet, - validateMnemonic, getWalletDetails, getSavedWallets, migrateLegacyWallet, 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 @@ -21,6 +21,7 @@ isValidContactList, parseInvalidSettingsForMigration, isValidCashtabCache, + validateMnemonic, } from '../validation'; import { currency } from 'components/Common/Ticker.js'; import { fromSatoshisToXec } from 'utils/cashMethods'; @@ -50,6 +51,20 @@ } from 'utils/__mocks__/mockCashtabCache'; describe('Validation utils', () => { + it(`validateMnemonic() returns true for a valid mnemonic`, () => { + const mnemonic = + 'labor tail bulb distance estate collect lecture into smile differ yard legal'; + expect(validateMnemonic(mnemonic)).toBe(true); + }); + it(`validateMnemonic() returns false for an invalid mnemonic`, () => { + const mnemonic = + 'labor tail bulb not valid collect lecture into smile differ yard legal'; + expect(validateMnemonic(mnemonic)).toBe(false); + }); + it(`validateMnemonic() returns false for an empty string mnemonic`, () => { + const mnemonic = ''; + expect(validateMnemonic(mnemonic)).toBe(false); + }); it(`Returns 'false' if ${currency.ticker} send amount is a valid send amount`, () => { expect(shouldRejectAmountInput('10', currency.ticker, 20.0, 300)).toBe( false, 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 @@ -2,6 +2,27 @@ import { currency } from 'components/Common/Ticker.js'; import { fromSatoshisToXec } from 'utils/cashMethods'; import cashaddr from 'ecashaddrjs'; +import * as bip39 from 'bip39'; + +export const validateMnemonic = ( + mnemonic, + wordlist = bip39.wordlists.english, +) => { + try { + if (!mnemonic || !wordlist) return false; + + // Preprocess the words + const words = mnemonic.split(' '); + // Detect blank phrase + if (words.length === 0) return false; + + // Check the words are valid + return bip39.validateMnemonic(mnemonic, wordlist); + } catch (err) { + console.log(err); + return false; + } +}; // Validate cash amount export const shouldRejectAmountInput = (