Mnemonic Delimiters (#552)

This commit is contained in:
timeffect 2017-12-14 20:08:24 -05:00 committed by Daniel Ternyak
parent 712af1418d
commit bc19c877a5
3 changed files with 49 additions and 11 deletions

View File

@ -3,6 +3,7 @@ import DPATHS from 'config/dpaths';
import React, { Component } from 'react'; import React, { Component } from 'react';
import translate, { translateRaw } from 'translations'; import translate, { translateRaw } from 'translations';
import DeterministicWalletsModal from './DeterministicWalletsModal'; import DeterministicWalletsModal from './DeterministicWalletsModal';
import { formatMnemonic } from 'utils/formatters';
const DEFAULT_PATH = DPATHS.MNEMONIC[0].value; const DEFAULT_PATH = DPATHS.MNEMONIC[0].value;
@ -11,6 +12,7 @@ interface Props {
} }
interface State { interface State {
phrase: string; phrase: string;
formattedPhrase: string;
pass: string; pass: string;
seed: string; seed: string;
dPath: string; dPath: string;
@ -19,14 +21,15 @@ interface State {
export default class MnemonicDecrypt extends Component<Props, State> { export default class MnemonicDecrypt extends Component<Props, State> {
public state: State = { public state: State = {
phrase: '', phrase: '',
formattedPhrase: '',
pass: '', pass: '',
seed: '', seed: '',
dPath: DEFAULT_PATH dPath: DEFAULT_PATH
}; };
public render() { public render() {
const { phrase, seed, dPath, pass } = this.state; const { phrase, formattedPhrase, seed, dPath, pass } = this.state;
const isValidMnemonic = validateMnemonic(phrase); const isValidMnemonic = validateMnemonic(formattedPhrase);
return ( return (
<section className="col-md-4 col-sm-6"> <section className="col-md-4 col-sm-6">
@ -85,19 +88,25 @@ export default class MnemonicDecrypt extends Component<Props, State> {
this.setState({ pass: (e.target as HTMLInputElement).value }); this.setState({ pass: (e.target as HTMLInputElement).value });
}; };
public onMnemonicChange = (e: React.SyntheticEvent<HTMLTextAreaElement>) => { public onMnemonicChange = (e: React.FormEvent<HTMLTextAreaElement>) => {
this.setState({ phrase: (e.target as HTMLTextAreaElement).value }); const phrase = e.currentTarget.value;
const formattedPhrase = formatMnemonic(phrase);
this.setState({
phrase,
formattedPhrase
});
}; };
public onDWModalOpen = () => { public onDWModalOpen = () => {
const { phrase, pass } = this.state; const { formattedPhrase, pass } = this.state;
if (!validateMnemonic(phrase)) { if (!validateMnemonic(formattedPhrase)) {
return; return;
} }
try { try {
const seed = mnemonicToSeed(phrase.trim(), pass).toString('hex'); const seed = mnemonicToSeed(formattedPhrase, pass).toString('hex');
this.setState({ seed }); this.setState({ seed });
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@ -113,19 +122,20 @@ export default class MnemonicDecrypt extends Component<Props, State> {
}; };
private handleUnlock = (address, index) => { private handleUnlock = (address, index) => {
const { phrase, pass, dPath } = this.state; const { formattedPhrase, pass, dPath } = this.state;
this.props.onUnlock({ this.props.onUnlock({
path: `${dPath}/${index}`, path: `${dPath}/${index}`,
pass, pass,
phrase, phrase: formattedPhrase,
address address
}); });
this.setState({ this.setState({
seed: '', seed: '',
pass: '', pass: '',
phrase: '' phrase: '',
formattedPhrase: ''
}); });
}; };
} }

View File

@ -94,3 +94,11 @@ export function formatGasLimit(limit: Wei, transactionUnit: string = 'ether') {
return limitStr; return limitStr;
} }
// Regex modified from this stackoverflow answer
// https://stackoverflow.com/a/10805198, with the comma character added as a
// delimiter (in the case of csv style mnemonic phrases) as well as any stray
// space characters. it should be fairly easy to add new delimiters as required
export function formatMnemonic(phrase: string) {
return phrase.replace(/(\r\n|\n|\r|\s+|,)/gm," ").trim();
};

View File

@ -2,7 +2,8 @@ import { Wei } from 'libs/units';
import { import {
toFixedIfLarger, toFixedIfLarger,
formatNumber, formatNumber,
formatGasLimit formatGasLimit,
formatMnemonic
} from '../../common/utils/formatters'; } from '../../common/utils/formatters';
describe('toFixedIfLarger', () => { describe('toFixedIfLarger', () => {
@ -93,3 +94,22 @@ describe('formatGasLimit', () => {
expect(formatGasLimit(Wei('1234'))).toEqual('1234'); expect(formatGasLimit(Wei('1234'))).toEqual('1234');
}); });
}); });
describe('formatMnemonic', () => {
const testPhraseNewLines = "first\ncatalog\naway\nfaculty\njelly\nnow\nlife\nkingdom\npigeon\nraise\ngain\naccident";
const testPhraseExtraSpaces = "first catalog away faculty jelly now life kingdom pigeon raise gain accident ";
const testPhraseCommas = "first,catalog,away,faculty,jelly,now,life,kingdom,pigeon,raise,gain,accident";
const formattedTestPhrase = "first catalog away faculty jelly now life kingdom pigeon raise gain accident";
it('should format phrases with new lines as a phrase with just spaces', () => {
expect(formatMnemonic(testPhraseNewLines)).toEqual(formattedTestPhrase);
})
it('should remove commas and replace with space characters', () => {
expect(formatMnemonic(testPhraseCommas)).toEqual(formattedTestPhrase);
})
it('should trim any stray space characters throughout the phrase', () => {
expect(formatMnemonic(testPhraseExtraSpaces)).toEqual(formattedTestPhrase);
})
})