@@ -0,0 +1,120 @@
1+import Maybe from 'folktale/maybe'
2+import React from 'react'
3+import * as keythereum from 'keythereum'
4+import { Button } from '../components/Base'
5+import { Input, InnerLabel, InputCaption } from '../components/Base'
6+import { Row, Col, H1, Form } from '../components/Base'
7+
8+import { ROUTE_NAMES } from '../lib/router'
9+import { EthereumWallet } from '../lib/wallet'
10+
11+class Keystore extends React.Component {
12+
13+ constructor(props) {
14+ super(props)
15+
16+ this.state = {
17+ keystore: '',
18+ password: ''
19+ }
20+
21+ this.handleKeystoreInput = this.handleKeystoreInput.bind(this)
22+ this.handlePasswordInput = this.handlePasswordInput.bind(this)
23+ this.constructWallet = this.constructWallet.bind(this)
24+ }
25+
26+ handleKeystoreInput(keystore) {
27+ this.setState({ keystore })
28+ }
29+
30+ handlePasswordInput(password) {
31+ this.setState({ password })
32+ }
33+
34+ constructWallet() {
35+ const { setWallet } = this.props
36+ const { keystore, password } = this.state
37+
38+ try {
39+ const json = JSON.parse(keystore)
40+ const privateKey = keythereum.recover(password, json)
41+ const wallet = new EthereumWallet(privateKey)
42+ setWallet(Maybe.Just(wallet))
43+ } catch (err) {
44+ setWallet(Maybe.Nothing())
45+ }
46+ }
47+
48+ render() {
49+ const { pushRoute, popRoute, wallet } = this.props
50+ const { keystore, password } = this.state
51+
52+ return (
53+ <Row>
54+ <Col className={'measure-md'}>
55+ <H1 className={'mb-4'}>{ 'Enter Your Keystore File' }</H1>
56+ <Form>
57+ <InputCaption>
58+ { `Please paste in your Ethereum keystore file. If your keystore
59+ file is encrypted with a password, you'll also need to enter
60+ that below.` }
61+ </InputCaption>
62+
63+ <Input
64+ className='pt-8 mt-8'
65+ prop-size='md'
66+ prop-format='innerLabel'
67+ type='text'
68+ name='keystore'
69+ onChange={ this.handleKeystoreInput }
70+ value={ keystore }
71+ autocomplete='off'
72+ autoFocus>
73+ <InnerLabel>{'Keystore File'}</InnerLabel>
74+ </Input>
75+
76+ <Input
77+ className='pt-8 mt-8'
78+ prop-size='md'
79+ prop-format='innerLabel'
80+ type='password'
81+ name='password'
82+ onChange={ this.handlePasswordInput }
83+ value={ password }
84+ autocomplete='off'
85+ autoFocus>
86+ <InnerLabel>{'Password'}</InnerLabel>
87+ </Input>
88+
89+ <Button
90+ className={'mt-10'}
91+ prop-size={ 'wide lg' }
92+ disabled={ keystore === '' }
93+ onClick={ this.constructWallet }
94+ >
95+ { 'Decrypt' }
96+ </Button>
97+
98+ <Button
99+ className={'mt-10'}
100+ prop-size={ 'wide lg' }
101+ disabled={ Maybe.Nothing.hasInstance(wallet) }
102+ onClick={ () => {
103+ popRoute()
104+ pushRoute(ROUTE_NAMES.SHIPS)
105+ }
106+ }
107+ >
108+ { 'Continue →' }
109+ </Button>
110+
111+ </Form>
112+ </Col>
113+ </Row>
114+
115+
116+ )
117+ }
118+}
119+
120+export default Keystore