@@ -1,66 +1,60 @@
1import { Just, Nothing } from 'folktale/maybe';
1import { Just, Nothing } from 'folktale/maybe';
2import { Ok, Error } from 'folktale/result';
2import { Ok, Error } from 'folktale/result';
3−import React from 'react';
3+import React, { useState } from 'react';
4import * as keythereum from 'keythereum';
4import * as keythereum from 'keythereum';
6+import View from '../../components/View';
7+import { PassphraseInput } from '../../components/Inputs';
8+import { ForwardButton } from '../../components/Buttons';
5−import { Button, UploadButton } from '../../components/old/Base';
11+ UploadButton,
6−import { Input, InnerLabel, InputCaption } from '../../components/old/Base';
12+ H3,
7−import { Row, Col, H1, H3, Warning } from '../../components/old/Base';
14+} from '../../components/old/Base';
9import * as need from '../../lib/need';
16import * as need from '../../lib/need';
10import { EthereumWallet } from '../../lib/wallet';
17import { EthereumWallet } from '../../lib/wallet';
11−import { compose } from '../../lib/lib';
12−import { withWallet } from '../../store/wallet';
18+import { useWallet } from '../../store/wallet';
14−class Keystore extends React.Component {
19− keystore: Nothing(), // Maybe<Result<String, String>>
21− decryptionProblem: false,
24− this.handleKeystoreUpload = this.handleKeystoreUpload.bind(this);
20+export default function Keystore({ loginCompleted }) {
25− this.handlePasswordInput = this.handlePasswordInput.bind(this);
21+ // globals
26− this.constructWallet = this.constructWallet.bind(this);
22+ const { wallet, setWallet } = useWallet();
29− handlePasswordInput(password) {
24+ // inputs
30− this.setState({ password });
25+ // keystore: Maybe<Result<String, String>>
31− }
26+ const [keystore, setKeystore] = useState(Nothing());
32−
27+ const [password, setPassword] = useState('');
33− constructWallet() {
28+ const [decryptionProblem, setDecryptionProblem] = useState(false);
34− const { setWallet } = this.props;
35− const { password } = this.state;
30+ const constructWallet = () => {
38− const text = need.keystore(this.state);
32+ const text = need.keystore(keystore);
40 const json = JSON.parse(text);
34 const json = JSON.parse(text);
41 const privateKey = keythereum.recover(password, json);
35 const privateKey = keythereum.recover(password, json);
43 const wallet = new EthereumWallet(privateKey);
37 const wallet = new EthereumWallet(privateKey);
44− this.setState({ decryptionProblem: false });
38+ setDecryptionProblem(false);
45 setWallet(Just(wallet));
39 setWallet(Just(wallet));
46 } catch (err) {
40 } catch (err) {
47− this.setState({ decryptionProblem: true });
41+ setDecryptionProblem(true);
48 setWallet(Nothing());
42 setWallet(Nothing());
52− handleKeystoreUpload = event => {
46+ const handleKeystoreUpload = event => {
53 const file = event.files.item(0);
47 const file = event.files.item(0);
54 const reader = new FileReader();
48 const reader = new FileReader();
56 reader.onload = e => {
50 reader.onload = e => {
57 const keystore = e.target.result;
51 const keystore = e.target.result;
58− this.setState({ keystore: Just(Ok(keystore)) });
52+ setKeystore(Just(Ok(keystore)));
61 const failure = _ => {
55 const failure = _ => {
62 const message = 'There was a problem uploading your Keystore file';
56 const message = 'There was a problem uploading your Keystore file';
63− this.setState({ keystore: Just(Error(message)) });
57+ setKeystore(Just(Error(message)));
66 reader.onerror = failure;
60 reader.onerror = failure;
@@ -69,83 +63,65 @@ class Keystore extends React.Component {
69 reader.readAsText(file);
63 reader.readAsText(file);
73− const { wallet } = this.props;
74− const { keystore, password, decryptionProblem } = this.state;
76− const uploadButtonClass = keystore.matchWith({
66+ const uploadButtonClass = keystore.matchWith({
77− Nothing: _ => 'bg-blue white',
67+ Nothing: _ => 'bg-blue white',
78− Just: ks =>
68+ Just: ks =>
79− ks.value.matchWith({
69+ ks.value.matchWith({
80− Ok: _ => 'bg-green white',
70+ Ok: _ => 'bg-green white',
81− Error: _ => 'bg-yellow black',
71+ Error: _ => 'bg-yellow black',
85− const decryptMessage =
75+ const decryptMessage =
86− decryptionProblem === false ? (
76+ decryptionProblem === false ? (
89− <Warning className={'mt-8'}>
79+ <Warning className={'mt-8'}>
90− <H3 style={{ marginTop: 0, paddingTop: 0 }}>
80+ <H3 style={{ marginTop: 0, paddingTop: 0 }}>
91− {"Couldn't decrypt wallet."}
81+ {"Couldn't decrypt wallet."}
93− {'You may have entered an incorrect password.'}
83+ {'You may have entered an incorrect password.'}
94− </Warning>
84+ </Warning>
99− <Col className={'measure-md'}>
100− <H1 className={'mb-4'}>{'Upload Your Keystore File'}</H1>
102− {`Please upload your Ethereum keystore file. If your keystore
103− file is encrypted with a password, you'll also need to enter
108− className={`btn ${uploadButtonClass} mt-10`}
109− onChange={this.handleKeystoreUpload}>
110− <div className={'flex-center-all fs-4 h-11 pointer'}>
111− {'Upload Keystore file'}
116− className="pt-8 mt-8"
118− prop-format="innerLabel"
121− onChange={this.handlePasswordInput}
125− <InnerLabel>{'Password'}</InnerLabel>
129− className={` mt-10`}
130− prop-size={'wide lg'}
131− disabled={Nothing.hasInstance(keystore)}
132− onClick={this.constructWallet}>
140− prop-size={'wide lg'}
141− disabled={Nothing.hasInstance(wallet)}
142− onClick={this.props.loginCompleted}>
151−export default compose(withWallet)(Keystore);
87+ return (
90+ {`Please upload your Ethereum keystore file. If your keystore
91+ file is encrypted with a password, you'll also need to enter
96+ className={`${uploadButtonClass} mt3`}
97+ onChange={handleKeystoreUpload}>
98+ <div className={'flex-center-all fs-4 h-11 pointer'}>
99+ {'Upload Keystore file'}
105+ label="Keystore password"
106+ initialValue={password}
107+ onValue={setPassword}
108+ autoFocus></PassphraseInput>
112+ disabled={Nothing.hasInstance(keystore)}
113+ onClick={constructWallet}>
121+ disabled={Nothing.hasInstance(wallet)}
122+ onClick={loginCompleted}>