on 616e621 help sign in
bridge/src/views/Ticket.js
142 lines 4.0 kB history raw
1import Maybe from 'folktale/maybe'
2import React from 'react'
3import { Button } from '../components/Base'
4import { InnerLabel, ValidatedSigil, PointInput, TicketInput } from '../components/Base'
5import { Row, Col, H1, P, Form } from '../components/Base'
6import * as kg from '../../node_modules/urbit-key-generation/dist/index'
7import * as ob from 'urbit-ob'
9import { ROUTE_NAMES } from '../lib/router'
10import { DEFAULT_HD_PATH, walletFromMnemonic } from '../lib/wallet'
12const placeholder = (len) => {
13 let bytes = window.crypto.getRandomValues(new Uint8Array(len))
14 let hex = bytes.reduce((acc, byt) =>
15 acc + byt.toString(16).padStart(2, '0'),
16 ''
17 )
18 return ob.hex2patq(hex)
21class Ticket extends React.Component {
23 constructor(props) {
24 super(props)
26 this.state = {
27 ticket: '',
28 pointName: ''
29 }
31 this.pointPlaceholder = placeholder(4)
32 this.ticketPlaceholder = placeholder(8)
34 this.handleTicketInput = this.handleTicketInput.bind(this)
35 this.handlePointNameInput = this.handlePointNameInput.bind(this)
36 }
38 handleTicketInput(ticket) {
39 this.setState({ ticket })
40 }
42 handlePointNameInput(pointName) {
43 if (pointName.length < 15) {
44 this.setState({ pointName })
45 }
46 }
48 // buttonTriState = (wallet) => {
49 // if (wallet.isNothing()) return 'blue'
50 // if (wallet === false) return 'yellow'
51 // if (Maybe.Nothing.hasInstance(wallet)) return 'green'
52 // }
54 async walletFromTicket(ticket, pointName) {
55 const { setWallet, setUrbitWallet } = this.props
56 const urbitWallet = await kg.generateWallet({
57 ticket: ticket,
58 ship: ob.patp2dec(pointName)
59 })
60 const mnemonic = urbitWallet.ownership.seed
61 const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH)
62 setWallet(wallet)
63 setUrbitWallet(Maybe.Just(urbitWallet))
64 }
66 render() {
67 const { popRoute, pushRoute, wallet } = this.props
68 const { ticket, pointName } = 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 <Form>
84 <PointInput
85 className='mono mt-8'
86 prop-size='lg'
87 prop-format='innerLabel'
88 type='text'
89 autoFocus
90 placeholder={ `e.g. ${phPoint}` }
91 value={ pointName }
92 onChange={ this.handlePointNameInput }>
93 <InnerLabel>{ 'Point' }</InnerLabel>
94 <ValidatedSigil
95 className={'tr-0 mt-05 mr-0 abs'}
96 patp={pointName}
97 size={68}
98 margin={8} />
99 </PointInput>
102 <TicketInput
103 className='mono mt-8'
104 prop-size='md'
105 prop-format='innerLabel'
106 type='text'
107 name='ticket'
108 placeholder={ `e.g. ${phTick}` }
109 value={ ticket }
110 onChange={ this.handleTicketInput }>
111 <InnerLabel>{ 'Ticket' }</InnerLabel>
112 </TicketInput>
114 <Button
115 className={'mt-8'}
116 prop-size={'lg wide'}
117 // prop-color={this.buttonTriState(wallet)}
118 onClick={() => this.walletFromTicket(ticket, pointName)}>
119 {'Unlock Wallet →'}
120 </Button>
122 <Button
123 className={'mt-4'}
124 prop-size={'xl wide'}
125 disabled={ Maybe.Nothing.hasInstance(wallet) }
126 onClick={ () => {
127 popRoute()
128 pushRoute(ROUTE_NAMES.SHIPS)
129 }
130 }
131 >
132 { 'Continue →' }
133 </Button>
135 </Form>
136 </Col>
137 </Row>
138 )
139 }
142export default Ticket