1import React from 'react'
2import * as sigil from 'sigil-js'
3import ob from 'urbit-ob'
4import classnames from 'classnames'
5import * as wg from '../lib/lib'
8import Button from '../components/Button'
9import ReactSVGComponents from '../components/ReactSVGComponents'
10import PaperCollateralRenderer from 'PaperCollateralRenderer'
12import { MAX_GALAXY, MIN_STAR, MAX_STAR, GEN_STATES } from '../lib/constants'
14const NEXT_STEP_NUM = 6;
16const shipInfo = ship => {
17 const name = ob.patp(ship)
18 const sig = sigil.pour({
19 colorway: ['black', 'white'],
21 renderer: ReactSVGComponents,
25 return ship < MAX_GALAXY
26 ? galaxyInfo(name, sig)
29 : planetInfo(name, sig)
32const infoHeader = ship =>
33 <div className={'row text-600 text-mono'} key={ ship + '-header' }>
37const infoSigil = (ship, sig) => {
39 <div className={ '' } key={ 'sigil-' + ship }>
45const getColor = (classOf, seedType) => {
46 if (classOf === 'galaxy') {
47 if (seedType === 'manage') return 'bg-medium';
48 if (seedType === 'voting') return 'bg-medium';
49 if (seedType === 'spawn') return 'bg-high';
50 if (seedType === 'master') return 'bg-very-high';
51 if (seedType === 'masterShard') return 'bg-very-high';
53 if (classOf === 'star') {
54 if (seedType === 'manage') return 'bg-low';
55 if (seedType === 'spawn') return 'bg-medium';
56 if (seedType === 'master') return 'bg-high';
58 if (classOf === 'planet') {
59 if (seedType === 'manage') return 'bg-low';
60 if (seedType === 'master') return 'bg-medium';
67const infoManagementSeed = ship => {
68 const classOf = ob.clan(ship)
69 const colorClass = getColor(classOf, 'manage')
70 return <Tile colorClass={colorClass} key={`info-${ship}-manage`} col1={`Management Proxy`} col2={''} />
74const infoVotingSeed = ship => {
75 const classOf = ob.clan(ship)
76 const colorClass = getColor(classOf, 'voting')
77 return <Tile colorClass={colorClass} key={`info-${ship}-voting`} col1={`Voting Proxy`} col2={''} />
82const infoSpawnSeed = ship => {
83 const classOf = ob.clan(ship)
84 const colorClass = getColor(classOf, 'spawn')
85 return <Tile colorClass={colorClass} key={`info-${ship}-spawn`} col1={`Spawn Proxy`} col2={''} />
90const infoMasterTicket = ship => {
91 const classOf = ob.clan(ship);
92 const colorClass = getColor(classOf, 'master');
93 return <Tile colorClass={colorClass} key={`info-${ship}-master`} col1={`Master Ticket`} col2={''} />;
98const infoMasterTicketShard = ship => {
99 const classOf = ob.clan(ship);
100 const colorClass = getColor(classOf, 'master');
102 <Tile colorClass={colorClass} key={`info-${ship}-master-1`} col1={`Master Ticket Shard 1 of 3`} col2={''} />,
103 <Tile colorClass={colorClass} key={`info-${ship}-master-2`} col1={`Master Ticket Shard 2 of 3`} col2={''} />,
104 <Tile colorClass={colorClass} key={`info-${ship}-master-3`} col1={`Master Ticket Shard 3 of 3`} col2={''} />,
110const Tile = (props) => {
113 className={ `${props.colorClass} white row pl-4 text-mono` }
114 style={{borderBottom:'2px solid black', height: '39px' }}
117 <div className={'col-md-8 flex align-center text-600'}>{props.col1}</div>
118 <div className={'col-md-4 flex align-center text-500'}>{props.col2}</div>
124const galaxyInfo = (ship, sig) =>
125 <div className={'mt-8'} key={ 'wallet-' + ship }>
127 <div className={'row'} key={ ship + '-body' }>
128 { infoSigil(ship, sig) }
129 <div className={ 'col-md-7 ml-2' } key={ 'info-' + ship }>
130 { infoMasterTicketShard(ship) }
131 { infoSpawnSeed(ship) }
132 { infoManagementSeed(ship) }
133 { infoVotingSeed(ship) }
138const starInfo = (ship, sig) =>
139 <div className={'mt-8'} key={ 'wallet-' + ship }>
141 <div className={'row'} key={ ship + '-body' }>
142 { infoSigil(ship, sig) }
143 <div className={ 'col-md-7 ml-2' } key={ 'info-' + ship }>
144 { infoMasterTicket(ship) }
145 { infoSpawnSeed(ship) }
146 { infoManagementSeed(ship) }
151const planetInfo = (ship, sig) =>
152 <div className={'mt-8'} key={ 'wallet-' + ship }>
154 <div className={'row'} key={ ship + '-body' }>
155 { infoSigil(ship, sig) }
156 <div className={ 'col-md-7 ml-2' } key={ 'info-' + ship }>
157 { infoMasterTicket(ship) }
158 { infoManagementSeed(ship) }
163class Generate extends React.Component {
166 this.handleGenerate = this.handleGenerate.bind(this);
169 handleGenerate = async () => {
170 const { props } = this;
171 const { setGlobalState } = this.props;
173 setGlobalState({ 'eny.state': GEN_STATES.ENY_PENDING });
176 ...props['profile.value'].galaxies,
177 ...props['profile.value'].stars,
178 ...props['profile.value'].planets,
181 const enyPromises = ships.map(async ship => {
184 ticket: await wg.makeTicket(ship),
188 const enyTable = await Promise.all(enyPromises);
191 'eny.value': enyTable,
192 'eny.state': GEN_STATES.ENY_SUCCESS,
193 'wallets.state': GEN_STATES.DERIVATION_PENDING,
196 await this.forciblyExecuteArgon2Once(enyTable);
198 const walletPromises = enyTable.map(async ({ ship, ticket }) => {
199 const boot = ship < MIN_STAR || ship > MAX_STAR;
202 wallet: await wg.generateWallet(ship, ticket, boot),
206 const wallets = await Promise.all(walletPromises);
208 const reshapedWallet = wallets.reduce((acc, {ship, wallet}) => ({...acc, [ship]: wallet }), {})
211 'wallets.value': reshapedWallet,
212 'wallets.state': GEN_STATES.DERIVATION_SUCCESS,
213 'paperCollateral.state': GEN_STATES.PAPER_PENDING,
219 forciblyExecuteArgon2Once = async enyTable => {
222 // following is some insane thing required so as not to run into bizarre
224 if (enyTable.length === 0) {
225 throw new Error('no ship information provided')
227 let throwawayEntry = enyTable[0]
228 // eslint-disable-next-line
229 let throwaway = await genWallet(throwawayEntry.ship, throwawayEntry.ticket, () => {})
236 const { props } = this;
237 const { setGlobalState } = this.props;
254 const es = props['eny.state'];
255 const ws = props['wallets.state'];
256 const ps = props['paperCollateral.state'];
260 es === ENY_SUCCESS &&
261 ws === DERIVATION_SUCCESS &&
262 ps === PAPER_SUCCESS;
265 es === ENY_NOSTART &&
266 ws === DERIVATION_NOSTART &&
267 ps === PAPER_NOSTART;
270 es === ENY_FAILURE ||
271 ws === DERIVATION_FAILURE ||
272 ps === PAPER_FAILURE;
275 es === ENY_PENDING ||
276 ws === DERIVATION_PENDING ||
277 ps === PAPER_PENDING;
279 const genButtonClass = classnames({
280 'bg-blue white': true,
281 'bg-green noClick black': ALL_SUCCESS,
284 const entropyBarClassnames = classnames({
285 'bg-blue': es === ENY_SUCCESS,
286 'bg-lightBlue': es === ENY_PENDING,
287 'bg-gray': es === ENY_NOSTART,
288 'bg-orange': es === ENY_FAILURE,
289 'bg-green': ALL_SUCCESS,
292 const walletsBarClassnames = classnames({
293 'bg-blue': ws === DERIVATION_SUCCESS,
294 'bg-lightBlue': ws === DERIVATION_PENDING,
295 'bg-gray': ws === DERIVATION_NOSTART,
296 'bg-orange': ws === DERIVATION_FAILURE,
297 'bg-green': ALL_SUCCESS,
300 const paperBarClassnames = classnames({
301 'bg-blue': ps === PAPER_SUCCESS,
302 'bg-lightBlue': ps === PAPER_PENDING,
303 'bg-gray': ps === PAPER_NOSTART,
304 'bg-orange': ps === PAPER_FAILURE,
305 'bg-green': ALL_SUCCESS,
308 const isGenerateButtonDisabled = () => {
309 if (NONE_START === true) return false;
310 if (ANY_PENDING === true) return true;
311 if (ANY_ERROR === true) return false;
312 if (ALL_SUCCESS === true) return true;
315 const getGenButtonText = () => {
316 // const N = props['wallets.genCounter'] + 1;
317 // const X = props['eny.value'].length;
319 if (NONE_START === true) r = 'Generate All';
320 if (es === ENY_PENDING) r = 'Generating Entropy';
321 // if (ws === DERIVATION_PENDING) r = `Generating Wallet ${N} / ${X}`;
322 if (ws === DERIVATION_PENDING) r = `Generating Wallets`;
323 if (ps === PAPER_PENDING) r = 'Making Paper Collateral';
324 if (ALL_SUCCESS === true) r = 'Success.';
325 if (ANY_ERROR === true) r = 'Try Again';
329 const disableGenerateButton = isGenerateButtonDisabled();
330 const genText = getGenButtonText();
332 const nextButtonClass = classnames({
333 'bg-blue white': ALL_SUCCESS === true,
334 'bg-gray black': ALL_SUCCESS !== true,
337 const nextButtonDisabled = ws !== ALL_SUCCESS;
340 <div className={'row'}>
341 <div className={'col-md-8'}>
342 <div className={'col-md-8'}>
343 <h2>{`Review your paper wallet storage recommendations.`}</h2>
345 {`Each ship is placed into its own wallet with proxies that differ in
346 importance and security requirements. These are listed as examples below. A key to our security recommendations can be found to the right of the page.`}
350 { props['profile.value'].galaxies.map(ship => shipInfo(ship)) }
351 { props['profile.value'].stars.map(ship => shipInfo(ship)) }
352 { props['profile.value'].planets.map(ship => shipInfo(ship)) }
356 <div className="col-md-3 col-md-offset-1 mt-9">
357 <div className="fixed" style={{width: '230px'}}>
358 <div className="col-md-12 bg-very-high h-2 mt-4"></div>
359 <h4 className="text-600 mt-2">Very High Friction</h4>
360 <p className="text-sm" style={{lineHeight: '16px'}}>
361 Extremely valuable. Cold storage on a 3 part sharded paper wallet. Store each shard in a separate geographic location with protection against fire, water and other elements.
363 <div className="col-md-12 bg-high h-2 mt-4"></div>
364 <h4 className="text-600 mt-2">High Friction</h4>
365 <p className="text-sm" style={{lineHeight: '16px'}}>
366 Very valuable. Cold storage on a paper wallet in a different location than your computer, such as a safe.
368 <div className="col-md-12 bg-medium h-2 mt-4"></div>
369 <h4 className="text-600 mt-2">Medium Friction</h4>
370 <p className="text-sm" style={{lineHeight: '16px'}}>
371 Store cold in a paper wallet; can be stored in a desk drawer in a trusted environment.
373 <div className="col-md-12 bg-low h-2 mt-4"></div>
374 <h4 className="text-600 mt-2">Low Friction</h4>
375 <p className="text-sm" style={{lineHeight: '16px'}}>
376 Ok to store hot on a trusted networked computer.
381 <div className={'col-md-9 btn-tray col-'}>
382 <h3>{"Got it? Then it's time to generate your wallets."}</h3>
383 <p className={'col-md-8'}>{"If you have a large number of ships, this may take several minutes and the page may hang or become unresponsive. If you close this browser window, you will have to start from the beginning."}</p>
385 <div className={'flex h-12 mt-8 mb-4'}>
387 className={ `${genButtonClass} b-r-1-black w-50 m-0` }
389 onClick={ this.handleGenerate }
390 disable={disableGenerateButton} />
391 <div className={`${entropyBarClassnames} f-1 b-r-1-black`} />
392 <div className={`${walletsBarClassnames} f-3 b-r-1-black`} />
393 <div className={`${paperBarClassnames} f-3 b-r-1-black`} />
395 className={ `${nextButtonClass} m-0` }
396 text={'View wallets →'}
397 disable={ nextButtonDisabled }
398 onClick= { () => setGlobalState({ route: '/Download' , 'currentStep': NEXT_STEP_NUM })} />
402 <div className={'extremely-hidden'}>
403 <div className={'text-300'}>{'text-300'}</div>
404 <div className={'text-400'}>{'text-400'}</div>
405 <div className={'text-500'}>{'text-500'}</div>
406 <div className={'text-600'}>{'text-600'}</div>
407 <div className={'text-400 text-mono'}>{'text-400 text-mono'}</div>
408 <div className={'text-600 text-mono'}>{'text-600 text-mono'}</div>
409 <div className={'text-500 h-font'}>{'text-500 h-font'}</div>
410 <div className={'text-600 h-font'}>{'text-600 h-font'}</div>
413 { props['wallets.state'] === GEN_STATES.DERIVATION_SUCCESS
414 ? <PaperCollateralRenderer
415 wallet={props['wallets.value']}
416 className={'extremely-hidden'}
417 callback={data => setGlobalState({
418 'paperCollateral.value': data,
419 'paperCollateral.state': GEN_STATES.PAPER_SUCCESS
421 mode={'REGISTRATION'} />
430export default Generate
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