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