mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-27 04:46:10 +01:00
f49e5076f3
This is a pure refactor that extracts the SRP input from the `CreateNewVault` component. This is intended to make future changes to the SRP input easier, and to reduce duplication between the old and new onboarding flows. Extensive unit tests have been added for the new SRP input component. A new test library was added (`@testing-library/user-event`) for simulating user events with components rendered using the `@testing-library` library. A new helper method has been added (`renderWithLocalization`) for rendering components using `@testing-library` with just our localization contexts added as a wrapper. The localization contexts were already added by the `renderWithProviders` helper function, but there is no need for a Redux provider in these unit tests.
113 lines
3.4 KiB
JavaScript
113 lines
3.4 KiB
JavaScript
import { ethers } from 'ethers';
|
|
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 CheckBox from '../../ui/check-box';
|
|
import Typography from '../../ui/typography';
|
|
import { COLORS } from '../../../helpers/constants/design-system';
|
|
import { parseSecretRecoveryPhrase } from './parse-secret-recovery-phrase';
|
|
|
|
const { isValidMnemonic } = ethers.utils;
|
|
|
|
export default function SrpInput({ onChange }) {
|
|
const [srpError, setSrpError] = useState('');
|
|
const [draftSrp, setDraftSrp] = useState('');
|
|
const [showSrp, setShowSrp] = useState(false);
|
|
|
|
const t = useI18nContext();
|
|
|
|
const onSrpChange = useCallback(
|
|
(event) => {
|
|
const rawSrp = event.target.value;
|
|
let newSrpError = '';
|
|
const parsedSeedPhrase = parseSecretRecoveryPhrase(rawSrp);
|
|
|
|
if (rawSrp) {
|
|
const wordCount = parsedSeedPhrase.split(/\s/u).length;
|
|
if (wordCount % 3 !== 0 || wordCount > 24 || wordCount < 12) {
|
|
newSrpError = t('seedPhraseReq');
|
|
} else if (!isValidMnemonic(parsedSeedPhrase)) {
|
|
newSrpError = t('invalidSeedPhrase');
|
|
}
|
|
}
|
|
|
|
setDraftSrp(rawSrp);
|
|
setSrpError(newSrpError);
|
|
onChange(newSrpError ? '' : parsedSeedPhrase);
|
|
},
|
|
[setDraftSrp, setSrpError, t, onChange],
|
|
);
|
|
|
|
const toggleShowSrp = useCallback(() => {
|
|
setShowSrp((currentShowSrp) => !currentShowSrp);
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<label htmlFor="import-srp__srp" className="import-srp__srp-label">
|
|
<Typography>{t('secretRecoveryPhrase')}</Typography>
|
|
</label>
|
|
{showSrp ? (
|
|
<textarea
|
|
id="import-srp__srp"
|
|
className="import-srp__srp-shown"
|
|
onChange={onSrpChange}
|
|
onPaste={clearClipboard}
|
|
value={draftSrp}
|
|
placeholder={t('seedPhrasePlaceholder')}
|
|
autoComplete="off"
|
|
/>
|
|
) : (
|
|
<TextField
|
|
id="import-srp__srp"
|
|
type="password"
|
|
onChange={onSrpChange}
|
|
value={draftSrp}
|
|
placeholder={t('seedPhrasePlaceholderPaste')}
|
|
autoComplete="off"
|
|
onPaste={clearClipboard}
|
|
/>
|
|
)}
|
|
{srpError ? (
|
|
<Typography
|
|
color={COLORS.ERROR1}
|
|
tag="span"
|
|
className="import-srp__srp-error"
|
|
>
|
|
{srpError}
|
|
</Typography>
|
|
) : null}
|
|
<div className="import-srp__show-srp">
|
|
<CheckBox
|
|
id="import-srp__show-srp-checkbox"
|
|
checked={showSrp}
|
|
onClick={toggleShowSrp}
|
|
title={t('showSeedPhrase')}
|
|
/>
|
|
<label
|
|
className="import-srp__show-srp-label"
|
|
htmlFor="import-srp__show-srp-checkbox"
|
|
>
|
|
<Typography tag="span">{t('showSeedPhrase')}</Typography>
|
|
</label>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
SrpInput.propTypes = {
|
|
/**
|
|
* Event handler for SRP changes.
|
|
*
|
|
* This is only called with a valid, well-formated (i.e. exactly one space
|
|
* between each word) SRP or with an empty string.
|
|
*
|
|
* This is called each time the draft SRP is updated. If the draft SRP is
|
|
* valid, this is called with a well-formatted version of that draft SRP.
|
|
* Otherwise, this is called with an empty string.
|
|
*/
|
|
onChange: PropTypes.func.isRequired,
|
|
};
|