on adbcda8 help sign in
bridge/src/views/Login/Keystore.js
123 lines 3.3 kB history raw
1import { Just, Nothing } from 'folktale/maybe';
2import { Ok, Error } from 'folktale/result';
3import React, { useState } from 'react';
4import * as keythereum from 'keythereum';
6import View from 'components/View';
7import { usePassphraseInput } from 'components/Inputs';
8import { ForwardButton } from 'components/Buttons';
9import { H3, Input } from 'indigo-react';
10import { InputCaption, UploadButton, Warning } from 'components/old/Base';
12import * as need from 'lib/need';
13import { EthereumWallet } from 'lib/wallet';
14import { useWallet } from 'store/wallet';
16export default function Keystore({ loginCompleted }) {
17 // globals
18 const { wallet, setWallet } = useWallet();
20 // inputs
21 // keystore: Maybe<Result<String, String>>
22 const [keystore, setKeystore] = useState(Nothing());
23 const passphraseInput = usePassphraseInput({
24 name: 'password',
25 label: 'Keystore password',
26 autoFocus: true,
27 });
28 const passphrase = passphraseInput.data;
30 const [decryptionProblem, setDecryptionProblem] = useState(false);
32 const constructWallet = () => {
33 try {
34 const text = need.keystore(keystore);
36 const json = JSON.parse(text);
37 const privateKey = keythereum.recover(passphrase, json);
39 const newWallet = new EthereumWallet(privateKey);
40 setDecryptionProblem(false);
41 setWallet(Just(newWallet));
42 } catch (err) {
43 setDecryptionProblem(true);
44 setWallet(Nothing());
45 }
46 };
48 const handleKeystoreUpload = event => {
49 const file = event.files.item(0);
50 const reader = new FileReader();
52 reader.onload = e => {
53 const keystore = e.target.result;
54 setKeystore(Just(Ok(keystore)));
55 };
57 const failure = _ => {
58 const message = 'There was a problem uploading your Keystore file';
59 setKeystore(Just(Error(message)));
60 };
62 reader.onerror = failure;
63 reader.onabort = failure;
65 reader.readAsText(file);
66 };
68 const uploadButtonClass = keystore.matchWith({
69 Nothing: _ => 'bg-blue white',
70 Just: ks =>
71 ks.value.matchWith({
72 Ok: _ => 'bg-green white',
73 Error: _ => 'bg-yellow black',
74 }),
75 });
77 const decryptMessage =
78 decryptionProblem === false ? (
79 <div />
80 ) : (
81 <Warning className="mt-8">
82 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
83 Couldn't decrypt wallet.
84 </H3>
85 You may have entered an incorrect password.
86 </Warning>
87 );
89 return (
90 <View>
91 <InputCaption>
92 Please upload your Ethereum keystore file. If your keystore file is
93 encrypted with a password, you'll also need to enter that below.
94 </InputCaption>
96 <UploadButton
97 className={`${uploadButtonClass} mt3`}
98 onChange={handleKeystoreUpload}>
99 <div className="flex-center-all fs-4 h-11 pointer">
100 Upload Keystore file
101 </div>
102 </UploadButton>
104 <Input {...passphraseInput} />
106 <ForwardButton
107 className="mt3"
108 disabled={Nothing.hasInstance(keystore)}
109 onClick={constructWallet}>
110 Decrypt
111 </ForwardButton>
113 {decryptMessage}
115 <ForwardButton
116 className="mt3"
117 disabled={Nothing.hasInstance(wallet)}
118 onClick={loginCompleted}>
119 Continue
120 </ForwardButton>
121 </View>
122 );