on e366ef3 help sign in
bridge/src/views/Ticket.js
157 lines 4.2 kB history raw
1import { Just, Nothing } from 'folktale/maybe';
2import React from 'react';
3import { Button } from '../components/old/Base';
4import {
5 InnerLabel,
6 ValidatedSigil,
7 PointInput,
8 TicketInput,
9 Input,
10 InputCaption,
11} from '../components/old/Base';
12import { Row, Col, H1, P } from '../components/old/Base';
14import { randomPatq, compose } from '../lib/lib';
15import { ROUTE_NAMES } from '../lib/routeNames';
16import { withHistory } from '../store/history';
17import { urbitWalletFromTicket } from '../lib/wallet';
18import { withWallet } from '../store/wallet';
20class Ticket extends React.Component {
21 constructor(props) {
22 super(props);
24 this.state = {
25 ticket: '',
26 pointName: '',
27 passphrase: '',
28 isUnlocking: false,
29 };
31 this.pointPlaceholder = randomPatq(4);
32 this.ticketPlaceholder = randomPatq(8);
34 this.handleTicketInput = this.handleTicketInput.bind(this);
35 this.handlePassphraseInput = this.handlePassphraseInput.bind(this);
36 this.handlePointNameInput = this.handlePointNameInput.bind(this);
37 }
39 handleTicketInput(ticket) {
40 this.setState({ ticket });
41 }
43 handlePassphraseInput(passphrase) {
44 this.setState({ passphrase });
45 }
47 handlePointNameInput(pointName) {
48 if (pointName.length < 15) {
49 this.setState({ pointName });
50 }
51 }
53 async walletFromTicket(ticket, pointName, passphrase) {
54 this.setState({
55 isUnlocking: true,
56 });
58 const uhdw = await urbitWalletFromTicket(ticket, pointName, passphrase);
59 this.props.setUrbitWallet(Just(uhdw));
61 this.setState({
62 isUnlocking: false,
63 });
64 }
66 render() {
67 const { history, wallet } = this.props;
68 const { ticket, pointName, passphrase } = this.state;
70 const phPoint = this.pointPlaceholder;
71 const phTick = this.ticketPlaceholder;
73 return (
74 <Row>
75 <Col>
76 <H1>{'Authenticate'}</H1>
78 <P>
79 {`Please enter your point and Urbit master ticket here. This information is written on your Urbit HD paper wallets.`}
80 </P>
82 <PointInput
83 className="mono mt-8"
84 prop-size="lg"
85 prop-format="innerLabel"
86 type="text"
87 autoFocus
88 placeholder={`e.g. ${phPoint}`}
89 value={pointName}
90 onChange={this.handlePointNameInput}>
91 <InnerLabel>{'Point'}</InnerLabel>
92 <ValidatedSigil
93 className={'tr-0 mt-05 mr-0 abs'}
94 patp={pointName}
95 size={68}
96 margin={8}
97 />
98 </PointInput>
100 <TicketInput
101 className="mono mt-8"
102 prop-size="lg"
103 prop-format="innerLabel"
104 type="password"
105 name="ticket"
106 placeholder={`e.g. ${phTick}`}
107 value={ticket}
108 onChange={this.handleTicketInput}>
109 <InnerLabel>{'Ticket'}</InnerLabel>
110 </TicketInput>
112 <InputCaption>
113 {'If your wallet requires a passphrase, you may enter it below.'}
114 </InputCaption>
116 <Input
117 className="pt-8"
118 prop-size="md"
119 prop-format="innerLabel"
120 name="passphrase"
121 type="password"
122 value={passphrase}
123 autocomplete="off"
124 onChange={this.handlePassphraseInput}>
125 <InnerLabel>{'Passphrase'}</InnerLabel>
126 </Input>
128 <Button
129 className={'mt-8'}
130 prop-size={'lg wide'}
131 disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
132 onClick={() =>
133 this.walletFromTicket(ticket, pointName, passphrase)
134 }>
135 <span className="relative">
136 {this.state.isUnlocking && <span className="btn-spinner" />}
137 {'Unlock Wallet →'}
138 </span>
139 </Button>
141 <Button
142 className={'mt-4'}
143 prop-size={'xl wide'}
144 disabled={Nothing.hasInstance(wallet)}
145 onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
146 {'Continue →'}
147 </Button>
148 </Col>
149 </Row>
150 );
151 }
154export default compose(
155 withHistory,
156 withWallet
157)(Ticket);