on master help sign in
formatting update
b7e6d6fMatt Condon (shrugs)
src/bridge/Bridge.js+22−23
@@ -1,25 +1,25 @@
1−import React from "react";
1+import React from 'react';
2−import { Just, Nothing } from "folktale/maybe";
2+import { Just, Nothing } from 'folktale/maybe';
3−import { includes } from "lodash";
3+import { includes } from 'lodash';
4
4
5−import Footer from "./components/Footer";
5+import Footer from './components/Footer';
6−import Header from "./components/Header";
6+import Header from './components/Header';
7−import { Container, Row, Col } from "./components/Base";
7+import { Container, Row, Col } from './components/Base';
8
8
9−import { router } from "./lib/router";
9+import { router } from './lib/router';
10−import { initWeb3 } from "./lib/web3";
10+import { initWeb3 } from './lib/web3';
11−import { ROUTE_NAMES } from "./lib/routeNames";
11+import { ROUTE_NAMES } from './lib/routeNames';
12−import { HistoryProvider, withHistory, useHistory } from "./store/history";
12+import { HistoryProvider, withHistory, useHistory } from './store/history';
13−import { TxnConfirmationsProvider } from "./store/txnConfirmations";
13+import { TxnConfirmationsProvider } from './store/txnConfirmations';
14−import { NETWORK_NAMES } from "./lib/network";
14+import { NETWORK_NAMES } from './lib/network';
15import {
15import {
16 WALLET_NAMES,
16 WALLET_NAMES,
17 DEFAULT_HD_PATH,
17 DEFAULT_HD_PATH,
18 walletFromMnemonic,
18 walletFromMnemonic,
19 addressFromSecp256k1Public,
19 addressFromSecp256k1Public,
20−} from "./lib/wallet";
20+} from './lib/wallet';
21−import { BRIDGE_ERROR } from "./lib/error";
21+import { BRIDGE_ERROR } from './lib/error';
22−import { isLocal } from "./lib/flags";
22+import { isLocal } from './lib/flags';
23
23
24// NB(shrugs): toggle this variable to use the default local state.
24// NB(shrugs): toggle this variable to use the default local state.
25// don't commit changes to this line, but there shouldn't be a problem
25// don't commit changes to this line, but there shouldn't be a problem
@@ -51,13 +51,12 @@ const VariableWidthColumn = withHistory(({ history, children }) => (
51 <Col
51 <Col
52 className={
52 className={
53 history.includes(ROUTE_NAMES.INVITE_TICKET)
53 history.includes(ROUTE_NAMES.INVITE_TICKET)
54− ? "col-md-12"
54+ ? 'col-md-12'
55− : "col-md-offset-1 col-md-10"
55+ : 'col-md-offset-1 col-md-10'
56 }
56 }
57 style={
57 style={
58− history.includes(ROUTE_NAMES.INVITE_TICKET) ? {} : { maxWidth: "620px" }
58+ history.includes(ROUTE_NAMES.INVITE_TICKET) ? {} : { maxWidth: '620px' }
59− }
59+ }>
60− >
61 {children}
60 {children}
62 </Col>
61 </Col>
63));
62));
@@ -192,7 +191,7 @@ class Bridge extends React.Component {
192 wallet = walletFromMnemonic(
191 wallet = walletFromMnemonic(
193 mnemonic,
192 mnemonic,
194 DEFAULT_HD_PATH,
193 DEFAULT_HD_PATH,
195− urbitWallet.value.meta.passphrase,
194+ urbitWallet.value.meta.passphrase
196 );
195 );
197 wallet.map(wal => {
196 wallet.map(wal => {
198 wal.address = urbitWallet.value.ownership.keys.address;
197 wal.address = urbitWallet.value.ownership.keys.address;
@@ -250,7 +249,7 @@ class Bridge extends React.Component {
250 pointCursor={pointCursor}
249 pointCursor={pointCursor}
251 />
250 />
252
251
253− <Row className={"row wrapper"}>
252+ <Row className={'row wrapper'}>
254 <Router
253 <Router
255 // network
254 // network
256 setNetworkType={this.setNetworkType}
255 setNetworkType={this.setNetworkType}
@@ -284,7 +283,7 @@ class Bridge extends React.Component {
284 txnHashCursor={txnHashCursor}
283 txnHashCursor={txnHashCursor}
285 />
284 />
286
285
287− <div className={"push"} />
286+ <div className={'push'} />
288 </Row>
287 </Row>
289
288
290 <Footer />
289 <Footer />
src/bridge/components/DropdownItem.js+1−3
@@ -10,9 +10,7 @@ const DropdownItem = props => {
10 <button
10 <button
11 disabled={props.disabled}
11 disabled={props.disabled}
12 style={props.style}
12 style={props.style}
13− className={`h-10 m-0 p-0 ph-2 bg-white flex align-center items-start bs-solid brw-2 blw-2 btw-0 bbw-0 sans ${_disabled} ${
13+ className={`h-10 m-0 p-0 ph-2 bg-white flex align-center items-start bs-solid brw-2 blw-2 btw-0 bbw-0 sans ${_disabled} ${props.className}`}
14− props.className
15− }`}
16 onClick={props.onClick}>
14 onClick={props.onClick}>
17 {props.children}
15 {props.children}
18 </button>
16 </button>
src/bridge/components/Header.js+12−13
@@ -1,10 +1,10 @@
1−import React from "react";
1+import React from 'react';
2−import { Button, Chevron } from "../components/Base";
2+import { Button, Chevron } from '../components/Base';
3
3
4−import { getRouteBreadcrumb } from "../lib/router";
4+import { getRouteBreadcrumb } from '../lib/router';
5−import { ROUTE_NAMES } from "../lib/routeNames";
5+import { ROUTE_NAMES } from '../lib/routeNames';
6−import { useHistory } from "../store/history";
6+import { useHistory } from '../store/history';
7−import { isLast } from "../lib/lib";
7+import { isLast } from '../lib/lib';
8
8
9function Crumbs(props) {
9function Crumbs(props) {
10 const history = useHistory();
10 const history = useHistory();
@@ -13,20 +13,19 @@ function Crumbs(props) {
13 // return the reversed array of renders
13 // return the reversed array of renders
14 const rendered = history.routes.map((route, idx) => {
14 const rendered = history.routes.map((route, idx) => {
15 return (
15 return (
16− <div className={"flex items-center"} key={`history-${idx}`}>
16+ <div className={'flex items-center'} key={`history-${idx}`}>
17 <Button
17 <Button
18− prop-type={"link"}
18+ prop-type={'link'}
19− prop-size={"sm"}
19+ prop-size={'sm'}
20 key={`history-button-${idx}`}
20 key={`history-button-${idx}`}
21− onClick={() => history.pop(history.size - idx - 1)}
21+ onClick={() => history.pop(history.size - idx - 1)}>
22− >
23 {getRouteBreadcrumb(props, route)}
22 {getRouteBreadcrumb(props, route)}
24 </Button>
23 </Button>
25
24
26 {isLast(history.size, idx) ? (
25 {isLast(history.size, idx) ? (
27 <div />
26 <div />
28 ) : (
27 ) : (
29− <Chevron className={"h-4 mh-2"} />
28+ <Chevron className={'h-4 mh-2'} />
30 )}
29 )}
31 </div>
30 </div>
32 );
31 );
@@ -42,7 +41,7 @@ function Header(props) {
42
41
43 if (showCrumbs) {
42 if (showCrumbs) {
44 return (
43 return (
45− <div className={"flex items-center h-10"}>
44+ <div className={'flex items-center h-10'}>
46 <Crumbs
45 <Crumbs
47 networkType={props.networkType}
46 networkType={props.networkType}
48 wallet={props.wallet}
47 wallet={props.wallet}
src/bridge/components/HorizontalSelector.js+1−3
@@ -22,9 +22,7 @@ class HorizontalSelector extends React.Component {
22 let active = opt.value === this.state.option ? 'btn-primary active' : '';
22 let active = opt.value === this.state.option ? 'btn-primary active' : '';
23 return (
23 return (
24 <button
24 <button
25− className={`btn ${active} h-10 ph-4 flex sans ${
25+ className={`btn ${active} h-10 ph-4 flex sans ${this.props.className}`}
26− this.props.className
27− }`}
28 value={opt.value}
26 value={opt.value}
29 onClick={() => this.selectOption(opt.value)}>
27 onClick={() => this.selectOption(opt.value)}>
30 {opt.title}
28 {opt.title}
src/bridge/components/OldHeader.js+26−30
@@ -1,8 +1,8 @@
1import React from 'react';
1import React from 'react';
2import { Button, Chevron } from '../components/Base';
2import { Button, Chevron } from '../components/Base';
3
3
4−import { getRouteBreadcrumb } from '../lib/router'
4+import { getRouteBreadcrumb } from '../lib/router';
5−import { isLast } from '../lib/lib'
5+import { isLast } from '../lib/lib';
6
6
7const Crumbs = props => {
7const Crumbs = props => {
8 const { routeCrumbs, skipRoute } = props;
8 const { routeCrumbs, skipRoute } = props;
@@ -11,34 +11,30 @@ const Crumbs = props => {
11 // FIXME probably more straightforward to render them normally and just
11 // FIXME probably more straightforward to render them normally and just
12 // return the reversed array of renders
12 // return the reversed array of renders
13 const rendered = history.map((route, idx) => {
13 const rendered = history.map((route, idx) => {
14−
15− return (
14+ return (
16− <div className={'flex items-center'} key={ `history-${idx}` }>
15+ <div className={'flex items-center'} key={`history-${idx}`}>
17−
18− <Button
16+ <Button
19− size={'s'}
17+ size={'s'}
20− type={'link'}
18+ type={'link'}
21− color={'black'}
19+ color={'black'}
22− key={ `history-button-${idx}` }
20+ key={`history-button-${idx}`}
23− onClick={ () => skipRoute(history.size - idx - 1) }
21+ onClick={() => skipRoute(history.size - idx - 1)}>
24− >
25− { `${getRouteBreadcrumb(props, route)}` }
22+ {`${getRouteBreadcrumb(props, route)}`}
26− </Button>
23+ </Button>
27−
24+
28− {
29− isLast(history.size, idx)
25+ {isLast(history.size, idx) ? (
30− ? <div />
26+ <div />
27+ ) : (
31− : <Chevron className={'h-4 mh-2'} />
28+ <Chevron className={'h-4 mh-2'} />
32− }
29+ )}
33−
34− </div>
30+ </div>
35− )
31+ );
36− })
32+ });
37−
33+
38− return rendered
34+ return rendered;
39−}
35+};
40−
36+
41−const Header = (props) =>
37+const Header = props => (
42 <div className={'flex items-center h-8 pt-4'}>
38 <div className={'flex items-center h-8 pt-4'}>
43 <Crumbs
39 <Crumbs
44 routeCrumbs={props.routeCrumbs}
40 routeCrumbs={props.routeCrumbs}
src/bridge/components/RenderedPoint.js+15−18
@@ -1,12 +1,12 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Col } from "./Base";
3+import { Col } from './Base';
4−import { Button } from "./Base";
4+import { Button } from './Base';
5−import { pour } from "sigil-js";
5+import { pour } from 'sigil-js';
6−import * as ob from "urbit-ob";
6+import * as ob from 'urbit-ob';
7
7
8−import { ROUTE_NAMES } from "../lib/routeNames";
8+import { ROUTE_NAMES } from '../lib/routeNames';
9−import ReactSVGComponents from "./ReactSVGComponents";
9+import ReactSVGComponents from './ReactSVGComponents';
10
10
11const RenderedPoint = props => {
11const RenderedPoint = props => {
12 const { setPointCursor, routeHandler, point } = props;
12 const { setPointCursor, routeHandler, point } = props;
@@ -19,15 +19,14 @@ const RenderedPoint = props => {
19 });
19 });
20
20
21 return (
21 return (
22− <Col className={"col-md-3 mb-8"} key={`rendered-${point}`}>
22+ <Col className={'col-md-3 mb-8'} key={`rendered-${point}`}>
23 <div
23 <div
24 key={`rendered-sigil-${point}`}
24 key={`rendered-sigil-${point}`}
25 className="clickable"
25 className="clickable"
26 onClick={() => {
26 onClick={() => {
27 setPointCursor(Maybe.Just(point));
27 setPointCursor(Maybe.Just(point));
28 routeHandler(ROUTE_NAMES.SHIP);
28 routeHandler(ROUTE_NAMES.SHIP);
29− }}
29+ }}>
30− >
31 {sigil}
30 {sigil}
32 </div>
31 </div>
33 <div
32 <div
@@ -36,21 +35,19 @@ const RenderedPoint = props => {
36 onClick={() => {
35 onClick={() => {
37 setPointCursor(Maybe.Just(point));
36 setPointCursor(Maybe.Just(point));
38 routeHandler(ROUTE_NAMES.SHIP);
37 routeHandler(ROUTE_NAMES.SHIP);
39− }}
38+ }}>
40− >
41 <code>{name}</code>
39 <code>{name}</code>
42 </div>
40 </div>
43 <div key={`rendered-deets-${point}`}>
41 <div key={`rendered-deets-${point}`}>
44 <Button
42 <Button
45 key={`rendered-deets-button-${point}`}
43 key={`rendered-deets-button-${point}`}
46− prop-type={"link"}
44+ prop-type={'link'}
47− prop-size={"sm"}
45+ prop-size={'sm'}
48 onClick={() => {
46 onClick={() => {
49 setPointCursor(Maybe.Just(point));
47 setPointCursor(Maybe.Just(point));
50 routeHandler(ROUTE_NAMES.SHIP);
48 routeHandler(ROUTE_NAMES.SHIP);
51− }}
49+ }}>
52− >
53− {"Details →"}
50+ {'Details →'}
54 </Button>
51 </Button>
55 </div>
52 </div>
56 </Col>
53 </Col>
src/bridge/components/StatelessTransaction.js+95−102
@@ -1,17 +1,17 @@
1−import { Nothing, Just } from "folktale/maybe";
1+import { Nothing, Just } from 'folktale/maybe';
2−import { Ok } from "folktale/result";
2+import { Ok } from 'folktale/result';
3−import React from "react";
3+import React from 'react';
4−import * as need from "../lib/need";
4+import * as need from '../lib/need';
5
5
6−import { Code, H3 } from "./Base";
6+import { Code, H3 } from './Base';
7−import { Button } from "./Base";
7+import { Button } from './Base';
8−import { CheckboxButton, Input, InnerLabel, InnerLabelDropdown } from "./Base";
8+import { CheckboxButton, Input, InnerLabel, InnerLabelDropdown } from './Base';
9−import { Warning } from "../components/Base";
9+import { Warning } from '../components/Base';
10
10
11−import { BRIDGE_ERROR } from "../lib/error";
11+import { BRIDGE_ERROR } from '../lib/error';
12−import { ROUTE_NAMES } from "../lib/routeNames";
12+import { ROUTE_NAMES } from '../lib/routeNames';
13−import { withHistory } from "../store/history";
13+import { withHistory } from '../store/history';
14−import * as tank from "../lib/tank";
14+import * as tank from '../lib/tank';
15
15
16import {
16import {
17 sendSignedTransaction,
17 sendSignedTransaction,
@@ -20,14 +20,14 @@ import {
20 hexify,
20 hexify,
21 renderSignedTx,
21 renderSignedTx,
22 signTransaction,
22 signTransaction,
23−} from "../lib/txn";
23+} from '../lib/txn';
24−import { withTxnConfirmations } from "../store/txnConfirmations";
24+import { withTxnConfirmations } from '../store/txnConfirmations';
25
25
26const SUBMISSION_STATES = {
26const SUBMISSION_STATES = {
27− PROMPT: "Send transaction",
27+ PROMPT: 'Send transaction',
28− PREPARING: "Preparing...",
28+ PREPARING: 'Preparing...',
29− FUNDING: "Finding transaction funding...",
29+ FUNDING: 'Finding transaction funding...',
30− SENDING: "Sending transaction...",
30+ SENDING: 'Sending transaction...',
31};
31};
32
32
33class StatelessTransaction extends React.Component {
33class StatelessTransaction extends React.Component {
@@ -35,13 +35,13 @@ class StatelessTransaction extends React.Component {
35 super(props);
35 super(props);
36
36
37 this.state = {
37 this.state = {
38− gasPrice: "5",
38+ gasPrice: '5',
39− gasLimit: "600000",
39+ gasLimit: '600000',
40 showGasDetails: false,
40 showGasDetails: false,
41 userApproval: false,
41 userApproval: false,
42− chainId: "1",
42+ chainId: '1',
43 customChain: false,
43 customChain: false,
44− nonce: "0",
44+ nonce: '0',
45 stx: Nothing(),
45 stx: Nothing(),
46 txn: Nothing(),
46 txn: Nothing(),
47 txStatus: SUBMISSION_STATES.PROMPT,
47 txStatus: SUBMISSION_STATES.PROMPT,
@@ -82,7 +82,7 @@ class StatelessTransaction extends React.Component {
82 const txMetadata = {
82 const txMetadata = {
83 nonce: r[0],
83 nonce: r[0],
84 chainId: r[1],
84 chainId: r[1],
85− gasPrice: fromWei(r[2], "gwei"),
85+ gasPrice: fromWei(r[2], 'gwei'),
86 };
86 };
87
87
88 this.setState({ ...txMetadata });
88 this.setState({ ...txMetadata });
@@ -188,12 +188,12 @@ class StatelessTransaction extends React.Component {
188 try {
188 try {
189 this.setState({ txStatus: SUBMISSION_STATES.PREPARING });
189 this.setState({ txStatus: SUBMISSION_STATES.PREPARING });
190 const res = await props.beforeSend(stx);
190 const res = await props.beforeSend(stx);
191− if (res === false) throw new Error("beforeSend disallowed sending");
191+ if (res === false) throw new Error('beforeSend disallowed sending');
192 } catch (e) {
192 } catch (e) {
193− console.log("beforeSend error", e);
193+ console.log('beforeSend error', e);
194 this.setState({
194 this.setState({
195 txStatus: SUBMISSION_STATES.PROMPT,
195 txStatus: SUBMISSION_STATES.PROMPT,
196− txError: Just("Something went wrong!"),
196+ txError: Just('Something went wrong!'),
197 });
197 });
198 return;
198 return;
199 }
199 }
@@ -202,7 +202,7 @@ class StatelessTransaction extends React.Component {
202 this.setState({ txStatus: SUBMISSION_STATES.FUNDING });
202 this.setState({ txStatus: SUBMISSION_STATES.FUNDING });
203
203
204 const rawTx = hexify(stx.serialize());
204 const rawTx = hexify(stx.serialize());
205− const cost = state.gasLimit * toWei(state.gasPrice, "gwei");
205+ const cost = state.gasLimit * toWei(state.gasPrice, 'gwei');
206
206
207 const address = need.address(props);
207 const address = need.address(props);
208 let balance = await web3.eth.getBalance(address);
208 let balance = await web3.eth.getBalance(address);
@@ -232,7 +232,7 @@ class StatelessTransaction extends React.Component {
232 web3,
232 web3,
233 state.stx,
233 state.stx,
234 usedTank,
234 usedTank,
235− props.setTxnConfirmations,
235+ props.setTxnConfirmations
236 )
236 )
237 .then(txHash => {
237 .then(txHash => {
238 props.onSent(Just(Ok(txHash)), state.stx.value);
238 props.onSent(Just(Ok(txHash)), state.stx.value);
@@ -271,13 +271,13 @@ class StatelessTransaction extends React.Component {
271
271
272 getChainTitle(chainId) {
272 getChainTitle(chainId) {
273 let map = {
273 let map = {
274− "1": "Mainnet - 1",
274+ '1': 'Mainnet - 1',
275− "2": "Morden - 2",
275+ '2': 'Morden - 2',
276− "3": "Ropsten - 3",
276+ '3': 'Ropsten - 3',
277− "4": "Goerli - 4",
277+ '4': 'Goerli - 4',
278− "42": "Kovan - 42",
278+ '42': 'Kovan - 42',
279− "1337": "Geth private chains - 1337",
279+ '1337': 'Geth private chains - 1337',
280− custom: "Custom",
280+ custom: 'Custom',
281 };
281 };
282
282
283 return map[chainId];
283 return map[chainId];
@@ -286,32 +286,32 @@ class StatelessTransaction extends React.Component {
286 getChainOptions() {
286 getChainOptions() {
287 return [
287 return [
288 {
288 {
289− title: this.getChainTitle("1"),
289+ title: this.getChainTitle('1'),
290− value: "1",
290+ value: '1',
291 },
291 },
292 {
292 {
293− title: this.getChainTitle("2"),
293+ title: this.getChainTitle('2'),
294− value: "2",
294+ value: '2',
295 },
295 },
296 {
296 {
297− title: this.getChainTitle("3"),
297+ title: this.getChainTitle('3'),
298− value: "3",
298+ value: '3',
299 },
299 },
300 {
300 {
301− title: this.getChainTitle("4"),
301+ title: this.getChainTitle('4'),
302− value: "4",
302+ value: '4',
303 },
303 },
304 {
304 {
305− title: this.getChainTitle("42"),
305+ title: this.getChainTitle('42'),
306− value: "42",
306+ value: '42',
307 },
307 },
308 {
308 {
309− title: this.getChainTitle("1337"),
309+ title: this.getChainTitle('1337'),
310− value: "1337",
310+ value: '1337',
311 },
311 },
312 {
312 {
313− title: this.getChainTitle("custom"),
313+ title: this.getChainTitle('custom'),
314− value: "custom",
314+ value: 'custom',
315 },
315 },
316 ];
316 ];
317 }
317 }
@@ -351,27 +351,26 @@ class StatelessTransaction extends React.Component {
351
351
352 const chainOptions = this.getChainOptions();
352 const chainOptions = this.getChainOptions();
353
353
354− const generateButtonColor = Nothing.hasInstance(txn) ? "blue" : "green";
354+ const generateButtonColor = Nothing.hasInstance(txn) ? 'blue' : 'green';
355
355
356− const signerButtonColor = Nothing.hasInstance(stx) ? "blue" : "green";
356+ const signerButtonColor = Nothing.hasInstance(stx) ? 'blue' : 'green';
357
357
358 const generateTxnButton = (
358 const generateTxnButton = (
359 <Button
359 <Button
360− className={"mt-8"}
360+ className={'mt-8'}
361 disabled={!canGenerate}
361 disabled={!canGenerate}
362 prop-color={generateButtonColor}
362 prop-color={generateButtonColor}
363− prop-size={"lg wide"}
363+ prop-size={'lg wide'}
364− onClick={createUnsignedTxn}
364+ onClick={createUnsignedTxn}>
365− >
366− {"Generate Transaction"}
365+ {'Generate Transaction'}
367 </Button>
366 </Button>
368 );
367 );
369
368
370 const unsignedTxnDisplay = txn.matchWith({
369 const unsignedTxnDisplay = txn.matchWith({
371− Nothing: _ => "",
370+ Nothing: _ => '',
372 Just: tx => (
371 Just: tx => (
373 <React.Fragment>
372 <React.Fragment>
374− <H3 className={"mt-8"}>{"Unsigned Transaction"}</H3>
373+ <H3 className={'mt-8'}>{'Unsigned Transaction'}</H3>
375 <Code>{JSON.stringify(tx.value, null, 2)}</Code>
374 <Code>{JSON.stringify(tx.value, null, 2)}</Code>
376 </React.Fragment>
375 </React.Fragment>
377 ),
376 ),
@@ -417,48 +416,45 @@ class StatelessTransaction extends React.Component {
417
416
418 const gasPriceDialogue = (
417 const gasPriceDialogue = (
419 <Input
418 <Input
420− className={"mono mt-4"}
419+ className={'mono mt-4'}
421− prop-size={"md"}
420+ prop-size={'md'}
422− prop-format={"innerLabel"}
421+ prop-format={'innerLabel'}
423 value={gasPrice}
422 value={gasPrice}
424− onChange={setGasPrice}
423+ onChange={setGasPrice}>
425− >
426− <InnerLabel>{"Gas Price (gwei)"}</InnerLabel>
424+ <InnerLabel>{'Gas Price (gwei)'}</InnerLabel>
427 </Input>
425 </Input>
428 );
426 );
429
427
430 const gasLimitDialogue = (
428 const gasLimitDialogue = (
431 <Input
429 <Input
432− className={"mono mt-4"}
430+ className={'mono mt-4'}
433− prop-size={"md"}
431+ prop-size={'md'}
434− prop-format={"innerLabel"}
432+ prop-format={'innerLabel'}
435 value={gasLimit}
433 value={gasLimit}
436− onChange={setGasLimit}
434+ onChange={setGasLimit}>
437− >
438− <InnerLabel>{"Gas Limit"}</InnerLabel>
435+ <InnerLabel>{'Gas Limit'}</InnerLabel>
439 </Input>
436 </Input>
440 );
437 );
441
438
442 const nonceDialogue = (
439 const nonceDialogue = (
443 <Input
440 <Input
444− className={"mono mt-4 mb-4"}
441+ className={'mono mt-4 mb-4'}
445− prop-size={"md"}
442+ prop-size={'md'}
446− prop-format={"innerLabel"}
443+ prop-format={'innerLabel'}
447 value={nonce}
444 value={nonce}
448− onChange={setNonce}
445+ onChange={setNonce}>
449− >
450− <InnerLabel>{"Nonce"}</InnerLabel>
446+ <InnerLabel>{'Nonce'}</InnerLabel>
451 </Input>
447 </Input>
452 );
448 );
453
449
454 const chainDialogueTitle = customChain
450 const chainDialogueTitle = customChain
455− ? "Custom"
451+ ? 'Custom'
456 : this.getChainTitle(chainId);
452 : this.getChainTitle(chainId);
457 const chainDialogue = (
453 const chainDialogue = (
458 <InnerLabelDropdown
454 <InnerLabelDropdown
459− className={"mt-6"}
455+ className={'mt-6'}
460 fullWidth={true}
456 fullWidth={true}
461− title={"Chain ID"}
457+ title={'Chain ID'}
462 options={chainOptions}
458 options={chainOptions}
463 handleUpdate={handleChainUpdate}
459 handleUpdate={handleChainUpdate}
464 currentSelectionTitle={chainDialogueTitle}
460 currentSelectionTitle={chainDialogueTitle}
@@ -467,13 +463,12 @@ class StatelessTransaction extends React.Component {
467
463
468 const customChainDialogue = !customChain ? null : (
464 const customChainDialogue = !customChain ? null : (
469 <Input
465 <Input
470− className={"mono mt-4 mb-8"}
466+ className={'mono mt-4 mb-8'}
471− prop-size={"md"}
467+ prop-size={'md'}
472− prop-format={"innerLabel"}
468+ prop-format={'innerLabel'}
473 value={chainId}
469 value={chainId}
474− onChange={setChainId}
470+ onChange={setChainId}>
475− >
476− <InnerLabel>{"Chain ID"}</InnerLabel>
471+ <InnerLabel>{'Chain ID'}</InnerLabel>
477 </Input>
472 </Input>
478 );
473 );
479
474
@@ -491,22 +486,21 @@ class StatelessTransaction extends React.Component {
491 const signTxnButton = (
486 const signTxnButton = (
492 <Button
487 <Button
493 disabled={!canSign}
488 disabled={!canSign}
494− className={"mt-8"}
489+ className={'mt-8'}
495− prop-size={"lg wide"}
490+ prop-size={'lg wide'}
496 prop-color={signerButtonColor}
491 prop-color={signerButtonColor}
497 onClick={() =>
492 onClick={() =>
498 signTransaction({ ...this.props, ...this.state, setStx: this.setStx })
493 signTransaction({ ...this.props, ...this.state, setStx: this.setStx })
499− }
494+ }>
500− >
501− {"Sign Transaction"}
495+ {'Sign Transaction'}
502 </Button>
496 </Button>
503 );
497 );
504
498
505 const signedTxnDisplay = stx.matchWith({
499 const signedTxnDisplay = stx.matchWith({
506− Nothing: _ => "",
500+ Nothing: _ => '',
507 Just: tx => (
501 Just: tx => (
508 <React.Fragment>
502 <React.Fragment>
509− <H3 className={"mt-8"}>{"Signed Transaction"}</H3>
503+ <H3 className={'mt-8'}>{'Signed Transaction'}</H3>
510 <Code>{JSON.stringify(renderSignedTx(tx.value), null, 2)}</Code>
504 <Code>{JSON.stringify(renderSignedTx(tx.value), null, 2)}</Code>
511 </React.Fragment>
505 </React.Fragment>
512 ),
506 ),
@@ -514,7 +508,7 @@ class StatelessTransaction extends React.Component {
514
508
515 const confirmButton = (
509 const confirmButton = (
516 <CheckboxButton
510 <CheckboxButton
517− className={"mt-8"}
511+ className={'mt-8'}
518 disabled={!canApprove}
512 disabled={!canApprove}
519 onToggle={setUserApproval}
513 onToggle={setUserApproval}
520 state={userApproval}
514 state={userApproval}
@@ -523,14 +517,13 @@ class StatelessTransaction extends React.Component {
523 );
517 );
524
518
525 const sending = txStatus !== SUBMISSION_STATES.PROMPT;
519 const sending = txStatus !== SUBMISSION_STATES.PROMPT;
526− const sendTxnSpinner = sending ? "" : "hide";
520+ const sendTxnSpinner = sending ? '' : 'hide';
527 const sendTxnButton = (
521 const sendTxnButton = (
528 <Button
522 <Button
529− prop-size={"xl wide"}
523+ prop-size={'xl wide'}
530− className={"mt-8"}
524+ className={'mt-8'}
531 disabled={!canSend || sending}
525 disabled={!canSend || sending}
532− onClick={sendTxn}
526+ onClick={sendTxn}>
533− >
534 <span className="relative">
527 <span className="relative">
535 <span className={`btn-spinner ${sendTxnSpinner}`} />
528 <span className={`btn-spinner ${sendTxnSpinner}`} />
536 {txStatus}
529 {txStatus}
@@ -539,7 +532,7 @@ class StatelessTransaction extends React.Component {
539 );
532 );
540
533
541 const sendDialogue = web3.matchWith({
534 const sendDialogue = web3.matchWith({
542− Nothing: _ => "",
535+ Nothing: _ => '',
543 Just: _ => (
536 Just: _ => (
544 <React.Fragment>
537 <React.Fragment>
545 {confirmButton}
538 {confirmButton}
@@ -549,11 +542,11 @@ class StatelessTransaction extends React.Component {
549 });
542 });
550
543
551 const txnErrorDialogue = Nothing.hasInstance(state.txError) ? (
544 const txnErrorDialogue = Nothing.hasInstance(state.txError) ? (
552− ""
545+ ''
553 ) : (
546 ) : (
554− <Warning className={"mt-8"}>
547+ <Warning className={'mt-8'}>
555 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
548 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
556− {"There was an error sending your transaction."}
549+ {'There was an error sending your transaction.'}
557 </H3>
550 </H3>
558 {state.txError.value}
551 {state.txError.value}
559 </Warning>
552 </Warning>
src/bridge/components/icons/Chevron.js+1−3
@@ -4,9 +4,7 @@ import PropTypes from 'prop-types';
4const Chevron = props => {
4const Chevron = props => {
5 return (
5 return (
6 <img
6 <img
7− src={`data:image/svg+xml;utf8,<svg width="11" height="24" viewBox="0 0 11 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 12L10.387 12.3166L10.646 12L10.387 11.6833L10 12ZM0.613022 1.31662L9.61302 12.3166L10.387 11.6833L1.38698 0.68338L0.613022 1.31662ZM9.61302 11.6833L0.613021 22.6834L1.38698 23.3166L10.387 12.3166L9.61302 11.6833Z" stroke="${
7+ src={`data:image/svg+xml;utf8,<svg width="11" height="24" viewBox="0 0 11 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 12L10.387 12.3166L10.646 12L10.387 11.6833L10 12ZM0.613022 1.31662L9.61302 12.3166L10.387 11.6833L1.38698 0.68338L0.613022 1.31662ZM9.61302 11.6833L0.613021 22.6834L1.38698 23.3166L10.387 12.3166L9.61302 11.6833Z" stroke="${props.color}" stroke-width="${props.strokeWidth}" fill="${props.color}"/></svg>`}
8− props.color
9− }" stroke-width="${props.strokeWidth}" fill="${props.color}"/></svg>`}
10 alt=""
8 alt=""
11 style={props.style}
9 style={props.style}
12 className={props.className}
10 className={props.className}
src/bridge/lib/flags.js+1−1
@@ -1 +1 @@
1−export const isLocal = process.env.NODE_ENV === "development";
1+export const isLocal = process.env.NODE_ENV === 'development';
src/bridge/lib/invite.js+67−67
@@ -1,67 +1,67 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import Tx from "ethereumjs-tx";
2+import Tx from 'ethereumjs-tx';
3
3
4−import * as azimuth from "azimuth-js";
4+import * as azimuth from 'azimuth-js';
5−import * as kg from "urbit-key-generation/dist/index";
5+import * as kg from 'urbit-key-generation/dist/index';
6−import * as wg from "../../walletgen/lib/lib.js";
6+import * as wg from '../../walletgen/lib/lib.js';
7−import * as tank from "./tank";
7+import * as tank from './tank';
8
8
9−import JSZip from "jszip";
9+import JSZip from 'jszip';
10−import saveAs from "file-saver";
10+import saveAs from 'file-saver';
11
11
12−import { sendSignedTransaction } from "./txn";
12+import { sendSignedTransaction } from './txn';
13−import { BRIDGE_ERROR } from "../lib/error";
13+import { BRIDGE_ERROR } from '../lib/error';
14−import { attemptSeedDerivation } from "./keys";
14+import { attemptSeedDerivation } from './keys';
15−import { addHexPrefix, WALLET_NAMES } from "./wallet";
15+import { addHexPrefix, WALLET_NAMES } from './wallet';
16
16
17const INVITE_STAGES = {
17const INVITE_STAGES = {
18− INVITE_LOGIN: "invite login",
18+ INVITE_LOGIN: 'invite login',
19− INVITE_WALLET: "invite wallet",
19+ INVITE_WALLET: 'invite wallet',
20− INVITE_VERIFY: "invite verify",
20+ INVITE_VERIFY: 'invite verify',
21− INVITE_TRANSACTIONS: "invite transactions",
21+ INVITE_TRANSACTIONS: 'invite transactions',
22};
22};
23
23
24const WALLET_STATES = {
24const WALLET_STATES = {
25− UNLOCKING: "Unlocking invite wallet",
25+ UNLOCKING: 'Unlocking invite wallet',
26− GENERATING: "Generating your wallet",
26+ GENERATING: 'Generating your wallet',
27− RENDERING: "Creating paper collateral",
27+ RENDERING: 'Creating paper collateral',
28− PAPER_READY: "Download your wallet",
28+ PAPER_READY: 'Download your wallet',
29− DOWNLOADED: "Wallet downloaded",
29+ DOWNLOADED: 'Wallet downloaded',
30− TRANSACTIONS: "Sending transactions",
30+ TRANSACTIONS: 'Sending transactions',
31};
31};
32
32
33const TRANSACTION_STATES = {
33const TRANSACTION_STATES = {
34 GENERATING: {
34 GENERATING: {
35− label: "Generating transactions",
35+ label: 'Generating transactions',
36− pct: "0%",
36+ pct: '0%',
37 },
37 },
38 SIGNING: {
38 SIGNING: {
39− label: "Signing transactions",
39+ label: 'Signing transactions',
40− pct: "15%",
40+ pct: '15%',
41 },
41 },
42 FUNDING_INVITE: {
42 FUNDING_INVITE: {
43− label: "Funding invite wallet",
43+ label: 'Funding invite wallet',
44− pct: "30%",
44+ pct: '30%',
45 },
45 },
46 CLAIMING: {
46 CLAIMING: {
47− label: "Claiming invite",
47+ label: 'Claiming invite',
48− pct: "55%",
48+ pct: '55%',
49 },
49 },
50 FUNDING_RECIPIENT: {
50 FUNDING_RECIPIENT: {
51− label: "Funding recipient wallet",
51+ label: 'Funding recipient wallet',
52− pct: "65%",
52+ pct: '65%',
53 },
53 },
54 CONFIGURING: {
54 CONFIGURING: {
55− label: "Configuring planet",
55+ label: 'Configuring planet',
56− pct: "85%",
56+ pct: '85%',
57 },
57 },
58 CLEANING: {
58 CLEANING: {
59− label: "Cleaning up",
59+ label: 'Cleaning up',
60− pct: "95%",
60+ pct: '95%',
61 },
61 },
62 DONE: {
62 DONE: {
63− label: "Done",
63+ label: 'Done',
64− pct: "100%",
64+ pct: '100%',
65 },
65 },
66};
66};
67
67
@@ -77,11 +77,11 @@ async function downloadWallet(paper) {
77 const zip = new JSZip();
77 const zip = new JSZip();
78 //TODO the categories here aren't explained in bridge at all...
78 //TODO the categories here aren't explained in bridge at all...
79
79
80− const bin0 = paper.filter(item => item.bin === "0");
80+ const bin0 = paper.filter(item => item.bin === '0');
81− const bin1 = paper.filter(item => item.bin === "1");
81+ const bin1 = paper.filter(item => item.bin === '1');
82− const bin2 = paper.filter(item => item.bin === "2");
82+ const bin2 = paper.filter(item => item.bin === '2');
83− const bin3 = paper.filter(item => item.bin === "3");
83+ const bin3 = paper.filter(item => item.bin === '3');
84− const bin4 = paper.filter(item => item.bin === "4");
84+ const bin4 = paper.filter(item => item.bin === '4');
85
85
86 const bin0Folder = zip.folder('0. Public');
86 const bin0Folder = zip.folder('0. Public');
87 const bin1Folder = zip.folder('1. Very High Friction Custody');
87 const bin1Folder = zip.folder('1. Very High Friction Custody');
@@ -95,8 +95,8 @@ async function downloadWallet(paper) {
95 bin3.forEach(item => bin3Folder.file(`${item.pageTitle}.png`, item.png));
95 bin3.forEach(item => bin3Folder.file(`${item.pageTitle}.png`, item.png));
96 bin4.forEach(item => bin4Folder.file(`${item.pageTitle}.png`, item.png));
96 bin4.forEach(item => bin4Folder.file(`${item.pageTitle}.png`, item.png));
97
97
98− zip.generateAsync({ type: "blob" }).then(content => {
98+ zip.generateAsync({ type: 'blob' }).then(content => {
99− saveAs(content, "urbit-wallet.zip");
99+ saveAs(content, 'urbit-wallet.zip');
100 resolve(true);
100 resolve(true);
101 });
101 });
102 });
102 });
@@ -115,7 +115,7 @@ async function startTransactions(args) {
115
115
116 const askForFunding = (address, amount, current) => {
116 const askForFunding = (address, amount, current) => {
117 updateProgress({
117 updateProgress({
118− type: "notify",
118+ type: 'notify',
119 value: `Please make sure ${address} has at least ${amount} wei, we'll continue once that's true. Current balance: ${current}. Waiting`,
119 value: `Please make sure ${address} has at least ${amount} wei, we'll continue once that's true. Current balance: ${current}. Waiting`,
120 });
120 });
121 };
121 };
@@ -148,14 +148,14 @@ async function startTransactions(args) {
148 const point = realPointM.value;
148 const point = realPointM.value;
149
149
150 const inviteAddress = inviteWallet.address;
150 const inviteAddress = inviteWallet.address;
151− console.log("working as", inviteAddress);
151+ console.log('working as', inviteAddress);
152
152
153 // transfer from invite wallet to new wallet
153 // transfer from invite wallet to new wallet
154
154
155 let transferTx = azimuth.ecliptic.transferPoint(
155 let transferTx = azimuth.ecliptic.transferPoint(
156 contracts,
156 contracts,
157 point,
157 point,
158− realWallet.ownership.keys.address,
158+ realWallet.ownership.keys.address
159 );
159 );
160 transferTx.gas = 500000; //TODO can maybe be lower?
160 transferTx.gas = 500000; //TODO can maybe be lower?
161
161
@@ -169,11 +169,11 @@ async function startTransactions(args) {
169 //NOTE using web3.eth.accounts.signTransaction is broken (1.0.0-beta51)
169 //NOTE using web3.eth.accounts.signTransaction is broken (1.0.0-beta51)
170 let transferStx = new Tx(transferTx);
170 let transferStx = new Tx(transferTx);
171 transferStx.sign(inviteWallet.privateKey);
171 transferStx.sign(inviteWallet.privateKey);
172− let rawTransferStx = "0x" + transferStx.serialize().toString("hex");
172+ let rawTransferStx = '0x' + transferStx.serialize().toString('hex');
173
173
174 const transferCost = transferTx.gas * transferTx.gasPrice;
174 const transferCost = transferTx.gas * transferTx.gasPrice;
175 updateProgress({
175 updateProgress({
176− type: "progress",
176+ type: 'progress',
177 value: TRANSACTION_STATES.FUNDING_INVITE,
177 value: TRANSACTION_STATES.FUNDING_INVITE,
178 });
178 });
179 let usedTank = await tank.ensureFundsFor(
179 let usedTank = await tank.ensureFundsFor(
@@ -182,11 +182,11 @@ async function startTransactions(args) {
182 inviteAddress,
182 inviteAddress,
183 transferCost,
183 transferCost,
184 [rawTransferStx],
184 [rawTransferStx],
185− askForFunding,
185+ askForFunding
186 );
186 );
187
187
188 updateProgress({
188 updateProgress({
189− type: "progress",
189+ type: 'progress',
190 value: TRANSACTION_STATES.CLAIMING,
190 value: TRANSACTION_STATES.CLAIMING,
191 });
191 });
192
192
@@ -205,7 +205,7 @@ async function startTransactions(args) {
205 let managementTx = azimuth.ecliptic.setManagementProxy(
205 let managementTx = azimuth.ecliptic.setManagementProxy(
206 contracts,
206 contracts,
207 point,
207 point,
208− realWallet.management.keys.address,
208+ realWallet.management.keys.address
209 );
209 );
210 managementTx.gas = 200000;
210 managementTx.gas = 200000;
211 managementTx.nonce = 0;
211 managementTx.nonce = 0;
@@ -219,7 +219,7 @@ async function startTransactions(args) {
219 pointCache: { [point]: { keyRevisionNumber: 0 } },
219 pointCache: { [point]: { keyRevisionNumber: 0 } },
220 });
220 });
221 if (Nothing.hasInstance(networkSeed)) {
221 if (Nothing.hasInstance(networkSeed)) {
222− throw new Error("wtf network seed not derived");
222+ throw new Error('wtf network seed not derived');
223 }
223 }
224 networkSeed = networkSeed.value;
224 networkSeed = networkSeed.value;
225 const networkKeys = kg.deriveNetworkKeys(networkSeed);
225 const networkKeys = kg.deriveNetworkKeys(networkSeed);
@@ -230,7 +230,7 @@ async function startTransactions(args) {
230 addHexPrefix(networkKeys.crypt.public),
230 addHexPrefix(networkKeys.crypt.public),
231 addHexPrefix(networkKeys.auth.public),
231 addHexPrefix(networkKeys.auth.public),
232 1,
232 1,
233− false,
233+ false
234 );
234 );
235 keysTx.gas = 150000;
235 keysTx.gas = 150000;
236 keysTx.nonce = 1;
236 keysTx.nonce = 1;
@@ -247,12 +247,12 @@ async function startTransactions(args) {
247
247
248 let rawStxs = txs.map(tx => {
248 let rawStxs = txs.map(tx => {
249 let stx = new Tx(tx);
249 let stx = new Tx(tx);
250− stx.sign(Buffer.from(realWallet.ownership.keys.private, "hex"));
250+ stx.sign(Buffer.from(realWallet.ownership.keys.private, 'hex'));
251− return "0x" + stx.serialize().toString("hex");
251+ return '0x' + stx.serialize().toString('hex');
252 });
252 });
253
253
254 updateProgress({
254 updateProgress({
255− type: "progress",
255+ type: 'progress',
256 value: TRANSACTION_STATES.FUNDING_RECIPIENT,
256 value: TRANSACTION_STATES.FUNDING_RECIPIENT,
257 });
257 });
258 usedTank = await tank.ensureFundsFor(
258 usedTank = await tank.ensureFundsFor(
@@ -261,18 +261,18 @@ async function startTransactions(args) {
261 newAddress,
261 newAddress,
262 totalCost,
262 totalCost,
263 rawStxs,
263 rawStxs,
264− askForFunding,
264+ askForFunding
265 );
265 );
266
266
267 updateProgress({
267 updateProgress({
268− type: "progress",
268+ type: 'progress',
269 value: TRANSACTION_STATES.CONFIGURING,
269 value: TRANSACTION_STATES.CONFIGURING,
270 });
270 });
271
271
272 await sendAndAwaitConfirm(web3, rawStxs, usedTank);
272 await sendAndAwaitConfirm(web3, rawStxs, usedTank);
273
273
274 updateProgress({
274 updateProgress({
275− type: "progress",
275+ type: 'progress',
276 value: TRANSACTION_STATES.CLEANING,
276 value: TRANSACTION_STATES.CLEANING,
277 });
277 });
278
278
@@ -283,7 +283,7 @@ async function startTransactions(args) {
283 const sendEthCost = gasPrice * gasLimit;
283 const sendEthCost = gasPrice * gasLimit;
284 if (balance > sendEthCost) {
284 if (balance > sendEthCost) {
285 const value = balance - sendEthCost;
285 const value = balance - sendEthCost;
286− console.log("sending", value);
286+ console.log('sending', value);
287 const tx = {
287 const tx = {
288 to: newAddress,
288 to: newAddress,
289 value: value,
289 value: value,
@@ -293,15 +293,15 @@ async function startTransactions(args) {
293 };
293 };
294 let stx = new Tx(tx);
294 let stx = new Tx(tx);
295 stx.sign(inviteWallet.privateKey);
295 stx.sign(inviteWallet.privateKey);
296− const rawTx = "0x" + stx.serialize().toString("hex");
296+ const rawTx = '0x' + stx.serialize().toString('hex');
297 web3.eth.sendSignedTransaction(rawTx).catch(err => {
297 web3.eth.sendSignedTransaction(rawTx).catch(err => {
298− console.log("error sending value tx, who cares", err);
298+ console.log('error sending value tx, who cares', err);
299 });
299 });
300− console.log("sent old balance");
300+ console.log('sent old balance');
301 }
301 }
302
302
303 updateProgress({
303 updateProgress({
304− type: "progress",
304+ type: 'progress',
305 value: TRANSACTION_STATES.DONE,
305 value: TRANSACTION_STATES.DONE,
306 });
306 });
307
307
@@ -315,7 +315,7 @@ async function sendAndAwaitConfirm(web3, signedTxs, usedTank) {
315 return new Promise((resolve, reject) => {
315 return new Promise((resolve, reject) => {
316 sendSignedTransaction(web3, tx, usedTank, resolve);
316 sendSignedTransaction(web3, tx, usedTank, resolve);
317 });
317 });
318− }),
318+ })
319 );
319 );
320}
320}
321
321
src/bridge/lib/keys.js+20−20
@@ -1,18 +1,18 @@
1−import BN from "bn.js";
1+import BN from 'bn.js';
2−import Maybe from "folktale/maybe";
2+import Maybe from 'folktale/maybe';
3−import * as need from "../lib/need";
3+import * as need from '../lib/need';
4
4
5−import * as noun from "../nockjs/noun";
5+import * as noun from '../nockjs/noun';
6−import * as serial from "../nockjs/serial";
6+import * as serial from '../nockjs/serial';
7−import * as kg from "urbit-key-generation/dist/index";
7+import * as kg from 'urbit-key-generation/dist/index';
8
8
9−import { BRIDGE_ERROR } from "./error";
9+import { BRIDGE_ERROR } from './error';
10−import { WALLET_NAMES, eqAddr } from "./wallet";
10+import { WALLET_NAMES, eqAddr } from './wallet';
11
11
12// ctsy joemfb
12// ctsy joemfb
13const b64 = buf => {
13const b64 = buf => {
14− let hex = buf.reverse().toString("hex");
14+ let hex = buf.reverse().toString('hex');
15− let n = new BN(hex, "hex");
15+ let n = new BN(hex, 'hex');
16 let c = [];
16 let c = [];
17 while (1 === n.cmpn(0)) {
17 while (1 === n.cmpn(0)) {
18 c.push(n.andln(0x3f));
18 c.push(n.andln(0x3f));
@@ -24,11 +24,11 @@ const b64 = buf => {
24 10 > j ? j + 48 : 36 > j ? j + 87 : 62 > j ? j + 29 : 62 === j ? 45 : 126;
24 10 > j ? j + 48 : 36 > j ? j + 87 : 62 > j ? j + 29 : 62 === j ? 45 : 126;
25
25
26 return (
26 return (
27− "0w" +
27+ '0w' +
28 c.reduce(
28 c.reduce(
29 (a, b, i) =>
29 (a, b, i) =>
30− String.fromCharCode(trans(b)) + (i && 0 === i % 5 ? "." : "") + a,
30+ String.fromCharCode(trans(b)) + (i && 0 === i % 5 ? '.' : '') + a,
31− "",
31+ ''
32 )
32 )
33 );
33 );
34};
34};
@@ -38,19 +38,19 @@ const jam = seed => {
38 .jam(seed)
38 .jam(seed)
39 .toString()
39 .toString()
40 .slice(2);
40 .slice(2);
41− const pad = hex.length % 2 === 0 ? hex : "0" + hex;
41+ const pad = hex.length % 2 === 0 ? hex : '0' + hex;
42− return Buffer.from(pad, "hex").reverse();
42+ return Buffer.from(pad, 'hex').reverse();
43};
43};
44
44
45const genKey = (networkSeed, point, revision) => {
45const genKey = (networkSeed, point, revision) => {
46 const pair = kg.deriveNetworkKeys(networkSeed);
46 const pair = kg.deriveNetworkKeys(networkSeed);
47− const bnsec = new BN(pair.crypt.private + pair.auth.private + "42", "hex"); // '42' is curve parameter
47+ const bnsec = new BN(pair.crypt.private + pair.auth.private + '42', 'hex'); // '42' is curve parameter
48
48
49 const sed = noun.dwim(
49 const sed = noun.dwim(
50 noun.Atom.fromString(point),
50 noun.Atom.fromString(point),
51 noun.Atom.fromInt(revision),
51 noun.Atom.fromInt(revision),
52 noun.Atom.fromString(bnsec.toString()),
52 noun.Atom.fromString(bnsec.toString()),
53− noun.Atom.yes,
53+ noun.Atom.yes
54 );
54 );
55
55
56 return b64(jam(sed));
56 return b64(jam(sed));
@@ -74,7 +74,7 @@ const attemptSeedDerivation = async (next, args) => {
74 ? parseInt(pointDetails.keyRevisionNumber)
74 ? parseInt(pointDetails.keyRevisionNumber)
75 : parseInt(pointDetails.keyRevisionNumber) - 1;
75 : parseInt(pointDetails.keyRevisionNumber) - 1;
76
76
77− let managementSeed = "";
77+ let managementSeed = '';
78
78
79 const ticketLike = [WALLET_NAMES.TICKET, WALLET_NAMES.SHARDS];
79 const ticketLike = [WALLET_NAMES.TICKET, WALLET_NAMES.SHARDS];
80
80
@@ -110,8 +110,8 @@ const attemptSeedDerivation = async (next, args) => {
110
110
111 let networkSeed = Maybe.Nothing();
111 let networkSeed = Maybe.Nothing();
112
112
113− if (managementSeed !== "") {
113+ if (managementSeed !== '') {
114− const seed = await kg.deriveNetworkSeed(managementSeed, "", revision);
114+ const seed = await kg.deriveNetworkSeed(managementSeed, '', revision);
115
115
116 networkSeed = Maybe.Just(seed);
116 networkSeed = Maybe.Just(seed);
117 }
117 }
src/bridge/lib/routeNames.js+29−29
@@ -1,33 +1,33 @@
1export const ROUTE_NAMES = {
1export const ROUTE_NAMES = {
2− DEFAULT: Symbol("DEFAULT"),
2+ DEFAULT: Symbol('DEFAULT'),
3 //
3 //
4− INVITE_TICKET: Symbol("INVITE_TICKET"),
4+ INVITE_TICKET: Symbol('INVITE_TICKET'),
5− INVITE_TRANSACTIONS: Symbol("INVITE_TRANSACTIONS"),
5+ INVITE_TRANSACTIONS: Symbol('INVITE_TRANSACTIONS'),
6− INVITES_SEND: Symbol("INVITES_SEND"),
6+ INVITES_SEND: Symbol('INVITES_SEND'),
7− INVITES_MANAGE: Symbol("INVITES_MANAGE"),
7+ INVITES_MANAGE: Symbol('INVITES_MANAGE'),
8 //
8 //
9− ACCEPT_TRANSFER: Symbol("ACCEPT_TRANSFER"),
9+ ACCEPT_TRANSFER: Symbol('ACCEPT_TRANSFER'),
10− CANCEL_TRANSFER: Symbol("CANCEL_TRANSFER"),
10+ CANCEL_TRANSFER: Symbol('CANCEL_TRANSFER'),
11− LANDING: Symbol("LANDING"),
11+ LANDING: Symbol('LANDING'),
12− NETWORK: Symbol("NETWORK"),
12+ NETWORK: Symbol('NETWORK'),
13− WALLET: Symbol("WALLET"),
13+ WALLET: Symbol('WALLET'),
14− MNEMONIC: Symbol("MNEMONIC"),
14+ MNEMONIC: Symbol('MNEMONIC'),
15− TICKET: Symbol("TICKET"),
15+ TICKET: Symbol('TICKET'),
16− SHARDS: Symbol("SHARDS"),
16+ SHARDS: Symbol('SHARDS'),
17− LEDGER: Symbol("LEDGER"),
17+ LEDGER: Symbol('LEDGER'),
18− TREZOR: Symbol("TREZOR"),
18+ TREZOR: Symbol('TREZOR'),
19− PRIVATE_KEY: Symbol("PRIVATE_KEY"),
19+ PRIVATE_KEY: Symbol('PRIVATE_KEY'),
20− KEYSTORE: Symbol("KEYSTORE"),
20+ KEYSTORE: Symbol('KEYSTORE'),
21− VIEW_SHIP: Symbol("VIEW_SHIP"),
21+ VIEW_SHIP: Symbol('VIEW_SHIP'),
22− SHIPS: Symbol("SHIPS"),
22+ SHIPS: Symbol('SHIPS'),
23− SHIP: Symbol("SHIP"),
23+ SHIP: Symbol('SHIP'),
24− SET_MANAGEMENT_PROXY: Symbol("SET_MANAGEMENT_PROXY"),
24+ SET_MANAGEMENT_PROXY: Symbol('SET_MANAGEMENT_PROXY'),
25− SET_SPAWN_PROXY: Symbol("SET_SPAWN_PROXY"),
25+ SET_SPAWN_PROXY: Symbol('SET_SPAWN_PROXY'),
26− SET_TRANSFER_PROXY: Symbol("SET_TRANSFER_PROXY"),
26+ SET_TRANSFER_PROXY: Symbol('SET_TRANSFER_PROXY'),
27− CREATE_GALAXY: Symbol("CREATE_GALAXY"),
27+ CREATE_GALAXY: Symbol('CREATE_GALAXY'),
28− ISSUE_CHILD: Symbol("ISSUE_CHILD"),
28+ ISSUE_CHILD: Symbol('ISSUE_CHILD'),
29− SET_KEYS: Symbol("SET_KEYS"),
29+ SET_KEYS: Symbol('SET_KEYS'),
30− TRANSFER: Symbol("TRANSFER"),
30+ TRANSFER: Symbol('TRANSFER'),
31− SENT_TRANSACTION: Symbol("SENT_TRANSACTION"),
31+ SENT_TRANSACTION: Symbol('SENT_TRANSACTION'),
32− GEN_KEYFILE: Symbol("GEN_KEYFILE"),
32+ GEN_KEYFILE: Symbol('GEN_KEYFILE'),
33};
33};
src/bridge/lib/router.js+55−55
@@ -1,40 +1,40 @@
1−import React from "react";
1+import React from 'react';
2−import * as ob from "urbit-ob";
2+import * as ob from 'urbit-ob';
3−import * as need from "../lib/need";
3+import * as need from '../lib/need';
4
4
5−import Landing from "../views/Landing";
5+import Landing from '../views/Landing';
6−import InviteTicket from "../views/InviteTicket";
6+import InviteTicket from '../views/InviteTicket';
7−import InvitesSend from "../views/InvitesSend.js";
7+import InvitesSend from '../views/InvitesSend.js';
8−import InvitesManage from "../views/InvitesManage.js";
8+import InvitesManage from '../views/InvitesManage.js';
9−import AcceptTransfer from "../views/AcceptTransfer";
9+import AcceptTransfer from '../views/AcceptTransfer';
10−import CancelTransfer from "../views/CancelTransfer";
10+import CancelTransfer from '../views/CancelTransfer';
11−import CreateGalaxy from "../views/CreateGalaxy";
11+import CreateGalaxy from '../views/CreateGalaxy';
12−import GenKeyfile from "../views/GenKeyfile";
12+import GenKeyfile from '../views/GenKeyfile';
13−import IssueChild from "../views/IssueChild";
13+import IssueChild from '../views/IssueChild';
14−import Network from "../views/Network";
14+import Network from '../views/Network';
15−import Mnemonic from "../views/Mnemonic";
15+import Mnemonic from '../views/Mnemonic';
16−import Ledger from "../views/Ledger";
16+import Ledger from '../views/Ledger';
17−import Trezor from "../views/Trezor";
17+import Trezor from '../views/Trezor';
18−import PrivateKey from "../views/PrivateKey";
18+import PrivateKey from '../views/PrivateKey';
19−import Keystore from "../views/Keystore";
19+import Keystore from '../views/Keystore';
20−import ViewPoint from "../views/ViewPoint";
20+import ViewPoint from '../views/ViewPoint';
21−import SentTransaction from "../views/SentTransaction";
21+import SentTransaction from '../views/SentTransaction';
22−import SetKeys from "../views/SetKeys";
22+import SetKeys from '../views/SetKeys';
23import {
23import {
24 SetManagementProxy,
24 SetManagementProxy,
25 SetSpawnProxy,
25 SetSpawnProxy,
26 SetTransferProxy,
26 SetTransferProxy,
27−} from "../views/SetProxy";
27+} from '../views/SetProxy';
28−import Point from "../views/Point";
28+import Point from '../views/Point';
29−import Points from "../views/Points";
29+import Points from '../views/Points';
30−import Shards from "../views/Shards";
30+import Shards from '../views/Shards';
31−import Ticket from "../views/Ticket";
31+import Ticket from '../views/Ticket';
32−import Transfer from "../views/Transfer";
32+import Transfer from '../views/Transfer';
33−import Wallet from "../views/Wallet";
33+import Wallet from '../views/Wallet';
34
34
35−import { EthereumWallet } from "./wallet";
35+import { EthereumWallet } from './wallet';
36−import { renderNetworkType } from "./network";
36+import { renderNetworkType } from './network';
37−import { ROUTE_NAMES } from "./routeNames";
37+import { ROUTE_NAMES } from './routeNames';
38
38
39const ROUTES = {
39const ROUTES = {
40 [ROUTE_NAMES.DEFAULT]: Landing,
40 [ROUTE_NAMES.DEFAULT]: Landing,
@@ -72,18 +72,18 @@ export const getRouteBreadcrumb = (props, route) => {
72
72
73 switch (route.name) {
73 switch (route.name) {
74 case ROUTE_NAMES.INVITE_TICKET:
74 case ROUTE_NAMES.INVITE_TICKET:
75− return "Invite code";
75+ return 'Invite code';
76 case ROUTE_NAMES.INVITE_TRANSACTIONS:
76 case ROUTE_NAMES.INVITE_TRANSACTIONS:
77− return "Setting up new wallet";
77+ return 'Setting up new wallet';
78 case ROUTE_NAMES.INVITES_SEND:
78 case ROUTE_NAMES.INVITES_SEND:
79− return "Send invites";
79+ return 'Send invites';
80 case ROUTE_NAMES.INVITES_MANAGE:
80 case ROUTE_NAMES.INVITES_MANAGE:
81− return "Manage invites";
81+ return 'Manage invites';
82 case ROUTE_NAMES.NETWORK:
82 case ROUTE_NAMES.NETWORK:
83 return `${renderNetworkType(networkType)}`;
83 return `${renderNetworkType(networkType)}`;
84 case ROUTE_NAMES.WALLET:
84 case ROUTE_NAMES.WALLET:
85 return wallet.matchWith({
85 return wallet.matchWith({
86− Nothing: () => "Wallet",
86+ Nothing: () => 'Wallet',
87 Just: wal =>
87 Just: wal =>
88 wal.value instanceof EthereumWallet ? (
88 wal.value instanceof EthereumWallet ? (
89 <span className="text-mono">{wal.value.address}</span>
89 <span className="text-mono">{wal.value.address}</span>
@@ -92,48 +92,48 @@ export const getRouteBreadcrumb = (props, route) => {
92 ),
92 ),
93 });
93 });
94 case ROUTE_NAMES.MNEMONIC:
94 case ROUTE_NAMES.MNEMONIC:
95− return "Mnemonic";
95+ return 'Mnemonic';
96 case ROUTE_NAMES.TICKET:
96 case ROUTE_NAMES.TICKET:
97− return "Urbit Ticket";
97+ return 'Urbit Ticket';
98 case ROUTE_NAMES.SHARDS:
98 case ROUTE_NAMES.SHARDS:
99− return "Urbit Ticket";
99+ return 'Urbit Ticket';
100 case ROUTE_NAMES.LEDGER:
100 case ROUTE_NAMES.LEDGER:
101− return "Ledger";
101+ return 'Ledger';
102 case ROUTE_NAMES.TREZOR:
102 case ROUTE_NAMES.TREZOR:
103− return "Trezor";
103+ return 'Trezor';
104 case ROUTE_NAMES.PRIVATE_KEY:
104 case ROUTE_NAMES.PRIVATE_KEY:
105− return "Private Key";
105+ return 'Private Key';
106 case ROUTE_NAMES.KEYSTORE:
106 case ROUTE_NAMES.KEYSTORE:
107− return "Keystore File";
107+ return 'Keystore File';
108 case ROUTE_NAMES.SHIPS:
108 case ROUTE_NAMES.SHIPS:
109− return "Points";
109+ return 'Points';
110 case ROUTE_NAMES.VIEW_SHIP:
110 case ROUTE_NAMES.VIEW_SHIP:
111− return "View";
111+ return 'View';
112 case ROUTE_NAMES.SHIP:
112 case ROUTE_NAMES.SHIP:
113 return ob.patp(need.pointCursor(props));
113 return ob.patp(need.pointCursor(props));
114 case ROUTE_NAMES.SET_TRANSFER_PROXY:
114 case ROUTE_NAMES.SET_TRANSFER_PROXY:
115 case ROUTE_NAMES.SET_MANAGEMENT_PROXY:
115 case ROUTE_NAMES.SET_MANAGEMENT_PROXY:
116 case ROUTE_NAMES.SET_SPAWN_PROXY:
116 case ROUTE_NAMES.SET_SPAWN_PROXY:
117− return "Set Proxy";
117+ return 'Set Proxy';
118 case ROUTE_NAMES.CREATE_GALAXY:
118 case ROUTE_NAMES.CREATE_GALAXY:
119− return "Create Galaxy";
119+ return 'Create Galaxy';
120 case ROUTE_NAMES.ISSUE_CHILD:
120 case ROUTE_NAMES.ISSUE_CHILD:
121− return "Issue Child";
121+ return 'Issue Child';
122 case ROUTE_NAMES.TRANSFER:
122 case ROUTE_NAMES.TRANSFER:
123− return "Transfer";
123+ return 'Transfer';
124 case ROUTE_NAMES.ACCEPT_TRANSFER:
124 case ROUTE_NAMES.ACCEPT_TRANSFER:
125− return "Accept Transfer";
125+ return 'Accept Transfer';
126 case ROUTE_NAMES.CANCEL_TRANSFER:
126 case ROUTE_NAMES.CANCEL_TRANSFER:
127− return "Cancel Transfer";
127+ return 'Cancel Transfer';
128 case ROUTE_NAMES.GEN_KEYFILE:
128 case ROUTE_NAMES.GEN_KEYFILE:
129− return "Keyfile";
129+ return 'Keyfile';
130 case ROUTE_NAMES.SET_KEYS:
130 case ROUTE_NAMES.SET_KEYS:
131− return "Configure Keys";
131+ return 'Configure Keys';
132 case ROUTE_NAMES.SENT_TRANSACTION:
132 case ROUTE_NAMES.SENT_TRANSACTION:
133− return "Txn";
133+ return 'Txn';
134 case ROUTE_NAMES.LANDING:
134 case ROUTE_NAMES.LANDING:
135 default:
135 default:
136− return "Bridge";
136+ return 'Bridge';
137 }
137 }
138};
138};
139
139
src/bridge/lib/wallet.js+38−38
@@ -1,85 +1,85 @@
1−import * as bip32 from "bip32";
1+import * as bip32 from 'bip32';
2−import * as bip39 from "bip39";
2+import * as bip39 from 'bip39';
3−import keccak from "keccak";
3+import keccak from 'keccak';
4−import * as lodash from "lodash";
4+import * as lodash from 'lodash';
5−import Maybe from "folktale/maybe";
5+import Maybe from 'folktale/maybe';
6−import * as secp256k1 from "secp256k1";
6+import * as secp256k1 from 'secp256k1';
7−import * as ob from "urbit-ob";
7+import * as ob from 'urbit-ob';
8−import * as kg from "urbit-key-generation/dist/index";
8+import * as kg from 'urbit-key-generation/dist/index';
9−import { isAddress } from "web3-utils";
9+import { isAddress } from 'web3-utils';
10
10
11const DEFAULT_HD_PATH = "m/44'/60'/0'/0/0";
11const DEFAULT_HD_PATH = "m/44'/60'/0'/0/0";
12
12
13−const ETH_ZERO_ADDR = "0x0000000000000000000000000000000000000000";
13+const ETH_ZERO_ADDR = '0x0000000000000000000000000000000000000000';
14const CURVE_ZERO_ADDR =
14const CURVE_ZERO_ADDR =
15− "0x0000000000000000000000000000000000000000000000000000000000000000";
15+ '0x0000000000000000000000000000000000000000000000000000000000000000';
16
16
17const WALLET_NAMES = {
17const WALLET_NAMES = {
18− MNEMONIC: Symbol("MNEMONIC"),
18+ MNEMONIC: Symbol('MNEMONIC'),
19− TICKET: Symbol("TICKET"),
19+ TICKET: Symbol('TICKET'),
20− SHARDS: Symbol("SHARDS"),
20+ SHARDS: Symbol('SHARDS'),
21− LEDGER: Symbol("LEDGER"),
21+ LEDGER: Symbol('LEDGER'),
22− TREZOR: Symbol("TREZOR"),
22+ TREZOR: Symbol('TREZOR'),
23− PRIVATE_KEY: Symbol("PRIVATE_KEY"),
23+ PRIVATE_KEY: Symbol('PRIVATE_KEY'),
24− KEYSTORE: Symbol("KEYSTORE"),
24+ KEYSTORE: Symbol('KEYSTORE'),
25};
25};
26
26
27function EthereumWallet(privateKey) {
27function EthereumWallet(privateKey) {
28 this.privateKey = privateKey;
28 this.privateKey = privateKey;
29 this.publicKey = secp256k1.publicKeyCreate(this.privateKey);
29 this.publicKey = secp256k1.publicKeyCreate(this.privateKey);
30− const pub = this.publicKey.toString("hex");
30+ const pub = this.publicKey.toString('hex');
31 this.address = addressFromSecp256k1Public(pub);
31 this.address = addressFromSecp256k1Public(pub);
32}
32}
33
33
34const renderWalletType = wallet =>
34const renderWalletType = wallet =>
35 wallet === WALLET_NAMES.MNEMONIC
35 wallet === WALLET_NAMES.MNEMONIC
36− ? "Mnemonic"
36+ ? 'Mnemonic'
37 : wallet === WALLET_NAMES.TICKET
37 : wallet === WALLET_NAMES.TICKET
38− ? "Ticket"
38+ ? 'Ticket'
39 : wallet === WALLET_NAMES.SHARDS
39 : wallet === WALLET_NAMES.SHARDS
40− ? "Ticket Shards"
40+ ? 'Ticket Shards'
41 : wallet === WALLET_NAMES.LEDGER
41 : wallet === WALLET_NAMES.LEDGER
42− ? "Ledger"
42+ ? 'Ledger'
43 : wallet === WALLET_NAMES.TREZOR
43 : wallet === WALLET_NAMES.TREZOR
44− ? "Trezor"
44+ ? 'Trezor'
45 : wallet === WALLET_NAMES.PRIVATE_KEY
45 : wallet === WALLET_NAMES.PRIVATE_KEY
46− ? "Private Key"
46+ ? 'Private Key'
47 : wallet === WALLET_NAMES.KEYSTORE
47 : wallet === WALLET_NAMES.KEYSTORE
48− ? "Keystore File"
48+ ? 'Keystore File'
49− : "Wallet";
49+ : 'Wallet';
50
50
51const addressFromSecp256k1Public = pub => {
51const addressFromSecp256k1Public = pub => {
52 const compressed = false;
52 const compressed = false;
53 const uncompressed = secp256k1.publicKeyConvert(
53 const uncompressed = secp256k1.publicKeyConvert(
54− Buffer.from(pub, "hex"),
54+ Buffer.from(pub, 'hex'),
55− compressed,
55+ compressed
56 );
56 );
57 const chopped = uncompressed.slice(1); // chop parity byte
57 const chopped = uncompressed.slice(1); // chop parity byte
58 const hashed = keccak256(chopped);
58 const hashed = keccak256(chopped);
59− const addr = addHexPrefix(hashed.slice(-20).toString("hex"));
59+ const addr = addHexPrefix(hashed.slice(-20).toString('hex'));
60 return toChecksumAddress(addr);
60 return toChecksumAddress(addr);
61};
61};
62
62
63−const addHexPrefix = hex => (hex.slice(0, 2) === "0x" ? hex : "0x" + hex);
63+const addHexPrefix = hex => (hex.slice(0, 2) === '0x' ? hex : '0x' + hex);
64
64
65−const stripHexPrefix = hex => (hex.slice(0, 2) === "0x" ? hex.slice(2) : hex);
65+const stripHexPrefix = hex => (hex.slice(0, 2) === '0x' ? hex.slice(2) : hex);
66
66
67const keccak256 = str =>
67const keccak256 = str =>
68− keccak("keccak256")
68+ keccak('keccak256')
69 .update(str)
69 .update(str)
70 .digest();
70 .digest();
71
71
72−const isValidAddress = a => "0x0" === a || isAddress(a);
72+const isValidAddress = a => '0x0' === a || isAddress(a);
73
73
74const toChecksumAddress = address => {
74const toChecksumAddress = address => {
75 const addr = stripHexPrefix(address).toLowerCase();
75 const addr = stripHexPrefix(address).toLowerCase();
76− const hash = keccak256(addr).toString("hex");
76+ const hash = keccak256(addr).toString('hex');
77
77
78 return lodash.reduce(
78 return lodash.reduce(
79 addr,
79 addr,
80 (acc, char, idx) =>
80 (acc, char, idx) =>
81 parseInt(hash[idx], 16) >= 8 ? acc + char.toUpperCase() : acc + char,
81 parseInt(hash[idx], 16) >= 8 ? acc + char.toUpperCase() : acc + char,
82− "0x",
82+ '0x'
83 );
83 );
84};
84};
85
85
@@ -87,7 +87,7 @@ const eqAddr = (addr0, addr1) =>
87 toChecksumAddress(addr0) === toChecksumAddress(addr1);
87 toChecksumAddress(addr0) === toChecksumAddress(addr1);
88
88
89const urbitWalletFromTicket = async (ticket, point, passphrase) => {
89const urbitWalletFromTicket = async (ticket, point, passphrase) => {
90− if (typeof point === "string") {
90+ if (typeof point === 'string') {
91 //TODO why not in kg?
91 //TODO why not in kg?
92 point = ob.patp2dec(point);
92 point = ob.patp2dec(point);
93 }
93 }
@@ -100,7 +100,7 @@ const urbitWalletFromTicket = async (ticket, point, passphrase) => {
100};
100};
101
101
102const ownershipWalletFromTicket = async (ticket, point, passphrase) => {
102const ownershipWalletFromTicket = async (ticket, point, passphrase) => {
103− if (typeof point === "string") {
103+ if (typeof point === 'string') {
104 //TODO why not in kg?
104 //TODO why not in kg?
105 point = ob.patp2dec(point);
105 point = ob.patp2dec(point);
106 }
106 }
src/bridge/lib/web3.js+6−8
@@ -1,21 +1,19 @@
1−import * as azimuth from "azimuth-js";
1+import * as azimuth from 'azimuth-js';
2−import Web3 from "web3";
2+import Web3 from 'web3';
3
3
4−import { CONTRACT_ADDRESSES } from "./contracts";
4+import { CONTRACT_ADDRESSES } from './contracts';
5−import { NETWORK_NAMES } from "./network";
5+import { NETWORK_NAMES } from './network';
6
6
7export const initWeb3 = networkType => {
7export const initWeb3 = networkType => {
8 if (networkType === NETWORK_NAMES.MAINNET) {
8 if (networkType === NETWORK_NAMES.MAINNET) {
9− const endpoint = `https://mainnet.infura.io/v3/${
9+ const endpoint = `https://mainnet.infura.io/v3/${process.env.REACT_APP_INFURA_ENDPOINT}`;
10− process.env.REACT_APP_INFURA_ENDPOINT
11− }`;
12
10
13 const provider = new Web3.providers.HttpProvider(endpoint);
11 const provider = new Web3.providers.HttpProvider(endpoint);
14 const web3 = new Web3(provider);
12 const web3 = new Web3(provider);
15 const contracts = azimuth.initContracts(web3, CONTRACT_ADDRESSES.MAINNET);
13 const contracts = azimuth.initContracts(web3, CONTRACT_ADDRESSES.MAINNET);
16 return { web3: web3, contracts: contracts };
14 return { web3: web3, contracts: contracts };
17 } else if (networkType === NETWORK_NAMES.LOCAL) {
15 } else if (networkType === NETWORK_NAMES.LOCAL) {
18− const protocol = process.env.NODE_ENV === "development" ? "ws" : "wss";
16+ const protocol = process.env.NODE_ENV === 'development' ? 'ws' : 'wss';
19 const endpoint = `${protocol}://localhost:8545`;
17 const endpoint = `${protocol}://localhost:8545`;
20 const provider = new Web3.providers.WebsocketProvider(endpoint);
18 const provider = new Web3.providers.WebsocketProvider(endpoint);
21 const web3 = new Web3(provider);
19 const web3 = new Web3(provider);
src/bridge/store/history.js+4−4
@@ -1,8 +1,8 @@
1−import React, { useContext, useState, useEffect } from "react";
1+import React, { useContext, useState, useEffect } from 'react';
2−import { last, includes } from "lodash";
2+import { last, includes } from 'lodash';
3
3
4−import { BRIDGE_ERROR } from "../lib/error";
4+import { BRIDGE_ERROR } from '../lib/error';
5−import { ROUTE_NAMES } from "../lib/routeNames";
5+import { ROUTE_NAMES } from '../lib/routeNames';
6
6
7export const HistoryContext = React.createContext(null);
7export const HistoryContext = React.createContext(null);
8
8
src/bridge/store/txnConfirmations.js+2−3
@@ -1,4 +1,4 @@
1−import React, { useContext, useState } from "react";
1+import React, { useContext, useState } from 'react';
2
2
3export const TxnConfirmationsContext = React.createContext(null);
3export const TxnConfirmationsContext = React.createContext(null);
4
4
@@ -17,8 +17,7 @@ export function TxnConfirmationsProvider({ children }) {
17 value={{
17 value={{
18 txnConfirmations: confirmations,
18 txnConfirmations: confirmations,
19 setTxnConfirmations,
19 setTxnConfirmations,
20− }}
20+ }}>
21− >
22 {children}
21 {children}
23 </TxnConfirmationsContext.Provider>
22 </TxnConfirmationsContext.Provider>
24 );
23 );
src/bridge/views/AcceptTransfer.js+23−25
@@ -1,19 +1,19 @@
1−import { Just } from "folktale/maybe";
1+import { Just } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Row, Col, H1, P } from "../components/Base";
3+import { Row, Col, H1, P } from '../components/Base';
4import {
4import {
5 InnerLabel,
5 InnerLabel,
6 AddressInput,
6 AddressInput,
7 ShowBlockie,
7 ShowBlockie,
8 Anchor,
8 Anchor,
9−} from "../components/Base";
9+} from '../components/Base';
10−import * as azimuth from "azimuth-js";
10+import * as azimuth from 'azimuth-js';
11−import * as ob from "urbit-ob";
11+import * as ob from 'urbit-ob';
12−import * as need from "../lib/need";
12+import * as need from '../lib/need';
13
13
14−import StatelessTransaction from "../components/StatelessTransaction";
14+import StatelessTransaction from '../components/StatelessTransaction';
15−import { NETWORK_NAMES } from "../lib/network";
15+import { NETWORK_NAMES } from '../lib/network';
16−import { isValidAddress } from "../lib/wallet";
16+import { isValidAddress } from '../lib/wallet';
17
17
18class AcceptTransfer extends React.Component {
18class AcceptTransfer extends React.Component {
19 constructor(props) {
19 constructor(props) {
@@ -50,8 +50,8 @@ class AcceptTransfer extends React.Component {
50 validContracts,
50 validContracts,
51 validPoint,
51 validPoint,
52 state.receivingAddress,
52 state.receivingAddress,
53− true,
53+ true
54− ),
54+ )
55 );
55 );
56 }
56 }
57
57
@@ -66,20 +66,20 @@ class AcceptTransfer extends React.Component {
66
66
67 const esdomain =
67 const esdomain =
68 props.networkType === NETWORK_NAMES.ROPSTEN
68 props.networkType === NETWORK_NAMES.ROPSTEN
69− ? "ropsten.etherscan.io"
69+ ? 'ropsten.etherscan.io'
70− : "etherscan.io";
70+ : 'etherscan.io';
71
71
72 return (
72 return (
73 <Row>
73 <Row>
74 <Col>
74 <Col>
75 <H1>
75 <H1>
76− {"Accept Transfer of "}{" "}
76+ {'Accept Transfer of '}{' '}
77 <code>{` ${ob.patp(state.incomingPoint)} `}</code>
77 <code>{` ${ob.patp(state.incomingPoint)} `}</code>
78 </H1>
78 </H1>
79
79
80 <P>
80 <P>
81 {"By default, the recipient is the address you're logged in " +
81 {"By default, the recipient is the address you're logged in " +
82− "as. But you can transfer to any address you like."}
82+ 'as. But you can transfer to any address you like.'}
83 </P>
83 </P>
84
84
85 <AddressInput
85 <AddressInput
@@ -87,22 +87,20 @@ class AcceptTransfer extends React.Component {
87 prop-size="lg"
87 prop-size="lg"
88 prop-format="innerLabel"
88 prop-format="innerLabel"
89 value={state.receivingAddress}
89 value={state.receivingAddress}
90− onChange={v => this.handleAddressInput(v)}
90+ onChange={v => this.handleAddressInput(v)}>
91− >
92− <InnerLabel>{"Receiving Address"}</InnerLabel>
91+ <InnerLabel>{'Receiving Address'}</InnerLabel>
93− <ShowBlockie className={"mt-1"} address={state.receivingAddress} />
92+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
94 </AddressInput>
93 </AddressInput>
95
94
96 <Anchor
95 <Anchor
97− className={"mt-1 sm"}
96+ className={'mt-1 sm'}
98 prop-size="sm"
97 prop-size="sm"
99 prop-disabled={
98 prop-disabled={
100 !isValidAddress(state.receivingAddress) || !esvisible
99 !isValidAddress(state.receivingAddress) || !esvisible
101 }
100 }
102− target={"_blank"}
101+ target={'_blank'}
103− href={`https://${esdomain}/address/${state.receivingAddress}`}
102+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
104− >
105− {"View on Etherscan ↗"}
103+ {'View on Etherscan ↗'}
106 </Anchor>
104 </Anchor>
107
105
108 <StatelessTransaction
106 <StatelessTransaction
src/bridge/views/CancelTransfer.js+12−12
@@ -1,12 +1,12 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Row, Col, H1, P } from "../components/Base";
3+import { Row, Col, H1, P } from '../components/Base';
4−import * as azimuth from "azimuth-js";
4+import * as azimuth from 'azimuth-js';
5−import * as ob from "urbit-ob";
5+import * as ob from 'urbit-ob';
6−import * as need from "../lib/need";
6+import * as need from '../lib/need';
7
7
8−import StatelessTransaction from "../components/StatelessTransaction";
8+import StatelessTransaction from '../components/StatelessTransaction';
9−import { ETH_ZERO_ADDR } from "../lib/wallet";
9+import { ETH_ZERO_ADDR } from '../lib/wallet';
10
10
11class CancelTransfer extends React.Component {
11class CancelTransfer extends React.Component {
12 constructor(props) {
12 constructor(props) {
@@ -15,7 +15,7 @@ class CancelTransfer extends React.Component {
15 const pointInTransfer = need.pointCursor(props);
15 const pointInTransfer = need.pointCursor(props);
16
16
17 this.state = {
17 this.state = {
18− proxyAddress: "",
18+ proxyAddress: '',
19 pointInTransfer: pointInTransfer,
19 pointInTransfer: pointInTransfer,
20 };
20 };
21
21
@@ -32,7 +32,7 @@ class CancelTransfer extends React.Component {
32 const txn = azimuth.ecliptic.setTransferProxy(
32 const txn = azimuth.ecliptic.setTransferProxy(
33 validContracts,
33 validContracts,
34 validPoint,
34 validPoint,
35− ETH_ZERO_ADDR,
35+ ETH_ZERO_ADDR
36 );
36 );
37
37
38 return Maybe.Just(txn);
38 return Maybe.Just(txn);
@@ -45,7 +45,7 @@ class CancelTransfer extends React.Component {
45
45
46 const proxy = online
46 const proxy = online
47 ? props.pointCache[state.pointInTransfer].transferProxy
47 ? props.pointCache[state.pointInTransfer].transferProxy
48− : "any outgoing addresses";
48+ : 'any outgoing addresses';
49
49
50 // const canGenerate = validAddress === true
50 // const canGenerate = validAddress === true
51
51
@@ -55,7 +55,7 @@ class CancelTransfer extends React.Component {
55 <Row>
55 <Row>
56 <Col>
56 <Col>
57 <H1>
57 <H1>
58− {"Cancel Transfer of "}{" "}
58+ {'Cancel Transfer of '}{' '}
59 <code>{` ${ob.patp(state.pointInTransfer)} `}</code>
59 <code>{` ${ob.patp(state.pointInTransfer)} `}</code>
60 </H1>
60 </H1>
61
61
src/bridge/views/CreateGalaxy.js+39−43
@@ -1,37 +1,37 @@
1−import React from "react";
1+import React from 'react';
2−import Maybe from "folktale/maybe";
2+import Maybe from 'folktale/maybe';
3−import * as azimuth from "azimuth-js";
3+import * as azimuth from 'azimuth-js';
4−import * as ob from "urbit-ob";
4+import * as ob from 'urbit-ob';
5−import * as need from "../lib/need";
5+import * as need from '../lib/need';
6−
6+
7−import { Button } from "../components/Base";
7+import { Button } from '../components/Base';
8−import { Row, Col, H1, P, Anchor } from "../components/Base";
8+import { Row, Col, H1, P, Anchor } from '../components/Base';
9import {
9import {
10 InnerLabel,
10 InnerLabel,
11 GalaxyInput,
11 GalaxyInput,
12 AddressInput,
12 AddressInput,
13 ValidatedSigil,
13 ValidatedSigil,
14 ShowBlockie,
14 ShowBlockie,
15−} from "../components/Base";
15+} from '../components/Base';
16−import StatelessTransaction from "../components/StatelessTransaction";
16+import StatelessTransaction from '../components/StatelessTransaction';
17
17
18−import { NETWORK_NAMES } from "../lib/network";
18+import { NETWORK_NAMES } from '../lib/network';
19−import { canDecodePatp } from "../lib/txn";
19+import { canDecodePatp } from '../lib/txn';
20
20
21−import { ETH_ZERO_ADDR, isValidAddress, eqAddr } from "../lib/wallet";
21+import { ETH_ZERO_ADDR, isValidAddress, eqAddr } from '../lib/wallet';
22
22
23−import { isValidGalaxy } from "../lib/lib";
23+import { isValidGalaxy } from '../lib/lib';
24
24
25const buttonTriState = status => {
25const buttonTriState = status => {
26− if (status === null) return "blue";
26+ if (status === null) return 'blue';
27− if (status === false) return "yellow";
27+ if (status === false) return 'yellow';
28− if (status === true) return "green";
28+ if (status === true) return 'green';
29};
29};
30
30
31const buttonTriStateText = status => {
31const buttonTriStateText = status => {
32− if (status === null) return "Confirm Galaxy Availablility";
32+ if (status === null) return 'Confirm Galaxy Availablility';
33− if (status === false) return "Galaxy is Not Available";
33+ if (status === false) return 'Galaxy is Not Available';
34− if (status === true) return "Galaxy is Available";
34+ if (status === true) return 'Galaxy is Available';
35};
35};
36
36
37class CreateGalaxy extends React.Component {
37class CreateGalaxy extends React.Component {
@@ -42,7 +42,7 @@ class CreateGalaxy extends React.Component {
42
42
43 this.state = {
43 this.state = {
44 galaxyOwner: galaxyOwner,
44 galaxyOwner: galaxyOwner,
45− galaxyName: "",
45+ galaxyName: '',
46 isAvailable: null,
46 isAvailable: null,
47 };
47 };
48
48
@@ -77,7 +77,7 @@ class CreateGalaxy extends React.Component {
77 const txn = azimuth.ecliptic.createGalaxy(
77 const txn = azimuth.ecliptic.createGalaxy(
78 validContracts,
78 validContracts,
79 galaxyDec,
79 galaxyDec,
80− state.galaxyOwner,
80+ state.galaxyOwner
81 );
81 );
82
82
83 return Maybe.Just(txn);
83 return Maybe.Just(txn);
@@ -97,7 +97,7 @@ class CreateGalaxy extends React.Component {
97
97
98 const currentOwner = await azimuth.azimuth.getOwner(
98 const currentOwner = await azimuth.azimuth.getOwner(
99 validContracts,
99 validContracts,
100− galaxyDec,
100+ galaxyDec
101 );
101 );
102
102
103 const available = eqAddr(currentOwner, ETH_ZERO_ADDR);
103 const available = eqAddr(currentOwner, ETH_ZERO_ADDR);
@@ -122,17 +122,17 @@ class CreateGalaxy extends React.Component {
122
122
123 const esdomain =
123 const esdomain =
124 props.networkType === NETWORK_NAMES.ROPSTEN
124 props.networkType === NETWORK_NAMES.ROPSTEN
125− ? "ropsten.etherscan.io"
125+ ? 'ropsten.etherscan.io'
126− : "etherscan.io";
126+ : 'etherscan.io';
127
127
128 return (
128 return (
129 <Row>
129 <Row>
130 <Col>
130 <Col>
131− <H1> {"Create a Galaxy"} </H1>
131+ <H1> {'Create a Galaxy'} </H1>
132
132
133 <P>
133 <P>
134− {"Enter the galaxy to create and the address that will own " +
134+ {'Enter the galaxy to create and the address that will own ' +
135− "it (defaulting to this account, if not provided)."}
135+ 'it (defaulting to this account, if not provided).'}
136 </P>
136 </P>
137
137
138 <GalaxyInput
138 <GalaxyInput
@@ -142,9 +142,8 @@ class CreateGalaxy extends React.Component {
142 autoFocus
142 autoFocus
143 placeholder="e.g. ~zod"
143 placeholder="e.g. ~zod"
144 value={state.galaxyName}
144 value={state.galaxyName}
145− onChange={v => this.handleGalaxyNameInput(v)}
145+ onChange={v => this.handleGalaxyNameInput(v)}>
146− >
147− <InnerLabel>{"Galaxy Name"}</InnerLabel>
146+ <InnerLabel>{'Galaxy Name'}</InnerLabel>
148 <ValidatedSigil
147 <ValidatedSigil
149 className="tr-0 mt-05 mr-0 abs"
148 className="tr-0 mt-05 mr-0 abs"
150 patp={state.galaxyName}
149 patp={state.galaxyName}
@@ -158,20 +157,18 @@ class CreateGalaxy extends React.Component {
158 prop-size="lg"
157 prop-size="lg"
159 prop-format="innerLabel"
158 prop-format="innerLabel"
160 value={state.galaxyOwner}
159 value={state.galaxyOwner}
161− onChange={v => this.handleAddressInput(v)}
160+ onChange={v => this.handleAddressInput(v)}>
162− >
163− <InnerLabel>{"Address that will own this galaxy"}</InnerLabel>
161+ <InnerLabel>{'Address that will own this galaxy'}</InnerLabel>
164− <ShowBlockie className={"mt-1"} address={state.galaxyOwner} />
162+ <ShowBlockie className={'mt-1'} address={state.galaxyOwner} />
165 </AddressInput>
163 </AddressInput>
166
164
167 <Anchor
165 <Anchor
168− className={"mt-1"}
166+ className={'mt-1'}
169− prop-size={"sm"}
167+ prop-size={'sm'}
170 prop-disabled={!validAddress || !esvisible}
168 prop-disabled={!validAddress || !esvisible}
171− target={"_blank"}
169+ target={'_blank'}
172− href={`https://${esdomain}/address/${state.galaxyOwner}`}
170+ href={`https://${esdomain}/address/${state.galaxyOwner}`}>
173− >
174− {"View on Etherscan ↗"}
171+ {'View on Etherscan ↗'}
175 </Anchor>
172 </Anchor>
176
173
177 <Button
174 <Button
@@ -179,8 +176,7 @@ class CreateGalaxy extends React.Component {
179 className="mt-8"
176 className="mt-8"
180 prop-color={buttonTriState(state.isAvailable)}
177 prop-color={buttonTriState(state.isAvailable)}
181 disabled={!validGalaxy}
178 disabled={!validGalaxy}
182− onClick={() => this.confirmAvailability()}
179+ onClick={() => this.confirmAvailability()}>
183− >
184 {buttonTriStateText(state.isAvailable)}
180 {buttonTriStateText(state.isAvailable)}
185 </Button>
181 </Button>
186
182
src/bridge/views/GenKeyfile.js+22−23
@@ -1,23 +1,23 @@
1−import React from "react";
1+import React from 'react';
2−import Maybe from "folktale/maybe";
2+import Maybe from 'folktale/maybe';
3−import * as need from "../lib/need";
3+import * as need from '../lib/need';
4
4
5−import { Button } from "../components/Base";
5+import { Button } from '../components/Base';
6−import { Row, Col, H1, P } from "../components/Base";
6+import { Row, Col, H1, P } from '../components/Base';
7
7
8−import * as ob from "urbit-ob";
8+import * as ob from 'urbit-ob';
9−import * as kg from "urbit-key-generation/dist/index";
9+import * as kg from 'urbit-key-generation/dist/index';
10−import saveAs from "file-saver";
10+import saveAs from 'file-saver';
11
11
12−import { attemptSeedDerivation, genKey } from "../lib/keys";
12+import { attemptSeedDerivation, genKey } from '../lib/keys';
13−import { addHexPrefix } from "../lib/wallet";
13+import { addHexPrefix } from '../lib/wallet';
14
14
15class GenKeyfile extends React.Component {
15class GenKeyfile extends React.Component {
16 constructor(props) {
16 constructor(props) {
17 super(props);
17 super(props);
18
18
19 this.state = {
19 this.state = {
20− keyfile: "",
20+ keyfile: '',
21 loaded: false,
21 loaded: false,
22 };
22 };
23 }
23 }
@@ -42,7 +42,7 @@ class GenKeyfile extends React.Component {
42
42
43 async componentDidMount() {
43 async componentDidMount() {
44 const { point, pointDetails, revision } = this.getPointDetails();
44 const { point, pointDetails, revision } = this.getPointDetails();
45− let keyfile = "";
45+ let keyfile = '';
46
46
47 const hexRegExp = /[0-9A-Fa-f]{64}/g;
47 const hexRegExp = /[0-9A-Fa-f]{64}/g;
48 const networkSeed = await this.deriveSeed();
48 const networkSeed = await this.deriveSeed();
@@ -77,11 +77,11 @@ class GenKeyfile extends React.Component {
77 const next = false;
77 const next = false;
78 let seed = await attemptSeedDerivation(next, this.props);
78 let seed = await attemptSeedDerivation(next, this.props);
79
79
80− if (seed.getOrElse("") === "" && this.props.networkSeedCache) {
80+ if (seed.getOrElse('') === '' && this.props.networkSeedCache) {
81 seed = Maybe.Just(this.props.networkSeedCache);
81 seed = Maybe.Just(this.props.networkSeedCache);
82 }
82 }
83
83
84− return seed.getOrElse("");
84+ return seed.getOrElse('');
85 }
85 }
86
86
87 render() {
87 render() {
@@ -90,14 +90,14 @@ class GenKeyfile extends React.Component {
90
90
91 return (
91 return (
92 <Row>
92 <Row>
93− <Col className={"col-md-8"}>
93+ <Col className={'col-md-8'}>
94− <H1>{"Generate keyfile"}</H1>
94+ <H1>{'Generate keyfile'}</H1>
95
95
96− <P>{"Download a private key file for booting this point in Arvo."}</P>
96+ <P>{'Download a private key file for booting this point in Arvo.'}</P>
97
97
98− {keyfile === "" && !loaded && <P>{"Generating keyfile..."}</P>}
98+ {keyfile === '' && !loaded && <P>{'Generating keyfile...'}</P>}
99
99
100− {keyfile === "" && loaded && (
100+ {keyfile === '' && loaded && (
101 <React.Fragment>
101 <React.Fragment>
102 <P>
102 <P>
103 <b>Warning: </b>
103 <b>Warning: </b>
@@ -112,17 +112,16 @@ class GenKeyfile extends React.Component {
112 </React.Fragment>
112 </React.Fragment>
113 )}
113 )}
114
114
115− {keyfile !== "" && (
115+ {keyfile !== '' && (
116 <React.Fragment>
116 <React.Fragment>
117 <div className="pb-5 text-code keyfile">{keyfile}</div>
117 <div className="pb-5 text-code keyfile">{keyfile}</div>
118 <Button
118 <Button
119 onClick={() => {
119 onClick={() => {
120 let blob = new Blob([keyfile], {
120 let blob = new Blob([keyfile], {
121− type: "text/plain;charset=utf-8",
121+ type: 'text/plain;charset=utf-8',
122 });
122 });
123 saveAs(blob, `${ob.patp(point).slice(1)}-${revision}.key`);
123 saveAs(blob, `${ob.patp(point).slice(1)}-${revision}.key`);
124− }}
124+ }}>
125− >
126 Download →
125 Download →
127 </Button>
126 </Button>
128 </React.Fragment>
127 </React.Fragment>
src/bridge/views/InviteTicket.js+34−40
@@ -1,5 +1,5 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3import {
3import {
4 InnerLabel,
4 InnerLabel,
5 Warning,
5 Warning,
@@ -9,35 +9,35 @@ import {
9 Row,
9 Row,
10 Col,
10 Col,
11 Passport,
11 Passport,
12−} from "../components/Base";
12+} from '../components/Base';
13−import * as azimuth from "azimuth-js";
13+import * as azimuth from 'azimuth-js';
14−import * as need from "../lib/need";
14+import * as need from '../lib/need';
15
15
16−import { randomPatq } from "../lib/lib";
16+import { randomPatq } from '../lib/lib';
17−import { ROUTE_NAMES } from "../lib/routeNames";
17+import { ROUTE_NAMES } from '../lib/routeNames';
18−import { withHistory } from "../store/history";
18+import { withHistory } from '../store/history';
19import {
19import {
20 DEFAULT_HD_PATH,
20 DEFAULT_HD_PATH,
21 ownershipWalletFromTicket,
21 ownershipWalletFromTicket,
22 walletFromMnemonic,
22 walletFromMnemonic,
23−} from "../lib/wallet";
23+} from '../lib/wallet';
24−import { BRIDGE_ERROR } from "../lib/error";
24+import { BRIDGE_ERROR } from '../lib/error';
25import {
25import {
26 INVITE_STAGES,
26 INVITE_STAGES,
27 WALLET_STATES,
27 WALLET_STATES,
28 TRANSACTION_STATES,
28 TRANSACTION_STATES,
29−} from "../lib/invite";
29+} from '../lib/invite';
30−import { generateWallet, startTransactions } from "../lib/invite";
30+import { generateWallet, startTransactions } from '../lib/invite';
31
31
32class InviteTicket extends React.Component {
32class InviteTicket extends React.Component {
33 constructor(props) {
33 constructor(props) {
34 super(props);
34 super(props);
35
35
36 this.state = {
36 this.state = {
37− inviteTicket: "",
37+ inviteTicket: '',
38 inviteWallet: Nothing(),
38 inviteWallet: Nothing(),
39− verifyTicket: "",
39+ verifyTicket: '',
40− realTicket: "",
40+ realTicket: '',
41 realPoint: Nothing(),
41 realPoint: Nothing(),
42 realWallet: Nothing(),
42 realWallet: Nothing(),
43 walletReady: false,
43 walletReady: false,
@@ -92,7 +92,7 @@ class InviteTicket extends React.Component {
92 //TODO isn't all this accessible in the ownership object?
92 //TODO isn't all this accessible in the ownership object?
93 const inviteWallet = walletFromMnemonic(
93 const inviteWallet = walletFromMnemonic(
94 mnemonic,
94 mnemonic,
95− DEFAULT_HD_PATH,
95+ DEFAULT_HD_PATH
96 ).matchWith({
96 ).matchWith({
97 Just: w => w.value,
97 Just: w => w.value,
98 Nothing: () => {
98 Nothing: () => {
@@ -130,7 +130,7 @@ class InviteTicket extends React.Component {
130 }
130 }
131 } else {
131 } else {
132 errors = [
132 errors = [
133− "Invite code has no claimable ship. Check your invite code and try again.",
133+ 'Invite code has no claimable ship. Check your invite code and try again.',
134 ];
134 ];
135 }
135 }
136
136
@@ -140,7 +140,7 @@ class InviteTicket extends React.Component {
140 // dev mode: uncomment this out to autofill verified ticket
140 // dev mode: uncomment this out to autofill verified ticket
141 verifyTicket: !Nothing.hasInstance(realWallet)
141 verifyTicket: !Nothing.hasInstance(realWallet)
142 ? realWallet.value.ticket
142 ? realWallet.value.ticket
143− : "",
143+ : '',
144 walletStates: this.state.walletStates.concat(WALLET_STATES.RENDERING),
144 walletStates: this.state.walletStates.concat(WALLET_STATES.RENDERING),
145 errors,
145 errors,
146 });
146 });
@@ -157,11 +157,11 @@ class InviteTicket extends React.Component {
157 let handler = isLogin
157 let handler = isLogin
158 ? this.handleInviteTicketInput
158 ? this.handleInviteTicketInput
159 : this.handleVerifyTicketInput;
159 : this.handleVerifyTicketInput;
160− let label = isLogin ? "Activation code" : "ticket";
160+ let label = isLogin ? 'Activation code' : 'ticket';
161
161
162 // if realWallet is Just, then VerifyTicketInput appropriate contents; if Nothing, remain Nothing
162 // if realWallet is Just, then VerifyTicketInput appropriate contents; if Nothing, remain Nothing
163 const Verified = this.state.realWallet.map(realWallet =>
163 const Verified = this.state.realWallet.map(realWallet =>
164− VerifyTicketInput(realWallet.ticket),
164+ VerifyTicketInput(realWallet.ticket)
165 );
165 );
166
166
167 // Verified.getOrElse(TicketInput) falls back to TicketInput if Verified is Nothing
167 // Verified.getOrElse(TicketInput) falls back to TicketInput if Verified is Nothing
@@ -179,8 +179,7 @@ class InviteTicket extends React.Component {
179 name="invite"
179 name="invite"
180 placeholder={`e.g. ${phTick}`}
180 placeholder={`e.g. ${phTick}`}
181 value={value}
181 value={value}
182− onChange={handler}
182+ onChange={handler}>
183− >
184 <InnerLabel>{label}</InnerLabel>
183 <InnerLabel>{label}</InnerLabel>
185 </TicketElem>
184 </TicketElem>
186 );
185 );
@@ -256,7 +255,7 @@ class InviteTicket extends React.Component {
256
255
257 updateProgress(notification) {
256 updateProgress(notification) {
258 let newState =
257 let newState =
259− notification.type === "progress"
258+ notification.type === 'progress'
260 ? { transactionProgress: notification.value }
259 ? { transactionProgress: notification.value }
261 : notification.type === 'notify'
260 : notification.type === 'notify'
262 ? { errors: [notification.value] }
261 ? { errors: [notification.value] }
@@ -278,8 +277,8 @@ class InviteTicket extends React.Component {
278 const { web3, contracts, setUrbitWallet } = this.props;
277 const { web3, contracts, setUrbitWallet } = this.props;
279
278
280 const btnColor = this.state.walletStates.includes(WALLET_STATES.PAPER_READY)
279 const btnColor = this.state.walletStates.includes(WALLET_STATES.PAPER_READY)
281− ? "green"
280+ ? 'green'
282− : "black";
281+ : 'black';
283
282
284 const clickHandler =
283 const clickHandler =
285 stage === INVITE_STAGES.INVITE_LOGIN
284 stage === INVITE_STAGES.INVITE_LOGIN
@@ -297,7 +296,7 @@ class InviteTicket extends React.Component {
297 this.setState({
296 this.setState({
298 stage: INVITE_STAGES.INVITE_TRANSACTIONS,
297 stage: INVITE_STAGES.INVITE_TRANSACTIONS,
299 walletStates: this.state.walletStates.concat(
298 walletStates: this.state.walletStates.concat(
300− WALLET_STATES.TRANSACTIONS,
299+ WALLET_STATES.TRANSACTIONS
301 ),
300 ),
302 });
301 });
303
302
@@ -333,13 +332,12 @@ class InviteTicket extends React.Component {
333 const buttonElem =
332 const buttonElem =
334 stage === INVITE_STAGES.INVITE_TRANSACTIONS ? null : (
333 stage === INVITE_STAGES.INVITE_TRANSACTIONS ? null : (
335 <Button
334 <Button
336− className={"mt-4"}
335+ className={'mt-4'}
337− prop-size={"lg"}
336+ prop-size={'lg'}
338 prop-color={btnColor}
337 prop-color={btnColor}
339 disabled={!continueReady}
338 disabled={!continueReady}
340− onClick={clickHandler}
339+ onClick={clickHandler}>
341− >
342− {"Continue →"}
340+ {'Continue →'}
343 </Button>
341 </Button>
344 );
342 );
345
343
@@ -355,20 +353,17 @@ class InviteTicket extends React.Component {
355 <div className="mt-6 mb-8">
353 <div className="mt-6 mb-8">
356 <span
354 <span
357 className={`fs-35 mr-3 ${stage !== INVITE_STAGES.INVITE_WALLET &&
355 className={`fs-35 mr-3 ${stage !== INVITE_STAGES.INVITE_WALLET &&
358− "gray-20"}`}
356+ 'gray-20'}`}>
359− >
360 1 Passport
357 1 Passport
361 </span>
358 </span>
362 <span
359 <span
363 className={`fs-35 mr-3 ${stage !== INVITE_STAGES.INVITE_VERIFY &&
360 className={`fs-35 mr-3 ${stage !== INVITE_STAGES.INVITE_VERIFY &&
364− "gray-20"}`}
361+ 'gray-20'}`}>
365− >
366 2 Verify
362 2 Verify
367 </span>
363 </span>
368 <span
364 <span
369 className={`fs-35 mr-3 ${stage !==
365 className={`fs-35 mr-3 ${stage !==
370− INVITE_STAGES.INVITE_TRANSACTIONS && "gray-20"}`}
366+ INVITE_STAGES.INVITE_TRANSACTIONS && 'gray-20'}`}>
371− >
372 3 Invite
367 3 Invite
373 </span>
368 </span>
374 </div>
369 </div>
@@ -382,7 +377,7 @@ class InviteTicket extends React.Component {
382
377
383 return (
378 return (
384 <Warning>
379 <Warning>
385− <h3 className={"mb-2"}>{"Warning"}</h3>
380+ <h3 className={'mb-2'}>{'Warning'}</h3>
386 {errorElems}
381 {errorElems}
387 </Warning>
382 </Warning>
388 );
383 );
@@ -409,8 +404,7 @@ class InviteTicket extends React.Component {
409 prop-type={`link`}
404 prop-type={`link`}
410 prop-size={`sm`}
405 prop-size={`sm`}
411 className={`block mt-4`}
406 className={`block mt-4`}
412− onClick={this.navigateLogin}
407+ onClick={this.navigateLogin}>
413− >
414 {`Log in`}
408 {`Log in`}
415 </Button>
409 </Button>
416 )}
410 )}
src/bridge/views/InvitesManage.js+22−24
@@ -1,8 +1,8 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as ob from "urbit-ob";
3+import * as ob from 'urbit-ob';
4−import * as azimuth from "azimuth-js";
4+import * as azimuth from 'azimuth-js';
5−import * as need from "../lib/need";
5+import * as need from '../lib/need';
6
6
7import {
7import {
8 Row,
8 Row,
@@ -12,8 +12,8 @@ import {
12 PointInput,
12 PointInput,
13 InnerLabel,
13 InnerLabel,
14 ValidatedSigil,
14 ValidatedSigil,
15−} from "../components/Base";
15+} from '../components/Base';
16−import StatelessTransaction from "../components/StatelessTransaction";
16+import StatelessTransaction from '../components/StatelessTransaction';
17
17
18class InvitesManage extends React.Component {
18class InvitesManage extends React.Component {
19 constructor(props) {
19 constructor(props) {
@@ -21,7 +21,7 @@ class InvitesManage extends React.Component {
21
21
22 this.state = {
22 this.state = {
23 invitesWillWork: Nothing(),
23 invitesWillWork: Nothing(),
24− planetInput: "",
24+ planetInput: '',
25 targetPlanet: Nothing(),
25 targetPlanet: Nothing(),
26 currentPoolSize: Nothing(),
26 currentPoolSize: Nothing(),
27 cachedPoolSizes: {},
27 cachedPoolSizes: {},
@@ -44,7 +44,7 @@ class InvitesManage extends React.Component {
44 .isSpawnProxy(
44 .isSpawnProxy(
45 this.contracts,
45 this.contracts,
46 this.point,
46 this.point,
47− this.contracts.delegatedSending.address,
47+ this.contracts.delegatedSending.address
48 )
48 )
49 .then(isSpawnProxy => {
49 .then(isSpawnProxy => {
50 this.setState({ invitesWillWork: Just(isSpawnProxy) });
50 this.setState({ invitesWillWork: Just(isSpawnProxy) });
@@ -77,7 +77,7 @@ class InvitesManage extends React.Component {
77
77
78 checkCurrentInvites(who) {
78 checkCurrentInvites(who) {
79 const cachedPoolSizes = this.state.cachedPoolSizes;
79 const cachedPoolSizes = this.state.cachedPoolSizes;
80− if (typeof cachedPoolSizes[who] !== "undefined") {
80+ if (typeof cachedPoolSizes[who] !== 'undefined') {
81 return Just(cachedPoolSizes[who]);
81 return Just(cachedPoolSizes[who]);
82 } else {
82 } else {
83 azimuth.delegatedSending.getPool(this.contracts, who).then(pool => {
83 azimuth.delegatedSending.getPool(this.contracts, who).then(pool => {
@@ -112,8 +112,8 @@ class InvitesManage extends React.Component {
112 this.contracts,
112 this.contracts,
113 this.point,
113 this.point,
114 this.state.targetPlanet.value,
114 this.state.targetPlanet.value,
115− this.state.targetPoolSize,
115+ this.state.targetPoolSize
116− ),
116+ )
117 );
117 );
118 }
118 }
119
119
@@ -122,18 +122,18 @@ class InvitesManage extends React.Component {
122 if (this.state.invitesWillWork.value === false) {
122 if (this.state.invitesWillWork.value === false) {
123 spawnProxyWarning = (
123 spawnProxyWarning = (
124 <Warning>
124 <Warning>
125− <h3 className={"mb-2"}>{"Warning"}</h3>
125+ <h3 className={'mb-2'}>{'Warning'}</h3>
126− {"Planets under this star will not be able to send invites " +
126+ {'Planets under this star will not be able to send invites ' +
127− "until the invite contract ("}
127+ 'until the invite contract ('}
128 <code>{this.contracts.delegatedSending.address}</code>
128 <code>{this.contracts.delegatedSending.address}</code>
129− {") is made spawn proxy for this star."}
129+ {') is made spawn proxy for this star.'}
130 </Warning>
130 </Warning>
131 );
131 );
132 }
132 }
133
133
134 let poolSizeText = this.state.currentPoolSize.matchWith({
134 let poolSizeText = this.state.currentPoolSize.matchWith({
135 Just: ps => `(currently ${ps.value})`,
135 Just: ps => `(currently ${ps.value})`,
136− Nothing: _ => "",
136+ Nothing: _ => '',
137 });
137 });
138
138
139 return (
139 return (
@@ -141,7 +141,7 @@ class InvitesManage extends React.Component {
141 <Col>
141 <Col>
142 <p>
142 <p>
143 {
143 {
144− "manage invites here, for stars. can only give invites to child planets"
144+ 'manage invites here, for stars. can only give invites to child planets'
145 }
145 }
146 </p>
146 </p>
147
147
@@ -150,11 +150,10 @@ class InvitesManage extends React.Component {
150 <PointInput
150 <PointInput
151 prop-format="innerlabel"
151 prop-format="innerlabel"
152 prop-size="lg"
152 prop-size="lg"
153− placeholder={"~sampel-sipnem"}
153+ placeholder={'~sampel-sipnem'}
154 value={this.state.planetInput}
154 value={this.state.planetInput}
155− onChange={this.handlePointInput}
155+ onChange={this.handlePointInput}>
156− >
157− <InnerLabel>{"Planet to set invites for"}</InnerLabel>
156+ <InnerLabel>{'Planet to set invites for'}</InnerLabel>
158 <ValidatedSigil
157 <ValidatedSigil
159 patp={this.state.targetPlanet}
158 patp={this.state.targetPlanet}
160 validator={() => this.validatePoint}
159 validator={() => this.validatePoint}
@@ -165,8 +164,7 @@ class InvitesManage extends React.Component {
165 prop-format="innerlabel"
164 prop-format="innerlabel"
166 prop-size="lg"
165 prop-size="lg"
167 value={this.state.targetPoolSize}
166 value={this.state.targetPoolSize}
168− onChange={this.handlePoolSizeInput}
167+ onChange={this.handlePoolSizeInput}>
169− >
170 <InnerLabel>{`Available invites ${poolSizeText}`}</InnerLabel>
168 <InnerLabel>{`Available invites ${poolSizeText}`}</InnerLabel>
171 </Input>
169 </Input>
172
170
src/bridge/views/InvitesSend.js+69−72
@@ -1,13 +1,13 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as azimuth from "azimuth-js";
3+import * as azimuth from 'azimuth-js';
4−import * as need from "../lib/need";
4+import * as need from '../lib/need';
5
5
6−import { hasReceived, sendMail } from "../lib/inviteMail";
6+import { hasReceived, sendMail } from '../lib/inviteMail';
7−import { Row, Col, Button, Input, H3, Warning } from "../components/Base";
7+import { Row, Col, Button, Input, H3, Warning } from '../components/Base';
8
8
9// for wallet generation
9// for wallet generation
10−import * as wg from "../../walletgen/lib/lib";
10+import * as wg from '../../walletgen/lib/lib';
11
11
12// for transaction generation and signing
12// for transaction generation and signing
13import {
13import {
@@ -17,27 +17,27 @@ import {
17 hexify,
17 hexify,
18 fromWei,
18 fromWei,
19 toWei,
19 toWei,
20−} from "../lib/txn";
20+} from '../lib/txn';
21−import * as tank from "../lib/tank";
21+import * as tank from '../lib/tank';
22
22
23const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
23const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
24const GAS_LIMIT = 350000;
24const GAS_LIMIT = 350000;
25−const INVITE_COST = toWei((GAS_PRICE_GWEI * GAS_LIMIT).toString(), "gwei");
25+const INVITE_COST = toWei((GAS_PRICE_GWEI * GAS_LIMIT).toString(), 'gwei');
26
26
27const STATUS = {
27const STATUS = {
28− INPUT: "Generate invites",
28+ INPUT: 'Generate invites',
29− GENERATING: "Generating invites",
29+ GENERATING: 'Generating invites',
30− CAN_SEND: "Send invites",
30+ CAN_SEND: 'Send invites',
31− FUNDING: "Funding invites",
31+ FUNDING: 'Funding invites',
32− SENDING: "Sending invites",
32+ SENDING: 'Sending invites',
33− DONE: "Done",
33+ DONE: 'Done',
34− FAIL: "Some failed",
34+ FAIL: 'Some failed',
35};
35};
36
36
37const EMAIL_STATUS = {
37const EMAIL_STATUS = {
38− BUSY: "⋯",
38+ BUSY: '⋯',
39− DONE: "✔",
39+ DONE: '✔',
40− FAIL: "×",
40+ FAIL: '×',
41};
41};
42
42
43class InvitesSend extends React.Component {
43class InvitesSend extends React.Component {
@@ -47,7 +47,7 @@ class InvitesSend extends React.Component {
47 this.state = {
47 this.state = {
48 invitesAvailable: Nothing(),
48 invitesAvailable: Nothing(),
49 invited: Nothing(),
49 invited: Nothing(),
50− targets: [{ email: "", hasReceived: Nothing(), status: Nothing() }],
50+ targets: [{ email: '', hasReceived: Nothing(), status: Nothing() }],
51 status: STATUS.INPUT,
51 status: STATUS.INPUT,
52 errors: Nothing(),
52 errors: Nothing(),
53 //
53 //
@@ -89,7 +89,7 @@ class InvitesSend extends React.Component {
89 async findInvited() {
89 async findInvited() {
90 let invited = await azimuth.delegatedSending.getInvited(
90 let invited = await azimuth.delegatedSending.getInvited(
91 this.contracts,
91 this.contracts,
92− this.point,
92+ this.point
93 );
93 );
94 invited = invited.map(async point => {
94 invited = invited.map(async point => {
95 const active = await azimuth.azimuth.isActive(this.contracts, point);
95 const active = await azimuth.azimuth.isActive(this.contracts, point);
@@ -116,13 +116,13 @@ class InvitesSend extends React.Component {
116 const planets = await azimuth.delegatedSending.getPlanetsToSend(
116 const planets = await azimuth.delegatedSending.getPlanetsToSend(
117 this.contracts,
117 this.contracts,
118 this.point,
118 this.point,
119− targets.length,
119+ targets.length
120 );
120 );
121
121
122 // account for the race condition where invites got used up while we were
122 // account for the race condition where invites got used up while we were
123 // composing our target list
123 // composing our target list
124 if (planets.length < targets.length) {
124 if (planets.length < targets.length) {
125− this.addError("Can currently only send " + planets.length + " invites!");
125+ this.addError('Can currently only send ' + planets.length + ' invites!');
126 return;
126 return;
127 }
127 }
128
128
@@ -132,7 +132,7 @@ class InvitesSend extends React.Component {
132 // create invite wallets and transactions
132 // create invite wallets and transactions
133 let invites = []; // { email, ticket, signedTx, rawTx }
133 let invites = []; // { email, ticket, signedTx, rawTx }
134 for (let i = 0; i < targets.length; i++) {
134 for (let i = 0; i < targets.length; i++) {
135− console.log("generating email", i, targets[i].email);
135+ console.log('generating email', i, targets[i].email);
136 this.setEmailStatus(i, EMAIL_STATUS.BUSY);
136 this.setEmailStatus(i, EMAIL_STATUS.BUSY);
137
137
138 const email = targets[i].email;
138 const email = targets[i].email;
@@ -142,7 +142,7 @@ class InvitesSend extends React.Component {
142 this.contracts,
142 this.contracts,
143 this.point,
143 this.point,
144 planets[i],
144 planets[i],
145− wallet.owner,
145+ wallet.owner
146 );
146 );
147 const signedTx = await signTransaction({
147 const signedTx = await signTransaction({
148 ...this.props,
148 ...this.props,
@@ -183,7 +183,7 @@ class InvitesSend extends React.Component {
183 this.askForFunding,
183 this.askForFunding,
184 () => {
184 () => {
185 this.setState({ fundingMessage: Nothing() });
185 this.setState({ fundingMessage: Nothing() });
186− },
186+ }
187 );
187 );
188
188
189 this.setState({ status: STATUS.SENDING });
189 this.setState({ status: STATUS.SENDING });
@@ -200,11 +200,11 @@ class InvitesSend extends React.Component {
200 web3,
200 web3,
201 Just(invite.signedTx),
201 Just(invite.signedTx),
202 tankWasUsed,
202 tankWasUsed,
203− () => {},
203+ () => {}
204 );
204 );
205 } catch (err) {
205 } catch (err) {
206− console.error("invite tx sending failed", err);
206+ console.error('invite tx sending failed', err);
207− this.addError("Invite transaction not sent for " + invite.email);
207+ this.addError('Invite transaction not sent for ' + invite.email);
208 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
208 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
209 continue;
209 continue;
210 }
210 }
@@ -216,19 +216,19 @@ class InvitesSend extends React.Component {
216 const mailSuccess = await sendMail(
216 const mailSuccess = await sendMail(
217 invite.email,
217 invite.email,
218 invite.ticket,
218 invite.ticket,
219− invite.rawTx,
219+ invite.rawTx
220 );
220 );
221 if (!mailSuccess) throw new Error();
221 if (!mailSuccess) throw new Error();
222 this.setEmailStatus(i, EMAIL_STATUS.DONE);
222 this.setEmailStatus(i, EMAIL_STATUS.DONE);
223 } catch (e) {
223 } catch (e) {
224− console.log("email send failed");
224+ console.log('email send failed');
225 //NOTE this assumes that the transaction succeeds, but we don't know
225 //NOTE this assumes that the transaction succeeds, but we don't know
226 // that for a fact yet...
226 // that for a fact yet...
227 this.addError(
227 this.addError(
228− "Invite email failed to send for " +
228+ 'Invite email failed to send for ' +
229 invite.email +
229 invite.email +
230− ". Please give them this ticket: " +
230+ '. Please give them this ticket: ' +
231− invite.ticket,
231+ invite.ticket
232 );
232 );
233 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
233 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
234 continue;
234 continue;
@@ -240,12 +240,12 @@ class InvitesSend extends React.Component {
240 if (success) {
240 if (success) {
241 this.setEmailStatus(i, EMAIL_STATUS.DONE);
241 this.setEmailStatus(i, EMAIL_STATUS.DONE);
242 } else {
242 } else {
243− console.log("invite tx rejected");
243+ console.log('invite tx rejected');
244− this.addError("Invite transaction failed for " + invite.email);
244+ this.addError('Invite transaction failed for ' + invite.email);
245 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
245 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
246 }
246 }
247 return success;
247 return success;
248− }),
248+ })
249 );
249 );
250 }
250 }
251
251
@@ -279,9 +279,9 @@ class InvitesSend extends React.Component {
279 fundingMessage: Just(
279 fundingMessage: Just(
280 `Please make sure ${address} has at least ${fromWei(minBalance)} ETH,` +
280 `Please make sure ${address} has at least ${fromWei(minBalance)} ETH,` +
281 `we'll continue once that's true. Current balance: ${fromWei(
281 `we'll continue once that's true. Current balance: ${fromWei(
282− balance,
282+ balance
283 )}.` +
283 )}.` +
284− `Waiting...`,
284+ `Waiting...`
285 ),
285 ),
286 });
286 });
287 }
287 }
@@ -328,7 +328,7 @@ class InvitesSend extends React.Component {
328
328
329 addTarget() {
329 addTarget() {
330 let targets = this.state.targets;
330 let targets = this.state.targets;
331− targets.push({ email: "", hasReceived: Nothing(), status: Nothing() });
331+ targets.push({ email: '', hasReceived: Nothing(), status: Nothing() });
332 this.setState({ targets });
332 this.setState({ targets });
333 }
333 }
334
334
@@ -343,24 +343,24 @@ class InvitesSend extends React.Component {
343 this.state.status === STATUS.DONE ? this.state.targets.length : null;
343 this.state.status === STATUS.DONE ? this.state.targets.length : null;
344
344
345 const invitesAvailable = this.state.invitesAvailable.matchWith({
345 const invitesAvailable = this.state.invitesAvailable.matchWith({
346− Nothing: () => "Loading...",
346+ Nothing: () => 'Loading...',
347 Just: invites => {
347 Just: invites => {
348− const dia = dif ? `(-${dif})` : "";
348+ const dia = dif ? `(-${dif})` : '';
349 return `You currently have ${invites.value}${dia} invitations left.`;
349 return `You currently have ${invites.value}${dia} invitations left.`;
350 },
350 },
351 });
351 });
352
352
353 const invitesSent = this.state.invited.matchWith({
353 const invitesSent = this.state.invited.matchWith({
354− Nothing: () => <>{"Loading..."}</>,
354+ Nothing: () => <>{'Loading...'}</>,
355 Just: invited => {
355 Just: invited => {
356− const dit = dif ? `(+${dif})` : "";
356+ const dit = dif ? `(+${dif})` : '';
357 return (
357 return (
358 <>
358 <>
359− {"Out of the "}
359+ {'Out of the '}
360 {invited.value.total + dit}
360 {invited.value.total + dit}
361− {" invites you sent, "}
361+ {' invites you sent, '}
362 {invited.value.accepted}
362 {invited.value.accepted}
363− {" have been accepted."}
363+ {' have been accepted.'}
364 </>
364 </>
365 );
365 );
366 },
366 },
@@ -369,9 +369,9 @@ class InvitesSend extends React.Component {
369 const error = this.state.errors.matchWith({
369 const error = this.state.errors.matchWith({
370 Nothing: () => null,
370 Nothing: () => null,
371 Just: errors => (
371 Just: errors => (
372− <Warning className={"mt-8"}>
372+ <Warning className={'mt-8'}>
373 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
373 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
374− {"Something went wrong!"}
374+ {'Something went wrong!'}
375 </H3>
375 </H3>
376 {errors.value.map(err => (
376 {errors.value.map(err => (
377 <p>{err}</p>
377 <p>{err}</p>
@@ -382,31 +382,30 @@ class InvitesSend extends React.Component {
382
382
383 const fundingMessage = this.state.fundingMessage.matchWith({
383 const fundingMessage = this.state.fundingMessage.matchWith({
384 Nothing: () => null,
384 Nothing: () => null,
385− Just: msg => <Warning className={"mt-8"}>{msg.value}</Warning>,
385+ Just: msg => <Warning className={'mt-8'}>{msg.value}</Warning>,
386 });
386 });
387
387
388 let inputs;
388 let inputs;
389 if (this.state.status === STATUS.DONE) {
389 if (this.state.status === STATUS.DONE) {
390 //TODO proper clickable router thing
390 //TODO proper clickable router thing
391− inputs = "<- Back to Home";
391+ inputs = '<- Back to Home';
392 } else {
392 } else {
393 const inputDisabled = this.state.status !== STATUS.INPUT;
393 const inputDisabled = this.state.status !== STATUS.INPUT;
394
394
395 const lessButton = (
395 const lessButton = (
396 <Button
396 <Button
397− prop-size={"s narrow"}
397+ prop-size={'s narrow'}
398− className={"mt-8"}
398+ className={'mt-8'}
399 disabled={inputDisabled || this.state.targets.length === 1}
399 disabled={inputDisabled || this.state.targets.length === 1}
400− onClick={this.removeTarget}
400+ onClick={this.removeTarget}>
401− >
402− {"-"}
401+ {'-'}
403 </Button>
402 </Button>
404 );
403 );
405
404
406 const moreButton = (
405 const moreButton = (
407 <Button
406 <Button
408− prop-size={"s narrow"}
407+ prop-size={'s narrow'}
409− className={"mt-8"}
408+ className={'mt-8'}
410 disabled={
409 disabled={
411 inputDisabled ||
410 inputDisabled ||
412 this.state.invitesAvailable.matchWith({
411 this.state.invitesAvailable.matchWith({
@@ -414,9 +413,8 @@ class InvitesSend extends React.Component {
414 Just: inv => inv.value <= this.state.targets.length,
413 Just: inv => inv.value <= this.state.targets.length,
415 })
414 })
416 }
415 }
417− onClick={this.addTarget}
416+ onClick={this.addTarget}>
418− >
419− {"+"}
417+ {'+'}
420 </Button>
418 </Button>
421 );
419 );
422
420
@@ -424,7 +422,7 @@ class InvitesSend extends React.Component {
424 for (let i = 0; i < this.state.targets.length; i++) {
422 for (let i = 0; i < this.state.targets.length; i++) {
425 const target = this.state.targets[i];
423 const target = this.state.targets[i];
426 let progress = target.status.matchWith({
424 let progress = target.status.matchWith({
427− Nothing: () => "",
425+ Nothing: () => '',
428 Just: status => status.value,
426 Just: status => status.value,
429 });
427 });
430 targetInputs.push(
428 targetInputs.push(
@@ -434,23 +432,23 @@ class InvitesSend extends React.Component {
434 onChange={value => {
432 onChange={value => {
435 this.handleEmailInput(i, value);
433 this.handleEmailInput(i, value);
436 }}
434 }}
437− placeholder={"Email address"}
435+ placeholder={'Email address'}
438 disabled={inputDisabled}
436 disabled={inputDisabled}
439 />
437 />
440 {target.hasReceived.matchWith({
438 {target.hasReceived.matchWith({
441 Nothing: () => null,
439 Nothing: () => null,
442 Just: has =>
440 Just: has =>
443− has.value ? <span>{"×"}</span> : <span>{"°"}</span>,
441+ has.value ? <span>{'×'}</span> : <span>{'°'}</span>,
444 })}
442 })}
445 {progress}
443 {progress}
446− </>,
444+ </>
447 );
445 );
448 }
446 }
449
447
450 const submitButton = (
448 const submitButton = (
451 <Button
449 <Button
452− prop-size={"xl wide"}
450+ prop-size={'xl wide'}
453− className={"mt-8"}
451+ className={'mt-8'}
454 disabled={
452 disabled={
455 (inputDisabled && this.state.status !== STATUS.CAN_SEND) ||
453 (inputDisabled && this.state.status !== STATUS.CAN_SEND) ||
456 !this.canSend()
454 !this.canSend()
@@ -458,8 +456,7 @@ class InvitesSend extends React.Component {
458 onClick={() => {
456 onClick={() => {
459 if (this.state.status === STATUS.INPUT) this.generateInvites();
457 if (this.state.status === STATUS.INPUT) this.generateInvites();
460 if (this.state.status === STATUS.CAN_SEND) this.sendInvites();
458 if (this.state.status === STATUS.CAN_SEND) this.sendInvites();
461− }}
459+ }}>
462− >
463 {this.state.status}
460 {this.state.status}
464 </Button>
461 </Button>
465 );
462 );
@@ -477,9 +474,9 @@ class InvitesSend extends React.Component {
477 return (
474 return (
478 <Row>
475 <Row>
479 <Col>
476 <Col>
480− <p>{"send invites here, for planets"}</p>
477+ <p>{'send invites here, for planets'}</p>
481
478
482− <p>{"send invites here, for planets"}</p>
479+ <p>{'send invites here, for planets'}</p>
483
480
484 <p>{invitesAvailable}</p>
481 <p>{invitesAvailable}</p>
485
482
src/bridge/views/IssueChild.js+42−46
@@ -1,8 +1,8 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { azimuth, ecliptic } from "azimuth-js";
3+import { azimuth, ecliptic } from 'azimuth-js';
4−import * as ob from "urbit-ob";
4+import * as ob from 'urbit-ob';
5−import * as need from "../lib/need";
5+import * as need from '../lib/need';
6
6
7import {
7import {
8 Row,
8 Row,
@@ -15,15 +15,15 @@ import {
15 PointInput,
15 PointInput,
16 AddressInput,
16 AddressInput,
17 InnerLabel,
17 InnerLabel,
18−} from "../components/Base";
18+} from '../components/Base';
19
19
20−import StatelessTransaction from "../components/StatelessTransaction";
20+import StatelessTransaction from '../components/StatelessTransaction';
21
21
22−import { NETWORK_NAMES } from "../lib/network";
22+import { NETWORK_NAMES } from '../lib/network';
23−import { getSpawnCandidate } from "../lib/child";
23+import { getSpawnCandidate } from '../lib/child';
24−import { canDecodePatp } from "../lib/txn";
24+import { canDecodePatp } from '../lib/txn';
25
25
26−import { isValidAddress } from "../lib/wallet";
26+import { isValidAddress } from '../lib/wallet';
27
27
28const setFind = (set, pred) => {
28const setFind = (set, pred) => {
29 for (const e of set) {
29 for (const e of set) {
@@ -50,13 +50,13 @@ class IssueChild extends React.Component {
50 ];
50 ];
51
51
52 this.state = {
52 this.state = {
53− receivingAddress: "",
53+ receivingAddress: '',
54 issuingPoint: issuingPoint,
54 issuingPoint: issuingPoint,
55− desiredPoint: "",
55+ desiredPoint: '',
56 isAvailable: Nothing(), // use Nothing to allow attempt when offline
56 isAvailable: Nothing(), // use Nothing to allow attempt when offline
57 suggestions: suggestions,
57 suggestions: suggestions,
58 validChildren: new Set(),
58 validChildren: new Set(),
59− autoComplete: "",
59+ autoComplete: '',
60 };
60 };
61
61
62 this.handlePointInput = this.handlePointInput.bind(this);
62 this.handlePointInput = this.handlePointInput.bind(this);
@@ -84,9 +84,9 @@ class IssueChild extends React.Component {
84 if (desiredPoint.length < 15) {
84 if (desiredPoint.length < 15) {
85 const suggestedPoint =
85 const suggestedPoint =
86 setFind(this.state.validChildren, e => e.startsWith(desiredPoint)) ||
86 setFind(this.state.validChildren, e => e.startsWith(desiredPoint)) ||
87− "";
87+ '';
88 const rendered =
88 const rendered =
89− " ".repeat(desiredPoint.length) +
89+ ' '.repeat(desiredPoint.length) +
90 suggestedPoint.substring(desiredPoint.length);
90 suggestedPoint.substring(desiredPoint.length);
91
91
92 const available = Just(this.state.validChildren.has(desiredPoint));
92 const available = Just(this.state.validChildren.has(desiredPoint));
@@ -114,7 +114,7 @@ class IssueChild extends React.Component {
114 const txn = ecliptic.spawn(
114 const txn = ecliptic.spawn(
115 validContracts,
115 validContracts,
116 pointDec,
116 pointDec,
117− state.receivingAddress,
117+ state.receivingAddress
118 );
118 );
119
119
120 return Just(txn);
120 return Just(txn);
@@ -156,14 +156,14 @@ class IssueChild extends React.Component {
156
156
157 const esdomain =
157 const esdomain =
158 props.networkType === NETWORK_NAMES.ROPSTEN
158 props.networkType === NETWORK_NAMES.ROPSTEN
159− ? "ropsten.etherscan.io"
159+ ? 'ropsten.etherscan.io'
160− : "etherscan.io";
160+ : 'etherscan.io';
161
161
162 return (
162 return (
163 <Row>
163 <Row>
164 <Col>
164 <Col>
165 <H1>
165 <H1>
166− {"Issue a Child From "}{" "}
166+ {'Issue a Child From '}{' '}
167 <code>{`${ob.patp(state.issuingPoint)}`}</code>
167 <code>{`${ob.patp(state.issuingPoint)}`}</code>
168 </H1>
168 </H1>
169
169
@@ -177,38 +177,36 @@ class IssueChild extends React.Component {
177 {`Your point can only issue children with particular names. Some
177 {`Your point can only issue children with particular names. Some
178 valid suggestions for `}
178 valid suggestions for `}
179 {<code>{ob.patp(state.issuingPoint)}</code>}
179 {<code>{ob.patp(state.issuingPoint)}</code>}
180− {" are "}
180+ {' are '}
181 <code>{state.suggestions[0]}</code>
181 <code>{state.suggestions[0]}</code>
182− {", "}
182+ {', '}
183 <code>{state.suggestions[1]}</code>
183 <code>{state.suggestions[1]}</code>
184− {", and "}
184+ {', and '}
185 <code>{state.suggestions[2]}</code>
185 <code>{state.suggestions[2]}</code>
186− {"."}
186+ {'.'}
187 </P>
187 </P>
188
188
189 <PointInput
189 <PointInput
190 prop-size="lg"
190 prop-size="lg"
191 prop-format="innerLabel"
191 prop-format="innerLabel"
192− className={"mono mt-8"}
192+ className={'mono mt-8'}
193 placeholder={`e.g. ${state.suggestions[3]}`}
193 placeholder={`e.g. ${state.suggestions[3]}`}
194 value={state.desiredPoint}
194 value={state.desiredPoint}
195− onChange={this.handlePointInput}
195+ onChange={this.handlePointInput}>
196− >
197− <InnerLabel>{"Point to Issue"}</InnerLabel>
196+ <InnerLabel>{'Point to Issue'}</InnerLabel>
198 <div
197 <div
199 style={{
198 style={{
200− marginTop: "8.8rem",
199+ marginTop: '8.8rem',
201− marginLeft: "4.6rem",
200+ marginLeft: '4.6rem',
202− fontSize: "5rem",
201+ fontSize: '5rem',
203− color: "#757575",
202+ color: '#757575',
204− whiteSpace: "pre-wrap",
203+ whiteSpace: 'pre-wrap',
205 }}
204 }}
206− className="abs tl-0 mono"
205+ className="abs tl-0 mono">
207− >
208 {state.autoComplete}
206 {state.autoComplete}
209 </div>
207 </div>
210 <ValidatedSigil
208 <ValidatedSigil
211− className={"tr-0 mt-05 mr-0 abs"}
209+ className={'tr-0 mt-05 mr-0 abs'}
212 patp={state.desiredPoint}
210 patp={state.desiredPoint}
213 size={68}
211 size={68}
214 margin={8}
212 margin={8}
@@ -225,22 +223,20 @@ class IssueChild extends React.Component {
225 disabled={
223 disabled={
226 Nothing.hasInstance(state.isAvailable) || !state.isAvailable.value
224 Nothing.hasInstance(state.isAvailable) || !state.isAvailable.value
227 }
225 }
228− onChange={v => this.handleAddressInput(v)}
226+ onChange={v => this.handleAddressInput(v)}>
229− >
230− <InnerLabel>{"Receiving Address"}</InnerLabel>
227+ <InnerLabel>{'Receiving Address'}</InnerLabel>
231− <ShowBlockie className={"mt-1"} address={state.receivingAddress} />
228+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
232 </AddressInput>
229 </AddressInput>
233
230
234 <Anchor
231 <Anchor
235− className={"mt-1"}
232+ className={'mt-1'}
236− prop-size={"sm"}
233+ prop-size={'sm'}
237 prop-disabled={
234 prop-disabled={
238 !isValidAddress(state.receivingAddress) || !esvisible
235 !isValidAddress(state.receivingAddress) || !esvisible
239 }
236 }
240− target={"_blank"}
237+ target={'_blank'}
241− href={`https://${esdomain}/address/${state.receivingAddress}`}
238+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
242− >
243− {"View on Etherscan ↗"}
239+ {'View on Etherscan ↗'}
244 </Anchor>
240 </Anchor>
245
241
246 <StatelessTransaction
242 <StatelessTransaction
src/bridge/views/Keystore.js+33−37
@@ -1,15 +1,15 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import { Ok, Error } from "folktale/result";
2+import { Ok, Error } from 'folktale/result';
3−import React from "react";
3+import React from 'react';
4−import * as keythereum from "keythereum";
4+import * as keythereum from 'keythereum';
5−import { Button, UploadButton } from "../components/Base";
5+import { Button, UploadButton } from '../components/Base';
6−import { Input, InnerLabel, InputCaption } from "../components/Base";
6+import { Input, InnerLabel, InputCaption } from '../components/Base';
7−import { Row, Col, H1, H3, Warning } from "../components/Base";
7+import { Row, Col, H1, H3, Warning } from '../components/Base';
8−
8+
9−import { BRIDGE_ERROR } from "../lib/error";
9+import { BRIDGE_ERROR } from '../lib/error';
10−import { ROUTE_NAMES } from "../lib/routeNames";
10+import { ROUTE_NAMES } from '../lib/routeNames';
11−import { withHistory } from "../store/history";
11+import { withHistory } from '../store/history';
12−import { EthereumWallet } from "../lib/wallet";
12+import { EthereumWallet } from '../lib/wallet';
13
13
14class Keystore extends React.Component {
14class Keystore extends React.Component {
15 constructor(props) {
15 constructor(props) {
@@ -17,7 +17,7 @@ class Keystore extends React.Component {
17
17
18 this.state = {
18 this.state = {
19 keystore: Nothing(), // Maybe<Result<String, String>>
19 keystore: Nothing(), // Maybe<Result<String, String>>
20− password: "",
20+ password: '',
21 decryptionProblem: false,
21 decryptionProblem: false,
22 };
22 };
23
23
@@ -70,7 +70,7 @@ class Keystore extends React.Component {
70 };
70 };
71
71
72 const failure = _ => {
72 const failure = _ => {
73− const message = "There was a problem uploading your Keystore file";
73+ const message = 'There was a problem uploading your Keystore file';
74 this.setState({ keystore: Just(Error(message)) });
74 this.setState({ keystore: Just(Error(message)) });
75 };
75 };
76
76
@@ -85,11 +85,11 @@ class Keystore extends React.Component {
85 const { keystore, password, decryptionProblem } = this.state;
85 const { keystore, password, decryptionProblem } = this.state;
86
86
87 const uploadButtonClass = keystore.matchWith({
87 const uploadButtonClass = keystore.matchWith({
88− Nothing: _ => "bg-blue white",
88+ Nothing: _ => 'bg-blue white',
89 Just: ks =>
89 Just: ks =>
90 ks.value.matchWith({
90 ks.value.matchWith({
91− Ok: _ => "bg-green white",
91+ Ok: _ => 'bg-green white',
92− Error: _ => "bg-yellow black",
92+ Error: _ => 'bg-yellow black',
93 }),
93 }),
94 });
94 });
95
95
@@ -97,18 +97,18 @@ class Keystore extends React.Component {
97 decryptionProblem === false ? (
97 decryptionProblem === false ? (
98 <div />
98 <div />
99 ) : (
99 ) : (
100− <Warning className={"mt-8"}>
100+ <Warning className={'mt-8'}>
101 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
101 <H3 style={{ marginTop: 0, paddingTop: 0 }}>
102 {"Couldn't decrypt wallet."}
102 {"Couldn't decrypt wallet."}
103 </H3>
103 </H3>
104− {"You may have entered an incorrect password."}
104+ {'You may have entered an incorrect password.'}
105 </Warning>
105 </Warning>
106 );
106 );
107
107
108 return (
108 return (
109 <Row>
109 <Row>
110− <Col className={"measure-md"}>
110+ <Col className={'measure-md'}>
111− <H1 className={"mb-4"}>{"Upload Your Keystore File"}</H1>
111+ <H1 className={'mb-4'}>{'Upload Your Keystore File'}</H1>
112 <InputCaption>
112 <InputCaption>
113 {`Please upload your Ethereum keystore file. If your keystore
113 {`Please upload your Ethereum keystore file. If your keystore
114 file is encrypted with a password, you'll also need to enter
114 file is encrypted with a password, you'll also need to enter
@@ -117,10 +117,9 @@ class Keystore extends React.Component {
117
117
118 <UploadButton
118 <UploadButton
119 className={`btn ${uploadButtonClass} mt-10`}
119 className={`btn ${uploadButtonClass} mt-10`}
120− onChange={this.handleKeystoreUpload}
120+ onChange={this.handleKeystoreUpload}>
121− >
122− <div className={"flex-center-all fs-4 h-11 pointer"}>
121+ <div className={'flex-center-all fs-4 h-11 pointer'}>
123− {"Upload Keystore file"}
122+ {'Upload Keystore file'}
124 </div>
123 </div>
125 </UploadButton>
124 </UploadButton>
126
125
@@ -133,29 +132,26 @@ class Keystore extends React.Component {
133 onChange={this.handlePasswordInput}
132 onChange={this.handlePasswordInput}
134 value={password}
133 value={password}
135 autocomplete="off"
134 autocomplete="off"
136− autoFocus
135+ autoFocus>
137− >
138− <InnerLabel>{"Password"}</InnerLabel>
136+ <InnerLabel>{'Password'}</InnerLabel>
139 </Input>
137 </Input>
140
138
141 <Button
139 <Button
142 className={` mt-10`}
140 className={` mt-10`}
143− prop-size={"wide lg"}
141+ prop-size={'wide lg'}
144 disabled={Nothing.hasInstance(keystore)}
142 disabled={Nothing.hasInstance(keystore)}
145− onClick={this.constructWallet}
143+ onClick={this.constructWallet}>
146− >
147− {"Decrypt"}
144+ {'Decrypt'}
148 </Button>
145 </Button>
149
146
150 {decryptMessage}
147 {decryptMessage}
151
148
152 <Button
149 <Button
153− className={"mt-10"}
150+ className={'mt-10'}
154− prop-size={"wide lg"}
151+ prop-size={'wide lg'}
155 disabled={Nothing.hasInstance(wallet)}
152 disabled={Nothing.hasInstance(wallet)}
156− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
153+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
157− >
158− {"Continue →"}
154+ {'Continue →'}
159 </Button>
155 </Button>
160 </Col>
156 </Col>
161 </Row>
157 </Row>
src/bridge/views/Landing.js+24−27
@@ -1,10 +1,10 @@
1−import React from "react";
1+import React from 'react';
2−import { Button } from "../components/Base";
2+import { Button } from '../components/Base';
3−import { Row, Col } from "../components/Base";
3+import { Row, Col } from '../components/Base';
4−import { H1, P } from "../components/Base";
4+import { H1, P } from '../components/Base';
5
5
6−import { ROUTE_NAMES } from "../lib/routeNames";
6+import { ROUTE_NAMES } from '../lib/routeNames';
7−import { useHistory } from "../store/history";
7+import { useHistory } from '../store/history';
8
8
9function Landing(props) {
9function Landing(props) {
10 const history = useHistory();
10 const history = useHistory();
@@ -12,51 +12,48 @@ function Landing(props) {
12 return (
12 return (
13 <Row>
13 <Row>
14 <Col>
14 <Col>
15− <H1>{"Welcome"}</H1>
15+ <H1>{'Welcome'}</H1>
16
16
17 <P>
17 <P>
18− {"Bridge is a tool for managing and viewing assets on " +
18+ {'Bridge is a tool for managing and viewing assets on ' +
19− "Azimuth, the Urbit address space."}
19+ 'Azimuth, the Urbit address space.'}
20 </P>
20 </P>
21
21
22 <Button
22 <Button
23 prop-type="link"
23 prop-type="link"
24 prop-size="lg"
24 prop-size="lg"
25− className={"mb-4 mt-8"}
25+ className={'mb-4 mt-8'}
26− onClick={() => history.push(ROUTE_NAMES.INVITE_TICKET)}
26+ onClick={() => history.push(ROUTE_NAMES.INVITE_TICKET)}>
27− >
28− {"Claim an invite →"}
27+ {'Claim an invite →'}
29 </Button>
28 </Button>
30
29
31− <P>{"If you were sent an Azimuth invite code, start here."}</P>
30+ <P>{'If you were sent an Azimuth invite code, start here.'}</P>
32
31
33 <Button
32 <Button
34 prop-type="link"
33 prop-type="link"
35 prop-size="lg"
34 prop-size="lg"
36− className={"mb-4 mt-8"}
35+ className={'mb-4 mt-8'}
37− onClick={() => history.push(ROUTE_NAMES.NETWORK)}
36+ onClick={() => history.push(ROUTE_NAMES.NETWORK)}>
38− >
39− {"Unlock a Wallet →"}
37+ {'Unlock a Wallet →'}
40 </Button>
38 </Button>
41
39
42 <P>
40 <P>
43− {"If you own Azimuth assets and want to manage them in some " +
41+ {'If you own Azimuth assets and want to manage them in some ' +
44 "way, start here. You'll need either your Urbit ticket or a " +
42 "way, start here. You'll need either your Urbit ticket or a " +
45− "keypair."}
43+ 'keypair.'}
46 </P>
44 </P>
47
45
48 {
46 {
49 <Row>
47 <Row>
50 <Col>
48 <Col>
51 <Button
49 <Button
52− prop-type={"link"}
50+ prop-type={'link'}
53− prop-size={"lg"}
51+ prop-size={'lg'}
54− className={"mb-4 mt-8"}
52+ className={'mb-4 mt-8'}
55− onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}
53+ onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
56− >
57− {"View a point →"}
54+ {'View a point →'}
58 </Button>
55 </Button>
59− <P>{"View an Azimuth point without signing into a wallet."}</P>
56+ <P>{'View an Azimuth point without signing into a wallet.'}</P>
60 </Col>
57 </Col>
61 </Row>
58 </Row>
62 // FIXME add address view
59 // FIXME add address view
src/bridge/views/Ledger.js+63−67
@@ -1,20 +1,20 @@
1−import * as bip32 from "bip32";
1+import * as bip32 from 'bip32';
2−import React from "react";
2+import React from 'react';
3−import Maybe from "folktale/maybe";
3+import Maybe from 'folktale/maybe';
4−import { Button } from "../components/Base";
4+import { Button } from '../components/Base';
5−import { Row, Col, H1, P, H2 } from "../components/Base";
5+import { Row, Col, H1, P, H2 } from '../components/Base';
6−import { Input, InnerLabel, InnerLabelDropdown } from "../components/Base";
6+import { Input, InnerLabel, InnerLabelDropdown } from '../components/Base';
7−import Transport from "@ledgerhq/hw-transport-u2f";
7+import Transport from '@ledgerhq/hw-transport-u2f';
8−import Eth from "@ledgerhq/hw-app-eth";
8+import Eth from '@ledgerhq/hw-app-eth';
9−import * as secp256k1 from "secp256k1";
9+import * as secp256k1 from 'secp256k1';
10
10
11−import { LEDGER_LIVE_PATH, LEDGER_LEGACY_PATH } from "../lib/ledger";
11+import { LEDGER_LIVE_PATH, LEDGER_LEGACY_PATH } from '../lib/ledger';
12−import { ROUTE_NAMES } from "../lib/routeNames";
12+import { ROUTE_NAMES } from '../lib/routeNames';
13−import { withHistory } from "../store/history";
13+import { withHistory } from '../store/history';
14
14
15−const chopHdPrefix = str => (str.slice(0, 2) === "m/" ? str.slice(2) : str);
15+const chopHdPrefix = str => (str.slice(0, 2) === 'm/' ? str.slice(2) : str);
16
16
17−const addHdPrefix = str => (str.slice(0, 2) === "m/" ? str : "m/" + str);
17+const addHdPrefix = str => (str.slice(0, 2) === 'm/' ? str : 'm/' + str);
18
18
19class Ledger extends React.Component {
19class Ledger extends React.Component {
20 constructor(props) {
20 constructor(props) {
@@ -43,7 +43,7 @@ class Ledger extends React.Component {
43
43
44 updateHdPath(basePath, account) {
44 updateHdPath(basePath, account) {
45 let hdpath = this.state.hdpath;
45 let hdpath = this.state.hdpath;
46− if (basePath !== "custom") {
46+ if (basePath !== 'custom') {
47 hdpath = basePath.replace(/x/g, account);
47 hdpath = basePath.replace(/x/g, account);
48 }
48 }
49 this.setState({ basePath, account, hdpath });
49 this.setState({ basePath, account, hdpath });
@@ -63,8 +63,8 @@ class Ledger extends React.Component {
63
63
64 eth.getAddress(path, false, true).then(
64 eth.getAddress(path, false, true).then(
65 info => {
65 info => {
66− const publicKey = Buffer.from(info.publicKey, "hex");
66+ const publicKey = Buffer.from(info.publicKey, 'hex');
67− const chainCode = Buffer.from(info.chainCode, "hex");
67+ const chainCode = Buffer.from(info.chainCode, 'hex');
68 const pub = secp256k1.publicKeyConvert(publicKey, true);
68 const pub = secp256k1.publicKeyConvert(publicKey, true);
69 const hd = bip32.fromPublicKey(pub, chainCode);
69 const hd = bip32.fromPublicKey(pub, chainCode);
70 setWallet(Maybe.Just(hd));
70 setWallet(Maybe.Just(hd));
@@ -72,7 +72,7 @@ class Ledger extends React.Component {
72 },
72 },
73 _ => {
73 _ => {
74 setWallet(Maybe.Nothing());
74 setWallet(Maybe.Nothing());
75− },
75+ }
76 );
76 );
77 }
77 }
78
78
@@ -82,11 +82,11 @@ class Ledger extends React.Component {
82 const { handlePathSelection, handleAccountSelection } = this;
82 const { handlePathSelection, handleAccountSelection } = this;
83
83
84 const pathOptions = [
84 const pathOptions = [
85− { title: "Ledger Live", value: LEDGER_LIVE_PATH },
85+ { title: 'Ledger Live', value: LEDGER_LIVE_PATH },
86− { title: "Ledger Legacy", value: LEDGER_LEGACY_PATH },
86+ { title: 'Ledger Legacy', value: LEDGER_LEGACY_PATH },
87 {
87 {
88− title: "Custom path",
88+ title: 'Custom path',
89− value: "custom",
89+ value: 'custom',
90 },
90 },
91 ];
91 ];
92 let basePathTitle = pathOptions.find(o => o.value === basePath).title;
92 let basePathTitle = pathOptions.find(o => o.value === basePath).title;
@@ -94,7 +94,7 @@ class Ledger extends React.Component {
94 let accountOptions = [];
94 let accountOptions = [];
95 for (let i = 0; i < 20; i++) {
95 for (let i = 0; i < 20; i++) {
96 accountOptions.push({
96 accountOptions.push({
97− title: "Account #" + (i + 1),
97+ title: 'Account #' + (i + 1),
98 value: i,
98 value: i,
99 });
99 });
100 }
100 }
@@ -105,14 +105,14 @@ class Ledger extends React.Component {
105 className="mt-8"
105 className="mt-8"
106 options={pathOptions}
106 options={pathOptions}
107 handleUpdate={handlePathSelection}
107 handleUpdate={handlePathSelection}
108− title={"Derivation path"}
108+ title={'Derivation path'}
109 currentSelectionTitle={basePathTitle}
109 currentSelectionTitle={basePathTitle}
110 fullWidth={true}
110 fullWidth={true}
111 />
111 />
112 );
112 );
113
113
114 const truePathSelection =
114 const truePathSelection =
115− basePath === "custom" ? (
115+ basePath === 'custom' ? (
116 <Input
116 <Input
117 className="pt-8 mt-4 text-mono"
117 className="pt-8 mt-4 text-mono"
118 prop-size="md"
118 prop-size="md"
@@ -120,9 +120,8 @@ class Ledger extends React.Component {
120 name="hdpath"
120 name="hdpath"
121 value={addHdPrefix(hdpath)}
121 value={addHdPrefix(hdpath)}
122 autocomplete="off"
122 autocomplete="off"
123− onChange={this.handleHdPathInput}
123+ onChange={this.handleHdPathInput}>
124− >
125− <InnerLabel>{"HD Path"}</InnerLabel>
124+ <InnerLabel>{'HD Path'}</InnerLabel>
126 </Input>
125 </Input>
127 ) : (
126 ) : (
128 <InnerLabelDropdown
127 <InnerLabelDropdown
@@ -131,7 +130,7 @@ class Ledger extends React.Component {
131 prop-format="innerLabel"
130 prop-format="innerLabel"
132 options={accountOptions}
131 options={accountOptions}
133 handleUpdate={handleAccountSelection}
132 handleUpdate={handleAccountSelection}
134− title={"Account"}
133+ title={'Account'}
135 currentSelectionTitle={accountTitle}
134 currentSelectionTitle={accountTitle}
136 fullWidth={true}
135 fullWidth={true}
137 />
136 />
@@ -139,10 +138,10 @@ class Ledger extends React.Component {
139
138
140 return (
139 return (
141 <Row>
140 <Row>
142− <Col className={"measure-md"}>
141+ <Col className={'measure-md'}>
143− <H1>{"Authenticate With Your Ledger"}</H1>
142+ <H1>{'Authenticate With Your Ledger'}</H1>
144
143
145− <H2>{"Running on HTTPS?"}</H2>
144+ <H2>{'Running on HTTPS?'}</H2>
146
145
147 <P>
146 <P>
148 {`Connect and authenticate to your Ledger, and then open the
147 {`Connect and authenticate to your Ledger, and then open the
@@ -157,42 +156,41 @@ class Ledger extends React.Component {
157 it below.`}
156 it below.`}
158 </P>
157 </P>
159
158
160− <H2>{"Running on HTTP?"}</H2>
159+ <H2>{'Running on HTTP?'}</H2>
161
160
162 <P>{`To authenticate and sign transactions with a Ledger, Bridge
161 <P>{`To authenticate and sign transactions with a Ledger, Bridge
163 must be serving over HTTPS on localhost. You can do this via the
162 must be serving over HTTPS on localhost. You can do this via the
164 following:`}</P>
163 following:`}</P>
165
164
166− <ol className={"measure-md"}>
165+ <ol className={'measure-md'}>
167− <li className={"mt-4"}>
166+ <li className={'mt-4'}>
168− {"Install"}{" "}
167+ {'Install'}{' '}
169 <a
168 <a
170− target={"_blank"}
169+ target={'_blank'}
171− href={"https://github.com/FiloSottile/mkcert"}
170+ href={'https://github.com/FiloSottile/mkcert'}>
172− >
173− {"mkcert"}
171+ {'mkcert'}
174 </a>
172 </a>
175 </li>
173 </li>
176− <li className={"mt-4"}>
174+ <li className={'mt-4'}>
177− {"Install a local certificate authority via "}
175+ {'Install a local certificate authority via '}
178− <code>{"mkcert -install"}</code>
176+ <code>{'mkcert -install'}</code>
179 </li>
177 </li>
180− <li className={"mt-4"}>
178+ <li className={'mt-4'}>
181− {"In your "}
179+ {'In your '}
182− <code>{"bridge"}</code>
180+ <code>{'bridge'}</code>
183 {
181 {
184− " directory, generate a certificate valid for localhost via "
182+ ' directory, generate a certificate valid for localhost via '
185− }{" "}
183+ }{' '}
186− <code>{"mkcert localhost"}</code>
184+ <code>{'mkcert localhost'}</code>
187− {"."}
185+ {'.'}
188− {"This will produce two files: "}
186+ {'This will produce two files: '}
189− <code>{"localhost.pem"}</code> {", the local certificate, and "}
187+ <code>{'localhost.pem'}</code> {', the local certificate, and '}
190− <code>{"localhost-key.pem"}</code>
188+ <code>{'localhost-key.pem'}</code>
191− {", its corresponding private key."}
189+ {', its corresponding private key.'}
192 </li>
190 </li>
193− <li className={"mt-4"}>
191+ <li className={'mt-4'}>
194− {"Run "}
192+ {'Run '}
195− <code>{"python bridge-https.py"}</code>
193+ <code>{'python bridge-https.py'}</code>
196 </li>
194 </li>
197 </ol>
195 </ol>
198
196
@@ -200,20 +198,18 @@ class Ledger extends React.Component {
200 {truePathSelection}
198 {truePathSelection}
201
199
202 <Button
200 <Button
203− prop-size={"wide lg"}
201+ prop-size={'wide lg'}
204− className={"mt-8"}
202+ className={'mt-8'}
205− onClick={this.pollDevice}
203+ onClick={this.pollDevice}>
206− >
207− {"Authenticate →"}
204+ {'Authenticate →'}
208 </Button>
205 </Button>
209
206
210 <Button
207 <Button
211− className={"mt-8"}
208+ className={'mt-8'}
212− prop-size={"wide lg"}
209+ prop-size={'wide lg'}
213 disabled={Maybe.Nothing.hasInstance(wallet)}
210 disabled={Maybe.Nothing.hasInstance(wallet)}
214− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
211+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
215− >
216− {"Continue →"}
212+ {'Continue →'}
217 </Button>
213 </Button>
218 </Col>
214 </Col>
219 </Row>
215 </Row>
src/bridge/views/Mnemonic.js+28−32
@@ -1,26 +1,26 @@
1−import * as bip39 from "bip39";
1+import * as bip39 from 'bip39';
2−import { Just, Nothing } from "folktale/maybe";
2+import { Just, Nothing } from 'folktale/maybe';
3−import React from "react";
3+import React from 'react';
4−import { Button } from "../components/Base";
4+import { Button } from '../components/Base';
5import {
5import {
6 Input,
6 Input,
7 MnemonicInput,
7 MnemonicInput,
8 InnerLabel,
8 InnerLabel,
9 InputCaption,
9 InputCaption,
10−} from "../components/Base";
10+} from '../components/Base';
11−import { Row, Col, H1 } from "../components/Base";
11+import { Row, Col, H1 } from '../components/Base';
12
12
13−import { ROUTE_NAMES } from "../lib/routeNames";
13+import { ROUTE_NAMES } from '../lib/routeNames';
14−import { withHistory } from "../store/history";
14+import { withHistory } from '../store/history';
15−import { DEFAULT_HD_PATH, walletFromMnemonic } from "../lib/wallet";
15+import { DEFAULT_HD_PATH, walletFromMnemonic } from '../lib/wallet';
16
16
17class Mnemonic extends React.Component {
17class Mnemonic extends React.Component {
18 constructor(props) {
18 constructor(props) {
19 super(props);
19 super(props);
20
20
21 this.state = {
21 this.state = {
22− mnemonic: "",
22+ mnemonic: '',
23− passphrase: "",
23+ passphrase: '',
24 hdpath: DEFAULT_HD_PATH,
24 hdpath: DEFAULT_HD_PATH,
25 };
25 };
26
26
@@ -44,8 +44,8 @@ class Mnemonic extends React.Component {
44 const hdpath = state.hdpath;
44 const hdpath = state.hdpath;
45 this.attemptWalletDerivation(
45 this.attemptWalletDerivation(
46 mnemonic,
46 mnemonic,
47− hdpath === "" ? DEFAULT_HD_PATH : hdpath,
47+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
48− passphrase,
48+ passphrase
49 );
49 );
50 return {
50 return {
51 passphrase,
51 passphrase,
@@ -59,8 +59,8 @@ class Mnemonic extends React.Component {
59 const passphrase = state.passphrase;
59 const passphrase = state.passphrase;
60 this.attemptWalletDerivation(
60 this.attemptWalletDerivation(
61 mnemonic,
61 mnemonic,
62− hdpath === "" ? DEFAULT_HD_PATH : hdpath,
62+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
63− passphrase,
63+ passphrase
64 );
64 );
65 return {
65 return {
66 mnemonic,
66 mnemonic,
@@ -74,8 +74,8 @@ class Mnemonic extends React.Component {
74 const passphrase = state.passphrase;
74 const passphrase = state.passphrase;
75 this.attemptWalletDerivation(
75 this.attemptWalletDerivation(
76 mnemonic,
76 mnemonic,
77− hdpath === "" ? DEFAULT_HD_PATH : hdpath,
77+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
78− passphrase,
78+ passphrase
79 );
79 );
80 return {
80 return {
81 hdpath,
81 hdpath,
@@ -98,9 +98,9 @@ class Mnemonic extends React.Component {
98 return (
98 return (
99 <Row>
99 <Row>
100 <Col>
100 <Col>
101− <H1 className={"mb-4"}>{"Enter Your Mnemonic"}</H1>
101+ <H1 className={'mb-4'}>{'Enter Your Mnemonic'}</H1>
102 <InputCaption>
102 <InputCaption>
103− {"Please enter your BIP39 mnemonic here."}
103+ {'Please enter your BIP39 mnemonic here.'}
104 </InputCaption>
104 </InputCaption>
105
105
106 <MnemonicInput
106 <MnemonicInput
@@ -113,9 +113,8 @@ class Mnemonic extends React.Component {
113 onChange={this.handleMnemonicInput}
113 onChange={this.handleMnemonicInput}
114 value={mnemonic}
114 value={mnemonic}
115 autocomplete="off"
115 autocomplete="off"
116− autoFocus
116+ autoFocus>
117− >
118− <InnerLabel>{"Mnemonic"}</InnerLabel>
117+ <InnerLabel>{'Mnemonic'}</InnerLabel>
119 </MnemonicInput>
118 </MnemonicInput>
120
119
121 <InputCaption>
120 <InputCaption>
@@ -130,9 +129,8 @@ class Mnemonic extends React.Component {
130 type="password"
129 type="password"
131 value={passphrase}
130 value={passphrase}
132 autocomplete="off"
131 autocomplete="off"
133− onChange={this.handlePassphraseInput}
132+ onChange={this.handlePassphraseInput}>
134− >
135− <InnerLabel>{"Passphrase"}</InnerLabel>
133+ <InnerLabel>{'Passphrase'}</InnerLabel>
136 </Input>
134 </Input>
137
135
138 <InputCaption>
136 <InputCaption>
@@ -146,17 +144,15 @@ class Mnemonic extends React.Component {
146 name="hdpath"
144 name="hdpath"
147 value={hdpath}
145 value={hdpath}
148 autocomplete="off"
146 autocomplete="off"
149− onChange={this.handleHdPathInput}
147+ onChange={this.handleHdPathInput}>
150− >
151− <InnerLabel>{"HD Path"}</InnerLabel>
148+ <InnerLabel>{'HD Path'}</InnerLabel>
152 </Input>
149 </Input>
153
150
154 <Button
151 <Button
155− className={"mt-10"}
152+ className={'mt-10'}
156 disabled={Nothing.hasInstance(wallet)}
153 disabled={Nothing.hasInstance(wallet)}
157− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
154+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
158− >
159− {"Continue →"}
155+ {'Continue →'}
160 </Button>
156 </Button>
161 </Col>
157 </Col>
162 </Row>
158 </Row>
src/bridge/views/Network.js+30−35
@@ -1,15 +1,15 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Button } from "../components/Base";
3+import { Button } from '../components/Base';
4−import { InnerLabelDropdown } from "../components/Base";
4+import { InnerLabelDropdown } from '../components/Base';
5−import { Row, Col, H1, P } from "../components/Base";
5+import { Row, Col, H1, P } from '../components/Base';
6−import * as azimuth from "azimuth-js";
6+import * as azimuth from 'azimuth-js';
7−import Web3 from "web3";
7+import Web3 from 'web3';
8−
8+
9−import { CONTRACT_ADDRESSES } from "../lib/contracts";
9+import { CONTRACT_ADDRESSES } from '../lib/contracts';
10−import { NETWORK_NAMES, renderNetworkType } from "../lib/network";
10+import { NETWORK_NAMES, renderNetworkType } from '../lib/network';
11−import { ROUTE_NAMES } from "../lib/routeNames";
11+import { ROUTE_NAMES } from '../lib/routeNames';
12−import { withHistory } from "../store/history";
12+import { withHistory } from '../store/history';
13
13
14class Network extends React.Component {
14class Network extends React.Component {
15 constructor(props) {
15 constructor(props) {
@@ -24,7 +24,7 @@ class Network extends React.Component {
24 if (network === NETWORK_NAMES.LOCAL) {
24 if (network === NETWORK_NAMES.LOCAL) {
25 setNetworkType(network);
25 setNetworkType(network);
26
26
27− const endpoint = "ws://localhost:8545";
27+ const endpoint = 'ws://localhost:8545';
28 const provider = new Web3.providers.WebsocketProvider(endpoint);
28 const provider = new Web3.providers.WebsocketProvider(endpoint);
29 const web3 = new Web3(provider);
29 const web3 = new Web3(provider);
30 const contracts = azimuth.initContracts(web3, CONTRACT_ADDRESSES.DEV);
30 const contracts = azimuth.initContracts(web3, CONTRACT_ADDRESSES.DEV);
@@ -35,9 +35,7 @@ class Network extends React.Component {
35 if (network === NETWORK_NAMES.ROPSTEN) {
35 if (network === NETWORK_NAMES.ROPSTEN) {
36 setNetworkType(network);
36 setNetworkType(network);
37
37
38− const endpoint = `https://ropsten.infura.io/v3/${
38+ const endpoint = `https://ropsten.infura.io/v3/${process.env.REACT_APP_INFURA_ENDPOINT}`;
39− process.env.REACT_APP_INFURA_ENDPOINT
40− }`;
41
39
42 const provider = new Web3.providers.HttpProvider(endpoint);
40 const provider = new Web3.providers.HttpProvider(endpoint);
43 const web3 = new Web3(provider);
41 const web3 = new Web3(provider);
@@ -49,9 +47,7 @@ class Network extends React.Component {
49 if (network === NETWORK_NAMES.MAINNET) {
47 if (network === NETWORK_NAMES.MAINNET) {
50 setNetworkType(network);
48 setNetworkType(network);
51
49
52− const endpoint = `https://mainnet.infura.io/v3/${
50+ const endpoint = `https://mainnet.infura.io/v3/${process.env.REACT_APP_INFURA_ENDPOINT}`;
53− process.env.REACT_APP_INFURA_ENDPOINT
54− }`;
55
51
56 const provider = new Web3.providers.HttpProvider(endpoint);
52 const provider = new Web3.providers.HttpProvider(endpoint);
57 const web3 = new Web3(provider);
53 const web3 = new Web3(provider);
@@ -74,11 +70,11 @@ class Network extends React.Component {
74
70
75 // Note: localhost:3456 doesn't actually point to anything, we just need
71 // Note: localhost:3456 doesn't actually point to anything, we just need
76 // a provider to initialize the Web3 object
72 // a provider to initialize the Web3 object
77− const provider = new Web3.providers.HttpProvider("http://localhost:3456");
73+ const provider = new Web3.providers.HttpProvider('http://localhost:3456');
78 const web3 = new Web3(provider);
74 const web3 = new Web3(provider);
79
75
80 const target =
76 const target =
81− process.env.NODE_ENV === "development"
77+ process.env.NODE_ENV === 'development'
82 ? CONTRACT_ADDRESSES.DEV
78 ? CONTRACT_ADDRESSES.DEV
83 : CONTRACT_ADDRESSES.MAINNET;
79 : CONTRACT_ADDRESSES.MAINNET;
84
80
@@ -91,22 +87,22 @@ class Network extends React.Component {
91 getNetworkOptions() {
87 getNetworkOptions() {
92 return [
88 return [
93 {
89 {
94− title: "Main Network (default)",
90+ title: 'Main Network (default)',
95 value: NETWORK_NAMES.MAINNET,
91 value: NETWORK_NAMES.MAINNET,
96 },
92 },
97 {
93 {
98− title: "Local Node",
94+ title: 'Local Node',
99 value: NETWORK_NAMES.LOCAL,
95 value: NETWORK_NAMES.LOCAL,
100 },
96 },
101 {
97 {
102− title: "Ropsten",
98+ title: 'Ropsten',
103 value: NETWORK_NAMES.ROPSTEN,
99 value: NETWORK_NAMES.ROPSTEN,
104 },
100 },
105 {
101 {
106− type: "divider",
102+ type: 'divider',
107 },
103 },
108 {
104 {
109− title: "Offline",
105+ title: 'Offline',
110 value: NETWORK_NAMES.OFFLINE,
106 value: NETWORK_NAMES.OFFLINE,
111 },
107 },
112 ];
108 ];
@@ -119,27 +115,26 @@ class Network extends React.Component {
119 return (
115 return (
120 <Row>
116 <Row>
121 <Col>
117 <Col>
122− <H1>{"Select Network"}</H1>
118+ <H1>{'Select Network'}</H1>
123
119
124 <P>
120 <P>
125 {"Please select the Ethereum node you'd like to send " +
121 {"Please select the Ethereum node you'd like to send " +
126− "transactions to. For highly valuable keys, please select " +
122+ 'transactions to. For highly valuable keys, please select ' +
127− "offline mode."}
123+ 'offline mode.'}
128 </P>
124 </P>
129
125
130 <InnerLabelDropdown
126 <InnerLabelDropdown
131− className={"mt-6"}
127+ className={'mt-6'}
132− title={"Node:"}
128+ title={'Node:'}
133 handleUpdate={this.handleNetworkChange}
129 handleUpdate={this.handleNetworkChange}
134 options={networkOptions}
130 options={networkOptions}
135 currentSelectionTitle={renderNetworkType(networkType)}
131 currentSelectionTitle={renderNetworkType(networkType)}
136 />
132 />
137
133
138 <Button
134 <Button
139− className={"mt-10"}
135+ className={'mt-10'}
140− onClick={() => history.push(ROUTE_NAMES.WALLET)}
136+ onClick={() => history.push(ROUTE_NAMES.WALLET)}>
141− >
142− {"Continue →"}
137+ {'Continue →'}
143 </Button>
138 </Button>
144 </Col>
139 </Col>
145 </Row>
140 </Row>
src/bridge/views/Point.js+17−17
@@ -1,16 +1,16 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { pour } from "sigil-js";
3+import { pour } from 'sigil-js';
4−import * as ob from "urbit-ob";
4+import * as ob from 'urbit-ob';
5−import * as azimuth from "azimuth-js";
5+import * as azimuth from 'azimuth-js';
6−import * as need from "../lib/need";
6+import * as need from '../lib/need';
7−
7+
8−import PointList from "../components/PointList";
8+import PointList from '../components/PointList';
9−import ReactSVGComponents from "../components/ReactSVGComponents";
9+import ReactSVGComponents from '../components/ReactSVGComponents';
10−import KeysAndMetadata from "./Point/KeysAndMetadata";
10+import KeysAndMetadata from './Point/KeysAndMetadata';
11−import Actions from "./Point/Actions";
11+import Actions from './Point/Actions';
12−import { Row, Col, H1, H3 } from "../components/Base";
12+import { Row, Col, H1, H3 } from '../components/Base';
13−import { withHistory } from "../store/history";
13+import { withHistory } from '../store/history';
14
14
15class Point extends React.Component {
15class Point extends React.Component {
16 constructor(props) {
16 constructor(props) {
@@ -55,8 +55,8 @@ class Point extends React.Component {
55 .getTotalUsableInvites(ctrcs, point)
55 .getTotalUsableInvites(ctrcs, point)
56 .then(count => this.setState({ invites: Just(count) }));
56 .then(count => this.setState({ invites: Just(count) }));
57 this.updateSpawned(ctrcs, point);
57 this.updateSpawned(ctrcs, point);
58− }),
58+ })
59− ),
59+ )
60 );
60 );
61 }
61 }
62
62
@@ -100,7 +100,7 @@ class Point extends React.Component {
100 <div />
100 <div />
101 ) : (
101 ) : (
102 <div>
102 <div>
103− <H3>{"Issued Points"}</H3>
103+ <H3>{'Issued Points'}</H3>
104
104
105 <PointList
105 <PointList
106 setPointCursor={setPointCursor}
106 setPointCursor={setPointCursor}
@@ -113,7 +113,7 @@ class Point extends React.Component {
113 return (
113 return (
114 <Row>
114 <Row>
115 <Col>
115 <Col>
116− <div className={"mt-12 pt-6"}>{sigil}</div>
116+ <div className={'mt-12 pt-6'}>{sigil}</div>
117 <H1>
117 <H1>
118 <code>{name}</code>
118 <code>{name}</code>
119 </H1>
119 </H1>
src/bridge/views/Point/Actions.js+55−65
@@ -1,12 +1,12 @@
1−import React from "react";
1+import React from 'react';
2−import { azimuth } from "azimuth-js";
2+import { azimuth } from 'azimuth-js';
3−import * as need from "../../lib/need";
3+import * as need from '../../lib/need';
4
4
5−import { ETH_ZERO_ADDR, CURVE_ZERO_ADDR, eqAddr } from "../../lib/wallet";
5+import { ETH_ZERO_ADDR, CURVE_ZERO_ADDR, eqAddr } from '../../lib/wallet';
6−import { Row, Col, H2, P } from "../../components/Base";
6+import { Row, Col, H2, P } from '../../components/Base';
7−import { Button } from "../../components/Base";
7+import { Button } from '../../components/Base';
8−import { ROUTE_NAMES } from "../../lib/routeNames";
8+import { ROUTE_NAMES } from '../../lib/routeNames';
9−import { useHistory } from "../../store/history";
9+import { useHistory } from '../../store/history';
10
10
11const isPlanet = point =>
11const isPlanet = point =>
12 azimuth.getPointSize(point) === azimuth.PointSize.Planet;
12 azimuth.getPointSize(point) === azimuth.PointSize.Planet;
@@ -106,16 +106,15 @@ function Actions(props) {
106 inviteAction = (
106 inviteAction = (
107 <Button
107 <Button
108 disabled={!isActiveOwner || !online || !hasInvites}
108 disabled={!isActiveOwner || !online || !hasInvites}
109− prop-size={"sm"}
109+ prop-size={'sm'}
110− prop-type={"link"}
110+ prop-type={'link'}
111− onClick={() => history.push(ROUTE_NAMES.INVITES_SEND)}
111+ onClick={() => history.push(ROUTE_NAMES.INVITES_SEND)}>
112− >
113− {"Send invites ("}
112+ {'Send invites ('}
114 {invites.matchWith({
113 {invites.matchWith({
115− Nothing: () => "?",
114+ Nothing: () => '?',
116 Just: count => count.value,
115 Just: count => count.value,
117 })}
116 })}
118− {")"}
117+ {')'}
119 </Button>
118 </Button>
120 );
119 );
121 }
120 }
@@ -123,118 +122,109 @@ function Actions(props) {
123 inviteAction = (
122 inviteAction = (
124 <Button
123 <Button
125 disabled={!(isActiveOwner && canIssueChild) || !online}
124 disabled={!(isActiveOwner && canIssueChild) || !online}
126− prop-size={"sm"}
125+ prop-size={'sm'}
127− prop-type={"link"}
126+ prop-type={'link'}
128 onClick={() => {
127 onClick={() => {
129 history.push(ROUTE_NAMES.INVITES_MANAGE);
128 history.push(ROUTE_NAMES.INVITES_MANAGE);
130− }}
129+ }}>
131− >
132− {"Manage invites"}
130+ {'Manage invites'}
133 </Button>
131 </Button>
134 );
132 );
135 }
133 }
136
134
137 return (
135 return (
138 <div>
136 <div>
139− <H2>{"Actions"}</H2>
137+ <H2>{'Actions'}</H2>
140 {displayReminder ? (
138 {displayReminder ? (
141 <P>{`Before you can issue child points or generate your Arvo
139 <P>{`Before you can issue child points or generate your Arvo
142 keyfile, you need to set your public keys.`}</P>
140 keyfile, you need to set your public keys.`}</P>
143 ) : (
141 ) : (
144− ""
142+ ''
145 )}
143 )}
146 <Row>
144 <Row>
147− <Col className={"flex flex-column items-start col-md-4"}>
145+ <Col className={'flex flex-column items-start col-md-4'}>
148 <Button
146 <Button
149− prop-size={"sm"}
147+ prop-size={'sm'}
150− prop-type={"link"}
148+ prop-type={'link'}
151 disabled={(online || planet) && !canIssueChild}
149 disabled={(online || planet) && !canIssueChild}
152 onClick={() => {
150 onClick={() => {
153 history.push(ROUTE_NAMES.ISSUE_CHILD);
151 history.push(ROUTE_NAMES.ISSUE_CHILD);
154− }}
152+ }}>
155− >
156− {"Issue child"}
153+ {'Issue child'}
157 </Button>
154 </Button>
158
155
159 <Button
156 <Button
160− prop-size={"sm"}
157+ prop-size={'sm'}
161− prop-type={"link"}
158+ prop-type={'link'}
162 disabled={online && !canAcceptTransfer}
159 disabled={online && !canAcceptTransfer}
163 onClick={() => {
160 onClick={() => {
164 history.push(ROUTE_NAMES.ACCEPT_TRANSFER);
161 history.push(ROUTE_NAMES.ACCEPT_TRANSFER);
165− }}
162+ }}>
166− >
167− {"Accept incoming transfer"}
163+ {'Accept incoming transfer'}
168 </Button>
164 </Button>
169
165
170 <Button
166 <Button
171− prop-size={"sm"}
167+ prop-size={'sm'}
172− prop-type={"link"}
168+ prop-type={'link'}
173 disabled={online && !canCancelTransfer}
169 disabled={online && !canCancelTransfer}
174 onClick={() => {
170 onClick={() => {
175 history.push(ROUTE_NAMES.CANCEL_TRANSFER);
171 history.push(ROUTE_NAMES.CANCEL_TRANSFER);
176− }}
172+ }}>
177− >
178− {"Cancel outgoing transfer"}
173+ {'Cancel outgoing transfer'}
179 </Button>
174 </Button>
180
175
181 <Button
176 <Button
182− prop-size={"sm"}
177+ prop-size={'sm'}
183− prop-type={"link"}
178+ prop-type={'link'}
184 disabled={online && !canGenKeyfile}
179 disabled={online && !canGenKeyfile}
185 onClick={() => {
180 onClick={() => {
186 history.push(ROUTE_NAMES.GEN_KEYFILE);
181 history.push(ROUTE_NAMES.GEN_KEYFILE);
187− }}
182+ }}>
188− >
189− {"Generate Arvo keyfile"}
183+ {'Generate Arvo keyfile'}
190 </Button>
184 </Button>
191 </Col>
185 </Col>
192− <Col className={"flex flex-column items-start col-md-4"}>
186+ <Col className={'flex flex-column items-start col-md-4'}>
193 <Button
187 <Button
194 disabled={online && !canSetSpawnProxy}
188 disabled={online && !canSetSpawnProxy}
195− prop-size={"sm"}
189+ prop-size={'sm'}
196− prop-type={"link"}
190+ prop-type={'link'}
197 onClick={() => {
191 onClick={() => {
198 history.push(ROUTE_NAMES.SET_SPAWN_PROXY);
192 history.push(ROUTE_NAMES.SET_SPAWN_PROXY);
199− }}
193+ }}>
200− >
201− {"Change spawn proxy"}
194+ {'Change spawn proxy'}
202 </Button>
195 </Button>
203
196
204 <Button
197 <Button
205 disabled={online && !canSetManagementProxy}
198 disabled={online && !canSetManagementProxy}
206− prop-size={"sm"}
199+ prop-size={'sm'}
207− prop-type={"link"}
200+ prop-type={'link'}
208 onClick={() => {
201 onClick={() => {
209 history.push(ROUTE_NAMES.SET_MANAGEMENT_PROXY);
202 history.push(ROUTE_NAMES.SET_MANAGEMENT_PROXY);
210− }}
203+ }}>
211− >
212− {"Change management proxy"}
204+ {'Change management proxy'}
213 </Button>
205 </Button>
214
206
215 <Button
207 <Button
216 disabled={online && !canConfigureKeys}
208 disabled={online && !canConfigureKeys}
217− prop-size={"sm"}
209+ prop-size={'sm'}
218− prop-type={"link"}
210+ prop-type={'link'}
219 onClick={() => {
211 onClick={() => {
220 history.push(ROUTE_NAMES.SET_KEYS);
212 history.push(ROUTE_NAMES.SET_KEYS);
221− }}
213+ }}>
222− >
223− {"Set network keys"}
214+ {'Set network keys'}
224 </Button>
215 </Button>
225
216
226 <Button
217 <Button
227 disabled={online && !canTransfer}
218 disabled={online && !canTransfer}
228− prop-size={"sm"}
219+ prop-size={'sm'}
229− prop-type={"link"}
220+ prop-type={'link'}
230 onClick={() => {
221 onClick={() => {
231 history.push(ROUTE_NAMES.TRANSFER);
222 history.push(ROUTE_NAMES.TRANSFER);
232− }}
223+ }}>
233− >
234− {"Transfer"}
224+ {'Transfer'}
235 </Button>
225 </Button>
236 </Col>
226 </Col>
237− <Col className={"flex flex-column items-start col-md-4"}>
227+ <Col className={'flex flex-column items-start col-md-4'}>
238 {inviteAction}
228 {inviteAction}
239 </Col>
229 </Col>
240 </Row>
230 </Row>
src/bridge/views/Points.js+30−32
@@ -1,13 +1,13 @@
1−import React from "react";
1+import React from 'react';
2−import { Row, Col, H1, H2, P } from "../components/Base";
2+import { Row, Col, H1, H2, P } from '../components/Base';
3−import { Button } from "../components/Base";
3+import { Button } from '../components/Base';
4−import * as azimuth from "azimuth-js";
4+import * as azimuth from 'azimuth-js';
5
5
6−import PointList from "../components/PointList";
6+import PointList from '../components/PointList';
7−import { NETWORK_NAMES } from "../lib/network";
7+import { NETWORK_NAMES } from '../lib/network';
8−import { ROUTE_NAMES } from "../lib/routeNames";
8+import { ROUTE_NAMES } from '../lib/routeNames';
9−import { withHistory } from "../store/history";
9+import { withHistory } from '../store/history';
10−import { ETH_ZERO_ADDR, eqAddr } from "../lib/wallet";
10+import { ETH_ZERO_ADDR, eqAddr } from '../lib/wallet';
11
11
12const hasTransferProxy = (cache, point) =>
12const hasTransferProxy = (cache, point) =>
13 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
13 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
@@ -42,7 +42,7 @@ class Points extends React.Component {
42
42
43 const incoming = await azimuth.azimuth.getTransferringFor(
43 const incoming = await azimuth.azimuth.getTransferringFor(
44 ctrcs,
44 ctrcs,
45− addr,
45+ addr
46 );
46 );
47
47
48 const managing = await azimuth.azimuth.getManagerFor(ctrcs, addr);
48 const managing = await azimuth.azimuth.getManagerFor(ctrcs, addr);
@@ -66,8 +66,8 @@ class Points extends React.Component {
66 });
66 });
67
67
68 this.cachePoints(ctrcs, addToPointCache, points);
68 this.cachePoints(ctrcs, addToPointCache, points);
69− }),
69+ })
70− ),
70+ )
71 );
71 );
72 }
72 }
73
73
@@ -97,13 +97,12 @@ class Points extends React.Component {
97 <Row>
97 <Row>
98 <Col>
98 <Col>
99 <Button
99 <Button
100− prop-type={"link"}
100+ prop-type={'link'}
101− prop-size={"md"}
101+ prop-size={'md'}
102− onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}
102+ onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
103− >
104− {"View a point →"}
103+ {'View a point →'}
105 </Button>
104 </Button>
106− <P>{"View a point on Azimuth."}</P>
105+ <P>{'View a point on Azimuth.'}</P>
107 </Col>
106 </Col>
108 </Row>
107 </Row>
109 );
108 );
@@ -115,15 +114,14 @@ class Points extends React.Component {
115 <Row>
114 <Row>
116 <Col>
115 <Col>
117 <Button
116 <Button
118− prop-type={"link"}
117+ prop-type={'link'}
119− prop-size={"md"}
118+ prop-size={'md'}
120− onClick={() => history.push(ROUTE_NAMES.CREATE_GALAXY)}
119+ onClick={() => history.push(ROUTE_NAMES.CREATE_GALAXY)}>
121− >
122− {"Create a galaxy →"}
120+ {'Create a galaxy →'}
123 </Button>
121 </Button>
124 <P>
122 <P>
125 {
123 {
126− "You have the authority to create a new Galaxy and you can do so here."
124+ 'You have the authority to create a new Galaxy and you can do so here.'
127 }
125 }
128 </P>
126 </P>
129 </Col>
127 </Col>
@@ -131,13 +129,13 @@ class Points extends React.Component {
131 );
129 );
132
130
133 const outgoing = points.filter(point =>
131 const outgoing = points.filter(point =>
134− hasTransferProxy(pointCache, point),
132+ hasTransferProxy(pointCache, point)
135 );
133 );
136
134
137 const outgoingPoints =
135 const outgoingPoints =
138 outgoing.length !== 0 ? (
136 outgoing.length !== 0 ? (
139 <React.Fragment>
137 <React.Fragment>
140− <H2>{"Outgoing Transfers"}</H2>
138+ <H2>{'Outgoing Transfers'}</H2>
141 <P>
139 <P>
142 {`You own these points until the recipient accepts the incoming
140 {`You own these points until the recipient accepts the incoming
143 transfer. You may cancel the transfer until accepted.`}
141 transfer. You may cancel the transfer until accepted.`}
@@ -155,7 +153,7 @@ class Points extends React.Component {
155 const incomingPoints =
153 const incomingPoints =
156 incoming.length !== 0 ? (
154 incoming.length !== 0 ? (
157 <React.Fragment>
155 <React.Fragment>
158− <H2>{"Incoming Transfers"}</H2>
156+ <H2>{'Incoming Transfers'}</H2>
159 <P>
157 <P>
160 {`You do not own these points until you accept the incoming transfer.
158 {`You do not own these points until you accept the incoming transfer.
161 You may reject any incoming transfers.`}
159 You may reject any incoming transfers.`}
@@ -173,7 +171,7 @@ class Points extends React.Component {
173 const managingPoints =
171 const managingPoints =
174 managing.length !== 0 ? (
172 managing.length !== 0 ? (
175 <React.Fragment>
173 <React.Fragment>
176− <H2>{"You Are a Management Proxy For"}</H2>
174+ <H2>{'You Are a Management Proxy For'}</H2>
177 <P>
175 <P>
178 {`You can configure or set network keys and conduct sponsorship
176 {`You can configure or set network keys and conduct sponsorship
179 related operations for these points.`}
177 related operations for these points.`}
@@ -191,7 +189,7 @@ class Points extends React.Component {
191 const votingPoints =
189 const votingPoints =
192 voting.length !== 0 ? (
190 voting.length !== 0 ? (
193 <React.Fragment>
191 <React.Fragment>
194− <H2>{"You Are a Voting Proxy For"}</H2>
192+ <H2>{'You Are a Voting Proxy For'}</H2>
195 <P>
193 <P>
196 {`Since you are part of the Galactic Senate, you can cast votes on
194 {`Since you are part of the Galactic Senate, you can cast votes on
197 new Azimuth proposals on behalf of these points.`}
195 new Azimuth proposals on behalf of these points.`}
@@ -209,7 +207,7 @@ class Points extends React.Component {
209 const spawningPoints =
207 const spawningPoints =
210 spawning.length !== 0 ? (
208 spawning.length !== 0 ? (
211 <React.Fragment>
209 <React.Fragment>
212− <H2>{"You Are a Spawn Proxy For"}</H2>
210+ <H2>{'You Are a Spawn Proxy For'}</H2>
213 <P>{`You can create new child ships under these points.`}</P>
211 <P>{`You can create new child ships under these points.`}</P>
214 <PointList
212 <PointList
215 setPointCursor={setPointCursor}
213 setPointCursor={setPointCursor}
@@ -224,7 +222,7 @@ class Points extends React.Component {
224 return (
222 return (
225 <Row>
223 <Row>
226 <Col>
224 <Col>
227− <H1>{"Points"}</H1>
225+ <H1>{'Points'}</H1>
228
226
229 <P>{`A point is an identity on the Ethereum blockchain.
227 <P>{`A point is an identity on the Ethereum blockchain.
230 Points declare keys for ships on the Arvo network.`}</P>
228 Points declare keys for ships on the Arvo network.`}</P>
@@ -237,7 +235,7 @@ class Points extends React.Component {
237
235
238 {outgoingPoints}
236 {outgoingPoints}
239
237
240− <H2>{"Your Points"}</H2>
238+ <H2>{'Your Points'}</H2>
241
239
242 <PointList
240 <PointList
243 setPointCursor={setPointCursor}
241 setPointCursor={setPointCursor}
src/bridge/views/PrivateKey.js+18−20
@@ -1,19 +1,19 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Button } from "../components/Base";
3+import { Button } from '../components/Base';
4−import { RequiredInput, InnerLabel, InputCaption } from "../components/Base";
4+import { RequiredInput, InnerLabel, InputCaption } from '../components/Base';
5−import { Row, Col, H1 } from "../components/Base";
5+import { Row, Col, H1 } from '../components/Base';
6
6
7−import { ROUTE_NAMES } from "../lib/routeNames";
7+import { ROUTE_NAMES } from '../lib/routeNames';
8−import { withHistory } from "../store/history";
8+import { withHistory } from '../store/history';
9−import { EthereumWallet } from "../lib/wallet";
9+import { EthereumWallet } from '../lib/wallet';
10
10
11class PrivateKey extends React.Component {
11class PrivateKey extends React.Component {
12 constructor(props) {
12 constructor(props) {
13 super(props);
13 super(props);
14
14
15 this.state = {
15 this.state = {
16− privateKey: "",
16+ privateKey: '',
17 };
17 };
18
18
19 this.handlePrivateKeyInput = this.handlePrivateKeyInput.bind(this);
19 this.handlePrivateKeyInput = this.handlePrivateKeyInput.bind(this);
@@ -27,7 +27,7 @@ class PrivateKey extends React.Component {
27 constructWallet(privateKey) {
27 constructWallet(privateKey) {
28 const { setWallet } = this.props;
28 const { setWallet } = this.props;
29 if (/^[0-9A-Fa-f]{64}$/g.test(privateKey) === true) {
29 if (/^[0-9A-Fa-f]{64}$/g.test(privateKey) === true) {
30− const sec = Buffer.from(privateKey, "hex");
30+ const sec = Buffer.from(privateKey, 'hex');
31 const wallet = new EthereumWallet(sec);
31 const wallet = new EthereumWallet(sec);
32 setWallet(Maybe.Just(wallet));
32 setWallet(Maybe.Just(wallet));
33 } else {
33 } else {
@@ -41,8 +41,8 @@ class PrivateKey extends React.Component {
41
41
42 return (
42 return (
43 <Row>
43 <Row>
44− <Col className={"measure-md"}>
44+ <Col className={'measure-md'}>
45− <H1 className={"mb-4"}>{"Enter Your Private Key"}</H1>
45+ <H1 className={'mb-4'}>{'Enter Your Private Key'}</H1>
46 <InputCaption>
46 <InputCaption>
47 {`Please enter your raw Ethereum private key here.`}
47 {`Please enter your raw Ethereum private key here.`}
48 </InputCaption>
48 </InputCaption>
@@ -56,18 +56,16 @@ class PrivateKey extends React.Component {
56 onChange={this.handlePrivateKeyInput}
56 onChange={this.handlePrivateKeyInput}
57 value={privateKey}
57 value={privateKey}
58 autocomplete="off"
58 autocomplete="off"
59− autoFocus
59+ autoFocus>
60− >
61− <InnerLabel>{"Private Key"}</InnerLabel>
60+ <InnerLabel>{'Private Key'}</InnerLabel>
62 </RequiredInput>
61 </RequiredInput>
63
62
64 <Button
63 <Button
65− className={"mt-10"}
64+ className={'mt-10'}
66− prop-size={"wide lg"}
65+ prop-size={'wide lg'}
67 disabled={Maybe.Nothing.hasInstance(wallet)}
66 disabled={Maybe.Nothing.hasInstance(wallet)}
68− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
67+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
69− >
70− {"Continue →"}
68+ {'Continue →'}
71 </Button>
69 </Button>
72 </Col>
70 </Col>
73 </Row>
71 </Row>
src/bridge/views/SentTransaction.js+34−37
@@ -1,27 +1,27 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as need from "../lib/need";
3+import * as need from '../lib/need';
4−import { Row, Col, H1, H3, P, Warning, Anchor } from "../components/Base";
4+import { Row, Col, H1, H3, P, Warning, Anchor } from '../components/Base';
5−import { Button } from "../components/Base";
5+import { Button } from '../components/Base';
6−
6+
7−import { ROUTE_NAMES } from "../lib/routeNames";
7+import { ROUTE_NAMES } from '../lib/routeNames';
8−import { useHistory } from "../store/history";
8+import { useHistory } from '../store/history';
9−import { BRIDGE_ERROR, renderTxnError } from "../lib/error";
9+import { BRIDGE_ERROR, renderTxnError } from '../lib/error';
10−import { NETWORK_NAMES } from "../lib/network";
10+import { NETWORK_NAMES } from '../lib/network';
11−import { withTxnConfirmations } from "../store/txnConfirmations";
11+import { withTxnConfirmations } from '../store/txnConfirmations';
12
12
13class Success extends React.Component {
13class Success extends React.Component {
14 constructor(props) {
14 constructor(props) {
15 super(props);
15 super(props);
16
16
17 this.state = {
17 this.state = {
18− pending: ".",
18+ pending: '.',
19 interval: null,
19 interval: null,
20 };
20 };
21 }
21 }
22
22
23 componentDidMount() {
23 componentDidMount() {
24− const nextDot = { ".": "..", "..": "...", "...": "." };
24+ const nextDot = { '.': '..', '..': '...', '...': '.' };
25
25
26 const interval = setInterval(() => {
26 const interval = setInterval(() => {
27 this.setState(({ pending }) => ({ pending: nextDot[pending] }));
27 this.setState(({ pending }) => ({ pending: nextDot[pending] }));
@@ -44,28 +44,27 @@ class Success extends React.Component {
44
44
45 const esdomain =
45 const esdomain =
46 networkType === NETWORK_NAMES.ROPSTEN
46 networkType === NETWORK_NAMES.ROPSTEN
47− ? "ropsten.etherscan.io"
47+ ? 'ropsten.etherscan.io'
48− : "etherscan.io";
48+ : 'etherscan.io';
49
49
50 const esmessage =
50 const esmessage =
51 esvisible === true
51 esvisible === true
52− ? "If you’d like to keep track of it, click the Etherscan link below."
52+ ? 'If you’d like to keep track of it, click the Etherscan link below.'
53− : "";
53+ : '';
54
54
55 const esanchor =
55 const esanchor =
56 esvisible === false ? null : (
56 esvisible === false ? null : (
57 <Anchor
57 <Anchor
58− className={"mb-4 mt-1"}
58+ className={'mb-4 mt-1'}
59− prop-size={"sm"}
59+ prop-size={'sm'}
60− target={"_blank"}
60+ target={'_blank'}
61− href={`https://${esdomain}/tx/${hash}`}
61+ href={`https://${esdomain}/tx/${hash}`}>
62− >
63− {"View on Etherscan ↗"}
62+ {'View on Etherscan ↗'}
64 </Anchor>
63 </Anchor>
65 );
64 );
66
65
67 const confirmations = Maybe.fromNullable(txnConfirmations[hash]).getOrElse(
66 const confirmations = Maybe.fromNullable(txnConfirmations[hash]).getOrElse(
68− 0,
67+ 0
69 );
68 );
70
69
71 const requiredConfirmations = 1;
70 const requiredConfirmations = 1;
@@ -78,17 +77,17 @@ class Success extends React.Component {
78 return (
77 return (
79 <Row>
78 <Row>
80 <Col>
79 <Col>
81− <H1>{"Your Transaction was Sent"}</H1>
80+ <H1>{'Your Transaction was Sent'}</H1>
82
81
83 <P>
82 <P>
84 {`We sent your transaction to the chain. It can take some time to
83 {`We sent your transaction to the chain. It can take some time to
85 execute, especially if the network is busy. ${esmessage}`}
84 execute, especially if the network is busy. ${esmessage}`}
86 </P>
85 </P>
87
86
88− <H3>{"Transaction Hash"}</H3>
87+ <H3>{'Transaction Hash'}</H3>
89 <P>{hash}</P>
88 <P>{hash}</P>
90
89
91− <H3>{"Transaction Status"}</H3>
90+ <H3>{'Transaction Status'}</H3>
92 <P>{status}</P>
91 <P>{status}</P>
93 <P>{esanchor}</P>
92 <P>{esanchor}</P>
94 </Col>
93 </Col>
@@ -100,10 +99,10 @@ class Success extends React.Component {
100const Failure = props => (
99const Failure = props => (
101 <Row>
100 <Row>
102 <Col>
101 <Col>
103− <H1>{"Error!"}</H1>
102+ <H1>{'Error!'}</H1>
104
103
105 <Warning>
104 <Warning>
106− <H3>{"There was an error sending your transaction."}</H3>
105+ <H3>{'There was an error sending your transaction.'}</H3>
107 {renderTxnError(props.web3, props.message)}
106 {renderTxnError(props.web3, props.message)}
108 </Warning>
107 </Warning>
109 </Col>
108 </Col>
@@ -141,13 +140,12 @@ const SentTransaction = props => {
141 <Row>
140 <Row>
142 <Col>
141 <Col>
143 <Button
142 <Button
144− prop-type={"link"}
143+ prop-type={'link'}
145 onClick={() => {
144 onClick={() => {
146 setPointCursor(pointCursor);
145 setPointCursor(pointCursor);
147 history.pop();
146 history.pop();
148− }}
147+ }}>
149− >
150− {"Ok →"}
148+ {'Ok →'}
151 </Button>
149 </Button>
152 </Col>
150 </Col>
153 </Row>
151 </Row>
@@ -160,10 +158,9 @@ const SentTransaction = props => {
160 <Row>
158 <Row>
161 <Col>
159 <Col>
162 <Button
160 <Button
163− prop-type={"link"}
161+ prop-type={'link'}
164− onClick={() => history.popAndPush(ROUTE_NAMES.GEN_KEYFILE)}
162+ onClick={() => history.popAndPush(ROUTE_NAMES.GEN_KEYFILE)}>
165− >
166− {"Download Keyfile →"}
163+ {'Download Keyfile →'}
167 </Button>
164 </Button>
168 </Col>
165 </Col>
169 </Row>
166 </Row>
src/bridge/views/SetKeys.js+36−36
@@ -1,16 +1,16 @@
1−import React from "react";
1+import React from 'react';
2−import Maybe from "folktale/maybe";
2+import Maybe from 'folktale/maybe';
3−import * as azimuth from "azimuth-js";
3+import * as azimuth from 'azimuth-js';
4−import * as ob from "urbit-ob";
4+import * as ob from 'urbit-ob';
5−import * as need from "../lib/need";
5+import * as need from '../lib/need';
6−import { Row, Col, H1, P, Warning, CheckboxButton } from "../components/Base";
6+import { Row, Col, H1, P, Warning, CheckboxButton } from '../components/Base';
7
7
8−import StatelessTransaction from "../components/StatelessTransaction";
8+import StatelessTransaction from '../components/StatelessTransaction';
9−import { attemptSeedDerivation } from "../lib/keys";
9+import { attemptSeedDerivation } from '../lib/keys';
10
10
11−import * as kg from "urbit-key-generation/dist/index";
11+import * as kg from 'urbit-key-generation/dist/index';
12
12
13−import { addHexPrefix } from "../lib/wallet";
13+import { addHexPrefix } from '../lib/wallet';
14
14
15class SetKeys extends React.Component {
15class SetKeys extends React.Component {
16 constructor(props) {
16 constructor(props) {
@@ -19,9 +19,9 @@ class SetKeys extends React.Component {
19 const point = need.pointCursor(props);
19 const point = need.pointCursor(props);
20
20
21 this.state = {
21 this.state = {
22− auth: "",
22+ auth: '',
23− encr: "",
23+ encr: '',
24− networkSeed: "",
24+ networkSeed: '',
25 nondeterministicSeed: false,
25 nondeterministicSeed: false,
26 point: point,
26 point: point,
27 cryptoSuiteVersion: 1,
27 cryptoSuiteVersion: 1,
@@ -64,22 +64,22 @@ class SetKeys extends React.Component {
64 hex =
64 hex =
65 hex +
65 hex +
66 [
66 [
67− "0",
67+ '0',
68− "1",
68+ '1',
69− "2",
69+ '2',
70− "3",
70+ '3',
71− "4",
71+ '4',
72− "5",
72+ '5',
73− "6",
73+ '6',
74− "7",
74+ '7',
75− "8",
75+ '8',
76− "9",
76+ '9',
77− "A",
77+ 'A',
78− "B",
78+ 'B',
79− "C",
79+ 'C',
80− "D",
80+ 'D',
81− "E",
81+ 'E',
82− "F",
82+ 'F',
83 ][Math.floor(Math.random() * 16)];
83 ][Math.floor(Math.random() * 16)];
84 }
84 }
85
85
@@ -91,13 +91,13 @@ class SetKeys extends React.Component {
91 let seed = await attemptSeedDerivation(next, this.props);
91 let seed = await attemptSeedDerivation(next, this.props);
92 let nondeterministicSeed = false;
92 let nondeterministicSeed = false;
93
93
94− if (seed.getOrElse("") === "") {
94+ if (seed.getOrElse('') === '') {
95 seed = Maybe.Just(this.randomHex(64));
95 seed = Maybe.Just(this.randomHex(64));
96 nondeterministicSeed = true;
96 nondeterministicSeed = true;
97 }
97 }
98
98
99 this.setState({
99 this.setState({
100− networkSeed: seed.getOrElse(""),
100+ networkSeed: seed.getOrElse(''),
101 nondeterministicSeed: nondeterministicSeed,
101 nondeterministicSeed: nondeterministicSeed,
102 });
102 });
103 }
103 }
@@ -124,7 +124,7 @@ class SetKeys extends React.Component {
124 pencr,
124 pencr,
125 pauth,
125 pauth,
126 1,
126 1,
127− state.discontinuity,
127+ state.discontinuity
128 );
128 );
129
129
130 return Maybe.Just(txn);
130 return Maybe.Just(txn);
@@ -145,7 +145,7 @@ class SetKeys extends React.Component {
145 <Row>
145 <Row>
146 <Col>
146 <Col>
147 <H1>
147 <H1>
148− {"Set Network Keys For "} <code>{`${ob.patp(state.point)}`}</code>
148+ {'Set Network Keys For '} <code>{`${ob.patp(state.point)}`}</code>
149 </H1>
149 </H1>
150
150
151 <P className="mt-10">
151 <P className="mt-10">
@@ -154,7 +154,7 @@ class SetKeys extends React.Component {
154
154
155 {state.nondeterministicSeed && (
155 {state.nondeterministicSeed && (
156 <Warning>
156 <Warning>
157− <h3 className={"mb-2"}>{"Warning"}</h3>
157+ <h3 className={'mb-2'}>{'Warning'}</h3>
158 {`Your network seed could not be derived automatically. We've
158 {`Your network seed could not be derived automatically. We've
159 generated a random one for you, so you must download your Arvo
159 generated a random one for you, so you must download your Arvo
160 keyfile during this session after setting your keys.`}
160 keyfile during this session after setting your keys.`}
@@ -163,8 +163,8 @@ class SetKeys extends React.Component {
163
163
164 {pointDetails.keyRevisionNumber === 0 ? (
164 {pointDetails.keyRevisionNumber === 0 ? (
165 <Warning>
165 <Warning>
166− <h3 className={"mb-2"}>{"Warning"}</h3>
166+ <h3 className={'mb-2'}>{'Warning'}</h3>
167− {"Once these keys have been set, your point is considered " +
167+ {'Once these keys have been set, your point is considered ' +
168 "'linked'. This operation cannot be undone."}
168 "'linked'. This operation cannot be undone."}
169 </Warning>
169 </Warning>
170 ) : (
170 ) : (
src/bridge/views/SetProxy.js+29−31
@@ -1,7 +1,7 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as need from "../lib/need";
3+import * as need from '../lib/need';
4−import * as azimuth from "azimuth-js";
4+import * as azimuth from 'azimuth-js';
5import {
5import {
6 Row,
6 Row,
7 Col,
7 Col,
@@ -11,17 +11,17 @@ import {
11 ShowBlockie,
11 ShowBlockie,
12 Anchor,
12 Anchor,
13 HorizontalSelector,
13 HorizontalSelector,
14−} from "../components/Base";
14+} from '../components/Base';
15−import { AddressInput } from "../components/Base";
15+import { AddressInput } from '../components/Base';
16−import * as ob from "urbit-ob";
16+import * as ob from 'urbit-ob';
17
17
18−import { PROXY_TYPE, renderProxyType } from "../lib/proxy";
18+import { PROXY_TYPE, renderProxyType } from '../lib/proxy';
19
19
20−import { NETWORK_NAMES } from "../lib/network";
20+import { NETWORK_NAMES } from '../lib/network';
21
21
22−import StatelessTransaction from "../components/StatelessTransaction";
22+import StatelessTransaction from '../components/StatelessTransaction';
23
23
24−import { isValidAddress } from "../lib/wallet";
24+import { isValidAddress } from '../lib/wallet';
25
25
26const SetManagementProxy = props => (
26const SetManagementProxy = props => (
27 <SetProxy {...props} proxyType={PROXY_TYPE.MANAGEMENT_PROXY} />
27 <SetProxy {...props} proxyType={PROXY_TYPE.MANAGEMENT_PROXY} />
@@ -42,7 +42,7 @@ class SetProxy extends React.Component {
42 const issuingPoint = need.pointCursor(props);
42 const issuingPoint = need.pointCursor(props);
43
43
44 this.state = {
44 this.state = {
45− proxyAddress: "",
45+ proxyAddress: '',
46 issuingPoint: issuingPoint,
46 issuingPoint: issuingPoint,
47 setProxy: true,
47 setProxy: true,
48 };
48 };
@@ -54,10 +54,10 @@ class SetProxy extends React.Component {
54 }
54 }
55
55
56 handleSetUnset(selected) {
56 handleSetUnset(selected) {
57− const set = selected === "set";
57+ const set = selected === 'set';
58 this.setState({
58 this.setState({
59 setProxy: set,
59 setProxy: set,
60− proxyAddress: set ? "" : "0x0000000000000000000000000000000000000000",
60+ proxyAddress: set ? '' : '0x0000000000000000000000000000000000000000',
61 });
61 });
62 }
62 }
63
63
@@ -104,26 +104,26 @@ class SetProxy extends React.Component {
104
104
105 const esdomain =
105 const esdomain =
106 props.networkType === NETWORK_NAMES.ROPSTEN
106 props.networkType === NETWORK_NAMES.ROPSTEN
107− ? "ropsten.etherscan.io"
107+ ? 'ropsten.etherscan.io'
108− : "etherscan.io";
108+ : 'etherscan.io';
109
109
110 const ucFirst = w => w.charAt(0).toUpperCase() + w.slice(1);
110 const ucFirst = w => w.charAt(0).toUpperCase() + w.slice(1);
111
111
112 const setUnset = [
112 const setUnset = [
113− { title: "Set", value: "set" },
113+ { title: 'Set', value: 'set' },
114− { title: "Unset", value: "unset" },
114+ { title: 'Unset', value: 'unset' },
115 ];
115 ];
116
116
117− const titleVerb = this.state.setProxy ? "Set" : "Unset";
117+ const titleVerb = this.state.setProxy ? 'Set' : 'Unset';
118
118
119 let addressInput = null;
119 let addressInput = null;
120 if (this.state.setProxy) {
120 if (this.state.setProxy) {
121 addressInput = (
121 addressInput = (
122 <>
122 <>
123 <P className="mt-8">
123 <P className="mt-8">
124− {"Please provide an Ethereum address to act as the " +
124+ {'Please provide an Ethereum address to act as the ' +
125 `${renderedProxyType} proxy. You can also use Wallet ` +
125 `${renderedProxyType} proxy. You can also use Wallet ` +
126− "Generator to generate a keypair."}
126+ 'Generator to generate a keypair.'}
127 </P>
127 </P>
128
128
129 <AddressInput
129 <AddressInput
@@ -132,20 +132,18 @@ class SetProxy extends React.Component {
132 prop-format="innerLabel"
132 prop-format="innerLabel"
133 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
133 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
134 value={state.proxyAddress}
134 value={state.proxyAddress}
135− onChange={v => this.handleAddressInput(v)}
135+ onChange={v => this.handleAddressInput(v)}>
136− >
137− <InnerLabel>{"Proxy Address"}</InnerLabel>
136+ <InnerLabel>{'Proxy Address'}</InnerLabel>
138− <ShowBlockie className={"mt-1"} address={state.proxyAddress} />
137+ <ShowBlockie className={'mt-1'} address={state.proxyAddress} />
139 </AddressInput>
138 </AddressInput>
140
139
141 <Anchor
140 <Anchor
142− className={"mt-1"}
141+ className={'mt-1'}
143− prop-size={"sm"}
142+ prop-size={'sm'}
144 prop-disabled={!isValidAddress(state.proxyAddress) || !esvisible}
143 prop-disabled={!isValidAddress(state.proxyAddress) || !esvisible}
145− target={"_blank"}
144+ target={'_blank'}
146− href={`https://${esdomain}/address/${state.proxyAddress}`}
145+ href={`https://${esdomain}/address/${state.proxyAddress}`}>
147− >
148− {"View on Etherscan ↗"}
146+ {'View on Etherscan ↗'}
149 </Anchor>
147 </Anchor>
150 </>
148 </>
151 );
149 );
src/bridge/views/Shards.js+46−53
@@ -1,6 +1,6 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Button } from "../components/Base";
3+import { Button } from '../components/Base';
4import {
4import {
5 InnerLabel,
5 InnerLabel,
6 ValidatedSigil,
6 ValidatedSigil,
@@ -8,28 +8,28 @@ import {
8 ShardInput,
8 ShardInput,
9 InputCaption,
9 InputCaption,
10 Input,
10 Input,
11−} from "../components/Base";
11+} from '../components/Base';
12−import { Row, Col, H1, P } from "../components/Base";
12+import { Row, Col, H1, P } from '../components/Base';
13−import * as kg from "urbit-key-generation/dist/index";
13+import * as kg from 'urbit-key-generation/dist/index';
14−import * as ob from "urbit-ob";
14+import * as ob from 'urbit-ob';
15
15
16−import { ROUTE_NAMES } from "../lib/routeNames";
16+import { ROUTE_NAMES } from '../lib/routeNames';
17−import { withHistory } from "../store/history";
17+import { withHistory } from '../store/history';
18−import { urbitWalletFromTicket } from "../lib/wallet";
18+import { urbitWalletFromTicket } from '../lib/wallet';
19
19
20const placeholder = len => {
20const placeholder = len => {
21 let bytes = window.crypto.getRandomValues(new Uint8Array(len));
21 let bytes = window.crypto.getRandomValues(new Uint8Array(len));
22 let hex = bytes.reduce(
22 let hex = bytes.reduce(
23− (acc, byt) => acc + byt.toString(16).padStart(2, "0"),
23+ (acc, byt) => acc + byt.toString(16).padStart(2, '0'),
24− "",
24+ ''
25 );
25 );
26 return ob.hex2patq(hex);
26 return ob.hex2patq(hex);
27};
27};
28
28
29const SHARDS = {
29const SHARDS = {
30− SHARD1: Symbol("SHARD1"),
30+ SHARD1: Symbol('SHARD1'),
31− SHARD2: Symbol("SHARD2"),
31+ SHARD2: Symbol('SHARD2'),
32− SHARD3: Symbol("SHARD3"),
32+ SHARD3: Symbol('SHARD3'),
33};
33};
34
34
35class Shards extends React.Component {
35class Shards extends React.Component {
@@ -37,11 +37,11 @@ class Shards extends React.Component {
37 super(props);
37 super(props);
38
38
39 this.state = {
39 this.state = {
40− shard1: "",
40+ shard1: '',
41− shard2: "",
41+ shard2: '',
42− shard3: "",
42+ shard3: '',
43− passphrase: "",
43+ passphrase: '',
44− pointName: "",
44+ pointName: '',
45 };
45 };
46
46
47 this.pointPlaceholder = placeholder(4);
47 this.pointPlaceholder = placeholder(4);
@@ -73,9 +73,9 @@ class Shards extends React.Component {
73 }
73 }
74
74
75 async walletFromShards(shard1, shard2, shard3, pointName, passphrase) {
75 async walletFromShards(shard1, shard2, shard3, pointName, passphrase) {
76− const s1 = shard1 === "" ? undefined : shard1;
76+ const s1 = shard1 === '' ? undefined : shard1;
77− const s2 = shard2 === "" ? undefined : shard2;
77+ const s2 = shard2 === '' ? undefined : shard2;
78− const s3 = shard3 === "" ? undefined : shard3;
78+ const s3 = shard3 === '' ? undefined : shard3;
79
79
80 let ticket = undefined;
80 let ticket = undefined;
81 try {
81 try {
@@ -98,12 +98,12 @@ class Shards extends React.Component {
98 const phTick = this.ticketPlaceholder;
98 const phTick = this.ticketPlaceholder;
99
99
100 const shards = [shard1, shard2, shard3];
100 const shards = [shard1, shard2, shard3];
101− const ready = shards.filter(x => x !== "").length > 1;
101+ const ready = shards.filter(x => x !== '').length > 1;
102
102
103 return (
103 return (
104 <Row>
104 <Row>
105 <Col>
105 <Col>
106− <H1>{"Authenticate"}</H1>
106+ <H1>{'Authenticate'}</H1>
107
107
108 <P>
108 <P>
109 {`Enter your point and at least two of your three Urbit master
109 {`Enter your point and at least two of your three Urbit master
@@ -119,11 +119,10 @@ class Shards extends React.Component {
119 autoFocus
119 autoFocus
120 placeholder={`e.g. ${phPoint}`}
120 placeholder={`e.g. ${phPoint}`}
121 value={pointName}
121 value={pointName}
122− onChange={this.handlePointNameInput}
122+ onChange={this.handlePointNameInput}>
123− >
124− <InnerLabel>{"Point"}</InnerLabel>
123+ <InnerLabel>{'Point'}</InnerLabel>
125 <ValidatedSigil
124 <ValidatedSigil
126− className={"tr-0 mt-05 mr-0 abs"}
125+ className={'tr-0 mt-05 mr-0 abs'}
127 patp={pointName}
126 patp={pointName}
128 size={68}
127 size={68}
129 margin={8}
128 margin={8}
@@ -138,9 +137,8 @@ class Shards extends React.Component {
138 name="shard1"
137 name="shard1"
139 placeholder={`e.g. ${phTick}`}
138 placeholder={`e.g. ${phTick}`}
140 value={shard1}
139 value={shard1}
141− onChange={inp => this.handleShardInput(SHARDS.SHARD1, inp)}
140+ onChange={inp => this.handleShardInput(SHARDS.SHARD1, inp)}>
142− >
143− <InnerLabel>{"Shard 1"}</InnerLabel>
141+ <InnerLabel>{'Shard 1'}</InnerLabel>
144 </ShardInput>
142 </ShardInput>
145
143
146 <ShardInput
144 <ShardInput
@@ -151,9 +149,8 @@ class Shards extends React.Component {
151 name="shard2"
149 name="shard2"
152 placeholder={`e.g. ${phTick}`}
150 placeholder={`e.g. ${phTick}`}
153 value={shard2}
151 value={shard2}
154− onChange={inp => this.handleShardInput(SHARDS.SHARD2, inp)}
152+ onChange={inp => this.handleShardInput(SHARDS.SHARD2, inp)}>
155− >
156− <InnerLabel>{"Shard 2"}</InnerLabel>
153+ <InnerLabel>{'Shard 2'}</InnerLabel>
157 </ShardInput>
154 </ShardInput>
158
155
159 <ShardInput
156 <ShardInput
@@ -164,13 +161,12 @@ class Shards extends React.Component {
164 name="shard3"
161 name="shard3"
165 placeholder={`e.g. ${phTick}`}
162 placeholder={`e.g. ${phTick}`}
166 value={shard3}
163 value={shard3}
167− onChange={inp => this.handleShardInput(SHARDS.SHARD3, inp)}
164+ onChange={inp => this.handleShardInput(SHARDS.SHARD3, inp)}>
168− >
169− <InnerLabel>{"Shard 3"}</InnerLabel>
165+ <InnerLabel>{'Shard 3'}</InnerLabel>
170 </ShardInput>
166 </ShardInput>
171
167
172 <InputCaption>
168 <InputCaption>
173− {"If your wallet requires a passphrase, you may enter it below."}
169+ {'If your wallet requires a passphrase, you may enter it below.'}
174 </InputCaption>
170 </InputCaption>
175
171
176 <Input
172 <Input
@@ -181,15 +177,14 @@ class Shards extends React.Component {
181 type="password"
177 type="password"
182 value={passphrase}
178 value={passphrase}
183 autocomplete="off"
179 autocomplete="off"
184− onChange={this.handlePassphraseInput}
180+ onChange={this.handlePassphraseInput}>
185− >
186− <InnerLabel>{"Passphrase"}</InnerLabel>
181+ <InnerLabel>{'Passphrase'}</InnerLabel>
187 </Input>
182 </Input>
188
183
189 <Button
184 <Button
190 disabled={!ready}
185 disabled={!ready}
191− className={"mt-8"}
186+ className={'mt-8'}
192− prop-size={"lg wide"}
187+ prop-size={'lg wide'}
193 // prop-color={this.buttonTriState(wallet)}
188 // prop-color={this.buttonTriState(wallet)}
194 onClick={() =>
189 onClick={() =>
195 this.walletFromShards(
190 this.walletFromShards(
@@ -197,20 +192,18 @@ class Shards extends React.Component {
197 shard2,
192 shard2,
198 shard3,
193 shard3,
199 pointName,
194 pointName,
200− passphrase,
195+ passphrase
201 )
196 )
202− }
197+ }>
203− >
204− {"Unlock Wallet →"}
198+ {'Unlock Wallet →'}
205 </Button>
199 </Button>
206
200
207 <Button
201 <Button
208− className={"mt-4"}
202+ className={'mt-4'}
209− prop-size={"xl wide"}
203+ prop-size={'xl wide'}
210 disabled={Nothing.hasInstance(wallet)}
204 disabled={Nothing.hasInstance(wallet)}
211− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
205+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
212− >
213− {"Continue →"}
206+ {'Continue →'}
214 </Button>
207 </Button>
215 </Col>
208 </Col>
216 </Row>
209 </Row>
src/bridge/views/Ticket.js+31−34
@@ -1,6 +1,6 @@
1−import { Just, Nothing } from "folktale/maybe";
1+import { Just, Nothing } from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Button } from "../components/Base";
3+import { Button } from '../components/Base';
4import {
4import {
5 InnerLabel,
5 InnerLabel,
6 ValidatedSigil,
6 ValidatedSigil,
@@ -8,22 +8,22 @@ import {
8 TicketInput,
8 TicketInput,
9 Input,
9 Input,
10 InputCaption,
10 InputCaption,
11−} from "../components/Base";
11+} from '../components/Base';
12−import { Row, Col, H1, P } from "../components/Base";
12+import { Row, Col, H1, P } from '../components/Base';
13
13
14−import { randomPatq } from "../lib/lib";
14+import { randomPatq } from '../lib/lib';
15−import { ROUTE_NAMES } from "../lib/routeNames";
15+import { ROUTE_NAMES } from '../lib/routeNames';
16−import { withHistory } from "../store/history";
16+import { withHistory } from '../store/history';
17−import { urbitWalletFromTicket } from "../lib/wallet";
17+import { urbitWalletFromTicket } from '../lib/wallet';
18
18
19class Ticket extends React.Component {
19class Ticket extends React.Component {
20 constructor(props) {
20 constructor(props) {
21 super(props);
21 super(props);
22
22
23 this.state = {
23 this.state = {
24− ticket: "",
24+ ticket: '',
25− pointName: "",
25+ pointName: '',
26− passphrase: "",
26+ passphrase: '',
27 isUnlocking: false,
27 isUnlocking: false,
28 };
28 };
29
29
@@ -72,7 +72,7 @@ class Ticket extends React.Component {
72 return (
72 return (
73 <Row>
73 <Row>
74 <Col>
74 <Col>
75− <H1>{"Authenticate"}</H1>
75+ <H1>{'Authenticate'}</H1>
76
76
77 <P>
77 <P>
78 {`Please enter your point and Urbit master ticket here. This information is written on your Urbit HD paper wallets.`}
78 {`Please enter your point and Urbit master ticket here. This information is written on your Urbit HD paper wallets.`}
@@ -86,11 +86,10 @@ class Ticket extends React.Component {
86 autoFocus
86 autoFocus
87 placeholder={`e.g. ${phPoint}`}
87 placeholder={`e.g. ${phPoint}`}
88 value={pointName}
88 value={pointName}
89− onChange={this.handlePointNameInput}
89+ onChange={this.handlePointNameInput}>
90− >
91− <InnerLabel>{"Point"}</InnerLabel>
90+ <InnerLabel>{'Point'}</InnerLabel>
92 <ValidatedSigil
91 <ValidatedSigil
93− className={"tr-0 mt-05 mr-0 abs"}
92+ className={'tr-0 mt-05 mr-0 abs'}
94 patp={pointName}
93 patp={pointName}
95 size={68}
94 size={68}
96 margin={8}
95 margin={8}
@@ -105,13 +104,12 @@ class Ticket extends React.Component {
105 name="ticket"
104 name="ticket"
106 placeholder={`e.g. ${phTick}`}
105 placeholder={`e.g. ${phTick}`}
107 value={ticket}
106 value={ticket}
108− onChange={this.handleTicketInput}
107+ onChange={this.handleTicketInput}>
109− >
110− <InnerLabel>{"Ticket"}</InnerLabel>
108+ <InnerLabel>{'Ticket'}</InnerLabel>
111 </TicketInput>
109 </TicketInput>
112
110
113 <InputCaption>
111 <InputCaption>
114− {"If your wallet requires a passphrase, you may enter it below."}
112+ {'If your wallet requires a passphrase, you may enter it below.'}
115 </InputCaption>
113 </InputCaption>
116
114
117 <Input
115 <Input
@@ -122,30 +120,29 @@ class Ticket extends React.Component {
122 type="password"
120 type="password"
123 value={passphrase}
121 value={passphrase}
124 autocomplete="off"
122 autocomplete="off"
125− onChange={this.handlePassphraseInput}
123+ onChange={this.handlePassphraseInput}>
126− >
127− <InnerLabel>{"Passphrase"}</InnerLabel>
124+ <InnerLabel>{'Passphrase'}</InnerLabel>
128 </Input>
125 </Input>
129
126
130 <Button
127 <Button
131− className={"mt-8"}
128+ className={'mt-8'}
132− prop-size={"lg wide"}
129+ prop-size={'lg wide'}
133 disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
130 disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
131+ onClick={() =>
134− onClick={() => this.walletFromTicket(ticket, pointName, passphrase)}
132+ this.walletFromTicket(ticket, pointName, passphrase)
135− >
133+ }>
136 <span className="relative">
134 <span className="relative">
137 {this.state.isUnlocking && <span className="btn-spinner" />}
135 {this.state.isUnlocking && <span className="btn-spinner" />}
138− {"Unlock Wallet →"}
136+ {'Unlock Wallet →'}
139 </span>
137 </span>
140 </Button>
138 </Button>
141
139
142 <Button
140 <Button
143− className={"mt-4"}
141+ className={'mt-4'}
144− prop-size={"xl wide"}
142+ prop-size={'xl wide'}
145 disabled={Nothing.hasInstance(wallet)}
143 disabled={Nothing.hasInstance(wallet)}
146− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
144+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
147− >
148− {"Continue →"}
145+ {'Continue →'}
149 </Button>
146 </Button>
150 </Col>
147 </Col>
151 </Row>
148 </Row>
src/bridge/views/Transfer.js+25−27
@@ -1,8 +1,8 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as azimuth from "azimuth-js";
3+import * as azimuth from 'azimuth-js';
4−import * as ob from "urbit-ob";
4+import * as ob from 'urbit-ob';
5−import * as need from "../lib/need";
5+import * as need from '../lib/need';
6
6
7import {
7import {
8 Row,
8 Row,
@@ -12,13 +12,13 @@ import {
12 ShowBlockie,
12 ShowBlockie,
13 P,
13 P,
14 Anchor,
14 Anchor,
15−} from "../components/Base";
15+} from '../components/Base';
16−import { AddressInput } from "../components/Base";
16+import { AddressInput } from '../components/Base';
17−import StatelessTransaction from "../components/StatelessTransaction";
17+import StatelessTransaction from '../components/StatelessTransaction';
18
18
19−import { NETWORK_NAMES } from "../lib/network";
19+import { NETWORK_NAMES } from '../lib/network';
20
20
21−import { isValidAddress } from "../lib/wallet";
21+import { isValidAddress } from '../lib/wallet';
22
22
23class Transfer extends React.Component {
23class Transfer extends React.Component {
24 constructor(props) {
24 constructor(props) {
@@ -27,7 +27,7 @@ class Transfer extends React.Component {
27 const issuingPoint = need.pointCursor(props);
27 const issuingPoint = need.pointCursor(props);
28
28
29 this.state = {
29 this.state = {
30− receivingAddress: "",
30+ receivingAddress: '',
31 issuingPoint: issuingPoint,
31 issuingPoint: issuingPoint,
32 };
32 };
33
33
@@ -57,7 +57,7 @@ class Transfer extends React.Component {
57 const txn = azimuth.ecliptic.setTransferProxy(
57 const txn = azimuth.ecliptic.setTransferProxy(
58 validContracts,
58 validContracts,
59 validPoint,
59 validPoint,
60− state.receivingAddress,
60+ state.receivingAddress
61 );
61 );
62
62
63 return Maybe.Just(txn);
63 return Maybe.Just(txn);
@@ -75,15 +75,15 @@ class Transfer extends React.Component {
75
75
76 const esdomain =
76 const esdomain =
77 props.networkType === NETWORK_NAMES.ROPSTEN
77 props.networkType === NETWORK_NAMES.ROPSTEN
78− ? "ropsten.etherscan.io"
78+ ? 'ropsten.etherscan.io'
79− : "etherscan.io";
79+ : 'etherscan.io';
80
80
81 return (
81 return (
82 <Row>
82 <Row>
83 <Col>
83 <Col>
84 <H1>
84 <H1>
85− {"Transfer"} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
85+ {'Transfer'} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
86− {"To a New Owner"}
86+ {'To a New Owner'}
87 </H1>
87 </H1>
88
88
89 <P>
89 <P>
@@ -93,27 +93,25 @@ class Transfer extends React.Component {
93 </P>
93 </P>
94
94
95 <AddressInput
95 <AddressInput
96− className={"mono mt-8"}
96+ className={'mono mt-8'}
97 prop-size="lg"
97 prop-size="lg"
98 prop-format="innerLabel"
98 prop-format="innerLabel"
99 value={state.receivingAddress}
99 value={state.receivingAddress}
100 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
100 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
101− onChange={v => this.handleAddressInput(v)}
101+ onChange={v => this.handleAddressInput(v)}>
102− >
103− <InnerLabel>{"New ownership address"}</InnerLabel>
102+ <InnerLabel>{'New ownership address'}</InnerLabel>
104− <ShowBlockie className={"mt-1"} address={state.receivingAddress} />
103+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
105 </AddressInput>
104 </AddressInput>
106
105
107 <Anchor
106 <Anchor
108− className={"mt-1"}
107+ className={'mt-1'}
109− prop-size={"s"}
108+ prop-size={'s'}
110 prop-disabled={
109 prop-disabled={
111 !isValidAddress(state.receivingAddress) || !esvisible
110 !isValidAddress(state.receivingAddress) || !esvisible
112 }
111 }
113− target={"_blank"}
112+ target={'_blank'}
114− href={`https://${esdomain}/address/${state.receivingAddress}`}
113+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
115− >
116− {"View on Etherscan ↗"}
114+ {'View on Etherscan ↗'}
117 </Anchor>
115 </Anchor>
118
116
119 <StatelessTransaction
117 <StatelessTransaction
src/bridge/views/Trezor.js+34−37
@@ -1,15 +1,15 @@
1−import * as bip32 from "bip32";
1+import * as bip32 from 'bip32';
2−import React from "react";
2+import React from 'react';
3−import Maybe from "folktale/maybe";
3+import Maybe from 'folktale/maybe';
4−import { Button } from "../components/Base";
4+import { Button } from '../components/Base';
5−import { Row, Col, H1, P } from "../components/Base";
5+import { Row, Col, H1, P } from '../components/Base';
6−import { InnerLabel, Input, InnerLabelDropdown } from "../components/Base";
6+import { InnerLabel, Input, InnerLabelDropdown } from '../components/Base';
7−import TrezorConnect from "trezor-connect";
7+import TrezorConnect from 'trezor-connect';
8−import * as secp256k1 from "secp256k1";
8+import * as secp256k1 from 'secp256k1';
9−
9+
10−import { TREZOR_PATH } from "../lib/trezor";
10+import { TREZOR_PATH } from '../lib/trezor';
11−import { ROUTE_NAMES } from "../lib/routeNames";
11+import { ROUTE_NAMES } from '../lib/routeNames';
12−import { withHistory } from "../store/history";
12+import { withHistory } from '../store/history';
13
13
14class Trezor extends React.Component {
14class Trezor extends React.Component {
15 constructor(props) {
15 constructor(props) {
@@ -27,7 +27,7 @@ class Trezor extends React.Component {
27
27
28 handleAccountSelection(account) {
28 handleAccountSelection(account) {
29 let hdpath = this.state.hdpath;
29 let hdpath = this.state.hdpath;
30− if (account !== "custom") {
30+ if (account !== 'custom') {
31 hdpath = TREZOR_PATH.replace(/x/g, account);
31 hdpath = TREZOR_PATH.replace(/x/g, account);
32 }
32 }
33 this.setState({ account, hdpath });
33 this.setState({ account, hdpath });
@@ -42,14 +42,14 @@ class Trezor extends React.Component {
42 const { hdpath } = this.state;
42 const { hdpath } = this.state;
43
43
44 TrezorConnect.manifest({
44 TrezorConnect.manifest({
45− email: "bridge-trezor@urbit.org",
45+ email: 'bridge-trezor@urbit.org',
46− appUrl: "https://github.com/urbit/bridge",
46+ appUrl: 'https://github.com/urbit/bridge',
47 });
47 });
48 TrezorConnect.getPublicKey({ path: hdpath }).then(info => {
48 TrezorConnect.getPublicKey({ path: hdpath }).then(info => {
49 if (info.success === true) {
49 if (info.success === true) {
50 const payload = info.payload;
50 const payload = info.payload;
51− const publicKey = Buffer.from(payload.publicKey, "hex");
51+ const publicKey = Buffer.from(payload.publicKey, 'hex');
52− const chainCode = Buffer.from(payload.chainCode, "hex");
52+ const chainCode = Buffer.from(payload.chainCode, 'hex');
53 const pub = secp256k1.publicKeyConvert(publicKey, true);
53 const pub = secp256k1.publicKeyConvert(publicKey, true);
54 const hd = bip32.fromPublicKey(pub, chainCode);
54 const hd = bip32.fromPublicKey(pub, chainCode);
55 setWallet(Maybe.Just(hd));
55 setWallet(Maybe.Just(hd));
@@ -67,13 +67,13 @@ class Trezor extends React.Component {
67
67
68 let accountOptions = [
68 let accountOptions = [
69 {
69 {
70− title: "Custom path",
70+ title: 'Custom path',
71− value: "custom",
71+ value: 'custom',
72 },
72 },
73 ];
73 ];
74 for (let i = 0; i < 20; i++) {
74 for (let i = 0; i < 20; i++) {
75 accountOptions.push({
75 accountOptions.push({
76− title: "Account #" + (i + 1),
76+ title: 'Account #' + (i + 1),
77 value: i,
77 value: i,
78 });
78 });
79 }
79 }
@@ -86,14 +86,14 @@ class Trezor extends React.Component {
86 prop-format="innerLabel"
86 prop-format="innerLabel"
87 options={accountOptions}
87 options={accountOptions}
88 handleUpdate={handleAccountSelection}
88 handleUpdate={handleAccountSelection}
89− title={"Account"}
89+ title={'Account'}
90 currentSelectionTitle={accountTitle}
90 currentSelectionTitle={accountTitle}
91 fullWidth={true}
91 fullWidth={true}
92 />
92 />
93 );
93 );
94
94
95 const pathSelection =
95 const pathSelection =
96− account !== "custom" ? null : (
96+ account !== 'custom' ? null : (
97 <Input
97 <Input
98 className="mt-8 pt-8 text-mono"
98 className="mt-8 pt-8 text-mono"
99 prop-size="md"
99 prop-size="md"
@@ -101,16 +101,15 @@ class Trezor extends React.Component {
101 name="hdpath"
101 name="hdpath"
102 value={hdpath}
102 value={hdpath}
103 autocomplete="off"
103 autocomplete="off"
104− onChange={this.handleHdPathInput}
104+ onChange={this.handleHdPathInput}>
105− >
106− <InnerLabel>{"HD Path"}</InnerLabel>
105+ <InnerLabel>{'HD Path'}</InnerLabel>
107 </Input>
106 </Input>
108 );
107 );
109
108
110 return (
109 return (
111 <Row>
110 <Row>
112− <Col className={"measure-md"}>
111+ <Col className={'measure-md'}>
113− <H1>{"Authenticate With Your Trezor"}</H1>
112+ <H1>{'Authenticate With Your Trezor'}</H1>
114
113
115 <P>
114 <P>
116 {`Connect and authenticate to your Trezor. If you'd like
115 {`Connect and authenticate to your Trezor. If you'd like
@@ -121,20 +120,18 @@ class Trezor extends React.Component {
121 {pathSelection}
120 {pathSelection}
122
121
123 <Button
122 <Button
124− className={"mt-8"}
123+ className={'mt-8'}
125− prop-size={"wide lg"}
124+ prop-size={'wide lg'}
126− onClick={this.pollDevice}
125+ onClick={this.pollDevice}>
127− >
128− {"Authenticate →"}
126+ {'Authenticate →'}
129 </Button>
127 </Button>
130
128
131 <Button
129 <Button
132− className={"mt-8"}
130+ className={'mt-8'}
133− prop-size={"wide lg"}
131+ prop-size={'wide lg'}
134 disabled={Maybe.Nothing.hasInstance(wallet)}
132 disabled={Maybe.Nothing.hasInstance(wallet)}
135− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}
133+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
136− >
137− {"Continue →"}
134+ {'Continue →'}
138 </Button>
135 </Button>
139 </Col>
136 </Col>
140 </Row>
137 </Row>
src/bridge/views/ViewPoint.js+17−19
@@ -1,20 +1,20 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import * as ob from "urbit-ob";
3+import * as ob from 'urbit-ob';
4
4
5−import { Button } from "../components/Base";
5+import { Button } from '../components/Base';
6−import { Row, Col, H1, P } from "../components/Base";
6+import { Row, Col, H1, P } from '../components/Base';
7−import { InnerLabel, PointInput, ValidatedSigil } from "../components/Base";
7+import { InnerLabel, PointInput, ValidatedSigil } from '../components/Base';
8
8
9−import { ROUTE_NAMES } from "../lib/routeNames";
9+import { ROUTE_NAMES } from '../lib/routeNames';
10−import { withHistory } from "../store/history";
10+import { withHistory } from '../store/history';
11
11
12class ViewPoint extends React.Component {
12class ViewPoint extends React.Component {
13 constructor(props) {
13 constructor(props) {
14 super(props);
14 super(props);
15
15
16 this.state = {
16 this.state = {
17− pointName: "",
17+ pointName: '',
18 };
18 };
19
19
20 this.handlePointInput = this.handlePointInput.bind(this);
20 this.handlePointInput = this.handlePointInput.bind(this);
@@ -43,9 +43,9 @@ class ViewPoint extends React.Component {
43 return (
43 return (
44 <Row>
44 <Row>
45 <Col>
45 <Col>
46− <H1>{"View a Point"}</H1>
46+ <H1>{'View a Point'}</H1>
47
47
48− <P>{"Enter a point name to view its public information."}</P>
48+ <P>{'Enter a point name to view its public information.'}</P>
49
49
50 <PointInput
50 <PointInput
51 autoFocus
51 autoFocus
@@ -54,11 +54,10 @@ class ViewPoint extends React.Component {
54 className="mono"
54 className="mono"
55 placeholder="e.g. ~zod"
55 placeholder="e.g. ~zod"
56 onChange={this.handlePointInput}
56 onChange={this.handlePointInput}
57− value={pointName}
57+ value={pointName}>
58− >
59− <InnerLabel>{"Point Name"}</InnerLabel>
58+ <InnerLabel>{'Point Name'}</InnerLabel>
60 <ValidatedSigil
59 <ValidatedSigil
61− className={"tr-0 mt-05 mr-0 abs"}
60+ className={'tr-0 mt-05 mr-0 abs'}
62 patp={pointName}
61 patp={pointName}
63 show
62 show
64 size={68}
63 size={68}
@@ -67,14 +66,13 @@ class ViewPoint extends React.Component {
67 </PointInput>
66 </PointInput>
68
67
69 <Button
68 <Button
70− className={"mt-8"}
69+ className={'mt-8'}
71 disabled={valid === false}
70 disabled={valid === false}
72 onClick={() => {
71 onClick={() => {
73 setPointCursor(Maybe.Just(ob.patp2dec(pointName)));
72 setPointCursor(Maybe.Just(ob.patp2dec(pointName)));
74 history.popAndPush(ROUTE_NAMES.SHIP);
73 history.popAndPush(ROUTE_NAMES.SHIP);
75− }}
74+ }}>
76− >
77− {"Continue →"}
75+ {'Continue →'}
78 </Button>
76 </Button>
79 </Col>
77 </Col>
80 </Row>
78 </Row>
src/bridge/views/Wallet.js+24−25
@@ -1,12 +1,12 @@
1−import Maybe from "folktale/maybe";
1+import Maybe from 'folktale/maybe';
2−import React from "react";
2+import React from 'react';
3−import { Button, H1, P } from "../components/Base";
3+import { Button, H1, P } from '../components/Base';
4−import { InnerLabelDropdown } from "../components/Base";
4+import { InnerLabelDropdown } from '../components/Base';
5−import { Row, Col } from "../components/Base";
5+import { Row, Col } from '../components/Base';
6
6
7−import { ROUTE_NAMES } from "../lib/routeNames";
7+import { ROUTE_NAMES } from '../lib/routeNames';
8−import { withHistory } from "../store/history";
8+import { withHistory } from '../store/history';
9−import { WALLET_NAMES, renderWalletType } from "../lib/wallet";
9+import { WALLET_NAMES, renderWalletType } from '../lib/wallet';
10
10
11class Wallet extends React.Component {
11class Wallet extends React.Component {
12 componentDidMount() {
12 componentDidMount() {
@@ -17,37 +17,37 @@ class Wallet extends React.Component {
17 getWalletOptions() {
17 getWalletOptions() {
18 return [
18 return [
19 {
19 {
20− title: "Urbit Master Ticket",
20+ title: 'Urbit Master Ticket',
21 value: WALLET_NAMES.TICKET,
21 value: WALLET_NAMES.TICKET,
22 },
22 },
23 {
23 {
24− title: "Urbit Master Ticket (Shards)",
24+ title: 'Urbit Master Ticket (Shards)',
25 value: WALLET_NAMES.SHARDS,
25 value: WALLET_NAMES.SHARDS,
26 },
26 },
27 {
27 {
28− type: "divider",
28+ type: 'divider',
29 },
29 },
30 {
30 {
31− title: "Ledger",
31+ title: 'Ledger',
32 value: WALLET_NAMES.LEDGER,
32 value: WALLET_NAMES.LEDGER,
33 },
33 },
34 {
34 {
35− title: "Trezor",
35+ title: 'Trezor',
36 value: WALLET_NAMES.TREZOR,
36 value: WALLET_NAMES.TREZOR,
37 },
37 },
38 {
38 {
39− type: "divider",
39+ type: 'divider',
40 },
40 },
41 {
41 {
42− title: "BIP39 Mnemonic",
42+ title: 'BIP39 Mnemonic',
43 value: WALLET_NAMES.MNEMONIC,
43 value: WALLET_NAMES.MNEMONIC,
44 },
44 },
45 {
45 {
46− title: "Ethereum Private Key",
46+ title: 'Ethereum Private Key',
47 value: WALLET_NAMES.PRIVATE_KEY,
47 value: WALLET_NAMES.PRIVATE_KEY,
48 },
48 },
49 {
49 {
50− title: "Ethereum Keystore File",
50+ title: 'Ethereum Keystore File',
51 value: WALLET_NAMES.KEYSTORE,
51 value: WALLET_NAMES.KEYSTORE,
52 },
52 },
53 ];
53 ];
@@ -60,7 +60,7 @@ class Wallet extends React.Component {
60 return (
60 return (
61 <Row>
61 <Row>
62 <Col>
62 <Col>
63− <H1>{"Unlock a Wallet"}</H1>
63+ <H1>{'Unlock a Wallet'}</H1>
64
64
65 <P>
65 <P>
66 {`To manage your assets, you need to unlock a wallet.
66 {`To manage your assets, you need to unlock a wallet.
@@ -68,15 +68,15 @@ class Wallet extends React.Component {
68 </P>
68 </P>
69
69
70 <InnerLabelDropdown
70 <InnerLabelDropdown
71− className={"mb-10 mt-6"}
71+ className={'mb-10 mt-6'}
72− title={"Wallet Type:"}
72+ title={'Wallet Type:'}
73 options={walletOptions}
73 options={walletOptions}
74 handleUpdate={props.setWalletType}
74 handleUpdate={props.setWalletType}
75 currentSelectionTitle={renderWalletType(props.walletType)}
75 currentSelectionTitle={renderWalletType(props.walletType)}
76 />
76 />
77
77
78 <Button
78 <Button
79− className={"mt-10"}
79+ className={'mt-10'}
80 onClick={() =>
80 onClick={() =>
81 props.history.push(
81 props.history.push(
82 props.walletType === WALLET_NAMES.MNEMONIC
82 props.walletType === WALLET_NAMES.MNEMONIC
@@ -93,11 +93,10 @@ class Wallet extends React.Component {
93 ? ROUTE_NAMES.PRIVATE_KEY
93 ? ROUTE_NAMES.PRIVATE_KEY
94 : props.walletType === WALLET_NAMES.KEYSTORE
94 : props.walletType === WALLET_NAMES.KEYSTORE
95 ? ROUTE_NAMES.KEYSTORE
95 ? ROUTE_NAMES.KEYSTORE
96− : ROUTE_NAMES.DEFAULT,
96+ : ROUTE_NAMES.DEFAULT
97 )
97 )
98− }
98+ }>
99− >
100− {"Continue →"}
99+ {'Continue →'}
101 </Button>
100 </Button>
102 </Col>
101 </Col>
103 </Row>
102 </Row>
src/walletgen/lib/lib.js+9−9
@@ -1,7 +1,7 @@
1−import * as ob from "urbit-ob";
1+import * as ob from 'urbit-ob';
2−import * as kg from "urbit-key-generation/dist/index";
2+import * as kg from 'urbit-key-generation/dist/index';
3−import * as more from "more-entropy";
3+import * as more from 'more-entropy';
4−import lodash from "lodash";
4+import lodash from 'lodash';
5import {
5import {
6 MIN_STAR,
6 MIN_STAR,
7 MIN_PLANET,
7 MIN_PLANET,
@@ -9,7 +9,7 @@ import {
9 GALAXY_ENTROPY_BITS,
9 GALAXY_ENTROPY_BITS,
10 STAR_ENTROPY_BITS,
10 STAR_ENTROPY_BITS,
11 PLANET_ENTROPY_BITS,
11 PLANET_ENTROPY_BITS,
12−} from "./constants";
12+} from './constants';
13
13
14const SEED_LENGTH_BYTES = SEED_ENTROPY_BITS / 8;
14const SEED_LENGTH_BYTES = SEED_ENTROPY_BITS / 8;
15
15
@@ -35,9 +35,9 @@ const makeTicket = point => {
35 const more = lodash.flatMap(desired, arr => arr[0] ^ arr[1]);
35 const more = lodash.flatMap(desired, arr => arr[0] ^ arr[1]);
36 const entropy = lodash.zipWith(some, more, (x, y) => x ^ y);
36 const entropy = lodash.zipWith(some, more, (x, y) => x ^ y);
37 const buf = Buffer.from(entropy);
37 const buf = Buffer.from(entropy);
38− const patq = ob.hex2patq(buf.toString("hex"));
38+ const patq = ob.hex2patq(buf.toString('hex'));
39 resolve(patq);
39 resolve(patq);
40− reject("Entropy generation failed");
40+ reject('Entropy generation failed');
41 });
41 });
42 });
42 });
43};
43};
@@ -48,7 +48,7 @@ const generateWallet = async (point, ticket, boot) => {
48 ticket: ticket,
48 ticket: ticket,
49 seedSize: SEED_LENGTH_BYTES,
49 seedSize: SEED_LENGTH_BYTES,
50 ship: point,
50 ship: point,
51− password: "",
51+ password: '',
52 revisions: {},
52 revisions: {},
53 boot: boot,
53 boot: boot,
54 };
54 };
@@ -57,7 +57,7 @@ const generateWallet = async (point, ticket, boot) => {
57
57
58 // This is here to notify anyone who opens console because the thread
58 // This is here to notify anyone who opens console because the thread
59 // hangs, blocking UI updates so this cannot be done in the UI
59 // hangs, blocking UI updates so this cannot be done in the UI
60− console.log("Generating Wallet for point address: ", point);
60+ console.log('Generating Wallet for point address: ', point);
61
61
62 return wallet;
62 return wallet;
63};
63};