on master help sign in
cleanup unused views
commit5d887f39cafcf72a34609923b7c08e502ba701ba authorLiam Fitzgerald <liam@urizen.co> dateFri 6 Mar 2020, 13:32 (7 years ago) parent148df77
13 files changed+82−1480
src/lib/routeNames.js−1 src/lib/router.js−2 src/views/Admin/AdminEditPermissions.js−130 src/views/Admin/AdminHome.js−106 src/views/Admin/AdminNetworkingKeys.js−431 src/views/Admin/AdminReticket.js−62 src/views/Admin/AdminSetProxy.js−238 src/views/Admin/AdminTransfer.js−113 src/views/Admin/Reticket/ReticketConfirm.js−91 src/views/Admin/Reticket/ReticketDownload.js−39 src/views/Admin/Reticket/ReticketExecute.js−193 src/views/Admin/Reticket/ReticketVerify.js−71 src/views/CancelTransfer.js+82−3
src/lib/routeNames.js−1
@@ -8,7 +8,6 @@ export const ROUTE_NAMES = {
88 SENATE: Symbol('SENATE'),
99 //
1010 LOGIN: Symbol('LOGIN'),
11− ADMIN: Symbol('ADMIN'),
1211 REDOWNLOAD: Symbol('REDOWNLOAD'),
1312 RETICKET: Symbol('RETICKET'),
1413 PERMISSIONS: Symbol('PERMISSIONS'),
src/lib/router.js−2
@@ -1,6 +1,5 @@
11import Disclaimer from 'views/Disclaimer';
22import Login from 'views/Login.js';
3−import Admin from 'views/Admin';
43import Senate from 'views/Senate';
54import CreateGalaxy from 'views/CreateGalaxy';
65import IssueChild from 'views/IssueChild';
@@ -29,7 +28,6 @@ export const ROUTES = {
2928 [ROUTE_NAMES.POINT]: Point,
3029 [ROUTE_NAMES.CREATE_GALAXY]: CreateGalaxy,
3130 [ROUTE_NAMES.ISSUE_CHILD]: IssueChild,
32− [ROUTE_NAMES.ADMIN]: Admin,
3331 [ROUTE_NAMES.SENATE]: Senate,
3432 // TODO: nest this route under the Party.js router
3533 [ROUTE_NAMES.PARTY_SET_POOL_SIZE]: PartySetPoolSize,
src/views/Admin/AdminEditPermissions.jsdeleted−130
@@ -1,130 +0,0 @@
1−import React, { useCallback } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−import { Grid, LinkButton } from 'indigo-react';
4−import { azimuth } from 'azimuth-js';
5−
6−import { useNetwork } from 'store/network';
7−import { usePointCursor } from 'store/pointCursor';
8−import { usePointCache } from 'store/pointCache';
9−
10−import * as need from 'lib/need';
11−import { isZeroAddress } from 'lib/wallet';
12−import { PROXY_TYPE, proxyTypeToHuman } from 'lib/proxy';
13−import { useLocalRouter } from 'lib/LocalRouter';
14−import capitalize from 'lib/capitalize';
15−import { eqAddr } from 'lib/wallet';
16−import useCurrentPermissions from 'lib/useCurrentPermissions';
17−
18−import ViewHeader from 'components/ViewHeader';
19−import { ForwardButton } from 'components/Buttons';
20−import { matchBlinkyDate } from 'components/Blinky';
21−import CopyButton from 'components/CopyButton';
22−import convertToInt from 'lib/convertToInt';
23−
24−export default function AdminEditPermissions() {
25− const { push, names } = useLocalRouter();
26− const { contracts } = useNetwork();
27− const { pointCursor } = usePointCursor();
28− const { getDetails, getRekeyDate } = usePointCache();
29−
30− const _contracts = need.contracts(contracts);
31−
32− const point = need.point(pointCursor);
33− const pointSize = azimuth.getPointSize(point);
34− const isParent = pointSize !== azimuth.PointSize.Planet;
35− const isSenate = pointSize === azimuth.PointSize.Galaxy;
36−
37− const details = need.details(getDetails(point));
38− const networkRevision = convertToInt(details.keyRevisionNumber, 10);
39− const { canManage, isOwner } = useCurrentPermissions();
40−
41− const goSetProxy = useCallback(
42− proxyType => push(names.SET_PROXY, { proxyType }),
43− [push, names]
44− );
45−
46− const goNetworkingKeys = useCallback(() => push(names.NETWORKING_KEYS), [
47− push,
48− names,
49− ]);
50−
51− const renderProxyAction = (proxyType, address) => {
52− if (isZeroAddress(address)) {
53− address = 'Not set';
54− } else if (eqAddr(address, _contracts.delegatedSending.address)) {
55− address = `${address} (invites contract)`;
56− }
57−
58− return (
59− <>
60− <Grid.Item
61− full
62− as={ForwardButton}
63− disabled={!isOwner}
64− onClick={() => goSetProxy(proxyType)}
65− detail={address}
66− detailClassName="mono"
67− accessory={<LinkButton>Edit</LinkButton>}>
68− {capitalize(proxyTypeToHuman(proxyType))} Proxy Address
69− </Grid.Item>
70− <Grid.Divider />
71− </>
72− );
73− };
74−
75− const renderNetworkKeysDetail = () => {
76− if (networkRevision === 0) {
77− return 'Not yet configured.';
78− }
79−
80− const renderRevision = maybeDate => (
81− <>
82− Revision #{networkRevision}, since {matchBlinkyDate(maybeDate)}
83− </>
84− );
85−
86− return getRekeyDate(point).matchWith({
87− Nothing: () => renderRevision(Nothing()),
88− Just: p =>
89− p.value.matchWith({
90− Ok: r => renderRevision(Just(r.value)),
91− Error: 'Unknown',
92− }),
93− });
94− };
95−
96− return (
97− <Grid>
98− <Grid.Item full as={ViewHeader}>
99− Permissions
100− </Grid.Item>
101−
102− <Grid.Item
103− full
104− as={ForwardButton}
105− detail={details.owner}
106− detailClassName="mono"
107− accessory={<CopyButton text={details.owner} />}>
108− Ownership Address
109− </Grid.Item>
110− <Grid.Divider />
111−
112− {renderProxyAction(PROXY_TYPE.MANAGEMENT, details.managementProxy)}
113−
114− {isParent && renderProxyAction(PROXY_TYPE.SPAWN, details.spawnProxy)}
115−
116− {isSenate && renderProxyAction(PROXY_TYPE.VOTING, details.votingProxy)}
117−
118− <Grid.Item
119− full
120− as={ForwardButton}
121− disabled={!canManage}
122− onClick={goNetworkingKeys}
123− detail={renderNetworkKeysDetail()}
124− accessory={<LinkButton>View</LinkButton>}>
125− Networking Keys
126− </Grid.Item>
127− <Grid.Divider />
128− </Grid>
129− );
130−}
src/views/Admin/AdminHome.jsdeleted−106
@@ -1,106 +0,0 @@
1−import React, { useCallback } from 'react';
2−import { Just } from 'folktale/maybe';
3−import { Grid, B } from 'indigo-react';
4−
5−import { useWallet } from 'store/wallet';
6−
7−import { useLocalRouter } from 'lib/LocalRouter';
8−import useCurrentPermissions from 'lib/useCurrentPermissions';
9−import useKeyfileGenerator from 'lib/useKeyfileGenerator';
10−
11−import { ForwardButton } from 'components/Buttons';
12−import ViewHeader from 'components/ViewHeader';
13−import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
14−
15−export default function AdminHome() {
16− const { push, names } = useLocalRouter();
17− const { urbitWallet } = useWallet();
18−
19− const { bind: keyfileBind } = useKeyfileGenerator();
20−
21− const { isOwner, canTransfer, isTransferProxySet } = useCurrentPermissions();
22−
23− const goRedownload = useCallback(() => push(names.REDOWNLOAD), [push, names]);
24− const goReticket = useCallback(() => push(names.RETICKET), [push, names]);
25− const goEditPermissions = useCallback(() => push(names.EDIT_PERMISSIONS), [
26− push,
27− names,
28− ]);
29− const goCancelTransfer = useCallback(() => push(names.CANCEL_TRANSFER), [
30− names,
31− push,
32− ]);
33− const goTransfer = useCallback(() => push(names.TRANSFER), [names, push]);
34−
35− const canDownloadPassport = Just.hasInstance(urbitWallet);
36−
37− return (
38− <>
39− <Grid>
40− <Grid.Item full as={ViewHeader}>
41− Admin
42− </Grid.Item>
43−
44− <Grid.Item
45− full
46− as={ForwardButton}
47− disabled={!canDownloadPassport}
48− onClick={goRedownload}
49− detail="Re-download your paper wallet"
50− disabledDetail={
51− <B className="wrap ws-normal">
52− · Master Ticket Authentication required.
53− </B>
54− }>
55− Download Passport
56− </Grid.Item>
57− <Grid.Divider />
58− <Grid.Item
59− full
60− as={DownloadKeyfileButton}
61− {...keyfileBind}
62− detail="Download your current Arvo Keyfile">
63− Download Arvo Keyfile
64− </Grid.Item>
65− <Grid.Divider />
66− <Grid.Item
67− full
68− as={ForwardButton}
69− disabled={!isOwner}
70− onClick={goReticket}
71− detail="Move to brand new wallet, resetting all permissions">
72− Reticket
73− </Grid.Item>
74− <Grid.Divider />
75− <Grid.Item
76− full
77− as={ForwardButton}
78− onClick={goEditPermissions}
79− detail="Proxies, networking keys, etc.">
80− Edit Permissions
81− </Grid.Item>
82− <Grid.Divider />
83− {isTransferProxySet ? (
84− <Grid.Item
85− full
86− as={ForwardButton}
87− onClick={goCancelTransfer}
88− detail="Cancel outgoing transfer"
89− disabled={!canTransfer}>
90− Cancel Outgoing Transfer
91− </Grid.Item>
92− ) : (
93− <Grid.Item
94− full
95− as={ForwardButton}
96− onClick={goTransfer}
97− detail="Transfer ownership of this ID"
98− disabled={!canTransfer}>
99− Transfer
100− </Grid.Item>
101− )}
102− <Grid.Divider />
103− </Grid>
104− </>
105− );
106−}
src/views/Admin/AdminNetworkingKeys.jsdeleted−431
@@ -1,431 +0,0 @@
1−import React, { useCallback, useMemo, useRef, useState } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−import { Grid, Text, H5, Flex, ToggleInput, CheckboxInput } from 'indigo-react';
4−import * as azimuth from 'azimuth-js';
5−import ob from 'urbit-ob';
6−import { randomHex } from 'web3-utils';
7−
8−import { usePointCursor } from 'store/pointCursor';
9−import { usePointCache } from 'store/pointCache';
10−import { useNetwork } from 'store/network';
11−import { useWallet } from 'store/wallet';
12−
13−import { useLocalRouter } from 'lib/LocalRouter';
14−import * as need from 'lib/need';
15−import {
16− segmentNetworkKey,
17− attemptNetworkSeedDerivation,
18− deriveNetworkKeys,
19− CRYPTO_SUITE_VERSION,
20− CURVE_ZERO_ADDR,
21−} from 'lib/keys';
22−import { formatDotsWithTime } from 'lib/dateFormat';
23−import useEthereumTransaction from 'lib/useEthereumTransaction';
24−import { GAS_LIMITS } from 'lib/constants';
25−import { addHexPrefix } from 'lib/wallet';
26−import useKeyfileGenerator from 'lib/useKeyfileGenerator';
27−
28−import ViewHeader from 'components/ViewHeader';
29−import FooterButton from 'components/FooterButton';
30−import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
31−import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
32−import NoticeBox from 'components/NoticeBox';
33−
34−import { HexInput } from 'form/Inputs';
35−import {
36− composeValidator,
37− buildCheckboxValidator,
38− buildHexValidator,
39−} from 'form/validators';
40−import BridgeForm from 'form/BridgeForm';
41−import Condition from 'form/Condition';
42−import FormError from 'form/FormError';
43−import convertToInt from 'lib/convertToInt';
44−
45−const chainKeyProp = name => d =>
46− d[name] === CURVE_ZERO_ADDR ? Nothing() : Just(d[name]);
47−
48−const renderNetworkKey = key => {
49− const segments = segmentNetworkKey(key);
50−
51− if (!segments) {
52− return 'Unset';
53− }
54−
55− return segments.join('\n');
56−};
57−
58−function useSetKeys() {
59− const { urbitWallet, wallet, authMnemonic } = useWallet();
60− const { pointCursor } = usePointCursor();
61− const { syncDetails, syncRekeyDate, getDetails } = usePointCache();
62− const { contracts } = useNetwork();
63−
64− const _point = need.point(pointCursor);
65− const _contracts = need.contracts(contracts);
66− const _details = need.details(getDetails(_point));
67−
68− const networkRevision = convertToInt(_details.keyRevisionNumber, 10);
69− const randomSeed = useRef();
70−
71− // NOTE: nd = 'nondeterministic' (can also be a 'manual' seed)
72− const [ndNetworkSeed, setNdNetworkSeed] = useState();
73−
74− const {
75− available: keyfileAvailable,
76− filename,
77− bind: keyfileBind,
78− } = useKeyfileGenerator(ndNetworkSeed);
79−
80− const buildNetworkSeed = useCallback(
81− async manualSeed => {
82− if (manualSeed !== undefined) {
83− setNdNetworkSeed(manualSeed);
84− return manualSeed;
85− } else {
86− const newNetworkRevision = networkRevision + 1;
87− console.log(`deriving seed with revision ${newNetworkRevision}`);
88−
89− const networkSeed = await attemptNetworkSeedDerivation({
90− urbitWallet,
91− wallet,
92− authMnemonic,
93− details: _details,
94− revision: newNetworkRevision,
95− });
96−
97− if (Just.hasInstance(networkSeed)) {
98− return networkSeed.value;
99− }
100−
101− randomSeed.current = randomSeed.current || randomHex(32); // 32 bytes
102− setNdNetworkSeed(randomSeed.current);
103−
104− return randomSeed.current;
105− }
106− },
107− [_details, authMnemonic, networkRevision, urbitWallet, wallet]
108− );
109−
110− const { completed: _completed, ...rest } = useEthereumTransaction(
111− useCallback(
112− async (manualSeed, isDiscontinuity) => {
113− const seed = await buildNetworkSeed(manualSeed);
114− const pair = deriveNetworkKeys(seed);
115−
116− return azimuth.ecliptic.configureKeys(
117− _contracts,
118− _point,
119− addHexPrefix(pair.crypt.public),
120− addHexPrefix(pair.auth.public),
121− CRYPTO_SUITE_VERSION,
122− isDiscontinuity
123− );
124− },
125− [_contracts, _point, buildNetworkSeed]
126− ),
127− useCallback(
128− () => Promise.all([syncDetails(_point), syncRekeyDate(_point)]),
129− [_point, syncDetails, syncRekeyDate]
130− ),
131− GAS_LIMITS.CONFIGURE_KEYS
132− );
133−
134− // only treat the transaction as completed once we also have keys to download
135− const completed = _completed && keyfileAvailable;
136−
137− return {
138− completed,
139− ndNetworkSeed,
140− filename,
141− keyfileBind,
142− ...rest,
143− };
144−}
145−
146−export default function AdminNetworkingKeys() {
147− const { push, names, pop } = useLocalRouter();
148− const { pointCursor } = usePointCursor();
149− const { getDetails, getRekeyDate } = usePointCache();
150−
151− const point = need.point(pointCursor);
152− const details = getDetails(point);
153−
154− const hasKeys = details.matchWith({
155− Nothing: () => false,
156− Just: ({ value: details }) => parseInt(details.keyRevisionNumber, 10) > 0,
157− // we actually don't mind the default NaN behavior of parseInt here,
158− // since NaN > 0 === false and that's a reasonable result
159− });
160−
161− const [usedDiscontinuity, setUsedDiscontinuity] = useState(false);
162−
163− const {
164− isDefaultState,
165− construct,
166− unconstruct,
167− broadcasting,
168− completed,
169− inputsLocked,
170− filename,
171− bind,
172− keyfileBind,
173− } = useSetKeys();
174−
175− const validateForm = useCallback((values, errors) => {
176− if (values.useNetworkSeed && errors.networkSeed) {
177− return errors;
178− }
179− }, []);
180−
181− const validate = useMemo(
182− () =>
183− composeValidator(
184− {
185− useNetworkSeed: buildCheckboxValidator(),
186− networkSeed: buildHexValidator(64), // 64 chars
187− useDiscontinuity: buildCheckboxValidator(),
188− },
189− validateForm
190− ),
191− [validateForm]
192− );
193−
194− const onValues = useCallback(
195− ({ valid, values, form }) => {
196− if (valid) {
197− construct(
198− values.useNetworkSeed ? values.networkSeed : undefined,
199− values.useDiscontinuity
200− );
201− setUsedDiscontinuity(values.useDiscontinuity);
202− } else {
203− unconstruct();
204− }
205−
206− if (!values.useNetworkSeed && values.networkSeed) {
207− form.change('networkSeed', '');
208− }
209− },
210− [construct, unconstruct, setUsedDiscontinuity]
211− );
212−
213− const initialValues = useMemo(
214− () => ({
215− useNetworkSeed: false,
216− useDiscontinuity: false,
217− }),
218− []
219− );
220−
221− const goRelocate = useCallback(() => push(names.RELOCATE), [push, names]);
222−
223− const usageMessage = useMemo(() => {
224− const need = 'You need this keyfile to authenticate with Arvo.';
225− const boot = (
226− <>
227− boot fresh with{' '}
228− <code>
229− urbit -w {ob.patp(point).slice(1)} -k {filename}
230− </code>
231− </>
232− );
233− if (usedDiscontinuity) {
234− return (
235− <>
236− {need} Since you broke continuity, (re)move your old files, and {boot}
237− </>
238− );
239− } else {
240− return (
241− <>
242− {need} If you have already booted Arvo, run{' '}
243− <code>|rekey '0wkeyfile.contents'</code>. Otherwise, {boot}
244− </>
245− );
246− }
247− }, [usedDiscontinuity, filename, point]);
248−
249− const renderTitle = () => {
250− if (completed) {
251− return 'Networking keys are now set. Download your Keyfile to authenticate Arvo.';
252− }
253−
254− if (broadcasting) {
255− return 'Setting Network Keys...';
256− }
257−
258− if (!hasKeys) {
259− return 'Networking keys have not yet been set.';
260− }
261−
262− return 'Networking';
263− };
264−
265− const renderNetworkKeySection = (title, key) => (
266− <>
267− <Grid.Item full as={H5} className="mt3 gray4">
268− {title}
269− </Grid.Item>
270− {key.matchWith({
271− Nothing: () => (
272− <Grid.Item full as="code" className="f5 mono gray4">
273− Unset
274− </Grid.Item>
275− ),
276− Just: ({ value: key }) => (
277− <>
278− <Grid.Item full as="code" className="f5 mono wrap">
279− 0x
280− </Grid.Item>
281− <Grid.Item full as="code" className="f5 mono wrap">
282− {renderNetworkKey(key)}
283− </Grid.Item>
284− </>
285− ),
286− })}
287− </>
288− );
289−
290− const renderDetail = (title, value) => (
291− <Flex.Item as={Flex} col>
292− <Flex.Item as={H5} className="gray4">
293− {title}
294− </Flex.Item>
295− {value.matchWith({
296− Nothing: () => (
297− <Flex.Item as={Text} className="f5 gray4">
298− Unset
299− </Flex.Item>
300− ),
301− Just: ({ value }) => <Flex.Item as={Text}>{value}</Flex.Item>,
302− })}
303− </Flex.Item>
304− );
305−
306− const renderDetails = () => {
307− return (
308− <>
309− {renderNetworkKeySection(
310− 'Authentication',
311− details.chain(chainKeyProp('authenticationKey'))
312− )}
313− {renderNetworkKeySection(
314− 'Encryption',
315− details.chain(chainKeyProp('encryptionKey'))
316− )}
317− <Grid.Item full as={Flex} row justify="between" className="mt3">
318− {renderDetail('Revision', details.map(d => d.keyRevisionNumber))}
319− {renderDetail('Continuity Era', details.map(d => d.continuityNumber))}
320− {renderDetail(
321− 'Crypto Suite Ver.',
322− details.map(d => d.cryptoSuiteVersion)
323− )}
324− </Grid.Item>
325− {hasKeys && (
326− <Grid.Item full as={Flex} row justify="between" className="mt3">
327− {renderDetail(
328− 'Last Set',
329− getRekeyDate(point).map(date =>
330− date.matchWith({
331− Ok: r => formatDotsWithTime(r.value),
332− Error: () => Nothing(),
333− })
334− )
335− )}
336− </Grid.Item>
337− )}
338− </>
339− );
340− };
341−
342− return (
343− <>
344− <Grid>
345− <Grid.Item full as={ViewHeader}>
346− {renderTitle()}
347− </Grid.Item>
348−
349− <Grid.Item full as={Text} className="mb3">
350− {hasKeys
351− ? 'Here are your public keys that authenticate your Arvo.'
352− : 'Set your networking keys to authenticate with Arvo.'}
353− </Grid.Item>
354−
355− {completed && (
356− <>
357− <Grid.Item full as={NoticeBox} className="mb3">
358− {usageMessage}
359− </Grid.Item>
360− <Grid.Item full as={DownloadKeyfileButton} solid {...keyfileBind} />
361− </>
362− )}
363−
364− {!completed && (
365− <BridgeForm
366− validate={validate}
367− onValues={onValues}
368− initialValues={initialValues}>
369− {() => (
370− <>
371− <Grid.Item
372− full
373− as={ToggleInput}
374− name="useNetworkSeed"
375− label="Use Custom Network Seed"
376− inverseLabel="Back to Derived Network Seed"
377− disabled={inputsLocked}
378− />
379− <Condition when="useNetworkSeed" is={true}>
380− <Grid.Item full as={NoticeBox} className="mb2">
381− When using a custom network seed, you'll need to download
382− your Arvo keyfile immediately after this transaction is
383− Bridge does not store your seed.
384− </Grid.Item>
385− <Grid.Item
386− full
387− as={HexInput}
388− name="networkSeed"
389− label="Network Seed (32 bytes)"
390− disabled={inputsLocked}
391− />
392− </Condition>
393− <Grid.Item
394− full
395− as={CheckboxInput}
396− name="useDiscontinuity"
397− label="Breach Continuity"
398− disabled={inputsLocked}
399− />
400−
401− <Grid.Item full as={FormError} />
402−
403− <Grid.Item
404− full
405− as={InlineEthereumTransaction}
406− {...bind}
407− label={`${hasKeys ? 'Reset' : 'Set'} Networking Keys`}
408− onReturn={() => pop()}
409− />
410− </>
411− )}
412− </BridgeForm>
413− )}
414−
415− {isDefaultState && renderDetails()}
416−
417− {completed && (
418− <>
419− <Grid.Divider />
420− </>
421− )}
422− </Grid>
423−
424− {isDefaultState && (
425− <FooterButton onClick={goRelocate} disabled>
426− Relocate
427− </FooterButton>
428− )}
429− </>
430− );
431−}
src/views/Admin/AdminReticket.jsdeleted−62
@@ -1,62 +0,0 @@
1−import React, { useCallback, useState } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−import { Grid, Flex } from 'indigo-react';
4−
5−import { LocalRouterProvider } from 'lib/LocalRouter';
6−import useRouter from 'lib/useRouter';
7−
8−import Steps from 'components/Steps';
9−
10−import ReticketConfirm from './Reticket/ReticketConfirm';
11−import ReticketDownload from './Reticket/ReticketDownload';
12−import ReticketVerify from './Reticket/ReticketVerify';
13−import ReticketExecute from './Reticket/ReticketExecute';
14−
15−const NAMES = {
16− CONFIRM: 'CONFIRM',
17− DOWNLOAD: 'DOWNLOAD',
18− VERIFY: 'VERIFY',
19− EXECUTE: 'EXECUTE',
20−};
21−
22−const VIEWS = {
23− CONFIRM: ReticketConfirm,
24− DOWNLOAD: ReticketDownload,
25− VERIFY: ReticketVerify,
26− EXECUTE: ReticketExecute,
27−};
28−
29−const STEPS = [NAMES.CONFIRM, NAMES.DOWNLOAD, NAMES.VERIFY, NAMES.RETICKET];
30−
31−export default function AdminReticket() {
32− const { Route, ...router } = useRouter({
33− names: NAMES,
34− views: VIEWS,
35− initialRoutes: [{ key: NAMES.CONFIRM }],
36− });
37−
38− const [newWallet, _setNewWallet] = useState(Nothing());
39−
40− const setNewWallet = useCallback(
41− (wallet, paper) => {
42− _setNewWallet(
43− Just({
44− wallet,
45− paper,
46− })
47− );
48− },
49− [_setNewWallet]
50− );
51−
52− return (
53− <LocalRouterProvider value={router}>
54− <Grid>
55− <Grid.Item full as={Flex} row align="center">
56− <Flex.Item as={Steps} num={router.size} total={STEPS.length} />
57− </Grid.Item>
58− </Grid>
59− <Route newWallet={newWallet} setNewWallet={setNewWallet} />
60− </LocalRouterProvider>
61− );
62−}
src/views/Admin/AdminSetProxy.jsdeleted−238
@@ -1,238 +0,0 @@
1−import React, { useCallback, useMemo } from 'react';
2−import cn from 'classnames';
3−import { Grid, Text, Flex, ToggleInput } from 'indigo-react';
4−import * as azimuth from 'azimuth-js';
5−
6−import { useNetwork } from 'store/network';
7−import { usePointCache } from 'store/pointCache';
8−import { usePointCursor } from 'store/pointCursor';
9−
10−import {
11− PROXY_TYPE,
12− proxyTypeToHuman,
13− proxyTypeToHumanDescription,
14−} from 'lib/proxy';
15−import * as need from 'lib/need';
16−import { useLocalRouter } from 'lib/LocalRouter';
17−import { ETH_ZERO_ADDR, eqAddr, isZeroAddress } from 'lib/wallet';
18−import capitalize from 'lib/capitalize';
19−import useEthereumTransaction from 'lib/useEthereumTransaction';
20−
21−import ViewHeader from 'components/ViewHeader';
22−import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
23−import { GAS_LIMITS } from 'lib/constants';
24−import { AddressInput } from 'form/Inputs';
25−import {
26− composeValidator,
27− buildCheckboxValidator,
28− buildAddressValidator,
29−} from 'form/validators';
30−import BridgeForm from 'form/BridgeForm';
31−import FormError from 'form/FormError';
32−import CopiableAddress from 'components/CopiableAddress';
33−
34−const proxyFromDetails = (details, contracts, proxyType) => {
35− switch (proxyType) {
36− case PROXY_TYPE.MANAGEMENT:
37− return details.managementProxy;
38− case PROXY_TYPE.SPAWN:
39− return details.spawnProxy;
40− case PROXY_TYPE.TRANSFER:
41− return details.transferProxy;
42− case PROXY_TYPE.VOTING:
43− if (eqAddr(details.votingProxy, contracts.delegatedSending.address)) {
44− return `${details.votingProxy} (invites contract)`;
45− } else {
46− return details.votingProxy;
47− }
48− default:
49− throw new Error(`Unknown proxyType: ${proxyType}`);
50− }
51−};
52−
53−function useSetProxy(proxyType) {
54− const { contracts } = useNetwork();
55− const { pointCursor } = usePointCursor();
56− const { syncDetails } = usePointCache();
57−
58− const _contracts = need.contracts(contracts);
59− const _point = need.point(pointCursor);
60−
61− const { construct, ...rest } = useEthereumTransaction(
62− useCallback(
63− address => {
64− const txArgs = [_contracts, _point, address];
65−
66− switch (proxyType) {
67− case PROXY_TYPE.MANAGEMENT:
68− return azimuth.ecliptic.setManagementProxy(...txArgs);
69− case PROXY_TYPE.SPAWN:
70− return azimuth.ecliptic.setSpawnProxy(...txArgs);
71− case PROXY_TYPE.TRANSFER:
72− return azimuth.ecliptic.setTransferProxy(...txArgs);
73− case PROXY_TYPE.VOTING:
74− return azimuth.ecliptic.setVotingProxy(...txArgs);
75− default:
76− throw new Error(`Unknown proxyType ${proxyType}`);
77− }
78− },
79− [_contracts, _point, proxyType]
80− ),
81− useCallback(() => syncDetails(_point), [_point, syncDetails]),
82− GAS_LIMITS.SET_PROXY
83− );
84−
85− // force-unset
86− const unset = useCallback(() => {
87− construct(ETH_ZERO_ADDR);
88− }, [construct]);
89−
90− return {
91− construct,
92− unset,
93− ...rest,
94− };
95−}
96−
97−export default function AdminSetProxy() {
98− const { data, pop } = useLocalRouter();
99− const { getDetails } = usePointCache();
100− const { pointCursor } = usePointCursor();
101− const { contracts } = useNetwork();
102−
103− const _point = need.point(pointCursor);
104− const _details = need.details(getDetails(_point));
105− const _contracts = need.contracts(contracts);
106−
107− const properProxyType = capitalize(proxyTypeToHuman(data.proxyType));
108−
109− const {
110− construct,
111− unconstruct,
112− unset,
113− inputsLocked,
114− completed,
115− bind,
116− } = useSetProxy(data.proxyType);
117−
118− const validateForm = useCallback((values, errors) => {
119− if (!values.unset && errors.address) {
120− return errors;
121− }
122− }, []);
123−
124− const validate = useMemo(
125− () =>
126− composeValidator(
127− {
128− unset: buildCheckboxValidator(),
129− address: buildAddressValidator(),
130− },
131− validateForm
132− ),
133− [validateForm]
134− );
135−
136− const onValues = useCallback(
137− ({ valid, values, form }) => {
138− if (valid) {
139− if (values.unset) {
140− unset();
141− form.change('address', '');
142− } else {
143− construct(values.address);
144− }
145− } else {
146− unconstruct();
147− }
148− },
149− [construct, unconstruct, unset]
150− );
151−
152− const initialValues = useMemo(() => ({ unset: false }), []);
153−
154− const proxyAddress = proxyFromDetails(_details, _contracts, data.proxyType);
155− const isProxySet = !isZeroAddress(proxyAddress);
156−
157− const proxyAddressLabel = `${
158− completed ? 'New' : 'Current'
159− } ${properProxyType} Address`;
160−
161− return (
162− <Grid>
163− <Grid.Item full as={ViewHeader}>
164− {properProxyType} Address
165− </Grid.Item>
166−
167− <Grid.Item full as={Text} className="mb4 f5">
168− {proxyTypeToHumanDescription(data.proxyType)}
169− </Grid.Item>
170−
171− <Grid.Item
172− full
173− as={Text}
174− className={cn('f6 mb1', {
175− green3: completed,
176− })}>
177− {proxyAddressLabel}
178− </Grid.Item>
179−
180− <BridgeForm
181− validate={validate}
182− onValues={onValues}
183− initialValues={initialValues}>
184− {({ handleSubmit, values }) => (
185− <>
186− <Grid.Item full as={Flex} row justify="between" align="center">
187− <Flex.Item
188− flex
189− as={Text}
190− className={cn('mono', {
191− black: !completed && isProxySet,
192− gray4: !completed && !isProxySet,
193− green3: completed,
194− })}>
195− {isProxySet ? (
196− <CopiableAddress>{proxyAddress}</CopiableAddress>
197− ) : (
198− 'Unset'
199− )}
200− </Flex.Item>
201− {!completed && isProxySet && (
202− <Flex.Item
203− as={ToggleInput}
204− name="unset"
205− label="Unset"
206− inverseLabel="Specify"
207− disabled={inputsLocked}
208− />
209− )}
210− </Grid.Item>
211−
212− {completed ? (
213− <Grid.Item full className="mb4" />
214− ) : (
215− <Grid.Item
216− full
217− as={AddressInput}
218− className="mv4"
219− name="address"
220− label={`New ${properProxyType} Address`}
221− disabled={inputsLocked || values.unset}
222− />
223− )}
224−
225− <Grid.Item full as={FormError} />
226−
227− <Grid.Item
228− full
229− as={InlineEthereumTransaction}
230− {...bind}
231− onReturn={() => pop()}
232− />
233− </>
234− )}
235− </BridgeForm>
236− </Grid>
237− );
238−}
src/views/Admin/AdminTransfer.jsdeleted−113
@@ -1,113 +0,0 @@
1−import React, { useCallback, useMemo } from 'react';
2−import cn from 'classnames';
3−import { Grid, Text } from 'indigo-react';
4−import * as azimuth from 'azimuth-js';
5−
6−import { useNetwork } from 'store/network';
7−import { usePointCursor } from 'store/pointCursor';
8−import { usePointCache } from 'store/pointCache';
9−
10−import * as need from 'lib/need';
11−import { useLocalRouter } from 'lib/LocalRouter';
12−import useCurrentPointName from 'lib/useCurrentPointName';
13−import useEthereumTransaction from 'lib/useEthereumTransaction';
14−import { GAS_LIMITS } from 'lib/constants';
15−
16−import ViewHeader from 'components/ViewHeader';
17−import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
18−import { AddressInput } from 'form/Inputs';
19−import { composeValidator, buildAddressValidator } from 'form/validators';
20−import BridgeForm from 'form/BridgeForm';
21−import FormError from 'form/FormError';
22−
23−function useTransfer() {
24− const { contracts } = useNetwork();
25− const { pointCursor } = usePointCursor();
26− const { syncDetails } = usePointCache();
27−
28− const _contracts = need.contracts(contracts);
29− const _point = need.point(pointCursor);
30−
31− return useEthereumTransaction(
32− useCallback(
33− address => azimuth.ecliptic.setTransferProxy(_contracts, _point, address),
34− [_contracts, _point]
35− ),
36− useCallback(() => syncDetails(_point), [_point, syncDetails]),
37− GAS_LIMITS.SET_PROXY
38− );
39−}
40−
41−export default function AdminTransfer() {
42− const { pop } = useLocalRouter();
43− const name = useCurrentPointName();
44−
45− const {
46− construct,
47− unconstruct,
48− completed,
49− inputsLocked,
50− bind,
51− } = useTransfer();
52−
53− const validate = useMemo(
54− () => composeValidator({ address: buildAddressValidator() }),
55− []
56− );
57−
58− const onValues = useCallback(
59− ({ valid, values }) => {
60− if (valid) {
61− construct(values.address);
62− } else {
63− unconstruct();
64− }
65− },
66− [construct, unconstruct]
67− );
68−
69− return (
70− <Grid>
71− <Grid.Item full as={ViewHeader}>
72− Transfer Point
73− </Grid.Item>
74−
75− <BridgeForm validate={validate} onValues={onValues}>
76− {({ handleSubmit, values }) => (
77− <>
78− <Grid.Item
79− full
80− as={Text}
81− className={cn('f5 wrap', {
82− green3: completed,
83− })}>
84− {completed
85− ? `${values.address} is now the Transfer Proxy for ${name} and can accept the transfer by logging into Bridge themselves. Until they accept your transfer, you will still have ownership over ${name}.`
86− : `Transfer ${name} to a new owner.`}
87− </Grid.Item>
88−
89− {!completed && (
90− <Grid.Item
91− full
92− as={AddressInput}
93− className="mv4"
94− name="address"
95− label="Ethereum Address"
96− disabled={inputsLocked}
97− />
98− )}
99−
100− <Grid.Item full as={FormError} />
101−
102− <Grid.Item
103− full
104− as={InlineEthereumTransaction}
105− {...bind}
106− onReturn={() => pop()}
107− />
108− </>
109− )}
110− </BridgeForm>
111− </Grid>
112− );
113−}
src/views/Admin/Reticket/ReticketConfirm.jsdeleted−91
@@ -1,91 +0,0 @@
1−import React, { useState, useCallback } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−import { Grid, Text } from 'indigo-react';
4−import * as need from 'lib/need';
5−
6−import { usePointCursor } from 'store/pointCursor';
7−
8−import useLifecycle from 'lib/useLifecycle';
9−import { generateWallet } from 'lib/invite';
10−import { useLocalRouter } from 'lib/LocalRouter';
11−import { isDevelopment } from 'lib/flags';
12−
13−import { ForwardButton } from 'components/Buttons';
14−import PaperBuilder from 'components/PaperBuilder';
15−import WarningBox from 'components/WarningBox';
16−import { blinkIf } from 'components/Blinky';
17−import useCurrentPointName from 'lib/useCurrentPointName';
18−
19−export default function ReticketConfirm({ newWallet, setNewWallet }) {
20− const { push, names } = useLocalRouter();
21− const { pointCursor } = usePointCursor();
22− const point = need.point(pointCursor);
23− const name = useCurrentPointName();
24−
25− const [generatedWallet, setGeneratedWallet] = useState(Nothing());
26−
27− // generating new wallet on mount, conveniently using it to 'force' users
28− // to read the disclaimer text
29− //TODO also check we can pay for the transactions?
30− useLifecycle(() => {
31− let mounted = true;
32− (async () => {
33− if (Just.hasInstance(newWallet)) {
34− // skip if already computed (hitting the back button for example)
35− return;
36− }
37−
38− const wal = await generateWallet(point);
39− if (isDevelopment) {
40− console.log(`The new ticket for ${name} is ${wal.ticket}`);
41− }
42− if (!mounted) {
43− return;
44− }
45−
46− setGeneratedWallet(Just(wal));
47− })();
48−
49− return () => (mounted = false);
50− });
51−
52− const goDownload = useCallback(() => push(names.DOWNLOAD), [push, names]);
53−
54− const paperRenderer = generatedWallet.matchWith({
55− Nothing: () => null,
56− Just: ({ value: wallet }) => (
57− <PaperBuilder
58− point={point}
59− wallets={[wallet]}
60− callback={paper => {
61− setNewWallet(wallet, paper);
62− }}
63− />
64− ),
65− });
66−
67− return (
68− <Grid className="mt4">
69− <Grid.Item full as={Text}>
70− Reticketing is the process of generating a completely fresh wallet and
71− transferring ownership of your point to that wallet.
72− </Grid.Item>
73− <Grid.Item full as={WarningBox} className="mt4">
74− Beware, this resets your proxy addresses; if you're using smart
75− contracts, this might break them! It will also change your networking
76− keys!
77− </Grid.Item>
78− <Grid.Item
79− full
80− as={ForwardButton}
81− solid
82− className="mt4"
83− accessory={blinkIf(Nothing.hasInstance(newWallet))}
84− disabled={Nothing.hasInstance(newWallet)}
85− onClick={goDownload}>
86− I understand, continue
87− </Grid.Item>
88− {paperRenderer}
89− </Grid>
90− );
91−}
src/views/Admin/Reticket/ReticketDownload.jsdeleted−39
@@ -1,39 +0,0 @@
1−import React, { useState, useCallback } from 'react';
2−import { Nothing } from 'folktale/maybe';
3−import { Grid, Text } from 'indigo-react';
4−
5−import { useLocalRouter } from 'lib/LocalRouter';
6−import { downloadWallet } from 'lib/invite';
7−
8−import { ForwardButton, DownloadButton } from 'components/Buttons';
9−
10−export default function ReticketDownload({ newWallet }) {
11− const { push, names } = useLocalRouter();
12−
13− const [downloaded, setDownloaded] = useState(false);
14−
15− const download = () => {
16− downloadWallet(newWallet.value.paper);
17− setDownloaded(true);
18− };
19−
20− const goVerify = useCallback(() => push(names.VERIFY), [push, names]);
21−
22− return (
23− <Grid className="mt4">
24− <Grid.Item full as={Text}>
25− Download the new passport, and keep it somewhere safe!
26− </Grid.Item>
27− <Grid.Item
28− full
29− as={!downloaded ? DownloadButton : ForwardButton}
30− className="mt4"
31− disabled={Nothing.hasInstance(newWallet)}
32− onClick={!downloaded ? download : goVerify}
33− success={downloaded}
34− solid>
35− {!downloaded ? 'Download Passport' : 'Continue'}
36− </Grid.Item>
37− </Grid>
38− );
39−}
src/views/Admin/Reticket/ReticketExecute.jsdeleted−193
@@ -1,193 +0,0 @@
1−import React, { useState, useCallback } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−import { Grid, H4, Text, ErrorText } from 'indigo-react';
4−
5−import {
6− reticketPointBetweenWallets,
7− TRANSACTION_PROGRESS,
8−} from 'lib/reticket';
9−import * as need from 'lib/need';
10−import useLifecycle from 'lib/useLifecycle';
11−import { WALLET_TYPES } from 'lib/wallet';
12−import convertToInt from 'lib/convertToInt';
13−import useBlockWindowClose from 'lib/useBlockWindowClose';
14−
15−import { useNetwork } from 'store/network';
16−import { useWallet } from 'store/wallet';
17−import { usePointCursor } from 'store/pointCursor';
18−import { usePointCache } from 'store/pointCache';
19−import { useHistory } from 'store/history';
20−
21−import { RestartButton, ForwardButton } from 'components/Buttons';
22−import WarningBox from 'components/WarningBox';
23−import LoadingBar from 'components/LoadingBar';
24−import NeedFundsNotice from 'components/NeedFundsNotice';
25−
26−const labelForProgress = progress => {
27− if (progress <= 0) {
28− return 'Starting...';
29− } else if (progress <= TRANSACTION_PROGRESS.GENERATING) {
30− return 'Generating Ethereum Transactions...';
31− } else if (progress <= TRANSACTION_PROGRESS.SIGNING) {
32− return 'Signing Ethereum Transactions...';
33− } else if (progress <= TRANSACTION_PROGRESS.FUNDING) {
34− return 'Funding Ethereum Transactions...';
35− } else if (progress <= TRANSACTION_PROGRESS.TRANSFERRING) {
36− return 'Transferring ID...';
37− } else if (progress <= TRANSACTION_PROGRESS.CLEANING) {
38− return 'Cleaning Up...';
39− } else if (progress <= TRANSACTION_PROGRESS.DONE) {
40− return 'Done';
41− }
42−};
43−
44−export default function ReticketExecute({ newWallet, setNewWallet }) {
45− const { popTo, names, reset } = useHistory();
46− const { web3, contracts, networkType } = useNetwork();
47− const {
48− wallet,
49− setWalletType,
50− resetWallet,
51− setUrbitWallet,
52− walletType,
53− walletHdPath,
54− } = useWallet();
55− const { pointCursor } = usePointCursor();
56− const { getDetails } = usePointCache();
57−
58− const [generalError, setGeneralError] = useState();
59− const [progress, setProgress] = useState(0);
60− const [needFunds, setNeedFunds] = useState();
61− const isDone = progress >= 1.0;
62−
63− useBlockWindowClose();
64−
65− // start reticketing transactions on mount
66− useLifecycle(() => {
67− (async () => {
68− const point = need.point(pointCursor);
69− const details = need.details(getDetails(point));
70− const networkRevision = convertToInt(details.keyRevisionNumber, 10);
71− try {
72− await reticketPointBetweenWallets({
73− fromWallet: need.wallet(wallet),
74− fromWalletType: walletType,
75− fromWalletHdPath: walletHdPath,
76− toWallet: newWallet.value.wallet,
77− point: point,
78− web3: need.web3(web3),
79− contracts: need.contracts(contracts),
80− networkType,
81− onUpdate: handleUpdate,
82− nextRevision: networkRevision + 1,
83− });
84− } catch (err) {
85− console.error(err);
86− setGeneralError(err);
87− }
88− })();
89− });
90−
91− const goToRestart = useCallback(() => {
92− reset();
93− setNewWallet(Nothing());
94− }, [reset, setNewWallet]);
95−
96− const loginAndGoHome = useCallback(() => {
97− // set wallet state
98− resetWallet();
99− setWalletType(WALLET_TYPES.TICKET);
100− setUrbitWallet(Just(newWallet.value.wallet));
101− // (implicit) pointCursor stays the same
102− // rediect to point
103− popTo(names.POINT);
104− }, [resetWallet, setWalletType, setUrbitWallet, newWallet, popTo, names]);
105−
106− const handleUpdate = useCallback(
107− ({ type, state, value }) => {
108− switch (type) {
109− case 'progress':
110− return setProgress(state);
111− case 'askFunding':
112− return setNeedFunds(value);
113− case 'gotFunding':
114− return setNeedFunds(false);
115− default:
116− console.error(`Unknown update: ${type}`);
117− }
118− },
119− [setProgress, setNeedFunds]
120− );
121−
122− const renderAdditionalInfo = () => {
123− if (generalError) {
124− console.log(generalError);
125− generalError.message = generalError.message || 'Something went wrong!';
126− return (
127− <>
128− <Grid.Item full className="mt4">
129− <ErrorText>{generalError.message.toString()}</ErrorText>
130− </Grid.Item>
131− <Grid.Item
132− full
133− className="mt4"
134− as={RestartButton}
135− solid
136− onClick={goToRestart}>
137− Restart
138− </Grid.Item>
139− </>
140− );
141− }
142−
143− if (needFunds) {
144− return (
145− <Grid.Item full as={NeedFundsNotice} className="mt4" {...needFunds} />
146− );
147− }
148−
149− return (
150− <Grid.Item full as={WarningBox} className="mt4">
151− Never give your Master Ticket to anyone
152− </Grid.Item>
153− );
154− };
155−
156− return (
157− <Grid className="mt4">
158− <Grid.Item full as={H4}>
159− {labelForProgress(progress)}
160− </Grid.Item>
161−
162− {isDone ? (
163− <>
164− <Grid.Item full as={Text} className="mt4">
165− Your changes are now reflected on-chain and you can use the new
166− ticket to manage your point.
167− </Grid.Item>
168− <Grid.Item
169− full
170− as={ForwardButton}
171− solid
172− className="mt4"
173− accessory="↺"
174− onClick={loginAndGoHome}>
175− Login with New Master Ticket
176− </Grid.Item>
177− </>
178− ) : (
179− <>
180− <Grid.Item full as={Grid} className="mt4" gap={3}>
181− <Grid.Item full as={LoadingBar} progress={progress} />
182− <Grid.Item full as={Text} className="f5 green4">
183− This process can take up to 5 minutes to complete. Don't close
184− this page until the process is complete.
185− </Grid.Item>
186− </Grid.Item>
187−
188− {renderAdditionalInfo()}
189− </>
190− )}
191− </Grid>
192− );
193−}
src/views/Admin/Reticket/ReticketVerify.jsdeleted−71
@@ -1,71 +0,0 @@
1−import React, { useCallback, useMemo } from 'react';
2−import { Text, Grid, CheckboxInput } from 'indigo-react';
3−
4−import { useLocalRouter } from 'lib/LocalRouter';
5−import { validateExactly } from 'lib/validators';
6−import { isDevelopment } from 'lib/flags';
7−
8−import BridgeForm from 'form/BridgeForm';
9−import { TicketInput } from 'form/Inputs';
10−import { composeValidator, buildPatqValidator } from 'form/validators';
11−import SubmitButton from 'form/SubmitButton';
12−import FormError from 'form/FormError';
13−
14−const STUB_VERIFY_TICKET = isDevelopment;
15−
16−export default function ReticketVerify({ newWallet }) {
17− const { push, names } = useLocalRouter();
18−
19− const ticket = newWallet.value.wallet.ticket;
20− const validate = useMemo(
21− () =>
22− composeValidator({
23− ticket: buildPatqValidator([
24− validateExactly(ticket, 'Does not match expected master ticket.'),
25− ]),
26− }),
27− [ticket]
28− );
29−
30− const initialValues = useMemo(
31− () => ({
32− ticket: STUB_VERIFY_TICKET ? ticket : undefined,
33− }),
34− [ticket]
35− );
36−
37− const goExecute = useCallback(() => push(names.EXECUTE), [push, names]);
38−
39− return (
40− <Grid className="mt4">
41− <Grid.Item full as={Text}>
42− Verify New Master Ticket
43− </Grid.Item>
44− <BridgeForm
45− validate={validate}
46− afterSubmit={goExecute}
47− initialValues={initialValues}>
48− {({ handleSubmit, values }) => (
49− <>
50− <Grid.Item
51− full
52− as={TicketInput}
53− className="mt4"
54− type={values.showTicket ? 'text' : 'password'}
55− name="ticket"
56− label="New master ticket"
57− />
58−
59− <Grid.Item full as={CheckboxInput} name="showTicket" label="Show" />
60−
61− <Grid.Item full as={FormError} />
62−
63− <Grid.Item full as={SubmitButton} handleSubmit={handleSubmit}>
64− Verify & Reticket
65− </Grid.Item>
66− </>
67− )}
68− </BridgeForm>
69− </Grid>
70− );
71−}
src/views/CancelTransfer.js+82−3
@@ -1,9 +1,88 @@
1−import React from 'react';
1+import React, { useCallback } from 'react';
2+import cn from 'classnames';
3+import { Grid, Text } from 'indigo-react';
4+import * as azimuth from 'azimuth-js';
25
3−import View from 'components/View';
6+import { useNetwork } from 'store/network';
7+import { usePointCursor } from 'store/pointCursor';
8+import { usePointCache } from 'store/pointCache';
49
5−import AdminCancelTransfer from './Admin/AdminCancelTransfer';
10+import * as need from 'lib/need';
611import { useLocalRouter } from 'lib/LocalRouter';
12+import useCurrentPointName from 'lib/useCurrentPointName';
13+import useEthereumTransaction from 'lib/useEthereumTransaction';
14+import { GAS_LIMITS } from 'lib/constants';
15+import { ETH_ZERO_ADDR } from 'lib/wallet';
16+import useLifecycle from 'lib/useLifecycle';
17+
18+import ViewHeader from 'components/ViewHeader';
19+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
20+import View from 'components/ViewHeader';
21+
22+function useCancelTransfer() {
23+ const { contracts } = useNetwork();
24+ const { pointCursor } = usePointCursor();
25+ const { syncDetails } = usePointCache();
26+
27+ const _contracts = need.contracts(contracts);
28+ const _point = need.point(pointCursor);
29+
30+ const { construct, ...rest } = useEthereumTransaction(
31+ useCallback(
32+ () =>
33+ azimuth.ecliptic.setTransferProxy(_contracts, _point, ETH_ZERO_ADDR),
34+ [_contracts, _point]
35+ ),
36+ useCallback(() => syncDetails(_point), [_point, syncDetails]),
37+ GAS_LIMITS.SET_PROXY
38+ );
39+
40+ useLifecycle(() => {
41+ construct();
42+ });
43+
44+ return {
45+ ...rest,
46+ };
47+}
48+
49+function AdminCancelTransfer() {
50+ const { pop } = useLocalRouter();
51+ const { getDetails } = usePointCache();
52+ const { pointCursor } = usePointCursor();
53+ const _point = need.point(pointCursor);
54+
55+ const name = useCurrentPointName();
56+ const _details = need.details(getDetails(_point));
57+
58+ const { completed, bind } = useCancelTransfer();
59+
60+ return (
61+ <Grid>
62+ <Grid.Item full as={ViewHeader}>
63+ Cancel Outgoing Transfer
64+ </Grid.Item>
65+
66+ <Grid.Item
67+ full
68+ as={Text}
69+ className={cn('f5 wrap', {
70+ green3: completed,
71+ })}>
72+ {completed
73+ ? `The outgoing transfer of ${name} has been cancelled.`
74+ : `Cancel the outgoing transfer of ${name} to ${_details.transferProxy}.`}
75+ </Grid.Item>
76+
77+ <Grid.Item
78+ full
79+ as={InlineEthereumTransaction}
80+ {...bind}
81+ onReturn={() => pop()}
82+ />
83+ </Grid>
84+ );
85+}
786
887export default function CancelTransfer() {
988 const { pop } = useLocalRouter();