import { Just, Nothing } from 'folktale/maybe'; import React from 'react'; import { Button } from '../components/old/Base'; import { InnerLabel, ValidatedSigil, PointInput, ShardInput, InputCaption, Input, } from '../components/old/Base'; import { H1, P } from '../components/old/Base'; import * as kg from 'urbit-key-generation/dist'; import * as ob from 'urbit-ob'; import { ROUTE_NAMES } from '../lib/routeNames'; import { withHistory } from '../store/history'; import { urbitWalletFromTicket } from '../lib/wallet'; import { compose } from '../lib/lib'; import { withWallet } from '../store/wallet'; import View from 'components/View'; const placeholder = len => { let bytes = window.crypto.getRandomValues(new Uint8Array(len)); let hex = bytes.reduce( (acc, byt) => acc + byt.toString(16).padStart(2, '0'), '' ); return ob.hex2patq(hex); }; const SHARDS = { SHARD1: Symbol('SHARD1'), SHARD2: Symbol('SHARD2'), SHARD3: Symbol('SHARD3'), }; class Shards extends React.Component { constructor(props) { super(props); this.state = { shard1: '', shard2: '', shard3: '', passphrase: '', pointName: '', }; this.pointPlaceholder = placeholder(4); this.ticketPlaceholder = placeholder(16); this.handlePassphraseInput = this.handlePassphraseInput.bind(this); this.handleShardInput = this.handleShardInput.bind(this); this.handlePointNameInput = this.handlePointNameInput.bind(this); } handleShardInput(shard, input) { if (shard === SHARDS.SHARD1) { this.setState({ shard1: input }); } else if (shard === SHARDS.SHARD2) { this.setState({ shard2: input }); } else if (shard === SHARDS.SHARD3) { this.setState({ shard3: input }); } } handlePassphraseInput(passphrase) { this.setState({ passphrase }); } handlePointNameInput(pointName) { if (pointName.length < 15) { this.setState({ pointName }); } } async walletFromShards(shard1, shard2, shard3, pointName, passphrase) { const s1 = shard1 === '' ? undefined : shard1; const s2 = shard2 === '' ? undefined : shard2; const s3 = shard3 === '' ? undefined : shard3; let ticket = undefined; try { ticket = kg.combine([s1, s2, s3]); } catch (_) { // do nothing } if (ticket !== undefined) { const uhdw = await urbitWalletFromTicket(ticket, pointName, passphrase); this.props.setUrbitWallet(Just(uhdw)); } } render() { const { history, wallet } = this.props; const { shard1, shard2, shard3, pointName, passphrase } = this.state; const phPoint = this.pointPlaceholder; const phTick = this.ticketPlaceholder; const shards = [shard1, shard2, shard3]; const ready = shards.filter(x => x !== '').length > 1; return (

{'Authenticate'}

{`Enter your point and at least two of your three Urbit master ticket shards here. The index of the input field needs to match the index of the shard.`}

{'Point'} this.handleShardInput(SHARDS.SHARD1, inp)}> {'Shard 1'} this.handleShardInput(SHARDS.SHARD2, inp)}> {'Shard 2'} this.handleShardInput(SHARDS.SHARD3, inp)}> {'Shard 3'} {'If your wallet requires a passphrase, you may enter it below.'} {'Passphrase'}
); } } export default compose( withHistory, withWallet )(Shards);