Skip to content

Commit 3095c6c

Browse files
committed
Unlock wallet screen is added to unlock with spending password
1 parent aaf6601 commit 3095c6c

File tree

9 files changed

+137
-8
lines changed

9 files changed

+137
-8
lines changed

examples/wallet/app/Routes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ChooseRestoreOrImport from './containers/ChooseRestoreOrImport';
1010
import Delegate from './pages/Delegate';
1111
import Index from './containers/Index';
1212
import InputKeys from './containers/InputKeys';
13+
import UnlockWallet from './containers/UnlockWallet';
1314

1415
export default () => (
1516
<App>
@@ -19,6 +20,7 @@ export default () => (
1920
<Route path={routes.STAKING} component={Delegate} />
2021
<Route path={routes.SETTINGS} component={Settings} />
2122
<Route path={routes.INPUT_KEYS} component={InputKeys} />
23+
<Route path={routes.UNLOCK_WALLET} component={UnlockWallet} />
2224
<Route
2325
path={routes.CHOOSE_RESTORE_OR_IMPORT}
2426
component={ChooseRestoreOrImport}

examples/wallet/app/actions/account.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type {
66
AppState,
77
Thunk,
88
AccountKeys,
9-
AccountState
9+
AccountState,
10+
SpendingPassword
1011
} from '../reducers/types';
1112
import type {
1213
Amount,
@@ -30,12 +31,20 @@ import {
3031
getTransactions
3132
} from '../utils/nodeConnection';
3233
import { isValidMnemonic, createSeedFromMnemonic } from '../utils/mnemonic';
33-
import { saveAccountInfoInDEN, saveSpendingPassword } from '../utils/storage';
34+
import {
35+
saveAccountInfoInDEN,
36+
saveSpendingPassword,
37+
readAccountKeysFromDEN
38+
} from '../utils/storage';
3439

3540
import routes from '../constants/routes.json';
3641

3742
export type SetKeysAction = { type: 'SET_KEYS' } & AccountKeys;
43+
export type SetKeysWithSpendingPasswordAction = {
44+
type: 'SET_SPENDING_PASSWORD'
45+
} & SpendingPassword;
3846
export const SET_KEYS = 'SET_KEYS';
47+
export const SET_SPENDING_PASSWORD = 'SET_SPENDING_PASSWORD';
3948

4049
export function setAccount(
4150
privateKey: string,
@@ -48,6 +57,29 @@ export function setAccount(
4857
};
4958
}
5059

60+
export function setKeysWithSpendingPassword(
61+
spendingPassword: ?string = ''
62+
): Thunk<SetKeysAction> {
63+
return function setKeysWithSpendingPasswordThunk(dispatch) {
64+
const accountKeys = readAccountKeysFromDEN(spendingPassword);
65+
if (accountKeys) {
66+
const spendingPasswordKeys = {
67+
walletId: 'wallet01',
68+
spendingPassword
69+
};
70+
dispatch({
71+
type: SET_SPENDING_PASSWORD,
72+
...spendingPasswordKeys
73+
});
74+
75+
return getAccountFromPrivateKey(accountKeys.privateKey).then(keys =>
76+
curry(initializeKeysAndRedirect)(dispatch, keys, spendingPassword)
77+
);
78+
}
79+
throw new Error('Invalid password');
80+
};
81+
}
82+
5183
export function setAccountFromPrivateKey(
5284
privateKey: string
5385
): Thunk<SetKeysAction> {

examples/wallet/app/actions/router.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@ import type { Address } from '../models';
55
import routes from '../constants/routes';
66
import { setAccountFromPrivateKey } from './account';
77

8-
import { readAccountKeysFromDEN } from '../utils/storage';
8+
import {
9+
isSpedingPasswordCreated,
10+
readAccountKeysFromDEN
11+
} from '../utils/storage';
912

1013
// eslint-disable-next-line import/prefer-default-export
1114
export const redirectToFirstAppPage = () => {
1215
return (dispatch: Dispatch, getState: GetState) => {
16+
if (isSpedingPasswordCreated()) return dispatch(push(routes.UNLOCK_WALLET));
17+
1318
const accountKeys = readAccountKeysFromDEN('manteca');
1419
if (accountKeys !== undefined) {
1520
return dispatch(setAccountFromPrivateKey(accountKeys.privateKey));

examples/wallet/app/constants/routes.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"INPUT_KEYS": "/input_keys",
66
"SEND": "/send",
77
"STAKING": "/staking",
8-
"SETTINGS": "/settings"
8+
"SETTINGS": "/settings",
9+
"UNLOCK_WALLET": "/unlock"
910
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @flow
2+
import { bindActionCreators } from 'redux';
3+
import { connect } from 'react-redux';
4+
import UnlockWallet from '../pages/UnlockWallet';
5+
import { setKeysWithSpendingPassword } from '../actions/account';
6+
7+
function mapDispatchToProps(dispatch) {
8+
return bindActionCreators({ setKeysWithSpendingPassword }, dispatch);
9+
}
10+
11+
export default connect(
12+
undefined,
13+
mapDispatchToProps
14+
)(UnlockWallet);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// @flow
2+
import React, { useState } from 'react';
3+
import Form from 'react-bootstrap/Form';
4+
import Button from 'react-bootstrap/Button';
5+
import Container from 'react-bootstrap/Container';
6+
import Row from 'react-bootstrap/Row';
7+
import { isValidSpendingPassword } from '../utils/storage';
8+
import typeof { setKeysWithSpendingPassword as SetKeysWithSpendingPassword } from '../actions/account';
9+
10+
type Props = {
11+
setKeysWithSpendingPassword: SetKeysWithSpendingPassword
12+
};
13+
14+
export default ({ setKeysWithSpendingPassword }: Props) => {
15+
const handleSubmit = function handleSubmit(event) {
16+
event.preventDefault();
17+
if (isValidSpendingPassword(spendingPassword)) {
18+
setIsWrongSpendingPassword(false);
19+
setHiddenSpendingPassword(true);
20+
return Promise.all([setKeysWithSpendingPassword(spendingPassword)]);
21+
}
22+
setIsWrongSpendingPassword(true);
23+
setHiddenSpendingPassword(false);
24+
};
25+
26+
const [spendingPassword, setSpendingPassword] = useState('');
27+
const [isWrongSpendingPassword, setIsWrongSpendingPassword] = useState(false);
28+
const [hiddenSpendingPassword, setHiddenSpendingPassword] = useState(true);
29+
30+
return (
31+
<Container>
32+
<Form onSubmit={handleSubmit} className="mt-5">
33+
<Form.Group>
34+
<Form.Label>
35+
Wellcome! Please insert you password to unlock wallet
36+
</Form.Label>
37+
<Form.Control
38+
type="password"
39+
id="spendingPassword"
40+
name="spendingPassword"
41+
placeholder="Password"
42+
value={spendingPassword}
43+
isInvalid={isWrongSpendingPassword}
44+
onChange={event => setSpendingPassword(event.target.value)}
45+
/>
46+
<Form.Label className="text-danger" hidden={hiddenSpendingPassword}>
47+
<code>Incorrect password</code>
48+
</Form.Label>
49+
</Form.Group>
50+
<Row className="justify-content-center">
51+
<Button variant="primary" type="submit">
52+
Unlock wallet
53+
</Button>
54+
</Row>
55+
</Form>
56+
</Container>
57+
);
58+
};

examples/wallet/app/reducers/account.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @flow
22
import sortBy from 'lodash/sortBy';
33
import {
4+
SET_SPENDING_PASSWORD,
45
SET_KEYS,
56
SET_ACCOUNT_STATE,
67
SEND_TRANSACTION,
@@ -12,6 +13,7 @@ import type {
1213
SendTransactionAction,
1314
SetAccountStateAction,
1415
SetTransactionsAction,
16+
SetKeysWithSpendingPasswordAction,
1517
SendStakeDelegation
1618
} from '../actions/account';
1719
import type { Account } from './types';
@@ -21,6 +23,7 @@ export default function account(
2123
state: Account,
2224
// eslint-disable-next-line flowtype/space-after-type-colon
2325
action:
26+
| SetKeysWithSpendingPasswordAction
2427
| SetKeysAction
2528
| SetAccountStateAction
2629
| SendTransactionAction
@@ -31,6 +34,11 @@ export default function account(
3134
return { transactions: [] };
3235
}
3336
switch (action.type) {
37+
case SET_SPENDING_PASSWORD:
38+
return Object.assign({}, state, {
39+
walletId: action.walletId,
40+
spendingPassword: action.spendingPassword
41+
});
3442
case SET_KEYS:
3543
return Object.assign({}, state, {
3644
address: action.address,

examples/wallet/app/reducers/types.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export type AccountKeys = {
3737
identifier: Identifier
3838
};
3939

40+
export type SpendingPassword = {
41+
walletId: ?string,
42+
spendingPassword: ?string
43+
};
44+
4045
export type AccountState = {
4146
balance: Balance,
4247
counter: Counter,

examples/wallet/app/utils/storage.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,14 @@ export function readAccountKeysFromDEN(
4343
spendingPassword: ?string
4444
): ?AccountKeys {
4545
const encryptedHex = localStorage.getItem(WALLET_ENCRYPTED_KEYS);
46-
if (encryptedHex && encryptedHex.length > 0) {
47-
const plainText = aesDecrypt(spendingPassword, encryptedHex);
48-
const accountKeys = JSON.parse(plainText);
49-
return accountKeys;
46+
try {
47+
if (encryptedHex && encryptedHex.length > 0) {
48+
const plainText = aesDecrypt(spendingPassword, encryptedHex);
49+
const accountKeys = JSON.parse(plainText);
50+
return accountKeys;
51+
}
52+
} catch (e) {
53+
console.error('There was an error unlocking wallet', e.toString());
5054
}
5155
return undefined;
5256
}

0 commit comments

Comments
 (0)