diff --git a/specs/util/suri.spec.js b/specs/util/suri.spec.js
index 1f1502b5bf..d58fef63dd 100644
--- a/specs/util/suri.spec.js
+++ b/specs/util/suri.spec.js
@@ -78,6 +78,22 @@ describe('suri', () => {
'SURI must contain a phrase.'
);
});
+
+ it('should parse string with extra spaces as brain wallet', () => {
+ const extraSpaces = ' great sparta ';
+ expect(parseSURI(extraSpaces)).toEqual({
+ derivePath: '',
+ password: '',
+ phrase: ' great sparta '
+ });
+
+ const extraSpacesWithPath = ' great sparta //hard/soft///password';
+ expect(parseSURI(extraSpacesWithPath)).toEqual({
+ derivePath: '//hard/soft',
+ password: 'password',
+ phrase: ' great sparta '
+ });
+ });
});
describe('constructing', () => {
diff --git a/src/screens/AccountRecover.js b/src/screens/AccountRecover.js
index c945a3a30f..01264d2fb8 100644
--- a/src/screens/AccountRecover.js
+++ b/src/screens/AccountRecover.js
@@ -38,10 +38,7 @@ import { emptyAccount, validateSeed } from '../util/account';
import { debounce } from '../util/debounce';
import { brainWalletAddress, substrateAddress } from '../util/native';
import { constructSURI } from '../util/suri';
-import {
- alertErrorWithMessage,
- alertInvalidSeedRecovery
-} from '../util/alertUtils';
+import { alertErrorWithMessage, alertRisks } from '../util/alertUtils';
export default class AccountRecover extends React.PureComponent {
render() {
@@ -173,7 +170,11 @@ class AccountRecoverView extends React.PureComponent {
if (!validation.valid) {
if (validation.accountRecoveryAllowed) {
- return alertInvalidSeedRecovery(`${validation.reason}`, navigation);
+ return alertRisks(`${validation.reason}`, () =>
+ navigation.navigate('AccountPin', {
+ isNew: true
+ })
+ );
} else {
return alertErrorWithMessage(`${validation.reason}`, 'Back');
}
diff --git a/src/screens/IdentityNew.js b/src/screens/IdentityNew.js
index 079ccd5347..9a55802879 100644
--- a/src/screens/IdentityNew.js
+++ b/src/screens/IdentityNew.js
@@ -32,14 +32,21 @@ import {
navigateToNewIdentityNetwork,
setPin
} from '../util/navigationHelpers';
-import { alertIdentityCreationError } from '../util/alertUtils';
+import {
+ alertErrorWithMessage,
+ alertIdentityCreationError,
+ alertRisks
+} from '../util/alertUtils';
import testIDs from '../../e2e/testIDs';
import ScreenHeading from '../components/ScreenHeading';
import KeyboardScrollView from '../components/KeyboardScrollView';
+import { brainWalletAddress } from '../util/native';
+import { debounce } from '../util/debounce';
function IdentityNew({ accounts, navigation }) {
const isRecoverDefaultValue = navigation.getParam('isRecover', false);
const [isRecover, setIsRecover] = useState(isRecoverDefaultValue);
+ const [isSeedValid, setIsSeedValid] = useState(false);
const [seedPhrase, setSeedPhrase] = useState('');
useEffect(() => {
@@ -52,6 +59,18 @@ function IdentityNew({ accounts, navigation }) {
accounts.updateNewIdentity({ name });
};
+ const onSeedTextInput = inputSeedPhrase => {
+ setSeedPhrase(inputSeedPhrase);
+ const addressGeneration = () =>
+ brainWalletAddress(inputSeedPhrase)
+ .then(({ bip39 }) => {
+ setIsSeedValid(validateSeed(inputSeedPhrase, bip39));
+ })
+ .catch(() => setIsSeedValid(inputSeedPhrase, false));
+ const debouncedAddressGeneration = debounce(addressGeneration, 200);
+ debouncedAddressGeneration();
+ };
+
const onRecoverIdentity = async () => {
const pin = await setPin(navigation);
try {
@@ -63,6 +82,17 @@ function IdentityNew({ accounts, navigation }) {
}
};
+ const onRecoverConfirm = () => {
+ if (!isSeedValid.valid) {
+ if (isSeedValid.accountRecoveryAllowed) {
+ return alertRisks(`${isSeedValid.reason}`, onRecoverIdentity);
+ } else {
+ return alertErrorWithMessage(`${isSeedValid.reason}`, 'Back');
+ }
+ }
+ return onRecoverIdentity();
+ };
+
const onCreateNewIdentity = () => {
setSeedPhrase('');
navigation.navigate('IdentityBackup', {
@@ -74,8 +104,8 @@ function IdentityNew({ accounts, navigation }) {
<>
@@ -90,7 +120,7 @@ function IdentityNew({ accounts, navigation }) {
diff --git a/src/util/account.js b/src/util/account.js
index 4ddd83f148..45f3966e27 100644
--- a/src/util/account.js
+++ b/src/util/account.js
@@ -100,7 +100,7 @@ export function validateSeed(seed, validBip39Seed) {
return {
accountRecoveryAllowed: true,
reason:
- 'This recovery phrase will be treated as a legacy Parity brain wallet.',
+ 'This recovery phrase is not a valid BIP39 seed, will be treated as a legacy Parity brain wallet.',
valid: false
};
}
diff --git a/src/util/alertUtils.js b/src/util/alertUtils.js
index 443b648d74..e842345357 100644
--- a/src/util/alertUtils.js
+++ b/src/util/alertUtils.js
@@ -89,7 +89,7 @@ export const alertCopyBackupPhrase = seedPhrase =>
]
);
-const alertRisks = (message, onPress) =>
+export const alertRisks = (message, onPress) =>
Alert.alert('Warning', message, [
{
onPress,
@@ -102,13 +102,6 @@ const alertRisks = (message, onPress) =>
}
]);
-export const alertInvalidSeedRecovery = (message, navigation) =>
- alertRisks(message, () => {
- navigation.navigate('AccountPin', {
- isNew: true
- });
- });
-
export const alertMultipart = onNext =>
alertRisks(
'The payload of the transaction you are signing is too big to be decoded. Not seeing what you are signing is inherently unsafe. If possible, contact the developer of the application generating the transaction to ask for multipart support.',
diff --git a/src/util/debounce.js b/src/util/debounce.js
index b58e236d7e..3a674ee9c3 100644
--- a/src/util/debounce.js
+++ b/src/util/debounce.js
@@ -28,9 +28,9 @@
*
* @return {any} the debounced function
*/
-export function debounce(fn, time) {
- let timeout;
+let timeout;
+export function debounce(fn, time) {
return function() {
const functionCall = () => fn.apply(this, arguments);
diff --git a/src/util/suri.js b/src/util/suri.js
index 6c41f0899b..ccc9e3b7bf 100644
--- a/src/util/suri.js
+++ b/src/util/suri.js
@@ -36,7 +36,7 @@
*/
export function parseSURI(suri) {
- const RE_CAPTURE = /^(\w+(?: \w+)*)?(.*)$/;
+ const RE_CAPTURE = /^([\w ]+(?: +\w*)*)?(.*)$/;
const matches = suri.match(RE_CAPTURE);
let phrase,
parsedDerivationPath,