on master help sign in
Cleaned up the Point view
commit841a01ae2086c9f58307c5bf6d5c99188de54203 authorWill Galebach <willbach@gmail.com> dateWed 27 Oct 2021, 13:17 (5 years ago) parentae01be4
16 files changed+242−121
src/components/InlineEthereumTransaction.js+2−2 src/components/L2/Dropdowns/AccountsDropdown.tsx+16 src/components/L2/Dropdowns/FeeDropdown.scss+2−2 src/components/L2/Window/BodyPane.scss+22 src/lib/metamask.ts+6−2 src/lib/useRoller.ts+5−5 src/views/Activate/MasterKeyConfirm.tsx+1−1 src/views/Activate/MasterKeyDownload.tsx+1−1 src/views/Activate/MasterKeyReveal.tsx+2−2 src/views/Login/LoginSelector.tsx+92−7 src/views/Login/Other.tsx+2−2 src/views/Point/Point.tsx+24−53 src/views/Point/Residents.js+39 src/views/UrbitID/Home.tsx+9−24 src/views/UrbitID/ResetKeys/ResetExecute.js+2−2 src/views/UrbitOS/Home.tsx+17−18
src/components/InlineEthereumTransaction.js+2−2
@@ -224,13 +224,13 @@ export default function InlineEthereumTransaction({
224224 />
225225 )}
226226
227− {showSignedTx && fakeSigned && (
227+ {/* {showSignedTx && fakeSigned && (
228228 <>
229229 <Grid.Item className="mt2 eth-tx-button" full as={NoticeBox}>
230230 Your wallet will sign the transaction upon sending it.
231231 </Grid.Item>
232232 </>
233− )}
233+ )} */}
234234 </>
235235 )}
236236 </BridgeForm>
src/components/L2/Dropdowns/AccountsDropdown.tsx+16
@@ -22,6 +22,7 @@ import './AccountsDropdown.scss';
2222import Modal from '../Modal';
2323import { useHasNetworkKeysSet } from 'lib/useHasNetworkKeysSet';
2424import { useRollerStore } from 'store/roller';
25+import useCurrentPermissions from 'lib/useCurrentPermissions';
2526
2627interface AccountsDropdownProps {
2728 showMigrate: boolean;
@@ -59,20 +60,29 @@ const AccountsDropdown = ({ showMigrate = false }: AccountsDropdownProps) => {
5960 },
6061 [push, names.POINT, setOpen, setPointCursor]
6162 );
63+
6264 const goMigrate = useCallback(() => push(names.MIGRATE_L2), [
6365 names.MIGRATE_L2,
6466 push,
6567 ]);
68+
6669 const goBitcoin = useCallback(() => push(names.BITCOIN), [
6770 names.BITCOIN,
6871 push,
6972 ]);
7073
74+ const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
75+ names.ISSUE_CHILD,
76+ push,
77+ ]);
78+
7179 const onLogout = () => {
7280 clearInvitesStorage();
7381 reset();
7482 };
7583
84+ const { canSpawn, isParent } = useCurrentPermissions();
85+
7686 return (
7787 <Dropdown
7888 className="accounts-dropdown"
@@ -123,6 +133,12 @@ const AccountsDropdown = ({ showMigrate = false }: AccountsDropdownProps) => {
123133 <Icon icon="Bitcoin" />
124134 </Row>
125135 )}
136+ {isParent && canSpawn && (
137+ <Row className="entry" onClick={goIssuePoint}>
138+ <Box>Issue Point</Box>
139+ <Icon icon="Plus" />
140+ </Row>
141+ )}
126142 <Row className="entry" onClick={onLogout}>
127143 <Box>Logout</Box>
128144 <Icon icon="LogOut" />
src/components/L2/Dropdowns/FeeDropdown.scss+2−2
@@ -28,13 +28,13 @@
2828 }
2929
3030 .label {
31− margin-right: 32px;
31+ margin-right: 8px;
3232 }
3333
3434 .custom-input {
3535 font-family: "Inter", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji";
3636 text-align: right;
37− height: 32px;
37+ height: 24px;
3838 }
3939
4040 .unit {
src/components/L2/Window/BodyPane.scss+22
@@ -23,6 +23,10 @@
2323 .subtitle {
2424 margin-top: 4px;
2525 color: $mid-gray;
26+
27+ &.error-text {
28+ color: $warning-red;
29+ }
2630 }
2731
2832 .arrow-button {
@@ -31,6 +35,24 @@
3135 padding: 0 4px;
3236 }
3337
38+ button.primary {
39+ background-color: black;
40+ color: white;
41+ border-radius: $medium-border-radius;
42+ border: none;
43+ height: 32px;
44+ padding: 8px 16px;
45+ font-family: $default-font;
46+
47+ &:nth-child(2) {
48+ margin-left: 8px;
49+ }
50+
51+ &:hover {
52+ opacity: 0.8;
53+ }
54+ }
55+
3456 button.secondary {
3557 background-color: $washed-gray;
3658 border-radius: $medium-border-radius;
src/lib/metamask.ts+6−2
@@ -2,8 +2,12 @@ import Web3 from 'web3';
22import { toHex } from 'web3-utils';
33import { FakeSignableTx, FakeSignResult } from './txn';
44
5−export function MetamaskWallet(address) {
6− this.address = address;
5+export class MetamaskWallet {
6+ address: string;
7+
8+ constructor(address: string) {
9+ this.address = address;
10+ }
711}
812
913// Cheat a bit and pretend to sign transaction
src/lib/useRoller.ts+5−5
@@ -145,11 +145,11 @@ export default function useRoller() {
145145 throw new Error('Internal Error: Missing Contracts/Web3/Wallet');
146146 }
147147
148− if (Just.hasInstance(authMnemonic)) {
149− throw new Error(
150− "Auth key Error: A management mnemonic can't create invite codes"
151− );
152− }
148+ // if (Just.hasInstance(authMnemonic)) {
149+ // throw new Error(
150+ // "Auth key Error: A management mnemonic can't create invite codes"
151+ // );
152+ // }
153153 let planets: UnspawnedPoints = await api.getUnspawned(_point);
154154
155155 const pendingTxs = await api.getPendingByShip(_point);
src/views/Activate/MasterKeyConfirm.tsx+1−1
@@ -78,7 +78,7 @@ const MasterKeyConfirm = () => {
7878 <ActivateHeader content={'Confirm Backup'} />
7979 <ActivateParagraph
8080 copy={
81− 'Confirm that you have stored your Master Key somewhere safe by entering it below'
81+ 'Confirm that you have stored your Master Ticket somewhere safe by entering it below'
8282 }
8383 />
8484 </Box>
src/views/Activate/MasterKeyDownload.tsx+1−1
@@ -71,7 +71,7 @@ const MasterKeyDownload = () => {
7171 const header = useMemo(() => {
7272 return (
7373 <Box>
74− <ActivateHeader content={'Backup your Master Key.'} />
74+ <ActivateHeader content={'Backup your Master Ticket.'} />
7575 <ActivateParagraph
7676 copy={
7777 'Download your backup and store it somewhere safe, e.g. your security deposit box or password manager.'
src/views/Activate/MasterKeyReveal.tsx+2−2
@@ -34,10 +34,10 @@ const MasterKeyReveal = () => {
3434 const header = useMemo(() => {
3535 return (
3636 <Box>
37− <ActivateHeader content={'Here is your Master Key.'} />
37+ <ActivateHeader content={'Here is your Master Ticket.'} />
3838 <ActivateParagraph
3939 copy={
40− "Your Master Key is your 4-word password for your Urbit. Make sure you're in a private place before you reveal it."
40+ "Your Master Ticket is your 4-word password for your Urbit. Make sure you're in a private place before you reveal it."
4141 }
4242 />
4343 </Box>
src/views/Login/LoginSelector.tsx+92−7
@@ -1,16 +1,28 @@
11import React, { useCallback, useState } from 'react';
22import cn from 'classnames';
33import { Grid } from 'indigo-react';
4+import { Box, Button, Icon, Row, Text } from '@tlon/indigo-react';
5+import { useHistory } from 'store/history';
6+import { Just, Nothing } from 'folktale/maybe';
7+import { FORM_ERROR } from 'final-form';
8+
9+import { useWallet } from 'store/wallet';
10+import { useNetwork } from 'store/network';
11+import { usePointCursor } from 'store/pointCursor';
12+
13+import { WALLET_TYPES } from 'lib/constants';
14+import { MetamaskWallet } from 'lib/metamask';
15+import { getAuthToken } from 'lib/authToken';
16+import * as need from 'lib/need';
17+import { useWalletConnect } from 'lib/useWalletConnect';
18+
419import Window from 'components/L2/Window/Window';
520import HeaderPane from 'components/L2/Window/HeaderPane';
621import BodyPane from 'components/L2/Window/BodyPane';
7−import { Box, Button, Icon, Row, Text } from '@tlon/indigo-react';
8−import L2BackHeader from 'components/L2/Headers/L2BackHeader';
9−
10−import './LoginSelector.scss';
11−import { useHistory } from 'store/history';
1222import Modal from 'components/L2/Modal';
1323import L2BackButton from 'components/L2/Headers/L2BackButton';
24+import './LoginSelector.scss';
25+import { NAMES } from './Other';
1426
1527interface LoginSelectorProps {
1628 className: string;
@@ -23,6 +35,7 @@ interface LoginSelectorProps {
2335 }[];
2436 currentTab?: string;
2537 setCurrentTab: (tab?: string) => void;
38+ goHome: () => void;
2639}
2740
2841export default function LoginSelector({
@@ -31,17 +44,83 @@ export default function LoginSelector({
3144 options,
3245 currentTab,
3346 setCurrentTab,
47+ goHome,
3448 // Tab props
3549 ...rest
3650}: LoginSelectorProps) {
3751 const { push, names }: any = useHistory();
3852 const [showModal, setShowModal] = useState(false);
3953
54+ const {
55+ setWallet,
56+ setWalletType,
57+ resetWallet,
58+ setAuthToken,
59+ }: any = useWallet();
60+
61+ const { setPointCursor }: any = usePointCursor();
62+ const { authenticate } = useWalletConnect();
63+ const { web3 }: any = useNetwork();
64+ const _web3 = need.web3(web3);
65+
4066 const goToActivate = useCallback(() => push(names.ACTIVATE), [
4167 push,
4268 names.ACTIVATE,
4369 ]);
4470
71+ const connectWalletConnect = async () => {
72+ resetWallet();
73+ setWalletType(WALLET_TYPES.WALLET_CONNECT);
74+ setPointCursor(Nothing());
75+ await authenticate();
76+ goHome();
77+ };
78+
79+ const connectMetamask = useCallback(async () => {
80+ try {
81+ resetWallet();
82+ setWalletType(WALLET_TYPES.METAMASK);
83+ setPointCursor(Nothing());
84+
85+ const accounts = await (window as any).ethereum.send(
86+ 'eth_requestAccounts'
87+ );
88+ const wallet = new MetamaskWallet(accounts.result[0]);
89+
90+ const authToken = await getAuthToken({
91+ address: wallet.address,
92+ walletType: WALLET_TYPES.METAMASK,
93+ web3: _web3,
94+ });
95+
96+ setAuthToken(Just(authToken));
97+ setWallet(Just(wallet));
98+ setWalletType(WALLET_TYPES.METAMASK);
99+ goHome();
100+ } catch (e) {
101+ console.error(e);
102+ return { [FORM_ERROR]: (e as any).message };
103+ }
104+ }, [
105+ _web3,
106+ setAuthToken,
107+ setWallet,
108+ setWalletType,
109+ resetWallet,
110+ setPointCursor,
111+ goHome,
112+ ]);
113+
114+ const selectOption = (value: string) => () => {
115+ if (value === NAMES.METAMASK) {
116+ connectMetamask();
117+ } else if (value === NAMES.WALLET_CONNECT) {
118+ connectWalletConnect();
119+ } else {
120+ setCurrentTab(value);
121+ }
122+ };
123+
45124 if (!currentTab) {
46125 return (
47126 <Grid className={className}>
@@ -50,7 +129,7 @@ export default function LoginSelector({
50129 <Grid.Item
51130 full
52131 className={cn('f5 pv3 rel pointer login-menu-item')}
53− onClick={() => setCurrentTab(option.value)}>
132+ onClick={selectOption(option.value)}>
54133 {option.text}
55134 {option.menuIcon}
56135 </Grid.Item>
@@ -109,7 +188,13 @@ export default function LoginSelector({
109188 </Row>
110189 </HeaderPane>
111190 <BodyPane className="login-body-pane">
112− <Grid.Item full as={Tab} {...rest} className="login-selector" />
191+ <Grid.Item
192+ full
193+ as={Tab}
194+ {...rest}
195+ goHome={goHome}
196+ className="login-selector"
197+ />
113198 </BodyPane>
114199 </Window>
115200 </Box>
src/views/Login/Other.tsx+2−2
@@ -9,7 +9,7 @@ import LoginSelector from './LoginSelector';
99import { ReactComponent as MetamaskIcon } from 'assets/metamask.svg';
1010import { ReactComponent as WalletConnectIcon } from 'assets/wallet-connect.svg';
1111
12−const NAMES = {
12+export const NAMES = {
1313 METAMASK: 'METAMASK',
1414 MNEMONIC: 'MNEMONIC',
1515 WALLET_CONNECT: 'WALLET_CONNECT',
@@ -28,7 +28,7 @@ const settingsIcon = <Icon icon="Gear" />;
2828
2929const OPTIONS = [
3030 {
31− text: 'Master Key',
31+ text: 'Master Ticket',
3232 value: NAMES.MASTER_TICKET,
3333 menuIcon: rightArrowIcon,
3434 headerIcon: settingsIcon,
src/views/Point/Point.tsx+24−53
@@ -1,5 +1,4 @@
11import { useCallback, useEffect, useState } from 'react';
2−import { azimuth } from 'azimuth-js';
32import { Just } from 'folktale/maybe';
43import { Grid, Flex } from 'indigo-react';
54import { Box, Icon, Row, Button, Checkbox } from '@tlon/indigo-react';
@@ -12,7 +11,6 @@ import View from 'components/View';
1211import Greeting from 'components/Greeting';
1312import Passport from 'components/Passport';
1413import Blinky from 'components/Blinky';
15−import { ForwardButton } from 'components/Buttons';
1614import L2PointHeader from 'components/L2/Headers/L2PointHeader';
1715import LayerIndicator from 'components/L2/LayerIndicator';
1816import Card from 'components/L2/Card';
@@ -29,7 +27,7 @@ import { isL2 } from 'lib/utils/roller';
2927import { isDevelopment } from 'lib/flags';
3028import { usePointCache } from 'store/pointCache';
3129import Modal from 'components/L2/Modal';
32−import { isPlanet } from 'lib/utils/point';
30+import { isPlanet, isStar } from 'lib/utils/point';
3331import { useHasNetworkKeysSet } from 'lib/useHasNetworkKeysSet';
3432import { InviteForm } from './InviteForm';
3533
@@ -48,13 +46,21 @@ export default function Point() {
4846 setInvites,
4947 } = useRollerStore();
5048 const networkKeysSet = useHasNetworkKeysSet();
49+ const [seenMissingKeys, setSeenMissingKeys] = useSeenMissingKeys();
5150 const [showModal, setShowModal] = useState(false);
52− const [seenMissingKeys, setSeeingMissingKeys] = useSeenMissingKeys();
5351 const [hideMessage, setHideMessage] = useState(false);
5452
53+ const hideModal = useCallback(() => {
54+ if (hideMessage) {
55+ setSeenMissingKeys(true);
56+ }
57+
58+ setShowModal(false);
59+ }, [hideMessage, setShowModal, setSeenMissingKeys]);
60+
5561 useEffect(() => {
56− setShowModal(!networkKeysSet);
57− }, [networkKeysSet]);
62+ setShowModal(!networkKeysSet && !seenMissingKeys);
63+ }, [networkKeysSet, seenMissingKeys]);
5864
5965 const loadL1Info = useCallback(async () => {
6066 await syncExtras(point);
@@ -84,7 +90,7 @@ export default function Point() {
8490 setInvites([]);
8591 }, []); // eslint-disable-line react-hooks/exhaustive-deps
8692
87− const { isParent, canManage, canSpawn, canVote } = useCurrentPermissions();
93+ const { isParent, canManage } = useCurrentPermissions();
8894
8995 // L1 invites
9096 const l1Invites = useInvites(point);
@@ -104,46 +110,22 @@ export default function Point() {
104110
105111 const loadedInvites = Just.hasInstance(availableInvites);
106112
107− const goSenate = useCallback(() => push(names.SENATE), [push, names]);
108−
109113 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
110114
111115 const goUrbitOS = useCallback(() => {
112− if (hideMessage) setSeeingMissingKeys(hideMessage);
116+ if (hideMessage) setSeenMissingKeys(hideMessage);
113117
114118 push(names.URBIT_OS);
115− }, [push, names, hideMessage, setSeeingMissingKeys]);
119+ }, [push, names, hideMessage, setSeenMissingKeys]);
116120
117121 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
118122
119123 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
120124
121− const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
122− names.ISSUE_CHILD,
123− push,
124− ]);
125−
126125 const planet = isPlanet(point);
127126
128127 const [showInviteForm, setShowInviteForm] = useState(false);
129128
130− const senateButton = (() => {
131− if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
132− return null;
133− }
134− return (
135− <>
136− <Grid.Item
137− full
138− as={ForwardButton}
139− disabled={!canVote}
140− onClick={goSenate}>
141− Senate
142− </Grid.Item>
143− <Grid.Divider />
144− </>
145− );
146− })();
147129 const address = need.addressFromWallet(wallet);
148130 const spawnedPending = pendingTransactions.filter(
149131 ({ rawTx }) => rawTx?.tx?.type === 'spawn'
@@ -220,8 +202,12 @@ export default function Point() {
220202 {isParent && (
221203 <Grid.Item full as={Flex} justify="between">
222204 <Card
223− title="Residency"
224− subtitle="Manage peers that you service"
205+ title={`${isStar(point) ? 'Star' : 'Galaxy'} Ops`}
206+ subtitle={
207+ isStar(point)
208+ ? 'Manage planets you sponsor and spawn planets'
209+ : 'Manage stars you sponsor, spawn stars, and vote'
210+ }
225211 onClick={goResidents}
226212 />
227213 </Grid.Item>
@@ -263,25 +249,10 @@ export default function Point() {
263249 disabled={!canManage}
264250 />
265251 </Grid.Item>
266− {isParent && (
267− <>
268− <Grid.Item
269− full
270− as={ForwardButton}
271− disabled={!canSpawn}
272− onClick={goIssuePoint}>
273− Issue Point
274− </Grid.Item>
275− <Grid.Divider />
276− </>
277− )}
278− {senateButton}
279252 </Grid>
280− <Modal
281− show={showModal && !seenMissingKeys}
282− hide={() => setShowModal(false)}>
253+ <Modal show={showModal} hide={hideModal}>
283254 <Box className="network-keys-modal">
284− <Box className="close" onClick={() => setShowModal(false)}>
255+ <Box className="close" onClick={hideModal}>
285256 &#215;
286257 </Box>
287258 <Box className="title">No Network Keys Found</Box>
@@ -297,7 +268,7 @@ export default function Point() {
297268 <Box className="dont-show">Do not warn me again</Box>
298269 </Row>
299270 <Row className="buttons">
300− <Button className="cancel" onClick={() => setShowModal(false)}>
271+ <Button className="cancel" onClick={hideModal}>
301272 Cancel
302273 </Button>
303274 <Button className="migrate" onClick={goUrbitOS}>
src/views/Point/Residents.js+39
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback, useMemo } from 'react';
22import cn from 'classnames';
33import { Grid, H4, HelpText } from 'indigo-react';
44import { Just, Nothing } from 'folktale/maybe';
5+import { azimuth } from 'azimuth-js';
56import * as ob from 'urbit-ob';
67
78import View from 'components/View';
@@ -10,9 +11,11 @@ import Crumbs from 'components/Crumbs';
1011import Sigil from 'components/Sigil';
1112import Blinky from 'components/Blinky';
1213import NavHeader from 'components/NavHeader';
14+import { ForwardButton } from 'components/Buttons';
1315
1416import { useLocalRouter } from 'lib/LocalRouter';
1517import useCurrentPointName from 'lib/useCurrentPointName';
18+import useCurrentPermissions from 'lib/useCurrentPermissions';
1619import * as need from 'lib/need';
1720
1821import { usePointCursor } from 'store/pointCursor';
@@ -168,6 +171,13 @@ export default function Residents() {
168171 const [currentTab, _setCurrentTab] = useState(NAMES.ALL);
169172 const [page, setPage] = useState(0);
170173
174+ const goSenate = useCallback(() => push(names.SENATE), [push, names]);
175+
176+ const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
177+ names.ISSUE_CHILD,
178+ push,
179+ ]);
180+
171181 const setCurrentTab = useCallback(
172182 tab => {
173183 setPage(0);
@@ -199,6 +209,25 @@ export default function Residents() {
199209 const onDecline = isRequests && _onDecline;
200210
201211 const points = isRequests ? requests : residents;
212+ const { canSpawn, canVote } = useCurrentPermissions();
213+
214+ const senateButton = (() => {
215+ if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
216+ return null;
217+ }
218+ return (
219+ <>
220+ <Grid.Item
221+ full
222+ as={ForwardButton}
223+ disabled={!canVote}
224+ onClick={goSenate}>
225+ Senate
226+ </Grid.Item>
227+ <Grid.Divider />
228+ </>
229+ );
230+ })();
202231
203232 return (
204233 <View pop={pop} inset>
@@ -211,6 +240,16 @@ export default function Residents() {
211240 <Grid.Item full as={H4} className="mt4">
212241 Residents
213242 </Grid.Item>
243+ <Grid.Divider />
244+ <Grid.Item
245+ full
246+ as={ForwardButton}
247+ disabled={!canSpawn}
248+ onClick={goIssuePoint}>
249+ Issue Point
250+ </Grid.Item>
251+ <Grid.Divider />
252+ {senateButton}
214253 <Grid.Item
215254 full
216255 className="mt1"
src/views/UrbitID/Home.tsx+9−24
@@ -30,14 +30,12 @@ export default function UrbitIDHome() {
3030 const { urbitWallet }: any = useWallet();
3131 const { currentPoint } = useRollerStore();
3232
33− const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
34−
3533 const goDownloadKeys = useCallback(() => push(names.DOWNLOAD_KEYS), [
3634 push,
3735 names,
3836 ]);
3937
40− const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
38+ const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
4139
4240 const goResetKeys = useCallback(() => push(names.RESET_KEYS), [push, names]);
4341
@@ -68,7 +66,11 @@ export default function UrbitIDHome() {
6866 <HeaderPane>
6967 <Row className="header-row">
7068 <h5>ID</h5>
71− <Button className="header-button">Download Passport</Button>
69+ {isMasterTicket && (
70+ <Button onClick={goDownloadKeys} className="header-button">
71+ Download Passport
72+ </Button>
73+ )}
7274 </Row>
7375 </HeaderPane>
7476 <BodyPane>
@@ -98,7 +100,7 @@ export default function UrbitIDHome() {
98100 <Box>Management Address</Box>
99101 <div className="mt1 mono black subtitle">
100102 {noManagement
101− ? 'Unset'
103+ ? 'Not set'
102104 : abbreviateAddress(details.managementProxy)}
103105 </div>
104106 </Box>
@@ -148,7 +150,7 @@ export default function UrbitIDHome() {
148150 <Box>Master Ticket</Box>
149151 <Box className="subtitle">
150152 {isMasterTicket
151− ? 'Reset Master Key and all other keys'
153+ ? 'Reset Master Ticket and all other keys'
152154 : 'Transfer to Master Ticket, resetting all keys'}
153155 </Box>
154156 </Box>
@@ -163,26 +165,9 @@ export default function UrbitIDHome() {
163165 <Box>
164166 <Box>Network Keys Required</Box>
165167 <Box className="subtitle">
166− Set your network keys to spawn points
167− </Box>
168− </Box>
169− <Button className="secondary" onClick={goUrbitOS}>
170− Set Keys
171− </Button>
172− </Row>
173− )}
174−
175− {isMasterTicket && (
176− <Row className="between-row management">
177− <Box>
178− <Box>Download Keys</Box>
179− <Box className="subtitle">
180− Download the keys to your master ticket.
168+ Set your network keys in "OS" to spawn points
181169 </Box>
182170 </Box>
183− <Button className="secondary" onClick={goDownloadKeys}>
184− Download
185− </Button>
186171 </Row>
187172 )}
188173
src/views/UrbitID/ResetKeys/ResetExecute.js+2−2
@@ -194,7 +194,7 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
194194
195195 return (
196196 <Grid.Item full as={WarningBox} className="mt4">
197− Never give your Master Key to anyone
197+ Never give your Master Ticket to anyone
198198 </Grid.Item>
199199 );
200200 };
@@ -218,7 +218,7 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
218218 className="mt4"
219219 accessory="↺"
220220 onClick={loginAndGoHome}>
221− Login with New Master Key
221+ Login with New Master Ticket
222222 </Grid.Item>
223223 </>
224224 ) : (
src/views/UrbitOS/Home.tsx+17−18
@@ -59,13 +59,15 @@ export default function UrbitOSHome() {
5959 <HeaderPane>
6060 <Row className="header-row">
6161 <h5>OS</h5>
62− <Button
63− className="header-button keyfile"
64− disabled={!hasSetNetworkingKeys}
65− onClick={keyBind.download}>
66− <KeyfileIcon />
67− Download Keyfile
68− </Button>
62+ {hasSetNetworkingKeys && (
63+ <Button
64+ className="header-button keyfile"
65+ disabled={!hasSetNetworkingKeys}
66+ onClick={keyBind.download}>
67+ <KeyfileIcon />
68+ Download Keyfile
69+ </Button>
70+ )}
6971 </Row>
7072 </HeaderPane>
7173 <BodyPane>
@@ -90,14 +92,19 @@ export default function UrbitOSHome() {
9092 <Row className="between-row management">
9193 <Box>
9294 <Box>Network Keys</Box>
93− <Box className="subtitle">
95+ <Box
96+ className={`subtitle ${
97+ !hasSetNetworkingKeys ? 'error-text' : ''
98+ }`}>
9499 {hasSetNetworkingKeys
95100 ? `Revision: ${details.keyRevisionNumber}`
96− : 'Unset'}
101+ : 'No network keys found'}
97102 </Box>
98103 </Box>
99104 <Row>
100− <Button className="secondary" onClick={goNetworkingKeys}>
105+ <Button
106+ className={hasSetNetworkingKeys ? 'secondary' : 'primary'}
107+ onClick={goNetworkingKeys}>
101108 {hasSetNetworkingKeys ? 'Reset' : 'Initialize'}
102109 </Button>
103110 {hasSetNetworkingKeys && (
@@ -110,14 +117,6 @@ export default function UrbitOSHome() {
110117
111118 {showKeys && <Grid.Item full as={NetworkingKeys} point={point} />}
112119
113− {!hasSetNetworkingKeys && (
114− <>
115− <Grid.Item full as={AlertBox} className="mt4">
116− Networking Keys are required to generate a keyfile
117− </Grid.Item>
118− </>
119− )}
120−
121120 {!!code && (
122121 <Row className="between-row management">
123122 <Box>