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';
7import Button from '../components/Button';
8import ReactSVGComponents from '../components/ReactSVGComponents';
9import PaperCollateralRenderer from 'PaperCollateralRenderer';
11import { MAX_GALAXY, MIN_STAR, MAX_STAR, GEN_STATES } from '../lib/constants';
13const NEXT_STEP_NUM = 6;
15const shipInfo = ship => {
16 const name = ob.patp(ship);
17 const sig = sigil.pour({
18 colorway: ['black', 'white'],
20 renderer: ReactSVGComponents,
24 return ship < MAX_GALAXY
25 ? galaxyInfo(name, sig)
28 : planetInfo(name, sig);
31const infoHeader = ship => (
32 <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';
64const infoManagementSeed = ship => {
65 const classOf = ob.clan(ship);
66 const colorClass = getColor(classOf, 'manage');
69 colorClass={colorClass}
70 key={`info-${ship}-manage`}
71 col1={`Management Proxy`}
77const infoVotingSeed = ship => {
78 const classOf = ob.clan(ship);
79 const colorClass = getColor(classOf, 'voting');
82 colorClass={colorClass}
83 key={`info-${ship}-voting`}
90const infoSpawnSeed = ship => {
91 const classOf = ob.clan(ship);
92 const colorClass = getColor(classOf, 'spawn');
95 colorClass={colorClass}
96 key={`info-${ship}-spawn`}
103const infoMasterTicket = ship => {
104 const classOf = ob.clan(ship);
105 const colorClass = getColor(classOf, 'master');
108 colorClass={colorClass}
109 key={`info-${ship}-master`}
110 col1={`Master Ticket`}
116const infoMasterTicketShard = ship => {
117 const classOf = ob.clan(ship);
118 const colorClass = getColor(classOf, 'master');
121 colorClass={colorClass}
122 key={`info-${ship}-master-1`}
123 col1={`Master Ticket Shard 1 of 3`}
127 colorClass={colorClass}
128 key={`info-${ship}-master-2`}
129 col1={`Master Ticket Shard 2 of 3`}
133 colorClass={colorClass}
134 key={`info-${ship}-master-3`}
135 col1={`Master Ticket Shard 3 of 3`}
141const Tile = props => {
144 className={`${props.colorClass} white row pl-4 text-mono`}
145 style={{ borderBottom: '2px solid black', height: '39px' }}
147 <div className={'col-md-8 flex align-center text-600'}>{props.col1}</div>
148 <div className={'col-md-4 flex align-center text-500'}>{props.col2}</div>
153const galaxyInfo = (ship, sig) => (
154 <div className={'mt-8'} key={'wallet-' + ship}>
156 <div className={'row'} key={ship + '-body'}>
157 {infoSigil(ship, sig)}
158 <div className={'col-md-7 ml-2'} key={'info-' + ship}>
159 {infoMasterTicketShard(ship)}
160 {infoSpawnSeed(ship)}
161 {infoManagementSeed(ship)}
162 {infoVotingSeed(ship)}
168const starInfo = (ship, sig) => (
169 <div className={'mt-8'} key={'wallet-' + ship}>
171 <div className={'row'} key={ship + '-body'}>
172 {infoSigil(ship, sig)}
173 <div className={'col-md-7 ml-2'} key={'info-' + ship}>
174 {infoMasterTicket(ship)}
175 {infoSpawnSeed(ship)}
176 {infoManagementSeed(ship)}
182const planetInfo = (ship, sig) => (
183 <div className={'mt-8'} key={'wallet-' + ship}>
185 <div className={'row'} key={ship + '-body'}>
186 {infoSigil(ship, sig)}
187 <div className={'col-md-7 ml-2'} key={'info-' + ship}>
188 {infoMasterTicket(ship)}
189 {infoManagementSeed(ship)}
195class Generate extends React.Component {
198 this.handleGenerate = this.handleGenerate.bind(this);
201 handleGenerate = async () => {
202 const { props } = this;
203 const { setGlobalState } = this.props;
205 setGlobalState({ 'eny.state': GEN_STATES.ENY_PENDING });
208 ...props['profile.value'].galaxies,
209 ...props['profile.value'].stars,
210 ...props['profile.value'].planets,
213 const enyPromises = ships.map(async ship => {
216 ticket: await wg.makeTicket(ship),
220 const enyTable = await Promise.all(enyPromises);
223 'eny.value': enyTable,
224 'eny.state': GEN_STATES.ENY_SUCCESS,
225 'wallets.state': GEN_STATES.DERIVATION_PENDING,
228 await this.forciblyExecuteArgon2Once(enyTable);
230 const walletPromises = enyTable.map(async ({ ship, ticket }) => {
231 const boot = ship < MIN_STAR || ship > MAX_STAR;
234 wallet: await wg.generateWallet(ship, ticket, boot),
238 const wallets = await Promise.all(walletPromises);
240 const reshapedWallet = wallets.reduce(
241 (acc, { ship, wallet }) => ({ ...acc, [ship]: wallet }),
246 'wallets.value': reshapedWallet,
247 'wallets.state': GEN_STATES.DERIVATION_SUCCESS,
248 'paperCollateral.state': GEN_STATES.PAPER_PENDING,
252 forciblyExecuteArgon2Once = async enyTable => {
255 // following is some insane thing required so as not to run into bizarre
257 if (enyTable.length === 0) {
258 throw new Error('no ship information provided');
260 let throwawayEntry = enyTable[0];
261 // eslint-disable-next-line
262 let throwaway = await genWallet(
264 throwawayEntry.ticket,
271 const { props } = this;
272 const { setGlobalState } = this.props;
289 const es = props['eny.state'];
290 const ws = props['wallets.state'];
291 const ps = props['paperCollateral.state'];
294 es === ENY_SUCCESS && ws === DERIVATION_SUCCESS && ps === PAPER_SUCCESS;
297 es === ENY_NOSTART && ws === DERIVATION_NOSTART && ps === PAPER_NOSTART;
300 es === ENY_FAILURE || ws === DERIVATION_FAILURE || ps === PAPER_FAILURE;
303 es === ENY_PENDING || ws === DERIVATION_PENDING || ps === PAPER_PENDING;
305 const genButtonClass = classnames({
306 'bg-blue white': true,
307 'bg-green noClick black': ALL_SUCCESS,
310 const entropyBarClassnames = classnames({
311 'bg-blue': es === ENY_SUCCESS,
312 'bg-lightBlue': es === ENY_PENDING,
313 'bg-gray': es === ENY_NOSTART,
314 'bg-orange': es === ENY_FAILURE,
315 'bg-green': ALL_SUCCESS,
318 const walletsBarClassnames = classnames({
319 'bg-blue': ws === DERIVATION_SUCCESS,
320 'bg-lightBlue': ws === DERIVATION_PENDING,
321 'bg-gray': ws === DERIVATION_NOSTART,
322 'bg-orange': ws === DERIVATION_FAILURE,
323 'bg-green': ALL_SUCCESS,
326 const paperBarClassnames = classnames({
327 'bg-blue': ps === PAPER_SUCCESS,
328 'bg-lightBlue': ps === PAPER_PENDING,
329 'bg-gray': ps === PAPER_NOSTART,
330 'bg-orange': ps === PAPER_FAILURE,
331 'bg-green': ALL_SUCCESS,
334 const isGenerateButtonDisabled = () => {
335 if (NONE_START === true) return false;
336 if (ANY_PENDING === true) return true;
337 if (ANY_ERROR === true) return false;
338 if (ALL_SUCCESS === true) return true;
341 const getGenButtonText = () => {
342 // const N = props['wallets.genCounter'] + 1;
343 // const X = props['eny.value'].length;
345 if (NONE_START === true) r = 'Generate All';
346 if (es === ENY_PENDING) r = 'Generating Entropy';
347 // if (ws === DERIVATION_PENDING) r = `Generating Wallet ${N} / ${X}`;
348 if (ws === DERIVATION_PENDING) r = `Generating Wallets`;
349 if (ps === PAPER_PENDING) r = 'Making Paper Collateral';
350 if (ALL_SUCCESS === true) r = 'Success.';
351 if (ANY_ERROR === true) r = 'Try Again';
355 const disableGenerateButton = isGenerateButtonDisabled();
356 const genText = getGenButtonText();
358 const nextButtonClass = classnames({
359 'bg-blue white': ALL_SUCCESS === true,
360 'bg-gray black': ALL_SUCCESS !== true,
363 const nextButtonDisabled = ws !== ALL_SUCCESS;
366 <div className={'row'}>
367 <div className={'col-md-8'}>
368 <div className={'col-md-8'}>
369 <h2>{`Review your paper wallet storage recommendations.`}</h2>
371 {`Each ship is placed into its own wallet with proxies that differ in
372 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.`}
376 {props['profile.value'].galaxies.map(ship => shipInfo(ship))}
377 {props['profile.value'].stars.map(ship => shipInfo(ship))}
378 {props['profile.value'].planets.map(ship => shipInfo(ship))}
381 <div className="col-md-3 col-md-offset-1 mt-9">
382 <div className="fixed" style={{ width: '230px' }}>
383 <div className="col-md-12 bg-very-high h-2 mt-4" />
384 <h4 className="text-600 mt-2">Very High Friction</h4>
385 <p className="text-sm" style={{ lineHeight: '16px' }}>
386 Extremely valuable. Cold storage on a 3 part sharded paper wallet.
387 Store each shard in a separate geographic location with protection
388 against fire, water and other elements.
390 <div className="col-md-12 bg-high h-2 mt-4" />
391 <h4 className="text-600 mt-2">High Friction</h4>
392 <p className="text-sm" style={{ lineHeight: '16px' }}>
393 Very valuable. Cold storage on a paper wallet in a different
394 location than your computer, such as a safe.
396 <div className="col-md-12 bg-medium h-2 mt-4" />
397 <h4 className="text-600 mt-2">Medium Friction</h4>
398 <p className="text-sm" style={{ lineHeight: '16px' }}>
399 Store cold in a paper wallet; can be stored in a desk drawer in a
402 <div className="col-md-12 bg-low h-2 mt-4" />
403 <h4 className="text-600 mt-2">Low Friction</h4>
404 <p className="text-sm" style={{ lineHeight: '16px' }}>
405 Ok to store hot on a trusted networked computer.
410 <div className={'col-md-9 btn-tray col-'}>
411 <h3>{"Got it? Then it's time to generate your wallets."}</h3>
412 <p className={'col-md-8'}>
414 '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.'
418 <div className={'flex h-12 mt-8 mb-4'}>
420 className={`${genButtonClass} b-r-1-black w-50 m-0`}
422 onClick={this.handleGenerate}
423 disable={disableGenerateButton}
425 <div className={`${entropyBarClassnames} f-1 b-r-1-black`} />
426 <div className={`${walletsBarClassnames} f-3 b-r-1-black`} />
427 <div className={`${paperBarClassnames} f-3 b-r-1-black`} />
429 className={`${nextButtonClass} m-0`}
430 text={'View wallets →'}
431 disable={nextButtonDisabled}
435 currentStep: NEXT_STEP_NUM,
442 <div className={'extremely-hidden'}>
443 <div className={'text-300'}>{'text-300'}</div>
444 <div className={'text-400'}>{'text-400'}</div>
445 <div className={'text-500'}>{'text-500'}</div>
446 <div className={'text-600'}>{'text-600'}</div>
447 <div className={'text-400 text-mono'}>{'text-400 text-mono'}</div>
448 <div className={'text-600 text-mono'}>{'text-600 text-mono'}</div>
449 <div className={'text-500 h-font'}>{'text-500 h-font'}</div>
450 <div className={'text-600 h-font'}>{'text-600 h-font'}</div>
453 {props['wallets.state'] === GEN_STATES.DERIVATION_SUCCESS ? (
454 <PaperCollateralRenderer
455 wallet={props['wallets.value']}
456 className={'extremely-hidden'}
459 'paperCollateral.value': data,
460 'paperCollateral.state': GEN_STATES.PAPER_SUCCESS,
463 mode={'REGISTRATION'}
473export 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