1import Maybe from 'folktale/maybe'
2import React from 'react'
3import { Button } from '../components/Base'
4import { InnerLabel, ValidatedSigil, PointInput, ShardInput } 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'),
18 return ob.hex2patq(hex)
22 SHARD1: Symbol('SHARD1'),
23 SHARD2: Symbol('SHARD2'),
24 SHARD3: Symbol('SHARD3')
27class Shards extends React.Component {
39 this.pointPlaceholder = placeholder(4)
40 this.ticketPlaceholder = placeholder(16)
42 this.handleShardInput = this.handleShardInput.bind(this)
43 this.handlePointNameInput = this.handlePointNameInput.bind(this)
46 handleShardInput(shard, input) {
47 if (shard === SHARDS.SHARD1) {
48 this.setState({ shard1: input })
49 } else if (shard === SHARDS.SHARD2) {
50 this.setState({ shard2: input })
51 } else if (shard === SHARDS.SHARD3) {
52 this.setState({ shard3: input })
56 handlePointNameInput(pointName) {
57 if (pointName.length < 15) {
58 this.setState({ pointName })
62 // buttonTriState = (wallet) => {
63 // if (wallet.isNothing()) return 'blue'
64 // if (wallet === false) return 'yellow'
65 // if (Maybe.Nothing.hasInstance(wallet)) return 'green'
68 async walletFromShards(shard1, shard2, shard3, pointName) {
69 const { setWallet, setUrbitWallet } = this.props
71 const s1 = shard1 === '' ? undefined : shard1
72 const s2 = shard2 === '' ? undefined : shard2
73 const s3 = shard3 === '' ? undefined : shard3
75 let ticket = undefined
77 ticket = kg.combine([s1, s2, s3])
82 if (ticket !== undefined) {
83 const urbitWallet = await kg.generateWallet({
85 ship: ob.patp2dec(pointName)
87 const mnemonic = urbitWallet.ownership.seed
88 const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH)
90 setUrbitWallet(Maybe.Just(urbitWallet))
95 const { popRoute, pushRoute, wallet } = this.props
96 const { shard1, shard2, shard3, pointName } = this.state
98 const phPoint = this.pointPlaceholder
99 const phTick = this.ticketPlaceholder
101 const shards = [shard1, shard2, shard3]
102 const ready = shards.filter(x => x !== '').length > 1
107 <H1>{ 'Authenticate' }</H1>
111 `Enter your point and at least two of your three Urbit master
112 ticket shards here. The index of the input field needs to
113 match the index of the shard.`
119 className='mono mt-8'
121 prop-format='innerLabel'
124 placeholder={ `e.g. ${phPoint}` }
126 onChange={ this.handlePointNameInput }>
127 <InnerLabel>{ 'Point' }</InnerLabel>
129 className={'tr-0 mt-05 mr-0 abs'}
137 className='mono mt-8'
139 prop-format='innerLabel'
142 placeholder={ `e.g. ${phTick}` }
144 onChange={ inp => this.handleShardInput(SHARDS.SHARD1, inp) }>
145 <InnerLabel>{ 'Shard 1' }</InnerLabel>
149 className='mono mt-8'
151 prop-format='innerLabel'
154 placeholder={ `e.g. ${phTick}` }
156 onChange={ inp => this.handleShardInput(SHARDS.SHARD2, inp) }>
157 <InnerLabel>{ 'Shard 2' }</InnerLabel>
161 className='mono mt-8'
163 prop-format='innerLabel'
166 placeholder={ `e.g. ${phTick}` }
168 onChange={ inp => this.handleShardInput(SHARDS.SHARD3, inp) }>
169 <InnerLabel>{ 'Shard 3' }</InnerLabel>
175 prop-size={'lg wide'}
176 // prop-color={this.buttonTriState(wallet)}
178 this.walletFromShards(shard1, shard2, shard3, pointName)
185 prop-size={'xl wide'}
186 disabled={ Maybe.Nothing.hasInstance(wallet) }
189 pushRoute(ROUTE_NAMES.SHIPS)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list