on f6bf651 help sign in
bridge/src/views/Keystore.js
170 lines 4.7 kB history raw
1import { Just, Nothing } from 'folktale/maybe'
2import { Ok, Error } from 'folktale/result'
3import React from 'react'
4import * as keythereum from 'keythereum'
5import { Button, UploadButton } from '../components/Base'
6import { Input, InnerLabel, InputCaption } from '../components/Base'
7import { Row, Col, H1, H3, Form, Warning } from '../components/Base'
9import { BRIDGE_ERROR } from '../lib/error'
10import { ROUTE_NAMES } from '../lib/router'
11import { EthereumWallet } from '../lib/wallet'
13class Keystore extends React.Component {
15 constructor(props) {
16 super(props)
18 this.state = {
19 keystore: Nothing(), // Maybe<Result<String, String>>
20 password: '',
21 decryptionProblem: false
22 }
24 this.handleKeystoreUpload = this.handleKeystoreUpload.bind(this)
25 this.handlePasswordInput = this.handlePasswordInput.bind(this)
26 this.constructWallet = this.constructWallet.bind(this)
27 }
29 handlePasswordInput(password) {
30 this.setState({ password })
31 }
33 constructWallet() {
34 const { setWallet } = this.props
35 const { keystore, password } = this.state
37 try {
39 const text = keystore.matchWith({
40 Nothing: _ => { throw BRIDGE_ERROR.MISSING_KEYSTORE },
41 Just: ks => ks.value.matchWith({
42 Ok: result => result.value,
43 Error: _ => { throw BRIDGE_ERROR.MISSING_KEYSTORE }
44 })
45 })
47 const json = JSON.parse(text)
48 const privateKey = keythereum.recover(password, json)
50 const wallet = new EthereumWallet(privateKey)
51 this.setState({ decryptionProblem: false })
52 setWallet(Just(wallet))
54 } catch (err) {
56 this.setState({ decryptionProblem: true })
57 setWallet(Nothing())
59 }
60 }
62 handleKeystoreUpload = (event) => {
63 const file = event.files.item(0)
64 const reader = new FileReader()
66 reader.onload = (e) => {
67 const keystore = e.target.result
68 this.setState({ keystore: Just(Ok(keystore)) })
69 }
71 const failure = _ => {
72 const message = 'There was a problem uploading your Keystore file'
73 this.setState({ keystore: Just(Error(message)) })
74 }
76 reader.onerror = failure
77 reader.onabort = failure
79 reader.readAsText(file)
80 }
82 render() {
83 const { pushRoute, popRoute, wallet } = this.props
84 const { keystore, password, decryptionProblem } = this.state
86 const uploadButtonClass = keystore.matchWith({
87 Nothing: _ => 'bg-blue white',
88 Just: ks => ks.value.matchWith({
89 Ok: _ => 'bg-green white',
90 Error: _ => 'bg-yellow black'
91 })
92 })
94 const decryptMessage =
95 decryptionProblem === false
96 ? <div />
97 : <Warning className={'mt-8'}>
98 <H3 style={{marginTop: 0, paddingTop: 0}}>
99 {
100 "Couldn't decrypt wallet."
101 }
102 </H3>
103 { 'You may have entered an incorrect password.' }
104 </Warning>
106 return (
107 <Row>
108 <Col className={'measure-md'}>
109 <H1 className={'mb-4'}>{ 'Upload Your Keystore File' }</H1>
110 <Form>
111 <InputCaption>
112 { `Please upload your Ethereum keystore file. If your keystore
113 file is encrypted with a password, you'll also need to enter
114 that below.` }
115 </InputCaption>
117 <UploadButton
118 className={ `btn ${uploadButtonClass} mt-10` }
119 onChange={ this.handleKeystoreUpload }
120 >
121 <div className={'flex-center-all fs-4 h-11 pointer'}>{ 'Upload Keystore file' }</div>
122 </UploadButton>
124 <Input
125 className='pt-8 mt-8'
126 prop-size='md'
127 prop-format='innerLabel'
128 type='password'
129 name='password'
130 onChange={ this.handlePasswordInput }
131 value={ password }
132 autocomplete='off'
133 autoFocus>
134 <InnerLabel>{'Password'}</InnerLabel>
135 </Input>
137 <Button
138 className={` mt-10`}
139 prop-size={ 'wide lg' }
140 disabled={ Nothing.hasInstance(keystore) }
141 onClick={ this.constructWallet }
142 >
143 { 'Decrypt' }
144 </Button>
146 { decryptMessage }
148 <Button
149 className={'mt-10'}
150 prop-size={ 'wide lg' }
151 disabled={ Nothing.hasInstance(wallet) }
152 onClick={ () => {
153 popRoute()
154 pushRoute(ROUTE_NAMES.SHIPS)
155 }
156 }
157 >
158 { 'Continue →' }
159 </Button>
161 </Form>
162 </Col>
163 </Row>
166 )
167 }
170export default Keystore