on a8a4e1e help sign in
bridge/src/views/Ticket.js
139 lines 3.8 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 } 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 <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 </PointInput>
100 <TicketInput
101 className='mono mt-8'
102 prop-size='md'
103 prop-format='innerLabel'
104 type='text'
105 name='ticket'
106 placeholder={ `e.g. ${phTick}` }
107 value={ ticket }
108 onChange={ this.handleTicketInput }>
109 <InnerLabel>{ 'Ticket' }</InnerLabel>
110 </TicketInput>
112 <Button
113 className={'mt-8'}
114 prop-size={'lg wide'}
115 // prop-color={this.buttonTriState(wallet)}
116 onClick={() => this.walletFromTicket(ticket, pointName)}>
117 {'Unlock Wallet →'}
118 </Button>
120 <Button
121 className={'mt-4'}
122 prop-size={'xl wide'}
123 disabled={ Maybe.Nothing.hasInstance(wallet) }
124 onClick={ () => {
125 popRoute()
126 pushRoute(ROUTE_NAMES.SHIPS)
127 }
128 }
129 >
130 { 'Continue →' }
131 </Button>
133 </Col>
134 </Row>
135 )
136 }
139export default Ticket