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