on master help sign in
feat: add cancel transfer admin view
commit75e10004d3a166450dbb387dd544696defe67081 authorMatt Condon (shrugs) <mattgcondon@gmail.com> dateWed 17 Jul 2019, 13:23 (7 years ago) parent6e83c10
6 files changed+157−11
src/lib/constants.js+1 src/lib/usePermissionsForPoint.js+26−2 src/views/Admin.js+3 src/views/Admin/AdminCancelTransfer.js+91 src/views/Admin/AdminHome.js+27−9 src/views/Admin/AdminTransfer.js+9
src/lib/constants.js+1
@@ -30,6 +30,7 @@ const CRYPTO_SUITE_VERSION = 1;
3030const GAS_LIMITS = {
3131 SPAWN: 250000,
3232 TRANSFER: 550000,
33+ CANCEL_TRANSFER: 550000, //NOTE: no samples
3334 CONFIGURE_KEYS: 100000,
3435 SET_PROXY: 120000,
3536 //
src/lib/usePermissionsForPoint.js+26−2
@@ -2,12 +2,23 @@ import { azimuth } from 'azimuth-js';
22
33import { usePointCache } from 'store/pointCache';
44
5−import { eqAddr } from './wallet';
5+import { eqAddr, ETH_ZERO_ADDR } from './wallet';
66
77const NULL_PERMISSIONS = {
8+ isPlanet: false,
9+ isStar: false,
10+ isGalaxy: false,
11+ //
812 isOwner: false,
13+ isActiveOwner: false,
914 isTransferProxy: false,
1015 isManagementProxy: false,
16+ //
17+ isManagementProxySet: false,
18+ isSpawnProxySet: false,
19+ isVotingProxySet: false,
20+ isTransferProxySet: false,
21+ //
1122 canManage: false,
1223 canTransfer: false,
1324 canSpawn: false,
@@ -31,10 +42,18 @@ export default function usePermissionsForPoint(address, point) {
3142
3243 const isOwner = eqAddr(address, details.owner);
3344 const isActiveOwner = isOwner && details.active;
34− const isTransferProxy = eqAddr(address, details.transferProxy);
3545 const isManagementProxy = eqAddr(address, details.managementProxy);
3646 const isSpawnProxy = eqAddr(address, details.spawnProxy);
3747 const isVotingProxy = eqAddr(address, details.votingProxy);
48+ const isTransferProxy = eqAddr(address, details.transferProxy);
49+
50+ const isManagementProxySet = !eqAddr(
51+ ETH_ZERO_ADDR,
52+ details.managementProxy
53+ );
54+ const isSpawnProxySet = !eqAddr(ETH_ZERO_ADDR, details.spawnProxy);
55+ const isVotingProxySet = !eqAddr(ETH_ZERO_ADDR, details.votingProxy);
56+ const isTransferProxySet = !eqAddr(ETH_ZERO_ADDR, details.transferProxy);
3857
3958 const canManage = isOwner || isManagementProxy;
4059 const canTransfer = isOwner || isTransferProxy;
@@ -51,6 +70,11 @@ export default function usePermissionsForPoint(address, point) {
5170 isTransferProxy,
5271 isManagementProxy,
5372 //
73+ isManagementProxySet,
74+ isSpawnProxySet,
75+ isVotingProxySet,
76+ isTransferProxySet,
77+ //
5478 canManage,
5579 canTransfer,
5680 canSpawn,
src/views/Admin.js+3
@@ -16,6 +16,7 @@ import AdminRedownload from './Admin/AdminRedownload';
1616import AdminReticket from './Admin/AdminReticket';
1717import AdminSetProxy from './Admin/AdminSetProxy';
1818import AdminTransfer from './Admin/AdminTransfer';
19+import AdminCancelTransfer from './Admin/AdminCancelTransfer';
1920import AdminNetworkingKeys from './Admin/AdminNetworkingKeys';
2021
2122const NAMES = {
@@ -25,6 +26,7 @@ const NAMES = {
2526 RETICKET: 'RETICKET',
2627 SET_PROXY: 'SET_PROXY',
2728 TRANSFER: 'TRANSFER',
29+ CANCEL_TRANSFER: 'CANCEL_TRANSFER',
2830 NETWORKING_KEYS: 'NETWORKING_KEYS',
2931};
3032
@@ -35,6 +37,7 @@ const VIEWS = {
3537 [NAMES.RETICKET]: AdminReticket,
3638 [NAMES.SET_PROXY]: AdminSetProxy,
3739 [NAMES.TRANSFER]: AdminTransfer,
40+ [NAMES.CANCEL_TRANSFER]: AdminCancelTransfer,
3841 [NAMES.NETWORKING_KEYS]: AdminNetworkingKeys,
3942};
4043
src/views/Admin/AdminCancelTransfer.jsnew file+91
@@ -0,0 +1,91 @@
1+import React, { useEffect } 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+import { ETH_ZERO_ADDR } from 'lib/wallet';
16+import useLifecycle from 'lib/useLifecycle';
17+
18+import ViewHeader from 'components/ViewHeader';
19+import MiniBackButton from 'components/MiniBackButton';
20+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
21+
22+function useCancelTransfer() {
23+ const { contracts } = useNetwork();
24+ const { pointCursor } = usePointCursor();
25+ const { syncOwnedPoint } = usePointCache();
26+
27+ const _contracts = need.contracts(contracts);
28+ const _point = need.point(pointCursor);
29+
30+ const { construct, confirmed, bind } = useEthereumTransaction(
31+ GAS_LIMITS.CANCEL_TRANSFER
32+ );
33+
34+ useLifecycle(() => {
35+ construct(
36+ azimuth.ecliptic.setTransferProxy(_contracts, _point, ETH_ZERO_ADDR)
37+ );
38+ });
39+
40+ // sync point details after success
41+ useEffect(() => {
42+ if (confirmed) {
43+ syncOwnedPoint(_point);
44+ }
45+ }, [_point, confirmed, syncOwnedPoint]);
46+
47+ return {
48+ confirmed,
49+ bind,
50+ };
51+}
52+
53+export default function AdminCancelTransfer() {
54+ const { pop } = useLocalRouter();
55+ const { getDetails } = usePointCache();
56+ const { pointCursor } = usePointCursor();
57+ const _point = need.point(pointCursor);
58+
59+ const name = useCurrentPointName();
60+ const _details = need.details(getDetails(_point));
61+
62+ const { confirmed, bind } = useCancelTransfer();
63+
64+ return (
65+ <Grid>
66+ <Grid.Item full as={MiniBackButton} onClick={() => pop()} />
67+
68+ <Grid.Item full as={ViewHeader}>
69+ Cancel Outgoing Transfer
70+ </Grid.Item>
71+
72+ <Grid.Item
73+ full
74+ as={Text}
75+ className={cn('f5', {
76+ green3: confirmed,
77+ })}>
78+ {confirmed
79+ ? `The outgoing transfer of ${name} has been cancelled.`
80+ : `Cancel the outgoing transfer of ${name} to ${_details.transferProxy}.`}
81+ </Grid.Item>
82+
83+ <Grid.Item
84+ full
85+ as={InlineEthereumTransaction}
86+ {...bind}
87+ onReturn={() => pop()}
88+ />
89+ </Grid>
90+ );
91+}
src/views/Admin/AdminHome.js+27−9
@@ -22,7 +22,10 @@ export default function AdminHome() {
2222
2323 const point = need.point(pointCursor);
2424 const address = need.addressFromWallet(wallet);
25− const { isOwner, canTransfer } = usePermissionsForPoint(address, point);
25+ const { isOwner, canTransfer, isTransferProxySet } = usePermissionsForPoint(
26+ address,
27+ point
28+ );
2629
2730 const goRedownload = useCallback(() => push(names.REDOWNLOAD), [push, names]);
2831 const goReticket = useCallback(() => push(names.RETICKET), [push, names]);
@@ -30,6 +33,10 @@ export default function AdminHome() {
3033 push,
3134 names,
3235 ]);
36+ const goCancelTransfer = useCallback(() => push(names.CANCEL_TRANSFER), [
37+ names,
38+ push,
39+ ]);
3340 const goTransfer = useCallback(() => push(names.TRANSFER), [names, push]);
3441
3542 const canDownloadPassport = Just.hasInstance(urbitWallet);
@@ -79,14 +86,25 @@ export default function AdminHome() {
7986 Edit Permissions
8087 </Grid.Item>
8188 <Grid.Divider />
82− <Grid.Item
83− full
84− as={ForwardButton}
85− onClick={goTransfer}
86− detail="Transfer ownership of this point"
87− disabled={!canTransfer}>
88− Transfer
89− </Grid.Item>
89+ {isTransferProxySet ? (
90+ <Grid.Item
91+ full
92+ as={ForwardButton}
93+ onClick={goCancelTransfer}
94+ detail="Cancel outgoing transfer"
95+ disabled={!canTransfer}>
96+ Cancel Outgoing Transfer
97+ </Grid.Item>
98+ ) : (
99+ <Grid.Item
100+ full
101+ as={ForwardButton}
102+ onClick={goTransfer}
103+ detail="Transfer ownership of this point"
104+ disabled={!canTransfer}>
105+ Transfer
106+ </Grid.Item>
107+ )}
90108 <Grid.Divider />
91109 </Grid>
92110 </>
src/views/Admin/AdminTransfer.js+9
@@ -5,6 +5,7 @@ import * as azimuth from 'azimuth-js';
55
66import { useNetwork } from 'store/network';
77import { usePointCursor } from 'store/pointCursor';
8+import { usePointCache } from 'store/pointCache';
89
910import * as need from 'lib/need';
1011import { useLocalRouter } from 'lib/LocalRouter';
@@ -20,6 +21,7 @@ import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
2021function useTransfer() {
2122 const { contracts } = useNetwork();
2223 const { pointCursor } = usePointCursor();
24+ const { syncOwnedPoint } = usePointCache();
2325
2426 const _contracts = need.contracts(contracts);
2527 const _point = need.point(pointCursor);
@@ -39,6 +41,13 @@ function useTransfer() {
3941 [_construct, _contracts, _point]
4042 );
4143
44+ // sync point details after success
45+ useEffect(() => {
46+ if (confirmed) {
47+ syncOwnedPoint(_point);
48+ }
49+ }, [_point, confirmed, syncOwnedPoint]);
50+
4251 return {
4352 construct,
4453 confirmed,