on master help sign in
feat: update views to use new grid insted of row/col and update need to not depend on props
1171039Matt Condon (shrugs)
src/Bridge.js+1−7
@@ -2,13 +2,10 @@ import React from 'react';
2import { Just, Nothing } from 'folktale/maybe';
2import { Just, Nothing } from 'folktale/maybe';
3import { IndigoApp } from 'indigo-react';
3import { IndigoApp } from 'indigo-react';
4
4
5−import View from 'components/View';
6import Router from 'components/Router';
5import Router from 'components/Router';
7
6
8import Provider from 'store/Provider';
7import Provider from 'store/Provider';
9
8
10−import Header from './components/old/Header';
11−
12import { ROUTE_NAMES } from 'lib/routeNames';
9import { ROUTE_NAMES } from 'lib/routeNames';
13import { NETWORK_TYPES } from 'lib/network';
10import { NETWORK_TYPES } from 'lib/network';
14import { walletFromMnemonic } from 'lib/wallet';
11import { walletFromMnemonic } from 'lib/wallet';
@@ -52,10 +49,7 @@ export default function Bridge() {
52 initialMnemonic={kInitialMnemonic}
49 initialMnemonic={kInitialMnemonic}
53 initialPointCursor={kInitialPointCursor}>
50 initialPointCursor={kInitialPointCursor}>
54 <IndigoApp>
51 <IndigoApp>
55− <View>
56− <Header />
57− <Router />
52+ <Router />
58− </View>
59 </IndigoApp>
53 </IndigoApp>
60 </Provider>
54 </Provider>
61 );
55 );
src/components/Grid.jsnew file+30
@@ -0,0 +1,30 @@
1+import React from 'react';
2+import cn from 'classnames';
3+
4+function Grid({ className, ...rest }) {
5+ return <div className={cn('grid12', className)} {...rest} />;
6+}
7+
8+Grid.Item = function GridItem({
9+ full,
10+ half,
11+ third,
12+ fourth,
13+ className,
14+ ...rest
15+}) {
16+ return (
17+ <div
18+ className={cn(
19+ full && `full`,
20+ half && `half-${half}`,
21+ third && `third-${third}`,
22+ fourth && `fourth-${fourth}`,
23+ className
24+ )}
25+ {...rest}
26+ />
27+ );
28+};
29+
30+export default Grid;
src/components/View.js+2−5
@@ -3,15 +3,12 @@ import cn from 'classnames';
3
3
4// View is a top-level component that all Views must render to inherit styling
4// View is a top-level component that all Views must render to inherit styling
5function View({ className, ...rest }) {
5function View({ className, ...rest }) {
6− return <div className={cn('mw-1', className)} {...rest} />;
6+ return <div className={cn('mw1', className)} {...rest} />;
7}
7}
8
8
9View.Full = function FullView({ className, ...rest }) {
9View.Full = function FullView({ className, ...rest }) {
10 return (
10 return (
11− <div
12− className={cn('mw-2 ph-1 ph-3-ns ph-9-md ph-10-lg', className)}
11+ <div className={cn('mw2 ph1 ph3-ns ph9-md ph10-lg', className)} {...rest} />
13− {...rest}
14− />
15 );
12 );
16};
13};
17
14
src/components/old/StatelessTransaction.js+2−2
@@ -69,7 +69,7 @@ class StatelessTransaction extends React.Component {
69 componentDidMount() {
69 componentDidMount() {
70 const { props } = this;
70 const { props } = this;
71
71
72− const addr = need.address(props);
72+ const addr = need.addressFromWallet(props.wallet);
73
73
74 props.web3.matchWith({
74 props.web3.matchWith({
75 Nothing: () => {},
75 Nothing: () => {},
@@ -208,7 +208,7 @@ class StatelessTransaction extends React.Component {
208 const rawTx = hexify(stx.serialize());
208 const rawTx = hexify(stx.serialize());
209 const cost = state.gasLimit * toWei(state.gasPrice, 'gwei');
209 const cost = state.gasLimit * toWei(state.gasPrice, 'gwei');
210
210
211− const address = need.address(props);
211+ const address = need.addressFromWallet(props.wallet);
212 let balance = await web3.eth.getBalance(address);
212 let balance = await web3.eth.getBalance(address);
213 let hasBalance = balance >= cost;
213 let hasBalance = balance >= cost;
214
214
src/lib/keys.js+3−3
@@ -73,8 +73,8 @@ const attemptNetworkSeedDerivation = async (next, args) => {
73 //
73 //
74 // following code is intentionally verbose for sake of clarity
74 // following code is intentionally verbose for sake of clarity
75
75
76− const point = need.pointCursor(args);
76+ const point = need.pointCursor(args.pointCursor);
77− const pointDetails = need.fromPointCache(args, point);
77+ const pointDetails = need.fromPointCache(args.pointCache, point);
78
78
79 const revision =
79 const revision =
80 next === true
80 next === true
@@ -95,7 +95,7 @@ const attemptNetworkSeedDerivation = async (next, args) => {
95
95
96 managementSeed = uwal.management.seed;
96 managementSeed = uwal.management.seed;
97 } else if (walletType === WALLET_TYPES.MNEMONIC) {
97 } else if (walletType === WALLET_TYPES.MNEMONIC) {
98− const walProxy = need.address(args);
98+ const walProxy = need.addressFromWallet(args.wallet);
99
99
100 const mnemonic = authMnemonic.matchWith({
100 const mnemonic = authMnemonic.matchWith({
101 Just: mnem => mnem.value,
101 Just: mnem => mnem.value,
src/lib/need.js+27−70
@@ -1,75 +1,32 @@
1// need.js: +need but worse
1// need.js: +need but worse
2//
2//
3−// generally, pass the props object into these functions
4
3
5import { BRIDGE_ERROR } from './error';
4import { BRIDGE_ERROR } from './error';
6
5
7−function web3(obj) {
6+const needBuilder = error => obj => {
8− return 'web3' in obj === false
7+ if (!obj) {
9− ? (() => {
8+ throw error;
10− throw BRIDGE_ERROR.MISSING_WEB3;
11− })()
9+ }
10+
12− : obj.web3.matchWith({
11+ return obj.matchWith({
13− Nothing: () => {
12+ Nothing: () => {
14− throw BRIDGE_ERROR.MISSING_WEB3;
13+ throw error;
15− },
14+ },
16− Just: w => w.value,
15+ Just: p => p.value,
17− });
16+ });
18−}
17+};
19−
18+
20−function contracts(obj) {
19+export const web3 = needBuilder(BRIDGE_ERROR.MISSING_WEB3);
21− return 'contracts' in obj === false
22− ? (() => {
23− throw BRIDGE_ERROR.MISSING_CONTRACTS;
24− })()
25− : obj.contracts.matchWith({
26− Nothing: () => {
27− throw BRIDGE_ERROR.MISSING_CONTRACTS;
20+export const contracts = needBuilder(BRIDGE_ERROR.MISSING_CONTRACTS);
28− },
29− Just: c => c.value,
30− });
31−}
32−
33−function wallet(obj) {
34− return 'wallet' in obj === false
35− ? (() => {
36− throw BRIDGE_ERROR.MISSING_WALLET;
21+export const wallet = needBuilder(BRIDGE_ERROR.MISSING_WALLET);
37− })()
38− : obj.wallet.matchWith({
39− Nothing: () => {
40− throw BRIDGE_ERROR.MISSING_WALLET;
41− },
42− Just: w => w.value,
43− });
44−}
45−
46−function address(obj) {
47− return wallet(obj).address;
22+export const addressFromWallet = obj => wallet(obj).address;
48−}
49−
50−function pointCursor(obj) {
51− return 'pointCursor' in obj === false
52− ? (() => {
53− throw BRIDGE_ERROR.MISSING_POINT;
23+export const pointCursor = needBuilder(BRIDGE_ERROR.MISSING_POINT);
54− })()
55− : obj.pointCursor.matchWith({
56− Nothing: () => {
57− throw BRIDGE_ERROR.MISSING_POINT;
24+export const pointCache = needBuilder(BRIDGE_ERROR.MISSING_POINT);
58− },
25+export const fromPointCache = (obj, point) => {
59− Just: p => p.value,
26+ const cache = pointCache(obj);
60− });
27+ if (!(point in cache)) {
61−}
62−
63−function fromPointCache(obj, point) {
64− return 'pointCache' in obj === false
65− ? (() => {
66− throw BRIDGE_ERROR.MISSING_POINT;
28+ throw BRIDGE_ERROR.MISSING_POINT;
67− })()
29+ }
68− : point in obj.pointCache
30+
69− ? obj.pointCache[point]
31+ return cache[point];
70− : (() => {
32+};
71− throw BRIDGE_ERROR.MISSING_POINT;
72− })();
73−}
74−
75−export { web3, contracts, wallet, address, pointCursor, fromPointCache };
src/lib/router.js+1−1
@@ -112,7 +112,7 @@ export const getRouteBreadcrumb = ({
112 case ROUTE_NAMES.VIEW_SHIP:
112 case ROUTE_NAMES.VIEW_SHIP:
113 return 'View';
113 return 'View';
114 case ROUTE_NAMES.SHIP:
114 case ROUTE_NAMES.SHIP:
115− return ob.patp(need.pointCursor({ pointCursor }));
115+ return ob.patp(need.pointCursor(pointCursor));
116 case ROUTE_NAMES.SET_TRANSFER_PROXY:
116 case ROUTE_NAMES.SET_TRANSFER_PROXY:
117 case ROUTE_NAMES.SET_MANAGEMENT_PROXY:
117 case ROUTE_NAMES.SET_MANAGEMENT_PROXY:
118 case ROUTE_NAMES.SET_SPAWN_PROXY:
118 case ROUTE_NAMES.SET_SPAWN_PROXY:
src/style/indigo-proposals.scss+2−2
@@ -1,9 +1,9 @@
1−.mw-1 {
1+.mw1 {
2 margin: 0 auto;
2 margin: 0 auto;
3 max-width: 30rem;
3 max-width: 30rem;
4}
4}
5
5
6−.mw-2 {
6+.mw2 {
7 margin: 0 auto;
7 margin: 0 auto;
8 max-width: 64rem;
8 max-width: 64rem;
9}
9}
src/views/AcceptTransfer.js+43−47
@@ -1,6 +1,6 @@
1import { Just } from 'folktale/maybe';
1import { Just } from 'folktale/maybe';
2import React from 'react';
2import React from 'react';
3−import { Row, Col, H1, P } from '../components/old/Base';
3+import { H1, P } from '../components/old/Base';
4import {
4import {
5 InnerLabel,
5 InnerLabel,
6 AddressInput,
6 AddressInput,
@@ -18,14 +18,14 @@ import { withNetwork } from '../store/network';
18import { compose } from '../lib/lib';
18import { compose } from '../lib/lib';
19import { withWallet } from '../store/wallet';
19import { withWallet } from '../store/wallet';
20import { withPointCursor } from '../store/pointCursor';
20import { withPointCursor } from '../store/pointCursor';
21+import View from 'components/View';
21
22
22class AcceptTransfer extends React.Component {
23class AcceptTransfer extends React.Component {
23 constructor(props) {
24 constructor(props) {
24 super(props);
25 super(props);
25
26
26− const receivingAddress = need.address(props);
27+ const receivingAddress = need.addressFromWallet(props.wallet);
27−
28− const incomingPoint = need.pointCursor(props);
28+ const incomingPoint = need.pointCursor(props.pointCursor);
29
29
30 this.state = {
30 this.state = {
31 receivingAddress: receivingAddress,
31 receivingAddress: receivingAddress,
@@ -45,9 +45,9 @@ class AcceptTransfer extends React.Component {
45 createUnsignedTxn() {
45 createUnsignedTxn() {
46 const { state, props } = this;
46 const { state, props } = this;
47
47
48− const validContracts = need.contracts(props);
48+ const validContracts = need.contracts(props.contracts);
49−
50− const validPoint = need.pointCursor(props); //TODO state.incomingPoint ?
49+ const validPoint = need.pointCursor(props.pointCursor);
50+ //TODO state.incomingPoint ?
51
51
52 return Just(
52 return Just(
53 azimuth.ecliptic.transferPoint(
53 azimuth.ecliptic.transferPoint(
@@ -74,46 +74,42 @@ class AcceptTransfer extends React.Component {
74 : 'etherscan.io';
74 : 'etherscan.io';
75
75
76 return (
76 return (
77− <Row>
77+ <View>
78− <Col>
79− <H1>
78+ <H1>
80− {'Accept Transfer of '}{' '}
79+ {'Accept Transfer of '}{' '}
81− <code>{` ${ob.patp(state.incomingPoint)} `}</code>
80+ <code>{` ${ob.patp(state.incomingPoint)} `}</code>
82− </H1>
81+ </H1>
83−
82+
84− <P>
83+ <P>
85− {"By default, the recipient is the address you're logged in " +
84+ {"By default, the recipient is the address you're logged in " +
86− 'as. But you can transfer to any address you like.'}
85+ 'as. But you can transfer to any address you like.'}
87− </P>
86+ </P>
88−
87+
89− <AddressInput
88+ <AddressInput
90− className="mono mt-8"
89+ className="mono mt-8"
91− prop-size="lg"
90+ prop-size="lg"
92− prop-format="innerLabel"
91+ prop-format="innerLabel"
93− value={state.receivingAddress}
92+ value={state.receivingAddress}
94− onChange={v => this.handleAddressInput(v)}>
93+ onChange={v => this.handleAddressInput(v)}>
95− <InnerLabel>{'Receiving Address'}</InnerLabel>
94+ <InnerLabel>{'Receiving Address'}</InnerLabel>
96− <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
95+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
97− </AddressInput>
96+ </AddressInput>
98−
97+
99− <Anchor
98+ <Anchor
100− className={'mt-1 sm'}
99+ className={'mt-1 sm'}
101− prop-size="sm"
100+ prop-size="sm"
102− prop-disabled={
103− !isValidAddress(state.receivingAddress) || !esvisible
101+ prop-disabled={!isValidAddress(state.receivingAddress) || !esvisible}
104− }
105− target={'_blank'}
102+ target={'_blank'}
106− href={`https://${esdomain}/address/${state.receivingAddress}`}>
103+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
107− {'View on Etherscan ↗'}
104+ {'View on Etherscan ↗'}
108− </Anchor>
105+ </Anchor>
109−
106+
110− <StatelessTransaction
107+ <StatelessTransaction
111− canGenerate={canGenerate}
108+ canGenerate={canGenerate}
112− createUnsignedTxn={this.createUnsignedTxn}
109+ createUnsignedTxn={this.createUnsignedTxn}
113− ref={this.statelessRef}
110+ ref={this.statelessRef}
114− />
111+ />
115− </Col>
112+ </View>
116− </Row>
117 );
113 );
118 }
114 }
119}
115}
src/views/CancelTransfer.js+18−19
@@ -1,6 +1,6 @@
1import Maybe from 'folktale/maybe';
1import Maybe from 'folktale/maybe';
2import React from 'react';
2import React from 'react';
3−import { Row, Col, H1, P } from '../components/old/Base';
3+import { H1, P } from '../components/old/Base';
4import * as azimuth from 'azimuth-js';
4import * as azimuth from 'azimuth-js';
5import * as ob from 'urbit-ob';
5import * as ob from 'urbit-ob';
6import * as need from '../lib/need';
6import * as need from '../lib/need';
@@ -11,12 +11,13 @@ import { withNetwork } from '../store/network';
11import { compose } from '../lib/lib';
11import { compose } from '../lib/lib';
12import { withPointCursor } from '../store/pointCursor';
12import { withPointCursor } from '../store/pointCursor';
13import { withPointCache } from '../store/pointCache';
13import { withPointCache } from '../store/pointCache';
14+import View from 'components/View';
14
15
15class CancelTransfer extends React.Component {
16class CancelTransfer extends React.Component {
16 constructor(props) {
17 constructor(props) {
17 super(props);
18 super(props);
18
19
19− const pointInTransfer = need.pointCursor(props);
20+ const pointInTransfer = need.pointCursor(props.pointCursor);
20
21
21 this.state = {
22 this.state = {
22 proxyAddress: '',
23 proxyAddress: '',
@@ -29,9 +30,9 @@ class CancelTransfer extends React.Component {
29 createUnsignedTxn() {
30 createUnsignedTxn() {
30 const { props } = this;
31 const { props } = this;
31
32
32− const validContracts = need.contracts(props);
33+ const validContracts = need.contracts(props.contracts);
33−
34− const validPoint = need.pointCursor(props); //TODO this.state.pointInTransfer ?
34+ const validPoint = need.pointCursor(props.pointCursor);
35+ //TODO this.state.pointInTransfer ?
35
36
36 const txn = azimuth.ecliptic.setTransferProxy(
37 const txn = azimuth.ecliptic.setTransferProxy(
37 validContracts,
38 validContracts,
@@ -56,20 +57,18 @@ class CancelTransfer extends React.Component {
56 const canGenerate = true;
57 const canGenerate = true;
57
58
58 return (
59 return (
59− <Row>
60+ <View>
60− <Col>
61− <H1>
61+ <H1>
62− {'Cancel Transfer of '}{' '}
62+ {'Cancel Transfer of '}{' '}
63− <code>{` ${ob.patp(state.pointInTransfer)} `}</code>
63+ <code>{` ${ob.patp(state.pointInTransfer)} `}</code>
64− </H1>
64+ </H1>
65−
65+
66− <P>{`This action will cancel the transfer to ${proxy}.`}</P>
66+ <P>{`This action will cancel the transfer to ${proxy}.`}</P>
67− <StatelessTransaction
67+ <StatelessTransaction
68− canGenerate={canGenerate}
68+ canGenerate={canGenerate}
69− createUnsignedTxn={this.createUnsignedTxn}
69+ createUnsignedTxn={this.createUnsignedTxn}
70− />
70+ />
71− </Col>
71+ </View>
72− </Row>
73 );
72 );
74 }
73 }
75}
74}
src/views/CreateGalaxy.js+63−64
@@ -5,7 +5,7 @@ import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
5import * as need from '../lib/need';
6
6
7import { Button } from '../components/old/Base';
7import { Button } from '../components/old/Base';
8−import { Row, Col, H1, P, Anchor } from '../components/old/Base';
8+import { H1, P, Anchor } from '../components/old/Base';
9import {
9import {
10 InnerLabel,
10 InnerLabel,
11 GalaxyInput,
11 GalaxyInput,
@@ -23,6 +23,7 @@ import { ETH_ZERO_ADDR, isValidAddress, eqAddr } from '../lib/wallet';
23import { isValidGalaxy, compose } from '../lib/lib';
23import { isValidGalaxy, compose } from '../lib/lib';
24import { withNetwork } from '../store/network';
24import { withNetwork } from '../store/network';
25import { withWallet } from '../store/wallet';
25import { withWallet } from '../store/wallet';
26+import View from 'components/View';
26
27
27const buttonTriState = status => {
28const buttonTriState = status => {
28 if (status === null) return 'blue';
29 if (status === null) return 'blue';
@@ -40,7 +41,7 @@ class CreateGalaxy extends React.Component {
40 constructor(props) {
41 constructor(props) {
41 super(props);
42 super(props);
42
43
43− const galaxyOwner = need.address(props);
44+ const galaxyOwner = need.addressFromWallet(props.wallet);
44
45
45 this.state = {
46 this.state = {
46 galaxyOwner: galaxyOwner,
47 galaxyOwner: galaxyOwner,
@@ -72,7 +73,7 @@ class CreateGalaxy extends React.Component {
72 if (canDecodePatp(state.galaxyName) === false) return Maybe.Nothing();
73 if (canDecodePatp(state.galaxyName) === false) return Maybe.Nothing();
73 if (isValidGalaxy(state.galaxyName) === false) return Maybe.Nothing();
74 if (isValidGalaxy(state.galaxyName) === false) return Maybe.Nothing();
74
75
75− const validContracts = need.contracts(props);
76+ const validContracts = need.contracts(props.contracts);
76
77
77 const galaxyDec = parseInt(ob.patp2dec(state.galaxyName), 10);
78 const galaxyDec = parseInt(ob.patp2dec(state.galaxyName), 10);
78
79
@@ -93,7 +94,7 @@ class CreateGalaxy extends React.Component {
93 return;
94 return;
94 }
95 }
95
96
96− const validContracts = need.contracts(props);
97+ const validContracts = need.contracts(props.contracts);
97
98
98 const galaxyDec = ob.patp2dec(state.galaxyName);
99 const galaxyDec = ob.patp2dec(state.galaxyName);
99
100
@@ -128,67 +129,65 @@ class CreateGalaxy extends React.Component {
128 : 'etherscan.io';
129 : 'etherscan.io';
129
130
130 return (
131 return (
131− <Row>
132+ <View>
132− <Col>
133− <H1> {'Create a Galaxy'} </H1>
133+ <H1> {'Create a Galaxy'} </H1>
134−
134+
135− <P>
135+ <P>
136− {'Enter the galaxy to create and the address that will own ' +
136+ {'Enter the galaxy to create and the address that will own ' +
137− 'it (defaulting to this account, if not provided).'}
137+ 'it (defaulting to this account, if not provided).'}
138− </P>
138+ </P>
139−
139+
140− <GalaxyInput
140+ <GalaxyInput
141− className="mono"
141+ className="mono"
142− prop-size="lg"
142+ prop-size="lg"
143− prop-format="innerLabel"
143+ prop-format="innerLabel"
144− autoFocus
144+ autoFocus
145− placeholder="e.g. ~zod"
145+ placeholder="e.g. ~zod"
146− value={state.galaxyName}
146+ value={state.galaxyName}
147− onChange={v => this.handleGalaxyNameInput(v)}>
147+ onChange={v => this.handleGalaxyNameInput(v)}>
148− <InnerLabel>{'Galaxy Name'}</InnerLabel>
148+ <InnerLabel>{'Galaxy Name'}</InnerLabel>
149− <ValidatedSigil
149+ <ValidatedSigil
150− className="tr-0 mt-05 mr-0 abs"
150+ className="tr-0 mt-05 mr-0 abs"
151− patp={state.galaxyName}
151+ patp={state.galaxyName}
152− size={68}
152+ size={68}
153− margin={8}
153+ margin={8}
154− />
155− </GalaxyInput>
156−
157− <AddressInput
158− className="mono mt-8"
159− prop-size="lg"
160− prop-format="innerLabel"
161− value={state.galaxyOwner}
162− onChange={v => this.handleAddressInput(v)}>
163− <InnerLabel>{'Address that will own this galaxy'}</InnerLabel>
164− <ShowBlockie className={'mt-1'} address={state.galaxyOwner} />
165− </AddressInput>
166−
167− <Anchor
168− className={'mt-1'}
169− prop-size={'sm'}
170− prop-disabled={!validAddress || !esvisible}
171− target={'_blank'}
172− href={`https://${esdomain}/address/${state.galaxyOwner}`}>
173− {'View on Etherscan ↗'}
174− </Anchor>
175−
176− <Button
177− prop-size="lg wide"
178− className="mt-8"
179− prop-color={buttonTriState(state.isAvailable)}
180− disabled={!validGalaxy}
181− onClick={() => this.confirmAvailability()}>
182− {buttonTriStateText(state.isAvailable)}
183− </Button>
184−
185− <StatelessTransaction
186− ref={this.statelessRef}
187− canGenerate={canGenerate}
188− createUnsignedTxn={this.createUnsignedTxn}
189 />
154 />
190− </Col>
155+ </GalaxyInput>
191− </Row>
156+
157+ <AddressInput
158+ className="mono mt-8"
159+ prop-size="lg"
160+ prop-format="innerLabel"
161+ value={state.galaxyOwner}
162+ onChange={v => this.handleAddressInput(v)}>
163+ <InnerLabel>{'Address that will own this galaxy'}</InnerLabel>
164+ <ShowBlockie className={'mt-1'} address={state.galaxyOwner} />
165+ </AddressInput>
166+
167+ <Anchor
168+ className={'mt-1'}
169+ prop-size={'sm'}
170+ prop-disabled={!validAddress || !esvisible}
171+ target={'_blank'}
172+ href={`https://${esdomain}/address/${state.galaxyOwner}`}>
173+ {'View on Etherscan ↗'}
174+ </Anchor>
175+
176+ <Button
177+ prop-size="lg wide"
178+ className="mt-8"
179+ prop-color={buttonTriState(state.isAvailable)}
180+ disabled={!validGalaxy}
181+ onClick={() => this.confirmAvailability()}>
182+ {buttonTriStateText(state.isAvailable)}
183+ </Button>
184+
185+ <StatelessTransaction
186+ ref={this.statelessRef}
187+ canGenerate={canGenerate}
188+ createUnsignedTxn={this.createUnsignedTxn}
189+ />
190+ </View>
192 );
191 );
193 }
192 }
194}
193}
src/views/GenKeyfile.js+36−38
@@ -2,7 +2,7 @@ import React from 'react';
2import * as need from '../lib/need';
2import * as need from '../lib/need';
3
3
4import { Button } from '../components/old/Base';
4import { Button } from '../components/old/Base';
5−import { Row, Col, H1, P } from '../components/old/Base';
5+import { H1, P } from '../components/old/Base';
6
6
7import * as ob from 'urbit-ob';
7import * as ob from 'urbit-ob';
8import * as kg from 'urbit-key-generation/dist';
8import * as kg from 'urbit-key-generation/dist';
@@ -14,6 +14,7 @@ import { compose } from '../lib/lib';
14import { withWallet } from '../store/wallet';
14import { withWallet } from '../store/wallet';
15import { withPointCursor } from '../store/pointCursor';
15import { withPointCursor } from '../store/pointCursor';
16import { withPointCache } from '../store/pointCache';
16import { withPointCache } from '../store/pointCache';
17+import View from 'components/View';
17
18
18class GenKeyfile extends React.Component {
19class GenKeyfile extends React.Component {
19 constructor(props) {
20 constructor(props) {
@@ -26,9 +27,8 @@ class GenKeyfile extends React.Component {
26 }
27 }
27
28
28 getPointDetails() {
29 getPointDetails() {
29− const point = need.pointCursor(this.props);
30+ const point = need.pointCursor(this.props.pointCursor);
30−
31− const pointDetails = need.fromPointCache(this.props, point);
31+ const pointDetails = need.fromPointCache(this.props.pointCache, point);
32
32
33 // in case we did SetKeys earlier this session, make sure to generate the
33 // in case we did SetKeys earlier this session, make sure to generate the
34 // newer keyfile, rather than the one that will expire soon
34 // newer keyfile, rather than the one that will expire soon
@@ -94,45 +94,43 @@ class GenKeyfile extends React.Component {
94 const { keyfile, loaded } = this.state;
94 const { keyfile, loaded } = this.state;
95
95
96 return (
96 return (
97− <Row>
97+ <View>
98− <Col className={'col-md-8'}>
99− <H1>{'Generate keyfile'}</H1>
98+ <H1>{'Generate keyfile'}</H1>
100
99
101− <P>{'Download a private key file for booting this point in Arvo.'}</P>
100+ <P>{'Download a private key file for booting this point in Arvo.'}</P>
102
101
103− {keyfile === '' && !loaded && <P>{'Generating keyfile...'}</P>}
102+ {keyfile === '' && !loaded && <P>{'Generating keyfile...'}</P>}
104
103
105− {keyfile === '' && loaded && (
104+ {keyfile === '' && loaded && (
106− <React.Fragment>
105+ <React.Fragment>
107− <P>
106+ <P>
108− <b>Warning: </b>
107+ <b>Warning: </b>
109− {`No valid network seed detected. To generate a keyfile, you
108+ {`No valid network seed detected. To generate a keyfile, you
110 must reset your networking keys, or try logging in with your
109 must reset your networking keys, or try logging in with your
111 master ticket or management mnemonic.`}
110 master ticket or management mnemonic.`}
112− </P>
111+ </P>
113−
112+
114− <P>
113+ <P>
115− {`If you've just reset your networking keys, you may need to wait for the transaction to go through. Check back shortly.`}
114+ {`If you've just reset your networking keys, you may need to wait for the transaction to go through. Check back shortly.`}
116− </P>
115+ </P>
117− </React.Fragment>
116+ </React.Fragment>
118− )}
117+ )}
119−
118+
120− {keyfile !== '' && (
119+ {keyfile !== '' && (
121− <React.Fragment>
120+ <React.Fragment>
122− <div className="pb-5 text-code keyfile">{keyfile}</div>
121+ <div className="pb-5 text-code keyfile">{keyfile}</div>
123− <Button
122+ <Button
124− onClick={() => {
123+ onClick={() => {
125− let blob = new Blob([keyfile], {
124+ let blob = new Blob([keyfile], {
126− type: 'text/plain;charset=utf-8',
125+ type: 'text/plain;charset=utf-8',
127− });
126+ });
128− saveAs(blob, `${ob.patp(point).slice(1)}-${revision}.key`);
127+ saveAs(blob, `${ob.patp(point).slice(1)}-${revision}.key`);
129− }}>
128+ }}>
130− Download →
129+ Download →
131− </Button>
130+ </Button>
132− </React.Fragment>
131+ </React.Fragment>
133− )}
132+ )}
134− </Col>
133+ </View>
135− </Row>
136 );
134 );
137 }
135 }
138}
136}
src/views/InviteTicket.js+37−33
@@ -1,17 +1,18 @@
1import { Just, Nothing } from 'folktale/maybe';
1import { Just, Nothing } from 'folktale/maybe';
2import React from 'react';
2import React from 'react';
3+import * as azimuth from 'azimuth-js';
4+import * as need from 'lib/need';
5+
6+import View from 'components/View';
7+
3import {
8import {
4 InnerLabel,
9 InnerLabel,
5 Warning,
10 Warning,
6 TicketInput,
11 TicketInput,
7 VerifyTicketInput,
12 VerifyTicketInput,
8 Button,
13 Button,
9− Row,
10− Col,
11 Passport,
14 Passport,
12} from '../components/old/Base';
15} from '../components/old/Base';
13−import * as azimuth from 'azimuth-js';
14−import * as need from '../lib/need';
15
16
16import { randomPatq, compose } from '../lib/lib';
17import { randomPatq, compose } from '../lib/lib';
17import { ROUTE_NAMES } from '../lib/routeNames';
18import { ROUTE_NAMES } from '../lib/routeNames';
@@ -30,6 +31,7 @@ import {
30import { generateWallet, startTransactions } from '../lib/invite';
31import { generateWallet, startTransactions } from '../lib/invite';
31import { withNetwork } from '../store/network';
32import { withNetwork } from '../store/network';
32import { withWallet } from '../store/wallet';
33import { withWallet } from '../store/wallet';
34+import Grid from 'components/Grid';
33
35
34class InviteTicket extends React.Component {
36class InviteTicket extends React.Component {
35 constructor(props) {
37 constructor(props) {
@@ -104,9 +106,9 @@ class InviteTicket extends React.Component {
104
106
105 const addr = inviteWallet.address;
107 const addr = inviteWallet.address;
106
108
107− const ctrcs = need.contracts(this.props);
109+ const contracts = need.contracts(this.props.contracts);
108
110
109− const incoming = await azimuth.azimuth.getTransferringFor(ctrcs, addr);
111+ const incoming = await azimuth.azimuth.getTransferringFor(contracts, addr);
110
112
111 this.setState({
113 this.setState({
112 walletStates: this.state.walletStates.concat(WALLET_STATES.GENERATING),
114 walletStates: this.state.walletStates.concat(WALLET_STATES.GENERATING),
@@ -393,33 +395,35 @@ class InviteTicket extends React.Component {
393 let errorDisplay = this.getErrors();
395 let errorDisplay = this.getErrors();
394
396
395 return (
397 return (
396− <Row>
398+ <View.Full>
397− <Col className="col-md-4 mt-">
399+ <Grid>
400+ <Grid.Item half={1}>
398− {stageDisplay}
401+ {stageDisplay}
399− {errorDisplay}
402+ {errorDisplay}
400− {stageText}
403+ {stageText}
401− {ticketElem}
404+ {ticketElem}
402− {continueButton}
405+ {continueButton}
403−
406+
404− {this.state.stage === INVITE_STAGES.INVITE_LOGIN && (
407+ {this.state.stage === INVITE_STAGES.INVITE_LOGIN && (
405− <Button
408+ <Button
406− prop-type={`link`}
409+ prop-type={`link`}
407− prop-size={`sm`}
410+ prop-size={`sm`}
408− className={`block mt-4`}
411+ className={`block mt-4`}
409− onClick={this.navigateLogin}>
412+ onClick={this.navigateLogin}>
410− {`Log in`}
413+ {`Log in`}
411− </Button>
414+ </Button>
412− )}
415+ )}
413− </Col>
416+ </Grid.Item>
414− <Col className="col-md-offset-3 col-md-5 mt-18">
417+ <Grid.Item half={2}>
415− <Passport
418+ <Passport
416− point={this.state.realPoint}
419+ point={this.state.realPoint}
417− wallet={this.state.realWallet}
420+ wallet={this.state.realWallet}
418− walletStates={this.state.walletStates}
421+ walletStates={this.state.walletStates}
419− pushWalletState={this.pushWalletState}
422+ pushWalletState={this.pushWalletState}
420− />
423+ />
421− </Col>
424+ </Grid.Item>
422− </Row>
425+ </Grid>
426+ </View.Full>
423 );
427 );
424 }
428 }
425}
429}
src/views/InvitesManage.js+38−41
@@ -5,8 +5,6 @@ import * as azimuth from 'azimuth-js';
5import * as need from '../lib/need';
5import * as need from '../lib/need';
6
6
7import {
7import {
8− Row,
9− Col,
10 Warning,
8 Warning,
11 Input,
9 Input,
12 PointInput,
10 PointInput,
@@ -17,6 +15,7 @@ import StatelessTransaction from '../components/old/StatelessTransaction';
17import { withNetwork } from '../store/network';
15import { withNetwork } from '../store/network';
18import { compose } from '../lib/lib';
16import { compose } from '../lib/lib';
19import { withPointCursor } from '../store/pointCursor';
17import { withPointCursor } from '../store/pointCursor';
18+import View from 'components/View';
20
19
21class InvitesManage extends React.Component {
20class InvitesManage extends React.Component {
22 constructor(props) {
21 constructor(props) {
@@ -40,8 +39,8 @@ class InvitesManage extends React.Component {
40 }
39 }
41
40
42 componentDidMount() {
41 componentDidMount() {
43− this.point = need.pointCursor(this.props);
42+ this.point = need.pointCursor(this.props.pointCursor);
44− this.contracts = need.contracts(this.props);
43+ this.contracts = need.contracts(this.props.contracts);
45
44
46 azimuth.azimuth
45 azimuth.azimuth
47 .isSpawnProxy(
46 .isSpawnProxy(
@@ -140,44 +139,42 @@ class InvitesManage extends React.Component {
140 });
139 });
141
140
142 return (
141 return (
143− <Row>
142+ <View>
144− <Col>
145− <p>
143+ <p>
146− {
144+ {
147− 'manage invites here, for stars. can only give invites to child planets'
145+ 'manage invites here, for stars. can only give invites to child planets'
148− }
146+ }
149− </p>
147+ </p>
150−
148+
151− {spawnProxyWarning}
149+ {spawnProxyWarning}
152−
150+
153− <PointInput
151+ <PointInput
154− prop-format="innerlabel"
152+ prop-format="innerlabel"
155− prop-size="lg"
153+ prop-size="lg"
156− placeholder={'~sampel-sipnem'}
154+ placeholder={'~sampel-sipnem'}
157− value={this.state.planetInput}
155+ value={this.state.planetInput}
158− onChange={this.handlePointInput}>
156+ onChange={this.handlePointInput}>
159− <InnerLabel>{'Planet to set invites for'}</InnerLabel>
157+ <InnerLabel>{'Planet to set invites for'}</InnerLabel>
160− <ValidatedSigil
158+ <ValidatedSigil
161− patp={this.state.targetPlanet}
159+ patp={this.state.targetPlanet}
162− validator={() => this.validatePoint}
160+ validator={() => this.validatePoint}
163− />
164− </PointInput>
165−
166− <Input
167− prop-format="innerlabel"
168− prop-size="lg"
169− value={this.state.targetPoolSize}
170− onChange={this.handlePoolSizeInput}>
171− <InnerLabel>{`Available invites ${poolSizeText}`}</InnerLabel>
172− </Input>
173−
174− <StatelessTransaction
175− canGenerate={this.state.canGenerate}
176− createUnsignedTxn={this.createUnsignedTxn}
177− ref={this.statelessRef}
178 />
161 />
179− </Col>
162+ </PointInput>
180− </Row>
163+
164+ <Input
165+ prop-format="innerlabel"
166+ prop-size="lg"
167+ value={this.state.targetPoolSize}
168+ onChange={this.handlePoolSizeInput}>
169+ <InnerLabel>{`Available invites ${poolSizeText}`}</InnerLabel>
170+ </Input>
171+
172+ <StatelessTransaction
173+ canGenerate={this.state.canGenerate}
174+ createUnsignedTxn={this.createUnsignedTxn}
175+ ref={this.statelessRef}
176+ />
177+ </View>
181 );
178 );
182 }
179 }
183}
180}
src/views/InvitesSend.js+14−15
@@ -4,7 +4,7 @@ import * as azimuth from 'azimuth-js';
4import * as need from '../lib/need';
4import * as need from '../lib/need';
5
5
6import { hasReceived, sendMail } from '../lib/inviteMail';
6import { hasReceived, sendMail } from '../lib/inviteMail';
7−import { Row, Col, Button, Input, H3, Warning } from '../components/old/Base';
7+import { Button, Input, H3, Warning } from '../components/old/Base';
8
8
9// for wallet generation
9// for wallet generation
10import * as wg from '../_walletgen/lib/lib';
10import * as wg from '../_walletgen/lib/lib';
@@ -23,6 +23,7 @@ import { withNetwork } from '../store/network';
23import { compose } from '../lib/lib';
23import { compose } from '../lib/lib';
24import { withWallet } from '../store/wallet';
24import { withWallet } from '../store/wallet';
25import { withPointCursor } from '../store/pointCursor';
25import { withPointCursor } from '../store/pointCursor';
26+import View from 'components/View';
26
27
27const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
28const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
28const GAS_LIMIT = 350000;
29const GAS_LIMIT = 350000;
@@ -72,10 +73,10 @@ class InvitesSend extends React.Component {
72 }
73 }
73
74
74 componentDidMount() {
75 componentDidMount() {
75− this.point = parseInt(need.pointCursor(this.props), 10);
76+ this.point = need.pointCursor(this.props.pointCursor);
76− this.address = need.address(this.props);
77+ this.address = need.addressFromWallet(this.props.wallet);
77− this.contracts = need.contracts(this.props);
78+ this.contracts = need.contracts(this.props.contracts);
78− this.web3 = need.web3(this.props);
79+ this.web3 = need.web3(this.props.web3);
79
80
80 console.log(azimuth.delegatedSending);
81 console.log(azimuth.delegatedSending);
81 azimuth.delegatedSending
82 azimuth.delegatedSending
@@ -476,21 +477,19 @@ class InvitesSend extends React.Component {
476 }
477 }
477
478
478 return (
479 return (
479− <Row>
480+ <View>
480− <Col>
481− <p>{'send invites here, for planets'}</p>
481+ <p>{'send invites here, for planets'}</p>
482
482
483− <p>{invitesAvailable}</p>
483+ <p>{invitesAvailable}</p>
484
484
485− <ul>{invitesSent}</ul>
485+ <ul>{invitesSent}</ul>
486
486
487− {error}
487+ {error}
488
488
489− {fundingMessage}
489+ {fundingMessage}
490
490
491− {inputs}
491+ {inputs}
492− </Col>
492+ </View>
493− </Row>
494 );
493 );
495 }
494 }
496}
495}
src/views/IssueChild.js+81−86
@@ -5,8 +5,6 @@ import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
5import * as need from '../lib/need';
6
6
7import {
7import {
8− Row,
9− Col,
10 H1,
8 H1,
11 P,
9 P,
12 Anchor,
10 Anchor,
@@ -27,6 +25,7 @@ import { isValidAddress } from '../lib/wallet';
27import { withNetwork } from '../store/network';
25import { withNetwork } from '../store/network';
28import { compose } from '../lib/lib';
26import { compose } from '../lib/lib';
29import { withPointCursor } from '../store/pointCursor';
27import { withPointCursor } from '../store/pointCursor';
28+import View from 'components/View';
30
29
31const setFind = (set, pred) => {
30const setFind = (set, pred) => {
32 for (const e of set) {
31 for (const e of set) {
@@ -41,7 +40,7 @@ class IssueChild extends React.Component {
41 constructor(props) {
40 constructor(props) {
42 super(props);
41 super(props);
43
42
44− const issuingPoint = parseInt(need.pointCursor(props), 10);
43+ const issuingPoint = need.pointCursor(props.pointCursor);
45
44
46 const getCandidate = () => ob.patp(getSpawnCandidate(issuingPoint));
45 const getCandidate = () => ob.patp(getSpawnCandidate(issuingPoint));
47
46
@@ -76,7 +75,7 @@ class IssueChild extends React.Component {
76 componentWillMount() {
75 componentWillMount() {
77 const { issuingPoint } = this.state;
76 const { issuingPoint } = this.state;
78
77
79− const validContracts = need.contracts(this.props);
78+ const validContracts = need.contracts(this.props.contracts);
80
79
81 azimuth
80 azimuth
82 .getUnspawnedChildren(validContracts, issuingPoint)
81 .getUnspawnedChildren(validContracts, issuingPoint)
@@ -110,7 +109,7 @@ class IssueChild extends React.Component {
110 if (state.isAvailable === false) return Nothing();
109 if (state.isAvailable === false) return Nothing();
111 if (canDecodePatp(state.desiredPoint) === false) return Nothing();
110 if (canDecodePatp(state.desiredPoint) === false) return Nothing();
112
111
113− const validContracts = need.contracts(props);
112+ const validContracts = need.contracts(props.contracts);
114
113
115 const pointDec = ob.patp2dec(state.desiredPoint);
114 const pointDec = ob.patp2dec(state.desiredPoint);
116
115
@@ -163,92 +162,88 @@ class IssueChild extends React.Component {
163 : 'etherscan.io';
162 : 'etherscan.io';
164
163
165 return (
164 return (
166− <Row>
165+ <View>
167− <Col>
168− <H1>
166+ <H1>
169− {'Issue a Child From '}{' '}
167+ {'Issue a Child From '}{' '}
170− <code>{`${ob.patp(state.issuingPoint)}`}</code>
168+ <code>{`${ob.patp(state.issuingPoint)}`}</code>
171− </H1>
169+ </H1>
172−
170+
173− <P>
171+ <P>
174− {`Please enter the point you would like to issue, and specify the
172+ {`Please enter the point you would like to issue, and specify the
175 receiving Ethereum address. If you need to create an address, you
173 receiving Ethereum address. If you need to create an address, you
176 can also use Wallet Generator.`}
174 can also use Wallet Generator.`}
177− </P>
175+ </P>
178
176
179− <P>
177+ <P>
180− {`Your point can only issue children with particular names. Some
178+ {`Your point can only issue children with particular names. Some
181 valid suggestions for `}
179 valid suggestions for `}
182− {<code>{ob.patp(state.issuingPoint)}</code>}
180+ {<code>{ob.patp(state.issuingPoint)}</code>}
183− {' are '}
181+ {' are '}
184− <code>{state.suggestions[0]}</code>
182+ <code>{state.suggestions[0]}</code>
185− {', '}
183+ {', '}
186− <code>{state.suggestions[1]}</code>
184+ <code>{state.suggestions[1]}</code>
187− {', and '}
185+ {', and '}
188− <code>{state.suggestions[2]}</code>
186+ <code>{state.suggestions[2]}</code>
189− {'.'}
187+ {'.'}
190− </P>
188+ </P>
191−
189+
192− <PointInput
190+ <PointInput
193− prop-size="lg"
191+ prop-size="lg"
194− prop-format="innerLabel"
192+ prop-format="innerLabel"
195− className={'mono mt-8'}
193+ className={'mono mt-8'}
196− placeholder={`e.g. ${state.suggestions[3]}`}
194+ placeholder={`e.g. ${state.suggestions[3]}`}
197− value={state.desiredPoint}
195+ value={state.desiredPoint}
198− onChange={this.handlePointInput}>
196+ onChange={this.handlePointInput}>
199− <InnerLabel>{'Point to Issue'}</InnerLabel>
197+ <InnerLabel>{'Point to Issue'}</InnerLabel>
200− <div
198+ <div
201− style={{
199+ style={{
202− marginTop: '8.8rem',
200+ marginTop: '8.8rem',
203− marginLeft: '4.6rem',
201+ marginLeft: '4.6rem',
204− fontSize: '5rem',
202+ fontSize: '5rem',
205− color: '#757575',
203+ color: '#757575',
206− whiteSpace: 'pre-wrap',
204+ whiteSpace: 'pre-wrap',
207− }}
205+ }}
208− className="abs tl-0 mono">
206+ className="abs tl-0 mono">
209− {state.autoComplete}
207+ {state.autoComplete}
210− </div>
208+ </div>
211− <ValidatedSigil
209+ <ValidatedSigil
212− className={'tr-0 mt-05 mr-0 abs'}
210+ className={'tr-0 mt-05 mr-0 abs'}
213− patp={state.desiredPoint}
211+ patp={state.desiredPoint}
214− size={68}
212+ size={68}
215− margin={8}
213+ margin={8}
216− validator={() => this.validatePoint(state.desiredPoint)}
214+ validator={() => this.validatePoint(state.desiredPoint)}
217− />
218− </PointInput>
219−
220− <AddressInput
221− className="text-mono mt-8"
222− prop-size="lg"
223− prop-format="innerLabel"
224− placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
225− value={state.receivingAddress}
226− disabled={
227− Nothing.hasInstance(state.isAvailable) || !state.isAvailable.value
228− }
229− onChange={v => this.handleAddressInput(v)}>
230− <InnerLabel>{'Receiving Address'}</InnerLabel>
231− <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
232− </AddressInput>
233−
234− <Anchor
235− className={'mt-1'}
236− prop-size={'sm'}
237− prop-disabled={
238− !isValidAddress(state.receivingAddress) || !esvisible
239− }
240− target={'_blank'}
241− href={`https://${esdomain}/address/${state.receivingAddress}`}>
242− {'View on Etherscan ↗'}
243− </Anchor>
244−
245− <StatelessTransaction
246− canGenerate={canGenerate}
247− createUnsignedTxn={this.createUnsignedTxn}
248− ref={this.statelessRef}
249 />
215 />
250− </Col>
216+ </PointInput>
251− </Row>
217+
218+ <AddressInput
219+ className="text-mono mt-8"
220+ prop-size="lg"
221+ prop-format="innerLabel"
222+ placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
223+ value={state.receivingAddress}
224+ disabled={
225+ Nothing.hasInstance(state.isAvailable) || !state.isAvailable.value
226+ }
227+ onChange={v => this.handleAddressInput(v)}>
228+ <InnerLabel>{'Receiving Address'}</InnerLabel>
229+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
230+ </AddressInput>
231+
232+ <Anchor
233+ className={'mt-1'}
234+ prop-size={'sm'}
235+ prop-disabled={!isValidAddress(state.receivingAddress) || !esvisible}
236+ target={'_blank'}
237+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
238+ {'View on Etherscan ↗'}
239+ </Anchor>
240+
241+ <StatelessTransaction
242+ canGenerate={canGenerate}
243+ createUnsignedTxn={this.createUnsignedTxn}
244+ ref={this.statelessRef}
245+ />
246+ </View>
252 );
247 );
253 }
248 }
254}
249}
src/views/Keystore.js+47−48
@@ -4,7 +4,7 @@ import React from 'react';
4import * as keythereum from 'keythereum';
4import * as keythereum from 'keythereum';
5import { Button, UploadButton } from '../components/old/Base';
5import { Button, UploadButton } from '../components/old/Base';
6import { Input, InnerLabel, InputCaption } from '../components/old/Base';
6import { Input, InnerLabel, InputCaption } from '../components/old/Base';
7−import { Row, Col, H1, H3, Warning } from '../components/old/Base';
7+import { H1, H3, Warning } from '../components/old/Base';
8
8
9import { BRIDGE_ERROR } from '../lib/error';
9import { BRIDGE_ERROR } from '../lib/error';
10import { ROUTE_NAMES } from '../lib/routeNames';
10import { ROUTE_NAMES } from '../lib/routeNames';
@@ -12,6 +12,7 @@ import { withHistory } from '../store/history';
12import { EthereumWallet } from '../lib/wallet';
12import { EthereumWallet } from '../lib/wallet';
13import { compose } from '../lib/lib';
13import { compose } from '../lib/lib';
14import { withWallet } from '../store/wallet';
14import { withWallet } from '../store/wallet';
15+import View from 'components/View';
15
16
16class Keystore extends React.Component {
17class Keystore extends React.Component {
17 constructor(props) {
18 constructor(props) {
@@ -108,55 +109,53 @@ class Keystore extends React.Component {
108 );
109 );
109
110
110 return (
111 return (
111− <Row>
112+ <View>
112− <Col className={'measure-md'}>
113− <H1 className={'mb-4'}>{'Upload Your Keystore File'}</H1>
113+ <H1 className={'mb-4'}>{'Upload Your Keystore File'}</H1>
114− <InputCaption>
114+ <InputCaption>
115− {`Please upload your Ethereum keystore file. If your keystore
115+ {`Please upload your Ethereum keystore file. If your keystore
116 file is encrypted with a password, you'll also need to enter
116 file is encrypted with a password, you'll also need to enter
117 that below.`}
117 that below.`}
118− </InputCaption>
118+ </InputCaption>
119−
119+
120− <UploadButton
120+ <UploadButton
121− className={`btn ${uploadButtonClass} mt-10`}
121+ className={`btn ${uploadButtonClass} mt-10`}
122− onChange={this.handleKeystoreUpload}>
122+ onChange={this.handleKeystoreUpload}>
123− <div className={'flex-center-all fs-4 h-11 pointer'}>
123+ <div className={'flex-center-all fs-4 h-11 pointer'}>
124− {'Upload Keystore file'}
124+ {'Upload Keystore file'}
125− </div>
125+ </div>
126− </UploadButton>
126+ </UploadButton>
127−
127+
128− <Input
128+ <Input
129− className="pt-8 mt-8"
129+ className="pt-8 mt-8"
130− prop-size="md"
130+ prop-size="md"
131− prop-format="innerLabel"
131+ prop-format="innerLabel"
132− type="password"
132+ type="password"
133− name="password"
133+ name="password"
134− onChange={this.handlePasswordInput}
134+ onChange={this.handlePasswordInput}
135− value={password}
135+ value={password}
136− autocomplete="off"
136+ autocomplete="off"
137− autoFocus>
137+ autoFocus>
138− <InnerLabel>{'Password'}</InnerLabel>
138+ <InnerLabel>{'Password'}</InnerLabel>
139− </Input>
139+ </Input>
140−
140+
141− <Button
141+ <Button
142− className={` mt-10`}
142+ className={` mt-10`}
143− prop-size={'wide lg'}
143+ prop-size={'wide lg'}
144− disabled={Nothing.hasInstance(keystore)}
144+ disabled={Nothing.hasInstance(keystore)}
145− onClick={this.constructWallet}>
145+ onClick={this.constructWallet}>
146− {'Decrypt'}
146+ {'Decrypt'}
147− </Button>
147+ </Button>
148−
148+
149− {decryptMessage}
149+ {decryptMessage}
150−
150+
151− <Button
151+ <Button
152− className={'mt-10'}
152+ className={'mt-10'}
153− prop-size={'wide lg'}
153+ prop-size={'wide lg'}
154− disabled={Nothing.hasInstance(wallet)}
154+ disabled={Nothing.hasInstance(wallet)}
155− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
155+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
156− {'Continue →'}
156+ {'Continue →'}
157− </Button>
157+ </Button>
158− </Col>
158+ </View>
159− </Row>
160 );
159 );
161 }
160 }
162}
161}
src/views/Landing.js+42−43
@@ -5,60 +5,59 @@ import { H1, P } from '../components/old/Base';
5
5
6import { ROUTE_NAMES } from '../lib/routeNames';
6import { ROUTE_NAMES } from '../lib/routeNames';
7import { useHistory } from '../store/history';
7import { useHistory } from '../store/history';
8+import View from 'components/View';
8
9
9function Landing(props) {
10function Landing(props) {
10 const history = useHistory();
11 const history = useHistory();
11
12
12 return (
13 return (
13− <Row>
14+ <View>
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− {'Claim an invite →'}
27+ {'Claim an invite →'}
28− </Button>
28+ </Button>
29
29
30− <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>
31
31
32− <Button
32+ <Button
33− prop-type="link"
33+ prop-type="link"
34− prop-size="lg"
34+ prop-size="lg"
35− className={'mb-4 mt-8'}
35+ className={'mb-4 mt-8'}
36− onClick={() => history.push(ROUTE_NAMES.NETWORK)}>
36+ onClick={() => history.push(ROUTE_NAMES.NETWORK)}>
37− {'Unlock a Wallet →'}
37+ {'Unlock a Wallet →'}
38− </Button>
38+ </Button>
39
39
40− <P>
40+ <P>
41− {'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 ' +
42− "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 " +
43− 'keypair.'}
43+ 'keypair.'}
44− </P>
44+ </P>
45
45
46− {
46+ {
47− <Row>
47+ <Row>
48− <Col>
48+ <Col>
49− <Button
49+ <Button
50− prop-type={'link'}
50+ prop-type={'link'}
51− prop-size={'lg'}
51+ prop-size={'lg'}
52− className={'mb-4 mt-8'}
52+ className={'mb-4 mt-8'}
53− onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
53+ onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
54− {'View a point →'}
54+ {'View a point →'}
55− </Button>
55+ </Button>
56− <P>{'View an Azimuth point without signing into a wallet.'}</P>
56+ <P>{'View an Azimuth point without signing into a wallet.'}</P>
57− </Col>
57+ </Col>
58− </Row>
58+ </Row>
59− }
59+ }
60− </Col>
60+ </View>
61− </Row>
62 );
61 );
63}
62}
64
63
src/views/Ledger.js+59−64
@@ -2,7 +2,7 @@ import * as bip32 from 'bip32';
2import React from 'react';
2import React from 'react';
3import Maybe from 'folktale/maybe';
3import Maybe from 'folktale/maybe';
4import { Button } from '../components/old/Base';
4import { Button } from '../components/old/Base';
5−import { Row, Col, H1, P, H2 } from '../components/old/Base';
5+import { H1, P, H2 } from '../components/old/Base';
6import { Input, InnerLabel, InnerLabelDropdown } from '../components/old/Base';
6import { Input, InnerLabel, InnerLabelDropdown } from '../components/old/Base';
7import Transport from '@ledgerhq/hw-transport-u2f';
7import Transport from '@ledgerhq/hw-transport-u2f';
8import Eth from '@ledgerhq/hw-app-eth';
8import Eth from '@ledgerhq/hw-app-eth';
@@ -13,6 +13,7 @@ import { ROUTE_NAMES } from '../lib/routeNames';
13import { withHistory } from '../store/history';
13import { withHistory } from '../store/history';
14import { compose } from '../lib/lib';
14import { compose } from '../lib/lib';
15import { withWallet } from '../store/wallet';
15import { withWallet } from '../store/wallet';
16+import View from 'components/View';
16
17
17const chopHdPrefix = str => (str.slice(0, 2) === 'm/' ? str.slice(2) : str);
18const chopHdPrefix = str => (str.slice(0, 2) === 'm/' ? str.slice(2) : str);
18
19
@@ -139,82 +140,76 @@ class Ledger extends React.Component {
139 );
140 );
140
141
141 return (
142 return (
142− <Row>
143+ <View>
143− <Col className={'measure-md'}>
144− <H1>{'Authenticate With Your Ledger'}</H1>
144+ <H1>{'Authenticate With Your Ledger'}</H1>
145
145
146− <H2>{'Running on HTTPS?'}</H2>
146+ <H2>{'Running on HTTPS?'}</H2>
147
147
148− <P>
148+ <P>
149− {`Connect and authenticate to your Ledger, and then open the
149+ {`Connect and authenticate to your Ledger, and then open the
150 "Ethereum" application. If you're running on older firmware,
150 "Ethereum" application. If you're running on older firmware,
151 make sure the "browser support" option is turned on. To sign
151 make sure the "browser support" option is turned on. To sign
152 transactions, you'll also need to enable the "contract data"
152 transactions, you'll also need to enable the "contract data"
153 option.`}
153 option.`}
154− </P>
154+ </P>
155
155
156− <P>
156+ <P>
157− {`If you'd like to use a custom derivation path, you may enter
157+ {`If you'd like to use a custom derivation path, you may enter
158 it below.`}
158 it below.`}
159− </P>
159+ </P>
160
160
161− <H2>{'Running on HTTP?'}</H2>
161+ <H2>{'Running on HTTP?'}</H2>
162
162
163− <P>{`To authenticate and sign transactions with a Ledger, Bridge
163+ <P>{`To authenticate and sign transactions with a Ledger, Bridge
164 must be serving over HTTPS on localhost. You can do this via the
164 must be serving over HTTPS on localhost. You can do this via the
165 following:`}</P>
165 following:`}</P>
166
166
167− <ol className={'measure-md'}>
167+ <ol className={'measure-md'}>
168− <li className={'mt-4'}>
168+ <li className={'mt-4'}>
169− {'Install'}{' '}
169+ {'Install'}{' '}
170− <a
171− target={'_blank'}
172− href={'https://github.com/FiloSottile/mkcert'}>
170+ <a target={'_blank'} href={'https://github.com/FiloSottile/mkcert'}>
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− {
184− ' directory, generate a certificate valid for localhost via '
181+ {' directory, generate a certificate valid for localhost via '}{' '}
185− }{' '}
186− <code>{'mkcert localhost'}</code>
182+ <code>{'mkcert localhost'}</code>
187− {'.'}
183+ {'.'}
188− {'This will produce two files: '}
184+ {'This will produce two files: '}
189− <code>{'localhost.pem'}</code> {', the local certificate, and '}
185+ <code>{'localhost.pem'}</code> {', the local certificate, and '}
190− <code>{'localhost-key.pem'}</code>
186+ <code>{'localhost-key.pem'}</code>
191− {', its corresponding private key.'}
187+ {', its corresponding private key.'}
192− </li>
188+ </li>
193− <li className={'mt-4'}>
189+ <li className={'mt-4'}>
194− {'Run '}
190+ {'Run '}
195− <code>{'python bridge-https.py'}</code>
191+ <code>{'python bridge-https.py'}</code>
196− </li>
192+ </li>
197− </ol>
193+ </ol>
198−
194+
199− {basePathSelection}
195+ {basePathSelection}
200− {truePathSelection}
196+ {truePathSelection}
201−
197+
202− <Button
198+ <Button
203− prop-size={'wide lg'}
199+ prop-size={'wide lg'}
204− className={'mt-8'}
200+ className={'mt-8'}
205− onClick={this.pollDevice}>
201+ onClick={this.pollDevice}>
206− {'Authenticate →'}
202+ {'Authenticate →'}
207− </Button>
203+ </Button>
208−
204+
209− <Button
205+ <Button
210− className={'mt-8'}
206+ className={'mt-8'}
211− prop-size={'wide lg'}
207+ prop-size={'wide lg'}
212− disabled={Maybe.Nothing.hasInstance(wallet)}
208+ disabled={Maybe.Nothing.hasInstance(wallet)}
213− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
209+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
214− {'Continue →'}
210+ {'Continue →'}
215− </Button>
211+ </Button>
216− </Col>
212+ </View>
217− </Row>
218 );
213 );
219 }
214 }
220}
215}
src/views/Mnemonic.js+58−61
@@ -8,13 +8,14 @@ import {
8 InnerLabel,
8 InnerLabel,
9 InputCaption,
9 InputCaption,
10} from '../components/old/Base';
10} from '../components/old/Base';
11−import { Row, Col, H1 } from '../components/old/Base';
11+import { H1 } from '../components/old/Base';
12
12
13import { ROUTE_NAMES } from '../lib/routeNames';
13import { ROUTE_NAMES } from '../lib/routeNames';
14import { withHistory } from '../store/history';
14import { withHistory } from '../store/history';
15import { DEFAULT_HD_PATH, walletFromMnemonic } from '../lib/wallet';
15import { DEFAULT_HD_PATH, walletFromMnemonic } from '../lib/wallet';
16import { compose } from '../lib/lib';
16import { compose } from '../lib/lib';
17import { withWallet } from '../store/wallet';
17import { withWallet } from '../store/wallet';
18+import View from 'components/View';
18
19
19class Mnemonic extends React.Component {
20class Mnemonic extends React.Component {
20 constructor(props) {
21 constructor(props) {
@@ -98,66 +99,62 @@ class Mnemonic extends React.Component {
98 const { mnemonic, hdpath, exampleMnemonic, passphrase } = this.state;
99 const { mnemonic, hdpath, exampleMnemonic, passphrase } = this.state;
99
100
100 return (
101 return (
101− <Row>
102+ <View>
102− <Col>
103− <H1 className={'mb-4'}>{'Enter Your Mnemonic'}</H1>
103+ <H1 className={'mb-4'}>{'Enter Your Mnemonic'}</H1>
104− <InputCaption>
105− {'Please enter your BIP39 mnemonic here.'}
104+ <InputCaption>{'Please enter your BIP39 mnemonic here.'}</InputCaption>
106− </InputCaption>
105+
107−
108− <MnemonicInput
106+ <MnemonicInput
109− className="pt-8"
107+ className="pt-8"
110− prop-size="md"
108+ prop-size="md"
111− prop-format="innerLabel"
109+ prop-format="innerLabel"
112− type="text"
110+ type="text"
113− name="mnemonic"
111+ name="mnemonic"
114− placeholder={`e.g. ${exampleMnemonic}`}
112+ placeholder={`e.g. ${exampleMnemonic}`}
115− onChange={this.handleMnemonicInput}
113+ onChange={this.handleMnemonicInput}
116− value={mnemonic}
114+ value={mnemonic}
117− autocomplete="off"
115+ autocomplete="off"
118− autoFocus>
116+ autoFocus>
119− <InnerLabel>{'Mnemonic'}</InnerLabel>
117+ <InnerLabel>{'Mnemonic'}</InnerLabel>
120− </MnemonicInput>
118+ </MnemonicInput>
121−
119+
122− <InputCaption>
120+ <InputCaption>
123− {`If your wallet requires a passphrase, you may enter it below.`}
121+ {`If your wallet requires a passphrase, you may enter it below.`}
124− </InputCaption>
122+ </InputCaption>
125−
123+
126− <Input
124+ <Input
127− className="pt-8"
125+ className="pt-8"
128− prop-size="md"
126+ prop-size="md"
129− prop-format="innerLabel"
127+ prop-format="innerLabel"
130− name="passphrase"
128+ name="passphrase"
131− type="password"
129+ type="password"
132− value={passphrase}
130+ value={passphrase}
133− autocomplete="off"
131+ autocomplete="off"
134− onChange={this.handlePassphraseInput}>
132+ onChange={this.handlePassphraseInput}>
135− <InnerLabel>{'Passphrase'}</InnerLabel>
133+ <InnerLabel>{'Passphrase'}</InnerLabel>
136− </Input>
134+ </Input>
137−
135+
138− <InputCaption>
136+ <InputCaption>
139− {`If you'd like to use a custom derivation path, you may enter it below.`}
137+ {`If you'd like to use a custom derivation path, you may enter it below.`}
140− </InputCaption>
138+ </InputCaption>
141−
139+
142− <Input
140+ <Input
143− className="pt-8 text-mono"
141+ className="pt-8 text-mono"
144− prop-size="md"
142+ prop-size="md"
145− prop-format="innerLabel"
143+ prop-format="innerLabel"
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− <InnerLabel>{'HD Path'}</InnerLabel>
148+ <InnerLabel>{'HD Path'}</InnerLabel>
151− </Input>
149+ </Input>
152−
150+
153− <Button
151+ <Button
154− className={'mt-10'}
152+ className={'mt-10'}
155− disabled={Nothing.hasInstance(wallet)}
153+ disabled={Nothing.hasInstance(wallet)}
156− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
154+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
157− {'Continue →'}
155+ {'Continue →'}
158− </Button>
156+ </Button>
159− </Col>
157+ </View>
160− </Row>
161 );
158 );
162 }
159 }
163}
160}
src/views/Network.js+22−23
@@ -2,11 +2,12 @@ import React from 'react';
2
2
3import { Button } from '../components/old/Base';
3import { Button } from '../components/old/Base';
4import { InnerLabelDropdown } from '../components/old/Base';
4import { InnerLabelDropdown } from '../components/old/Base';
5−import { Row, Col, H1, P } from '../components/old/Base';
5+import { H1, P } from '../components/old/Base';
6import { NETWORK_TYPES, renderNetworkType } from '../lib/network';
6import { NETWORK_TYPES, renderNetworkType } from '../lib/network';
7import { ROUTE_NAMES } from '../lib/routeNames';
7import { ROUTE_NAMES } from '../lib/routeNames';
8import { useHistory } from '../store/history';
8import { useHistory } from '../store/history';
9import { useNetwork } from '../store/network';
9import { useNetwork } from '../store/network';
10+import View from 'components/View';
10
11
11const kNetworkOptions = [
12const kNetworkOptions = [
12 {
13 {
@@ -35,31 +36,29 @@ function Network() {
35 const history = useHistory();
36 const history = useHistory();
36
37
37 return (
38 return (
38− <Row>
39+ <View>
39− <Col>
40− <H1>{'Select Network'}</H1>
40+ <H1>{'Select Network'}</H1>
41
41
42− <P>
42+ <P>
43− {"Please select the Ethereum node you'd like to send " +
43+ {"Please select the Ethereum node you'd like to send " +
44− 'transactions to. For highly valuable keys, please select ' +
44+ 'transactions to. For highly valuable keys, please select ' +
45− 'offline mode.'}
45+ 'offline mode.'}
46− </P>
46+ </P>
47
47
48− <InnerLabelDropdown
48+ <InnerLabelDropdown
49− className={'mt-6'}
49+ className={'mt-6'}
50− title={'Node:'}
50+ title={'Node:'}
51− handleUpdate={setNetworkType}
51+ handleUpdate={setNetworkType}
52− options={kNetworkOptions}
52+ options={kNetworkOptions}
53− currentSelectionTitle={renderNetworkType(networkType)}
53+ currentSelectionTitle={renderNetworkType(networkType)}
54− />
54+ />
55
55
56− <Button
56+ <Button
57− className={'mt-10'}
57+ className={'mt-10'}
58− onClick={() => history.push(ROUTE_NAMES.WALLET)}>
58+ onClick={() => history.push(ROUTE_NAMES.WALLET)}>
59− {'Continue →'}
59+ {'Continue →'}
60− </Button>
60+ </Button>
61− </Col>
61+ </View>
62− </Row>
63 );
62 );
64}
63}
65
64
src/views/Point.js+20−21
@@ -9,13 +9,14 @@ import PointList from '../components/old/PointList';
9import ReactSVGComponents from '../components/old/ReactSVGComponents';
9import ReactSVGComponents from '../components/old/ReactSVGComponents';
10import KeysAndMetadata from './Point/KeysAndMetadata';
10import KeysAndMetadata from './Point/KeysAndMetadata';
11import Actions from './Point/Actions';
11import Actions from './Point/Actions';
12−import { Row, Col, H1, H3 } from '../components/old/Base';
12+import { H1, H3 } from '../components/old/Base';
13import { withHistory } from '../store/history';
13import { withHistory } from '../store/history';
14import { withNetwork } from '../store/network';
14import { withNetwork } from '../store/network';
15import { compose } from '../lib/lib';
15import { compose } from '../lib/lib';
16import { withWallet } from '../store/wallet';
16import { withWallet } from '../store/wallet';
17import { withPointCursor } from '../store/pointCursor';
17import { withPointCursor } from '../store/pointCursor';
18import { withPointCache } from '../store/pointCache';
18import { withPointCache } from '../store/pointCache';
19+import View from 'components/View';
19
20
20class Point extends React.Component {
21class Point extends React.Component {
21 constructor(props) {
22 constructor(props) {
@@ -83,7 +84,7 @@ class Point extends React.Component {
83
84
84 const { spawned } = this.state;
85 const { spawned } = this.state;
85
86
86− const point = need.pointCursor(this.props);
87+ const point = need.pointCursor(this.props.pointCursor);
87
88
88 const pointDetails =
89 const pointDetails =
89 point in pointCache ? Just(pointCache[point]) : Nothing();
90 point in pointCache ? Just(pointCache[point]) : Nothing();
@@ -112,25 +113,23 @@ class Point extends React.Component {
112 );
113 );
113
114
114 return (
115 return (
115− <Row>
116+ <View>
116− <Col>
117− <div className={'mt-12 pt-6'}>{sigil}</div>
117+ <div className={'mt-12 pt-6'}>{sigil}</div>
118− <H1>
118+ <H1>
119− <code>{name}</code>
119+ <code>{name}</code>
120− </H1>
120+ </H1>
121− {authenticated ? (
121+ {authenticated ? (
122− <Actions
122+ <Actions
123− online={online}
123+ online={online}
124− point={point}
124+ point={point}
125− pointDetails={pointDetails}
125+ pointDetails={pointDetails}
126− invites={this.state.invites}
126+ invites={this.state.invites}
127− />
127+ />
128− ) : null}
128+ ) : null}
129−
129+
130− {online ? <KeysAndMetadata pointDetails={pointDetails} /> : <div />}
130+ {online ? <KeysAndMetadata pointDetails={pointDetails} /> : <div />}
131− {issuedPointList}
131+ {issuedPointList}
132− </Col>
132+ </View>
133− </Row>
134 );
133 );
135 }
134 }
136}
135}
src/views/Point/Actions.js+10−11
@@ -3,11 +3,12 @@ import { azimuth } from 'azimuth-js';
3import * as need from '../../lib/need';
3import * as need from '../../lib/need';
4
4
5import { ETH_ZERO_ADDR, CURVE_ZERO_ADDR, eqAddr } from '../../lib/wallet';
5import { ETH_ZERO_ADDR, CURVE_ZERO_ADDR, eqAddr } from '../../lib/wallet';
6−import { Row, Col, H2, P } from '../../components/old/Base';
6+import { H2, P } from '../../components/old/Base';
7import { Button } from '../../components/old/Base';
7import { Button } from '../../components/old/Base';
8import { ROUTE_NAMES } from '../../lib/routeNames';
8import { ROUTE_NAMES } from '../../lib/routeNames';
9import { useHistory } from '../../store/history';
9import { useHistory } from '../../store/history';
10import { useWallet } from '../../store/wallet';
10import { useWallet } from '../../store/wallet';
11+import Grid from 'components/Grid';
11
12
12const isPlanet = point =>
13const isPlanet = point =>
13 azimuth.getPointSize(point) === azimuth.PointSize.Planet;
14 azimuth.getPointSize(point) === azimuth.PointSize.Planet;
@@ -18,7 +19,7 @@ function Actions(props) {
18 const { wallet } = useWallet();
19 const { wallet } = useWallet();
19 const { online, point, pointDetails, invites } = props;
20 const { online, point, pointDetails, invites } = props;
20
21
21− const addr = need.address({ wallet });
22+ const addr = need.addressFromWallet(wallet);
22
23
23 const planet = isPlanet(point);
24 const planet = isPlanet(point);
24 const star = isStar(point);
25 const star = isStar(point);
@@ -143,8 +144,8 @@ function Actions(props) {
143 ) : (
144 ) : (
144 ''
145 ''
145 )}
146 )}
146− <Row>
147+ <Grid>
147− <Col className={'flex flex-column items-start col-md-4'}>
148+ <Grid.Item third={1}>
148 <Button
149 <Button
149 prop-size={'sm'}
150 prop-size={'sm'}
150 prop-type={'link'}
151 prop-type={'link'}
@@ -184,8 +185,8 @@ function Actions(props) {
184 }}>
185 }}>
185 {'Generate Arvo keyfile'}
186 {'Generate Arvo keyfile'}
186 </Button>
187 </Button>
187− </Col>
188+ </Grid.Item>
188− <Col className={'flex flex-column items-start col-md-4'}>
189+ <Grid.Item third={2}>
189 <Button
190 <Button
190 disabled={online && !canSetSpawnProxy}
191 disabled={online && !canSetSpawnProxy}
191 prop-size={'sm'}
192 prop-size={'sm'}
@@ -225,11 +226,9 @@ function Actions(props) {
225 }}>
226 }}>
226 {'Transfer'}
227 {'Transfer'}
227 </Button>
228 </Button>
228− </Col>
229+ </Grid.Item>
229− <Col className={'flex flex-column items-start col-md-4'}>
230− {inviteAction}
230+ <Grid.Item third={3}>{inviteAction}</Grid.Item>
231− </Col>
231+ </Grid>
232− </Row>
233 </div>
232 </div>
234 );
233 );
235}
234}
src/views/Point/KeysAndMetadata.js+44−50
@@ -1,7 +1,8 @@
1import React from 'react';
1import React from 'react';
2−import { Row, Col, H2, H4 } from '../../components/old/Base';
2+import { H2, H4 } from '../../components/old/Base';
3
3
4import { ETH_ZERO_ADDR, eqAddr } from '../../lib/wallet';
4import { ETH_ZERO_ADDR, eqAddr } from '../../lib/wallet';
5+import Grid from 'components/Grid';
5
6
6const NULL_KEY =
7const NULL_KEY =
7 '0x0000000000000000000000000000000000000000000000000000000000000000';
8 '0x0000000000000000000000000000000000000000000000000000000000000000';
@@ -53,47 +54,42 @@ const KeysAndMetadata = props => {
53 const { pointDetails } = props;
54 const { pointDetails } = props;
54
55
55 return (
56 return (
56− <Row>
57+ <Grid>
57− <Col>
58+ <Grid.Item full>
58 <H2>{'Ownership and Proxy Addresses'}</H2>
59 <H2>{'Ownership and Proxy Addresses'}</H2>
59−
60+ </Grid.Item>
60− <Row>
61+ <Grid.Item fourth={1}>
61− <Col className={'flex flex-column items-start col-md-3'}>
62− <H4>{'Owner'}</H4>
62+ <H4>{'Owner'}</H4>
63− {pointDetails.matchWith({
63+ {pointDetails.matchWith({
64− Nothing: () => <div />,
64+ Nothing: () => <div />,
65− Just: deets => renderAddress(deets.value.owner),
65+ Just: deets => renderAddress(deets.value.owner),
66− })}
66+ })}
67− </Col>
67+ </Grid.Item>
68−
68+ <Grid.Item fourth={2}>
69− <Col className={'flex flex-column items-start col-md-3'}>
70− <H4>{'Transfer Proxy'}</H4>
69+ <H4>{'Transfer Proxy'}</H4>
71− {pointDetails.matchWith({
70+ {pointDetails.matchWith({
72− Nothing: () => <div />,
71+ Nothing: () => <div />,
73− Just: deets => renderAddress(deets.value.transferProxy),
72+ Just: deets => renderAddress(deets.value.transferProxy),
74− })}
73+ })}
75− </Col>
74+ </Grid.Item>
76−
75+ <Grid.Item fourth={3}>
77− <Col className={'flex flex-column items-start col-md-3'}>
78− <H4>{'Spawn Proxy'}</H4>
76+ <H4>{'Spawn Proxy'}</H4>
79− {pointDetails.matchWith({
77+ {pointDetails.matchWith({
80− Nothing: () => <div />,
78+ Nothing: () => <div />,
81− Just: deets => renderAddress(deets.value.spawnProxy),
79+ Just: deets => renderAddress(deets.value.spawnProxy),
82− })}
80+ })}
83− </Col>
81+ </Grid.Item>
84−
82+ <Grid.Item fourth={4}>
85− <Col className={'flex flex-column items-start col-md-3'}>
86− <H4>{'Mgmt Proxy'}</H4>
83+ <H4>{'Mgmt Proxy'}</H4>
87− {pointDetails.matchWith({
84+ {pointDetails.matchWith({
88− Nothing: () => <div />,
85+ Nothing: () => <div />,
89− Just: deets => renderAddress(deets.value.managementProxy),
86+ Just: deets => renderAddress(deets.value.managementProxy),
90− })}
87+ })}
91− </Col>
88+ </Grid.Item>
92− </Row>
89+ <Grid.Item full>
93−
94 <UrbitNetworking pointDetails={pointDetails} />
90 <UrbitNetworking pointDetails={pointDetails} />
95− </Col>
91+ </Grid.Item>
96− </Row>
92+ </Grid>
97 );
93 );
98};
94};
99
95
@@ -108,24 +104,22 @@ const UrbitNetworking = props => {
108 const body = !booted ? (
104 const body = !booted ? (
109 <div>{'(not set)'}</div>
105 <div>{'(not set)'}</div>
110 ) : (
106 ) : (
111− <Row>
107+ <Grid>
112− <Col className={'flex flex-column items-start col-md-4'}>
108+ <Grid.Item third={1}>
113 <H4>{'Authentication'}</H4>
109 <H4>{'Authentication'}</H4>
114 {pointDetails.matchWith({
110 {pointDetails.matchWith({
115 Nothing: () => <div />,
111 Nothing: () => <div />,
116 Just: deets => renderNetworkKey(deets.value.authenticationKey),
112 Just: deets => renderNetworkKey(deets.value.authenticationKey),
117 })}
113 })}
118− </Col>
114+ </Grid.Item>
119−
115+ <Grid.Item third={2}>
120− <Col className={'flex flex-column items-start col-md-4'}>
121 <H4>{'Encryption'}</H4>
116 <H4>{'Encryption'}</H4>
122 {pointDetails.matchWith({
117 {pointDetails.matchWith({
123 Nothing: () => <div />,
118 Nothing: () => <div />,
124 Just: deets => renderNetworkKey(deets.value.encryptionKey),
119 Just: deets => renderNetworkKey(deets.value.encryptionKey),
125 })}
120 })}
126− </Col>
121+ </Grid.Item>
127−
122+ <Grid.Item third={3}>
128− <Col className={'flex flex-column items-start col-md-4'}>
129 <H4>{'Revision'}</H4>
123 <H4>{'Revision'}</H4>
130 {pointDetails.matchWith({
124 {pointDetails.matchWith({
131 Nothing: () => '-',
125 Nothing: () => '-',
@@ -143,8 +137,8 @@ const UrbitNetworking = props => {
143 Nothing: () => '-',
137 Nothing: () => '-',
144 Just: deets => deets.value.cryptoSuiteVersion,
138 Just: deets => deets.value.cryptoSuiteVersion,
145 })}
139 })}
146− </Col>
140+ </Grid.Item>
147− </Row>
141+ </Grid>
148 );
142 );
149
143
150 return (
144 return (
src/views/Points.js+28−28
@@ -1,5 +1,5 @@
1import React from 'react';
1import React from 'react';
2−import { Row, Col, H1, H2, P } from '../components/old/Base';
2+import { H1, H2, P } from '../components/old/Base';
3import { Button } from '../components/old/Base';
3import { Button } from '../components/old/Base';
4import * as azimuth from 'azimuth-js';
4import * as azimuth from 'azimuth-js';
5
5
@@ -12,6 +12,8 @@ import { withNetwork } from '../store/network';
12import { compose } from '../lib/lib';
12import { compose } from '../lib/lib';
13import { withWallet } from '../store/wallet';
13import { withWallet } from '../store/wallet';
14import { withPointCache } from '../store/pointCache';
14import { withPointCache } from '../store/pointCache';
15+import View from 'components/View';
16+import Grid from 'components/Grid';
15
17
16const hasTransferProxy = (cache, point) =>
18const hasTransferProxy = (cache, point) =>
17 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
19 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
@@ -97,8 +99,8 @@ class Points extends React.Component {
97 } = this.state;
99 } = this.state;
98
100
99 const lookupPointButton = (
101 const lookupPointButton = (
100− <Row>
102+ <Grid>
101− <Col>
103+ <Grid.Item full>
102 <Button
104 <Button
103 prop-type={'link'}
105 prop-type={'link'}
104 prop-size={'md'}
106 prop-size={'md'}
@@ -106,16 +108,16 @@ class Points extends React.Component {
106 {'View a point →'}
108 {'View a point →'}
107 </Button>
109 </Button>
108 <P>{'View a point on Azimuth.'}</P>
110 <P>{'View a point on Azimuth.'}</P>
109− </Col>
111+ </Grid.Item>
110− </Row>
112+ </Grid>
111 );
113 );
112
114
113 const createGalaxyButton =
115 const createGalaxyButton =
114 eclipticOwner === false ? (
116 eclipticOwner === false ? (
115 <div />
117 <div />
116 ) : (
118 ) : (
117− <Row>
119+ <Grid>
118− <Col>
120+ <Grid.Item full>
119 <Button
121 <Button
120 prop-type={'link'}
122 prop-type={'link'}
121 prop-size={'md'}
123 prop-size={'md'}
@@ -127,8 +129,8 @@ class Points extends React.Component {
127 'You have the authority to create a new Galaxy and you can do so here.'
129 'You have the authority to create a new Galaxy and you can do so here.'
128 }
130 }
129 </P>
131 </P>
130− </Col>
132+ </Grid.Item>
131− </Row>
133+ </Grid>
132 );
134 );
133
135
134 const outgoing = points.filter(point =>
136 const outgoing = points.filter(point =>
@@ -203,36 +205,34 @@ class Points extends React.Component {
203 );
205 );
204
206
205 return (
207 return (
206− <Row>
208+ <View>
207− <Col>
208− <H1>{'Points'}</H1>
209+ <H1>{'Points'}</H1>
209
210
210− <P>{`A point is an identity on the Ethereum blockchain.
211+ <P>{`A point is an identity on the Ethereum blockchain.
211 Points declare keys for ships on the Arvo network.`}</P>
212 Points declare keys for ships on the Arvo network.`}</P>
212
213
213− {lookupPointButton}
214+ {lookupPointButton}
214
215
215− {createGalaxyButton}
216+ {createGalaxyButton}
216
217
217− {incomingPoints}
218+ {incomingPoints}
218
219
219− {outgoingPoints}
220+ {outgoingPoints}
220
221
221− <H2>{'Your Points'}</H2>
222+ <H2>{'Your Points'}</H2>
222
223
223− <PointList
224+ <PointList
224− routeHandler={history.push}
225+ routeHandler={history.push}
225− points={points}
226+ points={points}
226− loading={loading}
227+ loading={loading}
227− />
228+ />
228
229
229− {managingPoints}
230+ {managingPoints}
230
231
231− {votingPoints}
232+ {votingPoints}
232
233
233− {spawningPoints}
234+ {spawningPoints}
234− </Col>
235+ </View>
235− </Row>
236 );
236 );
237 }
237 }
238}
238}
src/views/PrivateKey.js+27−28
@@ -6,13 +6,14 @@ import {
6 InnerLabel,
6 InnerLabel,
7 InputCaption,
7 InputCaption,
8} from '../components/old/Base';
8} from '../components/old/Base';
9−import { Row, Col, H1 } from '../components/old/Base';
9+import { H1 } from '../components/old/Base';
10
10
11import { ROUTE_NAMES } from '../lib/routeNames';
11import { ROUTE_NAMES } from '../lib/routeNames';
12import { withHistory } from '../store/history';
12import { withHistory } from '../store/history';
13import { EthereumWallet } from '../lib/wallet';
13import { EthereumWallet } from '../lib/wallet';
14import { compose } from '../lib/lib';
14import { compose } from '../lib/lib';
15import { withWallet } from '../store/wallet';
15import { withWallet } from '../store/wallet';
16+import View from 'components/View';
16
17
17class PrivateKey extends React.Component {
18class PrivateKey extends React.Component {
18 constructor(props) {
19 constructor(props) {
@@ -46,35 +47,33 @@ class PrivateKey extends React.Component {
46 const { privateKey } = this.state;
47 const { privateKey } = this.state;
47
48
48 return (
49 return (
49− <Row>
50+ <View>
50− <Col className={'measure-md'}>
51− <H1 className={'mb-4'}>{'Enter Your Private Key'}</H1>
51+ <H1 className={'mb-4'}>{'Enter Your Private Key'}</H1>
52− <InputCaption>
52+ <InputCaption>
53− {`Please enter your raw Ethereum private key here.`}
53+ {`Please enter your raw Ethereum private key here.`}
54− </InputCaption>
54+ </InputCaption>
55
55
56− <RequiredInput
56+ <RequiredInput
57− className="pt-8 mt-8"
57+ className="pt-8 mt-8"
58− prop-size="md"
58+ prop-size="md"
59− prop-format="innerLabel"
59+ prop-format="innerLabel"
60− type="password"
60+ type="password"
61− name="privateKey"
61+ name="privateKey"
62− onChange={this.handlePrivateKeyInput}
62+ onChange={this.handlePrivateKeyInput}
63− value={privateKey}
63+ value={privateKey}
64− autocomplete="off"
64+ autocomplete="off"
65− autoFocus>
65+ autoFocus>
66− <InnerLabel>{'Private Key'}</InnerLabel>
66+ <InnerLabel>{'Private Key'}</InnerLabel>
67− </RequiredInput>
67+ </RequiredInput>
68
68
69− <Button
69+ <Button
70− className={'mt-10'}
70+ className={'mt-10'}
71− prop-size={'wide lg'}
71+ prop-size={'wide lg'}
72− disabled={Maybe.Nothing.hasInstance(wallet)}
72+ disabled={Maybe.Nothing.hasInstance(wallet)}
73− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
73+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
74− {'Continue →'}
74+ {'Continue →'}
75− </Button>
75+ </Button>
76− </Col>
76+ </View>
77− </Row>
78 );
77 );
79 }
78 }
80}
79}
src/views/SentTransaction.js+22−21
@@ -1,7 +1,7 @@
1import Maybe from 'folktale/maybe';
1import Maybe from 'folktale/maybe';
2import React from 'react';
2import React from 'react';
3import * as need from '../lib/need';
3import * as need from '../lib/need';
4−import { Row, Col, H1, H3, P, Warning, Anchor } from '../components/old/Base';
4+import { H1, H3, P, Warning, Anchor } from '../components/old/Base';
5import { Button } from '../components/old/Base';
5import { Button } from '../components/old/Base';
6
6
7import { ROUTE_NAMES } from '../lib/routeNames';
7import { ROUTE_NAMES } from '../lib/routeNames';
@@ -11,6 +11,8 @@ import { NETWORK_TYPES } from '../lib/network';
11import { useTxnConfirmations } from '../store/txnConfirmations';
11import { useTxnConfirmations } from '../store/txnConfirmations';
12import { useNetwork } from '../store/network';
12import { useNetwork } from '../store/network';
13import { useTxnCursor } from '../store/txnCursor';
13import { useTxnCursor } from '../store/txnCursor';
14+import View from 'components/View';
15+import Grid from 'components/Grid';
14
16
15class Success extends React.Component {
17class Success extends React.Component {
16 constructor(props) {
18 constructor(props) {
@@ -77,8 +79,8 @@ class Success extends React.Component {
77 : `Confirmed! (x${confirmations} confirmations)!`;
79 : `Confirmed! (x${confirmations} confirmations)!`;
78
80
79 return (
81 return (
80− <Row>
82+ <Grid>
81− <Col>
83+ <Grid.Item full>
82 <H1>{'Your Transaction was Sent'}</H1>
84 <H1>{'Your Transaction was Sent'}</H1>
83
85
84 <P>
86 <P>
@@ -92,23 +94,23 @@ class Success extends React.Component {
92 <H3>{'Transaction Status'}</H3>
94 <H3>{'Transaction Status'}</H3>
93 <P>{status}</P>
95 <P>{status}</P>
94 <P>{esanchor}</P>
96 <P>{esanchor}</P>
95− </Col>
97+ </Grid.Item>
96− </Row>
98+ </Grid>
97 );
99 );
98 }
100 }
99}
101}
100
102
101const Failure = props => (
103const Failure = props => (
102− <Row>
104+ <Grid>
103− <Col>
105+ <Grid.Item full>
104 <H1>{'Error!'}</H1>
106 <H1>{'Error!'}</H1>
105
107
106 <Warning>
108 <Warning>
107 <H3>{'There was an error sending your transaction.'}</H3>
109 <H3>{'There was an error sending your transaction.'}</H3>
108 {renderTxnError(props.web3, props.message)}
110 {renderTxnError(props.web3, props.message)}
109 </Warning>
111 </Warning>
110− </Col>
112+ </Grid.Item>
111− </Row>
113+ </Grid>
112);
114);
113
115
114function SentTransaction(props) {
116function SentTransaction(props) {
@@ -119,8 +121,7 @@ function SentTransaction(props) {
119
121
120 const promptKeyfile = history.data && history.data.promptKeyfile;
122 const promptKeyfile = history.data && history.data.promptKeyfile;
121
123
122− // TODO: remove need's assumption about accepting the props object
123− const w3 = need.web3({ web3 });
124+ const w3 = need.web3(web3);
124
125
125 const result = txnCursor.matchWith({
126 const result = txnCursor.matchWith({
126 Nothing: _ => {
127 Nothing: _ => {
@@ -141,8 +142,8 @@ function SentTransaction(props) {
141 });
142 });
142
143
143 const ok = (
144 const ok = (
144− <Row>
145+ <Grid>
145− <Col>
146+ <Grid.Item full>
146 <Button
147 <Button
147 prop-type={'link'}
148 prop-type={'link'}
148 onClick={() => {
149 onClick={() => {
@@ -150,32 +151,32 @@ function SentTransaction(props) {
150 }}>
151 }}>
151 {'Ok →'}
152 {'Ok →'}
152 </Button>
153 </Button>
153− </Col>
154+ </Grid.Item>
154− </Row>
155+ </Grid>
155 );
156 );
156
157
157 let keyfile;
158 let keyfile;
158
159
159 if (promptKeyfile) {
160 if (promptKeyfile) {
160 keyfile = (
161 keyfile = (
161− <Row>
162+ <Grid>
162− <Col>
163+ <Grid.Item full>
163 <Button
164 <Button
164 prop-type={'link'}
165 prop-type={'link'}
165 onClick={() => history.popAndPush(ROUTE_NAMES.GEN_KEYFILE)}>
166 onClick={() => history.popAndPush(ROUTE_NAMES.GEN_KEYFILE)}>
166 {'Download Keyfile →'}
167 {'Download Keyfile →'}
167 </Button>
168 </Button>
168− </Col>
169+ </Grid.Item>
169− </Row>
170+ </Grid>
170 );
171 );
171 }
172 }
172
173
173 return (
174 return (
174− <div>
175+ <View>
175 {body}
176 {body}
176 {ok}
177 {ok}
177 {keyfile}
178 {keyfile}
178− </div>
179+ </View>
179 );
180 );
180}
181}
181
182
src/views/SetKeys.js+50−59
@@ -4,14 +4,7 @@ import * as azimuth from 'azimuth-js';
4import * as ob from 'urbit-ob';
4import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
5import * as need from '../lib/need';
6import * as kg from 'urbit-key-generation/dist';
6import * as kg from 'urbit-key-generation/dist';
7−import {
8− Row,
9− Col,
10− H1,
11− P,
12− Warning,
13− CheckboxButton,
14−} from '../components/old/Base';
7+import { H1, P, Warning, CheckboxButton } from '../components/old/Base';
15
8
16import StatelessTransaction from '../components/old/StatelessTransaction';
9import StatelessTransaction from '../components/old/StatelessTransaction';
17import { attemptNetworkSeedDerivation } from '../lib/keys';
10import { attemptNetworkSeedDerivation } from '../lib/keys';
@@ -23,12 +16,13 @@ import { withNetwork } from '../store/network';
23import { withWallet } from '../store/wallet';
16import { withWallet } from '../store/wallet';
24import { withPointCursor } from '../store/pointCursor';
17import { withPointCursor } from '../store/pointCursor';
25import { withPointCache } from '../store/pointCache';
18import { withPointCache } from '../store/pointCache';
19+import View from 'components/View';
26
20
27class SetKeys extends React.Component {
21class SetKeys extends React.Component {
28 constructor(props) {
22 constructor(props) {
29 super(props);
23 super(props);
30
24
31− const point = need.pointCursor(props);
25+ const point = need.pointCursor(props.pointCursor);
32
26
33 this.state = {
27 this.state = {
34 auth: '',
28 auth: '',
@@ -55,7 +49,7 @@ class SetKeys extends React.Component {
55
49
56 this.deriveSeed();
50 this.deriveSeed();
57
51
58− const addr = need.address(props);
52+ const addr = need.addressFromWallet(props.wallet);
59
53
60 this.determineManagementSeed(props.contracts.value, addr);
54 this.determineManagementSeed(props.contracts.value, addr);
61 }
55 }
@@ -120,9 +114,8 @@ class SetKeys extends React.Component {
120 createUnsignedTxn() {
114 createUnsignedTxn() {
121 const { state, props } = this;
115 const { state, props } = this;
122
116
123− const validContracts = need.contracts(props);
117+ const validContracts = need.contracts(props.contracts);
124−
125− const validPoint = need.pointCursor(props);
118+ const validPoint = need.pointCursor(props.pointCursor);
126
119
127 // TODO: move this to a lib for validating things
120 // TODO: move this to a lib for validating things
128 const hexRegExp = /[0-9A-Fa-f]{64}/g;
121 const hexRegExp = /[0-9A-Fa-f]{64}/g;
@@ -155,58 +148,56 @@ class SetKeys extends React.Component {
155 const canGenerate =
148 const canGenerate =
156 state.newNetworkSeed.length === 64 && state.newNetworkSeed.length === 64;
149 state.newNetworkSeed.length === 64 && state.newNetworkSeed.length === 64;
157
150
158− const pointDetails = need.fromPointCache(props, state.point);
151+ const pointDetails = need.fromPointCache(props.pointCache, state.point);
159
152
160 return (
153 return (
161− <Row>
154+ <View>
162− <Col>
163− <H1>
155+ <H1>
164− {'Set Network Keys For '} <code>{`${ob.patp(state.point)}`}</code>
156+ {'Set Network Keys For '} <code>{`${ob.patp(state.point)}`}</code>
165− </H1>
157+ </H1>
166−
158+
167− <P className="mt-10">
159+ <P className="mt-10">
168− {`Set new authentication and encryption keys for your Arvo ship.`}
160+ {`Set new authentication and encryption keys for your Arvo ship.`}
169− </P>
161+ </P>
170−
162+
171− {state.nondeterministicSeed && (
163+ {state.nondeterministicSeed && (
172− <Warning>
164+ <Warning>
173− <h3 className={'mb-2'}>{'Warning'}</h3>
165+ <h3 className={'mb-2'}>{'Warning'}</h3>
174− {`Your network seed could not be derived automatically. We've
166+ {`Your network seed could not be derived automatically. We've
175 generated a random one for you, so you must download your Arvo
167 generated a random one for you, so you must download your Arvo
176 keyfile during this session after setting your keys.`}
168 keyfile during this session after setting your keys.`}
177− </Warning>
169+ </Warning>
178− )}
170+ )}
179−
171+
180− {pointDetails.keyRevisionNumber === 0 ? (
172+ {pointDetails.keyRevisionNumber === 0 ? (
181− <Warning>
173+ <Warning>
182− <h3 className={'mb-2'}>{'Warning'}</h3>
174+ <h3 className={'mb-2'}>{'Warning'}</h3>
183− {'Once these keys have been set, your point is considered ' +
175+ {'Once these keys have been set, your point is considered ' +
184− "'linked'. This operation cannot be undone."}
176+ "'linked'. This operation cannot be undone."}
185− </Warning>
177+ </Warning>
186− ) : (
178+ ) : (
187− <div />
179+ <div />
188− )}
180+ )}
189−
181+
190− <CheckboxButton
182+ <CheckboxButton
191− className="mt-8"
183+ className="mt-8"
192− onToggle={this.toggleDiscontinuity}
184+ onToggle={this.toggleDiscontinuity}
193− state={state.discontinuity}
185+ state={state.discontinuity}
194− label={`I have lost important off-chain data relating to this point
186+ label={`I have lost important off-chain data relating to this point
195 and need to do a hard reset.
187 and need to do a hard reset.
196 (For example, rebooting an Arvo ship.)`}
188 (For example, rebooting an Arvo ship.)`}
197− />
189+ />
198−
190+
199− <StatelessTransaction
191+ <StatelessTransaction
200− // Upper scope
192+ // Upper scope
201− {...props}
193+ {...props}
202− // Tx
194+ // Tx
203− canGenerate={canGenerate}
195+ canGenerate={canGenerate}
204− createUnsignedTxn={this.createUnsignedTxn}
196+ createUnsignedTxn={this.createUnsignedTxn}
205− newNetworkSeed={state.newNetworkSeed}
197+ newNetworkSeed={state.newNetworkSeed}
206− newRevision={parseInt(pointDetails.keyRevisionNumber) + 1}
198+ newRevision={parseInt(pointDetails.keyRevisionNumber) + 1}
207− />
199+ />
208− </Col>
200+ </View>
209− </Row>
210 );
201 );
211 }
202 }
212}
203}
src/views/SetProxy.js+24−28
@@ -3,8 +3,6 @@ import React from 'react';
3import * as need from '../lib/need';
3import * as need from '../lib/need';
4import * as azimuth from 'azimuth-js';
4import * as azimuth from 'azimuth-js';
5import {
5import {
6− Row,
7− Col,
8 H1,
6 H1,
9 P,
7 P,
10 InnerLabel,
8 InnerLabel,
@@ -25,12 +23,13 @@ import { isValidAddress } from '../lib/wallet';
25import { withNetwork } from '../store/network';
23import { withNetwork } from '../store/network';
26import { compose } from '../lib/lib';
24import { compose } from '../lib/lib';
27import { withPointCursor } from '../store/pointCursor';
25import { withPointCursor } from '../store/pointCursor';
26+import View from 'components/View';
28
27
29class _SetProxy extends React.Component {
28class _SetProxy extends React.Component {
30 constructor(props) {
29 constructor(props) {
31 super(props);
30 super(props);
32
31
33− const issuingPoint = need.pointCursor(props);
32+ const issuingPoint = need.pointCursor(props.pointCursor);
34
33
35 this.state = {
34 this.state = {
36 proxyAddress: '',
35 proxyAddress: '',
@@ -61,9 +60,8 @@ class _SetProxy extends React.Component {
61 createUnsignedTxn(proxyAddress) {
60 createUnsignedTxn(proxyAddress) {
62 const { state, props } = this;
61 const { state, props } = this;
63
62
64− const validContracts = need.contracts(props);
63+ const validContracts = need.contracts(props.contracts);
65−
66− const validPoint = need.pointCursor(props);
64+ const validPoint = need.pointCursor(props.pointCursor);
67
65
68 const txArgs = [validContracts, validPoint, state.proxyAddress];
66 const txArgs = [validContracts, validPoint, state.proxyAddress];
69
67
@@ -141,28 +139,26 @@ class _SetProxy extends React.Component {
141 }
139 }
142
140
143 return (
141 return (
144− <Row>
142+ <View>
145− <Col>
146− <H1>
143+ <H1>
147− {`${titleVerb} ${ucFirst(renderedProxyType)} Proxy For `}
144+ {`${titleVerb} ${ucFirst(renderedProxyType)} Proxy For `}
148− <code>{`${ob.patp(state.issuingPoint)}`}</code>
145+ <code>{`${ob.patp(state.issuingPoint)}`}</code>
149− </H1>
146+ </H1>
150−
147+
151− <HorizontalSelector
148+ <HorizontalSelector
152− options={setUnset}
149+ options={setUnset}
153− onChange={this.handleSetUnset}
150+ onChange={this.handleSetUnset}
154− className="mt-8"
151+ className="mt-8"
155− />
152+ />
156−
153+
157− {addressInput}
154+ {addressInput}
158−
155+
159− <StatelessTransaction
156+ <StatelessTransaction
160− ref={this.statelessRef}
157+ ref={this.statelessRef}
161− createUnsignedTxn={this.createUnsignedTxn}
158+ createUnsignedTxn={this.createUnsignedTxn}
162− canGenerate={canGenerate}
159+ canGenerate={canGenerate}
163− />
160+ />
164− </Col>
161+ </View>
165− </Row>
166 );
162 );
167 }
163 }
168}
164}
src/views/Shards.js+97−104
@@ -9,7 +9,7 @@ import {
9 InputCaption,
9 InputCaption,
10 Input,
10 Input,
11} from '../components/old/Base';
11} from '../components/old/Base';
12−import { Row, Col, H1, P } from '../components/old/Base';
12+import { H1, P } from '../components/old/Base';
13import * as kg from 'urbit-key-generation/dist';
13import * as kg from 'urbit-key-generation/dist';
14import * as ob from 'urbit-ob';
14import * as ob from 'urbit-ob';
15
15
@@ -18,6 +18,7 @@ import { withHistory } from '../store/history';
18import { urbitWalletFromTicket } from '../lib/wallet';
18import { urbitWalletFromTicket } from '../lib/wallet';
19import { compose } from '../lib/lib';
19import { compose } from '../lib/lib';
20import { withWallet } from '../store/wallet';
20import { withWallet } from '../store/wallet';
21+import View from 'components/View';
21
22
22const placeholder = len => {
23const placeholder = len => {
23 let bytes = window.crypto.getRandomValues(new Uint8Array(len));
24 let bytes = window.crypto.getRandomValues(new Uint8Array(len));
@@ -103,112 +104,104 @@ class Shards extends React.Component {
103 const ready = shards.filter(x => x !== '').length > 1;
104 const ready = shards.filter(x => x !== '').length > 1;
104
105
105 return (
106 return (
106− <Row>
107+ <View>
107− <Col>
108− <H1>{'Authenticate'}</H1>
108+ <H1>{'Authenticate'}</H1>
109
109
110− <P>
110+ <P>
111− {`Enter your point and at least two of your three Urbit master
111+ {`Enter your point and at least two of your three Urbit master
112 ticket shards here. The index of the input field needs to
112 ticket shards here. The index of the input field needs to
113 match the index of the shard.`}
113 match the index of the shard.`}
114− </P>
114+ </P>
115−
115+
116− <PointInput
116+ <PointInput
117− className="mono mt-8"
117+ className="mono mt-8"
118− prop-size="lg"
118+ prop-size="lg"
119− prop-format="innerLabel"
119+ prop-format="innerLabel"
120− type="text"
120+ type="text"
121− autoFocus
121+ autoFocus
122− placeholder={`e.g. ${phPoint}`}
122+ placeholder={`e.g. ${phPoint}`}
123− value={pointName}
123+ value={pointName}
124− onChange={this.handlePointNameInput}>
124+ onChange={this.handlePointNameInput}>
125− <InnerLabel>{'Point'}</InnerLabel>
125+ <InnerLabel>{'Point'}</InnerLabel>
126− <ValidatedSigil
126+ <ValidatedSigil
127− className={'tr-0 mt-05 mr-0 abs'}
127+ className={'tr-0 mt-05 mr-0 abs'}
128− patp={pointName}
128+ patp={pointName}
129− size={68}
129+ size={68}
130− margin={8}
130+ margin={8}
131− />
131+ />
132− </PointInput>
132+ </PointInput>
133−
133+
134− <ShardInput
134+ <ShardInput
135− className="mono mt-8"
135+ className="mono mt-8"
136− prop-size="md"
136+ prop-size="md"
137− prop-format="innerLabel"
137+ prop-format="innerLabel"
138− type="text"
138+ type="text"
139− name="shard1"
139+ name="shard1"
140− placeholder={`e.g. ${phTick}`}
140+ placeholder={`e.g. ${phTick}`}
141− value={shard1}
141+ value={shard1}
142− onChange={inp => this.handleShardInput(SHARDS.SHARD1, inp)}>
142+ onChange={inp => this.handleShardInput(SHARDS.SHARD1, inp)}>
143− <InnerLabel>{'Shard 1'}</InnerLabel>
143+ <InnerLabel>{'Shard 1'}</InnerLabel>
144− </ShardInput>
144+ </ShardInput>
145−
145+
146− <ShardInput
146+ <ShardInput
147− className="mono mt-8"
147+ className="mono mt-8"
148− prop-size="md"
148+ prop-size="md"
149− prop-format="innerLabel"
149+ prop-format="innerLabel"
150− type="text"
150+ type="text"
151− name="shard2"
151+ name="shard2"
152− placeholder={`e.g. ${phTick}`}
152+ placeholder={`e.g. ${phTick}`}
153− value={shard2}
153+ value={shard2}
154− onChange={inp => this.handleShardInput(SHARDS.SHARD2, inp)}>
154+ onChange={inp => this.handleShardInput(SHARDS.SHARD2, inp)}>
155− <InnerLabel>{'Shard 2'}</InnerLabel>
155+ <InnerLabel>{'Shard 2'}</InnerLabel>
156− </ShardInput>
156+ </ShardInput>
157−
157+
158− <ShardInput
158+ <ShardInput
159− className="mono mt-8"
159+ className="mono mt-8"
160− prop-size="md"
160+ prop-size="md"
161− prop-format="innerLabel"
161+ prop-format="innerLabel"
162− type="text"
162+ type="text"
163− name="shard3"
163+ name="shard3"
164− placeholder={`e.g. ${phTick}`}
164+ placeholder={`e.g. ${phTick}`}
165− value={shard3}
165+ value={shard3}
166− onChange={inp => this.handleShardInput(SHARDS.SHARD3, inp)}>
166+ onChange={inp => this.handleShardInput(SHARDS.SHARD3, inp)}>
167− <InnerLabel>{'Shard 3'}</InnerLabel>
167+ <InnerLabel>{'Shard 3'}</InnerLabel>
168− </ShardInput>
168+ </ShardInput>
169−
169+
170− <InputCaption>
170+ <InputCaption>
171− {'If your wallet requires a passphrase, you may enter it below.'}
171+ {'If your wallet requires a passphrase, you may enter it below.'}
172− </InputCaption>
172+ </InputCaption>
173−
173+
174− <Input
174+ <Input
175− className="pt-8"
175+ className="pt-8"
176− prop-size="md"
176+ prop-size="md"
177− prop-format="innerLabel"
177+ prop-format="innerLabel"
178− name="passphrase"
178+ name="passphrase"
179− type="password"
179+ type="password"
180− value={passphrase}
180+ value={passphrase}
181− autocomplete="off"
181+ autocomplete="off"
182− onChange={this.handlePassphraseInput}>
182+ onChange={this.handlePassphraseInput}>
183− <InnerLabel>{'Passphrase'}</InnerLabel>
183+ <InnerLabel>{'Passphrase'}</InnerLabel>
184− </Input>
184+ </Input>
185−
185+
186− <Button
186+ <Button
187− disabled={!ready}
187+ disabled={!ready}
188− className={'mt-8'}
188+ className={'mt-8'}
189− prop-size={'lg wide'}
189+ prop-size={'lg wide'}
190− // prop-color={this.buttonTriState(wallet)}
190+ // prop-color={this.buttonTriState(wallet)}
191− onClick={() =>
191+ onClick={() =>
192− this.walletFromShards(
192+ this.walletFromShards(shard1, shard2, shard3, pointName, passphrase)
193− shard1,
194− shard2,
195− shard3,
196− pointName,
197− passphrase
198− )
199− }>
193+ }>
200− {'Unlock Wallet →'}
194+ {'Unlock Wallet →'}
201− </Button>
195+ </Button>
202−
196+
203− <Button
197+ <Button
204− className={'mt-4'}
198+ className={'mt-4'}
205− prop-size={'xl wide'}
199+ prop-size={'xl wide'}
206− disabled={Nothing.hasInstance(wallet)}
200+ disabled={Nothing.hasInstance(wallet)}
207− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
201+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
208− {'Continue →'}
202+ {'Continue →'}
209− </Button>
203+ </Button>
210− </Col>
204+ </View>
211− </Row>
212 );
205 );
213 }
206 }
214}
207}
src/views/Ticket.js+74−77
@@ -9,13 +9,14 @@ import {
9 Input,
9 Input,
10 InputCaption,
10 InputCaption,
11} from '../components/old/Base';
11} from '../components/old/Base';
12−import { Row, Col, H1, P } from '../components/old/Base';
12+import { H1, P } from '../components/old/Base';
13
13
14import { randomPatq, compose } from '../lib/lib';
14import { randomPatq, compose } from '../lib/lib';
15import { ROUTE_NAMES } from '../lib/routeNames';
15import { ROUTE_NAMES } from '../lib/routeNames';
16import { withHistory } from '../store/history';
16import { withHistory } from '../store/history';
17import { urbitWalletFromTicket } from '../lib/wallet';
17import { urbitWalletFromTicket } from '../lib/wallet';
18import { withWallet } from '../store/wallet';
18import { withWallet } from '../store/wallet';
19+import View from 'components/View';
19
20
20class Ticket extends React.Component {
21class Ticket extends React.Component {
21 constructor(props) {
22 constructor(props) {
@@ -71,82 +72,78 @@ class Ticket extends React.Component {
71 const phTick = this.ticketPlaceholder;
72 const phTick = this.ticketPlaceholder;
72
73
73 return (
74 return (
74− <Row>
75+ <View>
75− <Col>
76− <H1>{'Authenticate'}</H1>
76+ <H1>{'Authenticate'}</H1>
77−
77+
78− <P>
78+ <P>
79− {`Please enter your point and Urbit master ticket here. This information is written on your Urbit HD paper wallets.`}
79+ {`Please enter your point and Urbit master ticket here. This information is written on your Urbit HD paper wallets.`}
80− </P>
80+ </P>
81−
81+
82− <PointInput
82+ <PointInput
83− className="mono mt-8"
83+ className="mono mt-8"
84− prop-size="lg"
84+ prop-size="lg"
85− prop-format="innerLabel"
85+ prop-format="innerLabel"
86− type="text"
86+ type="text"
87− autoFocus
87+ autoFocus
88− placeholder={`e.g. ${phPoint}`}
88+ placeholder={`e.g. ${phPoint}`}
89− value={pointName}
89+ value={pointName}
90− onChange={this.handlePointNameInput}>
90+ onChange={this.handlePointNameInput}>
91− <InnerLabel>{'Point'}</InnerLabel>
91+ <InnerLabel>{'Point'}</InnerLabel>
92− <ValidatedSigil
92+ <ValidatedSigil
93− className={'tr-0 mt-05 mr-0 abs'}
93+ className={'tr-0 mt-05 mr-0 abs'}
94− patp={pointName}
94+ patp={pointName}
95− size={68}
95+ size={68}
96− margin={8}
96+ margin={8}
97− />
97+ />
98− </PointInput>
98+ </PointInput>
99−
99+
100− <TicketInput
100+ <TicketInput
101− className="mono mt-8"
101+ className="mono mt-8"
102− prop-size="lg"
102+ prop-size="lg"
103− prop-format="innerLabel"
103+ prop-format="innerLabel"
104− type="password"
104+ type="password"
105− name="ticket"
105+ name="ticket"
106− placeholder={`e.g. ${phTick}`}
106+ placeholder={`e.g. ${phTick}`}
107− value={ticket}
107+ value={ticket}
108− onChange={this.handleTicketInput}>
108+ onChange={this.handleTicketInput}>
109− <InnerLabel>{'Ticket'}</InnerLabel>
109+ <InnerLabel>{'Ticket'}</InnerLabel>
110− </TicketInput>
110+ </TicketInput>
111−
111+
112− <InputCaption>
112+ <InputCaption>
113− {'If your wallet requires a passphrase, you may enter it below.'}
113+ {'If your wallet requires a passphrase, you may enter it below.'}
114− </InputCaption>
114+ </InputCaption>
115−
115+
116− <Input
116+ <Input
117− className="pt-8"
117+ className="pt-8"
118− prop-size="md"
118+ prop-size="md"
119− prop-format="innerLabel"
119+ prop-format="innerLabel"
120− name="passphrase"
120+ name="passphrase"
121− type="password"
121+ type="password"
122− value={passphrase}
122+ value={passphrase}
123− autocomplete="off"
123+ autocomplete="off"
124− onChange={this.handlePassphraseInput}>
124+ onChange={this.handlePassphraseInput}>
125− <InnerLabel>{'Passphrase'}</InnerLabel>
125+ <InnerLabel>{'Passphrase'}</InnerLabel>
126− </Input>
126+ </Input>
127−
127+
128− <Button
128+ <Button
129− className={'mt-8'}
129+ className={'mt-8'}
130− prop-size={'lg wide'}
130+ prop-size={'lg wide'}
131− disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
131+ disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
132− onClick={() =>
133− this.walletFromTicket(ticket, pointName, passphrase)
132+ onClick={() => this.walletFromTicket(ticket, pointName, passphrase)}>
134− }>
135− <span className="relative">
133+ <span className="relative">
136− {this.state.isUnlocking && <span className="btn-spinner" />}
134+ {this.state.isUnlocking && <span className="btn-spinner" />}
137− {'Unlock Wallet →'}
135+ {'Unlock Wallet →'}
138− </span>
136+ </span>
139− </Button>
137+ </Button>
140−
138+
141− <Button
139+ <Button
142− className={'mt-4'}
140+ className={'mt-4'}
143− prop-size={'xl wide'}
141+ prop-size={'xl wide'}
144− disabled={Nothing.hasInstance(wallet)}
142+ disabled={Nothing.hasInstance(wallet)}
145− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
143+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
146− {'Continue →'}
144+ {'Continue →'}
147− </Button>
145+ </Button>
148− </Col>
146+ </View>
149− </Row>
150 );
147 );
151 }
148 }
152}
149}
src/views/Transfer.js+46−58
@@ -4,15 +4,7 @@ import * as azimuth from 'azimuth-js';
4import * as ob from 'urbit-ob';
4import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
5import * as need from '../lib/need';
6
6
7−import {
8− Row,
9− Col,
10− H1,
11− InnerLabel,
12− ShowBlockie,
13− P,
14− Anchor,
15−} from '../components/old/Base';
7+import { H1, InnerLabel, ShowBlockie, P, Anchor } from '../components/old/Base';
16import { AddressInput } from '../components/old/Base';
8import { AddressInput } from '../components/old/Base';
17import StatelessTransaction from '../components/old/StatelessTransaction';
9import StatelessTransaction from '../components/old/StatelessTransaction';
18
10
@@ -22,12 +14,13 @@ import { isValidAddress } from '../lib/wallet';
22import { withNetwork } from '../store/network';
14import { withNetwork } from '../store/network';
23import { compose } from '../lib/lib';
15import { compose } from '../lib/lib';
24import { withPointCursor } from '../store/pointCursor';
16import { withPointCursor } from '../store/pointCursor';
17+import View from 'components/View';
25
18
26class Transfer extends React.Component {
19class Transfer extends React.Component {
27 constructor(props) {
20 constructor(props) {
28 super(props);
21 super(props);
29
22
30− const issuingPoint = need.pointCursor(props);
23+ const issuingPoint = need.pointCursor(props.pointCursor);
31
24
32 this.state = {
25 this.state = {
33 receivingAddress: '',
26 receivingAddress: '',
@@ -53,9 +46,8 @@ class Transfer extends React.Component {
53 createUnsignedTxn() {
46 createUnsignedTxn() {
54 const { state, props } = this;
47 const { state, props } = this;
55
48
56− const validContracts = need.contracts(props);
49+ const validContracts = need.contracts(props.contracts);
57−
58− const validPoint = need.pointCursor(props);
50+ const validPoint = need.pointCursor(props.pointCursor);
59
51
60 const txn = azimuth.ecliptic.setTransferProxy(
52 const txn = azimuth.ecliptic.setTransferProxy(
61 validContracts,
53 validContracts,
@@ -82,53 +74,49 @@ class Transfer extends React.Component {
82 : 'etherscan.io';
74 : 'etherscan.io';
83
75
84 return (
76 return (
85− <Row>
77+ <View>
86− <Col>
87− <H1>
78+ <H1>
88− {'Transfer'} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
79+ {'Transfer'} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
89− {'To a New Owner'}
80+ {'To a New Owner'}
90− </H1>
81+ </H1>
91−
82+
92− <P>
83+ <P>
93− {`Please provide the Ethereum address of the new owner. You own these
84+ {`Please provide the Ethereum address of the new owner. You own these
94 points until the recipient accepts the incoming transfer.
85 points until the recipient accepts the incoming transfer.
95 You may cancel the transfer until the transfer is accepted.`}
86 You may cancel the transfer until the transfer is accepted.`}
96− </P>
87+ </P>
97−
88+
98− <AddressInput
89+ <AddressInput
99− className={'mono mt-8'}
90+ className={'mono mt-8'}
100− prop-size="lg"
91+ prop-size="lg"
101− prop-format="innerLabel"
92+ prop-format="innerLabel"
102− value={state.receivingAddress}
93+ value={state.receivingAddress}
103− placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
94+ placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
104− onChange={v => this.handleAddressInput(v)}>
95+ onChange={v => this.handleAddressInput(v)}>
105− <InnerLabel>{'New ownership address'}</InnerLabel>
96+ <InnerLabel>{'New ownership address'}</InnerLabel>
106− <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
97+ <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
107− </AddressInput>
98+ </AddressInput>
108−
99+
109− <Anchor
100+ <Anchor
110− className={'mt-1'}
101+ className={'mt-1'}
111− prop-size={'s'}
102+ prop-size={'s'}
112− prop-disabled={
113− !isValidAddress(state.receivingAddress) || !esvisible
103+ prop-disabled={!isValidAddress(state.receivingAddress) || !esvisible}
114− }
115− target={'_blank'}
104+ target={'_blank'}
116− href={`https://${esdomain}/address/${state.receivingAddress}`}>
105+ href={`https://${esdomain}/address/${state.receivingAddress}`}>
117− {'View on Etherscan ↗'}
106+ {'View on Etherscan ↗'}
118− </Anchor>
107+ </Anchor>
119−
108+
120− <StatelessTransaction
109+ <StatelessTransaction
121− // Upper scope
110+ // Upper scope
122− {...props}
111+ {...props}
123− // Checks
112+ // Checks
124− userApproval={state.userApproval}
113+ userApproval={state.userApproval}
125− canGenerate={canGenerate}
114+ canGenerate={canGenerate}
126− // Methods
115+ // Methods
127− createUnsignedTxn={this.createUnsignedTxn}
116+ createUnsignedTxn={this.createUnsignedTxn}
128− ref={this.statelessRef}
117+ ref={this.statelessRef}
129− />
118+ />
130− </Col>
119+ </View>
131− </Row>
132 );
120 );
133 }
121 }
134}
122}
src/views/Trezor.js+26−27
@@ -2,7 +2,7 @@ import * as bip32 from 'bip32';
2import React from 'react';
2import React from 'react';
3import Maybe from 'folktale/maybe';
3import Maybe from 'folktale/maybe';
4import { Button } from '../components/old/Base';
4import { Button } from '../components/old/Base';
5−import { Row, Col, H1, P } from '../components/old/Base';
5+import { H1, P } from '../components/old/Base';
6import { InnerLabel, Input, InnerLabelDropdown } from '../components/old/Base';
6import { InnerLabel, Input, InnerLabelDropdown } from '../components/old/Base';
7import TrezorConnect from 'trezor-connect';
7import TrezorConnect from 'trezor-connect';
8import * as secp256k1 from 'secp256k1';
8import * as secp256k1 from 'secp256k1';
@@ -12,6 +12,7 @@ import { ROUTE_NAMES } from '../lib/routeNames';
12import { withHistory } from '../store/history';
12import { withHistory } from '../store/history';
13import { compose } from '../lib/lib';
13import { compose } from '../lib/lib';
14import { withWallet } from '../store/wallet';
14import { withWallet } from '../store/wallet';
15+import View from 'components/View';
15
16
16class Trezor extends React.Component {
17class Trezor extends React.Component {
17 constructor(props) {
18 constructor(props) {
@@ -109,34 +110,32 @@ class Trezor extends React.Component {
109 );
110 );
110
111
111 return (
112 return (
112− <Row>
113+ <View>
113− <Col className={'measure-md'}>
114− <H1>{'Authenticate With Your Trezor'}</H1>
114+ <H1>{'Authenticate With Your Trezor'}</H1>
115
115
116− <P>
116+ <P>
117− {`Connect and authenticate to your Trezor. If you'd like
117+ {`Connect and authenticate to your Trezor. If you'd like
118 to use a custom derivation path, you may enter it below.`}
118 to use a custom derivation path, you may enter it below.`}
119− </P>
119+ </P>
120−
120+
121− {accountSelection}
121+ {accountSelection}
122− {pathSelection}
122+ {pathSelection}
123−
123+
124− <Button
124+ <Button
125− className={'mt-8'}
125+ className={'mt-8'}
126− prop-size={'wide lg'}
126+ prop-size={'wide lg'}
127− onClick={this.pollDevice}>
127+ onClick={this.pollDevice}>
128− {'Authenticate →'}
128+ {'Authenticate →'}
129− </Button>
129+ </Button>
130−
130+
131− <Button
131+ <Button
132− className={'mt-8'}
132+ className={'mt-8'}
133− prop-size={'wide lg'}
133+ prop-size={'wide lg'}
134− disabled={Maybe.Nothing.hasInstance(wallet)}
134+ disabled={Maybe.Nothing.hasInstance(wallet)}
135− onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
135+ onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
136− {'Continue →'}
136+ {'Continue →'}
137− </Button>
137+ </Button>
138− </Col>
138+ </View>
139− </Row>
140 );
139 );
141 }
140 }
142}
141}
src/views/ViewPoint.js+33−34
@@ -3,13 +3,14 @@ import React from 'react';
3import * as ob from 'urbit-ob';
3import * as ob from 'urbit-ob';
4
4
5import { Button } from '../components/old/Base';
5import { Button } from '../components/old/Base';
6−import { Row, Col, H1, P } from '../components/old/Base';
6+import { H1, P } from '../components/old/Base';
7import { InnerLabel, PointInput, ValidatedSigil } from '../components/old/Base';
7import { InnerLabel, PointInput, ValidatedSigil } from '../components/old/Base';
8
8
9import { ROUTE_NAMES } from '../lib/routeNames';
9import { ROUTE_NAMES } from '../lib/routeNames';
10import { withHistory } from '../store/history';
10import { withHistory } from '../store/history';
11import { compose } from '../lib/lib';
11import { compose } from '../lib/lib';
12import { withPointCursor } from '../store/pointCursor';
12import { withPointCursor } from '../store/pointCursor';
13+import View from 'components/View';
13
14
14class ViewPoint extends React.Component {
15class ViewPoint extends React.Component {
15 constructor(props) {
16 constructor(props) {
@@ -43,42 +44,40 @@ class ViewPoint extends React.Component {
43 }
44 }
44
45
45 return (
46 return (
46− <Row>
47+ <View>
47− <Col>
48− <H1>{'View a Point'}</H1>
48+ <H1>{'View a Point'}</H1>
49
49
50− <P>{'Enter a point name to view its public information.'}</P>
50+ <P>{'Enter a point name to view its public information.'}</P>
51
51
52− <PointInput
52+ <PointInput
53− autoFocus
53+ autoFocus
54− prop-size="lg"
54+ prop-size="lg"
55− prop-format="innerLabel"
55+ prop-format="innerLabel"
56− className="mono"
56+ className="mono"
57− placeholder="e.g. ~zod"
57+ placeholder="e.g. ~zod"
58− onChange={this.handlePointInput}
58+ onChange={this.handlePointInput}
59− value={pointName}>
59+ value={pointName}>
60− <InnerLabel>{'Point Name'}</InnerLabel>
60+ <InnerLabel>{'Point Name'}</InnerLabel>
61− <ValidatedSigil
61+ <ValidatedSigil
62− className={'tr-0 mt-05 mr-0 abs'}
62+ className={'tr-0 mt-05 mr-0 abs'}
63− patp={pointName}
63+ patp={pointName}
64− show
64+ show
65− size={68}
65+ size={68}
66− margin={8}
66+ margin={8}
67− />
67+ />
68− </PointInput>
68+ </PointInput>
69
69
70− <Button
70+ <Button
71− className={'mt-8'}
71+ className={'mt-8'}
72− disabled={valid === false}
72+ disabled={valid === false}
73− onClick={() => {
73+ onClick={() => {
74− setPointCursor(Maybe.Just(parseInt(ob.patp2dec(pointName), 10)));
74+ setPointCursor(Maybe.Just(parseInt(ob.patp2dec(pointName), 10)));
75− // ^ pointCursor expects native number type, not string
75+ // ^ pointCursor expects native number type, not string
76− history.popAndPush(ROUTE_NAMES.SHIP);
76+ history.popAndPush(ROUTE_NAMES.SHIP);
77− }}>
77+ }}>
78− {'Continue →'}
78+ {'Continue →'}
79− </Button>
79+ </Button>
80− </Col>
80+ </View>
81− </Row>
82 );
81 );
83 }
82 }
84}
83}
src/views/Wallet.js+37−39
@@ -2,13 +2,13 @@ import Maybe from 'folktale/maybe';
2import React from 'react';
2import React from 'react';
3import { Button, H1, P } from '../components/old/Base';
3import { Button, H1, P } from '../components/old/Base';
4import { InnerLabelDropdown } from '../components/old/Base';
4import { InnerLabelDropdown } from '../components/old/Base';
5−import { Row, Col } from '../components/old/Base';
6
5
7import { ROUTE_NAMES } from '../lib/routeNames';
6import { ROUTE_NAMES } from '../lib/routeNames';
8import { withHistory } from '../store/history';
7import { withHistory } from '../store/history';
9import { WALLET_TYPES, renderWalletType } from '../lib/wallet';
8import { WALLET_TYPES, renderWalletType } from '../lib/wallet';
10import { compose } from '../lib/lib';
9import { compose } from '../lib/lib';
11import { withWallet } from '../store/wallet';
10import { withWallet } from '../store/wallet';
11+import View from 'components/View';
12
12
13class Wallet extends React.Component {
13class Wallet extends React.Component {
14 componentDidMount() {
14 componentDidMount() {
@@ -60,48 +60,46 @@ class Wallet extends React.Component {
60 const walletOptions = this.getWalletOptions();
60 const walletOptions = this.getWalletOptions();
61
61
62 return (
62 return (
63− <Row>
63+ <View>
64− <Col>
65− <H1>{'Unlock a Wallet'}</H1>
64+ <H1>{'Unlock a Wallet'}</H1>
66
65
67− <P>
66+ <P>
68− {`To manage your assets, you need to unlock a wallet.
67+ {`To manage your assets, you need to unlock a wallet.
69 Please select how you would like to access your wallet.`}
68 Please select how you would like to access your wallet.`}
70− </P>
69+ </P>
71
70
72− <InnerLabelDropdown
71+ <InnerLabelDropdown
73− className={'mb-10 mt-6'}
72+ className={'mb-10 mt-6'}
74− title={'Wallet Type:'}
73+ title={'Wallet Type:'}
75− options={walletOptions}
74+ options={walletOptions}
76− handleUpdate={props.setWalletType}
75+ handleUpdate={props.setWalletType}
77− currentSelectionTitle={renderWalletType(props.walletType)}
76+ currentSelectionTitle={renderWalletType(props.walletType)}
78− />
77+ />
79
78
80− <Button
79+ <Button
81− className={'mt-10'}
80+ className={'mt-10'}
82− onClick={() =>
81+ onClick={() =>
83− props.history.push(
82+ props.history.push(
84− props.walletType === WALLET_TYPES.MNEMONIC
83+ props.walletType === WALLET_TYPES.MNEMONIC
85− ? ROUTE_NAMES.MNEMONIC
84+ ? ROUTE_NAMES.MNEMONIC
86− : props.walletType === WALLET_TYPES.TICKET
85+ : props.walletType === WALLET_TYPES.TICKET
87− ? ROUTE_NAMES.TICKET
86+ ? ROUTE_NAMES.TICKET
88− : props.walletType === WALLET_TYPES.SHARDS
87+ : props.walletType === WALLET_TYPES.SHARDS
89− ? ROUTE_NAMES.SHARDS
88+ ? ROUTE_NAMES.SHARDS
90− : props.walletType === WALLET_TYPES.LEDGER
89+ : props.walletType === WALLET_TYPES.LEDGER
91− ? ROUTE_NAMES.LEDGER
90+ ? ROUTE_NAMES.LEDGER
92− : props.walletType === WALLET_TYPES.TREZOR
91+ : props.walletType === WALLET_TYPES.TREZOR
93− ? ROUTE_NAMES.TREZOR
92+ ? ROUTE_NAMES.TREZOR
94− : props.walletType === WALLET_TYPES.PRIVATE_KEY
93+ : props.walletType === WALLET_TYPES.PRIVATE_KEY
95− ? ROUTE_NAMES.PRIVATE_KEY
94+ ? ROUTE_NAMES.PRIVATE_KEY
96− : props.walletType === WALLET_TYPES.KEYSTORE
95+ : props.walletType === WALLET_TYPES.KEYSTORE
97− ? ROUTE_NAMES.KEYSTORE
96+ ? ROUTE_NAMES.KEYSTORE
98− : ROUTE_NAMES.DEFAULT
97+ : ROUTE_NAMES.DEFAULT
99− )
98+ )
100− }>
99+ }>
101− {'Continue →'}
100+ {'Continue →'}
102− </Button>
101+ </Button>
103− </Col>
102+ </View>
104− </Row>
105 );
103 );
106 }
104 }
107}
105}