import { isValidMnemonic } from '@ethersproject/hdnode'; import React, { useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import { useI18nContext } from '../../../hooks/useI18nContext'; import TextField from '../../ui/text-field'; import { clearClipboard } from '../../../helpers/utils/util'; import ActionableMessage from '../../ui/actionable-message'; import Dropdown from '../../ui/dropdown'; import Typography from '../../ui/typography'; import ShowHideToggle from '../../ui/show-hide-toggle'; import { FONT_WEIGHT, TEXT_ALIGN, TYPOGRAPHY, } from '../../../helpers/constants/design-system'; import { parseSecretRecoveryPhrase } from './parse-secret-recovery-phrase'; const defaultNumberOfWords = 12; const hasUpperCase = (draftSrp) => { return draftSrp !== draftSrp.toLowerCase(); }; export default function SrpInput({ onChange, srpText }) { const [srpError, setSrpError] = useState(''); const [pasteFailed, setPasteFailed] = useState(false); const [draftSrp, setDraftSrp] = useState( new Array(defaultNumberOfWords).fill(''), ); const [showSrp, setShowSrp] = useState( new Array(defaultNumberOfWords).fill(false), ); const [numberOfWords, setNumberOfWords] = useState(defaultNumberOfWords); const t = useI18nContext(); const onSrpChange = useCallback( (newDraftSrp) => { let newSrpError = ''; const joinedDraftSrp = newDraftSrp.join(' ').trim(); if (newDraftSrp.some((word) => word !== '')) { if (newDraftSrp.some((word) => word === '')) { newSrpError = t('seedPhraseReq'); } else if (hasUpperCase(joinedDraftSrp)) { newSrpError = t('invalidSeedPhraseCaseSensitive'); } else if (!isValidMnemonic(joinedDraftSrp)) { newSrpError = t('invalidSeedPhrase'); } } setDraftSrp(newDraftSrp); setSrpError(newSrpError); onChange(newSrpError ? '' : joinedDraftSrp); }, [setDraftSrp, setSrpError, t, onChange], ); const toggleShowSrp = useCallback((index) => { setShowSrp((currentShowSrp) => { const newShowSrp = currentShowSrp.slice(); if (newShowSrp[index]) { newShowSrp[index] = false; } else { newShowSrp.fill(false); newShowSrp[index] = true; } return newShowSrp; }); }, []); const onSrpWordChange = useCallback( (index, newWord) => { if (pasteFailed) { setPasteFailed(false); } const newSrp = draftSrp.slice(); newSrp[index] = newWord.trim(); onSrpChange(newSrp); }, [draftSrp, onSrpChange, pasteFailed], ); const onSrpPaste = useCallback( (rawSrp) => { const parsedSrp = parseSecretRecoveryPhrase(rawSrp); let newDraftSrp = parsedSrp.split(' '); if (newDraftSrp.length > 24) { setPasteFailed(true); return; } else if (pasteFailed) { setPasteFailed(false); } let newNumberOfWords = numberOfWords; if (newDraftSrp.length !== numberOfWords) { if (newDraftSrp.length < 12) { newNumberOfWords = 12; } else if (newDraftSrp.length % 3 === 0) { newNumberOfWords = newDraftSrp.length; } else { newNumberOfWords = newDraftSrp.length + (3 - (newDraftSrp.length % 3)); } setNumberOfWords(newNumberOfWords); } if (newDraftSrp.length < newNumberOfWords) { newDraftSrp = newDraftSrp.concat( new Array(newNumberOfWords - newDraftSrp.length).fill(''), ); } setShowSrp(new Array(newNumberOfWords).fill(false)); onSrpChange(newDraftSrp); clearClipboard(); }, [numberOfWords, onSrpChange, pasteFailed, setPasteFailed], ); const numberOfWordsOptions = []; for (let i = 12; i <= 24; i += 3) { numberOfWordsOptions.push({ name: t('srpInputNumberOfWords', [`${i}`]), value: `${i}`, }); } return (