on fbcd6b6 help sign in
bridge/src/views/Login/Keystore.js
129 lines 3.5 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';
5import { H3, Input } from 'indigo-react';
7import View from 'components/View';
8import { usePassphraseInput } from 'components/Inputs';
9import { ForwardButton } from 'components/Buttons';
10import { InputCaption, UploadButton, Warning } from 'components/old/Base';
12import { useWallet } from 'store/wallet';
14import * as need from 'lib/need';
15import { EthereumWallet, WALLET_TYPES } from 'lib/wallet';
16import useWalletType from 'lib/useWalletType';
17import useResetPointCursor from 'lib/useResetPointCursor';
19export default function Keystore({ loginCompleted }) {
20 useResetPointCursor();
21 useWalletType(WALLET_TYPES.KEYSTORE);
23 // globals
24 const { wallet, setWallet } = useWallet();
26 // inputs
27 // keystore: Maybe<Result<String, String>>
28 const [keystore, setKeystore] = useState(Nothing());
29 const passphraseInput = usePassphraseInput({
30 name: 'password',
31 label: 'Keystore password',
32 autoFocus: true,
33 });
34 const passphrase = passphraseInput.data;
36 const [decryptionProblem, setDecryptionProblem] = useState(false);
38 const constructWallet = () => {
39 try {
40 const text = need.keystore(keystore);
42 const json = JSON.parse(text);
43 const privateKey = keythereum.recover(passphrase, json);
45 const newWallet = new EthereumWallet(privateKey);
46 setDecryptionProblem(false);
47 setWallet(Just(newWallet));
48 } catch (err) {
49 setDecryptionProblem(true);
50 setWallet(Nothing());
51 }
52 };
54 const handleKeystoreUpload = event => {
55 const file = event.files.item(0);
56 const reader = new FileReader();
58 reader.onload = e => {
59 const keystore = e.target.result;
60 setKeystore(Just(Ok(keystore)));
61 };
63 const failure = _ => {
64 const message = 'There was a problem uploading your Keystore file';
65 setKeystore(Just(Error(message)));
66 };
68 reader.onerror = failure;
69 reader.onabort = failure;
71 reader.readAsText(file);
72 };
74 const uploadButtonClass = keystore.matchWith({
75 Nothing: _ => 'bg-blue white',
76 Just: ks =>
77 ks.value.matchWith({
78 Ok: _ => 'bg-green white',
79 Error: _ => 'bg-yellow black',
80 }),
81 });
83 const decryptMessage =
84 decryptionProblem === false ? (
85 <div />
86 ) : (
87 <Warning className="mt-8">
88 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
89 Couldn't decrypt wallet.
90 </H3>
91 You may have entered an incorrect password.
92 </Warning>
93 );
95 return (
96 <View>
97 <InputCaption>
98 Please upload your Ethereum keystore file. If your keystore file is
99 encrypted with a password, you'll also need to enter that below.
100 </InputCaption>
102 <UploadButton
103 className={`${uploadButtonClass} mt3`}
104 onChange={handleKeystoreUpload}>
105 <div className="flex-center-all fs-4 h-11 pointer">
106 Upload Keystore file
107 </div>
108 </UploadButton>
110 <Input {...passphraseInput} />
112 <ForwardButton
113 className="mt3"
114 disabled={Nothing.hasInstance(keystore)}
115 onClick={constructWallet}>
116 Decrypt
117 </ForwardButton>
119 {decryptMessage}
121 <ForwardButton
122 className="mt3"
123 disabled={Nothing.hasInstance(wallet)}
124 onClick={loginCompleted}>
125 Continue
126 </ForwardButton>
127 </View>
128 );