@@ -1,25 +1,28 @@
1−import React, { useCallback } from 'react';
2−import { Grid, P, Text, Input, Flex, LinkButton } from 'indigo-react';
1+import React, { useCallback, useEffect, useState } from 'react';
2+import cn from 'classnames';
3+import { Grid, Text, Input, Flex, LinkButton } from 'indigo-react';
34import * as azimuth from 'azimuth-js';
45
56import { useNetwork } from 'store/network';
6−
7−import * as need from 'lib/need';
8−import { useLocalRouter } from 'lib/LocalRouter';
9−import { ETH_ZERO_ADDR, eqAddr } from 'lib/wallet';
10−
11−import ViewHeader from 'components/ViewHeader';
7+import { usePointCache } from 'store/pointCache';
128import { usePointCursor } from 'store/pointCursor';
9+
1310import {
1411 PROXY_TYPE,
1512 proxyTypeToHuman,
1613 proxyTypeToHumanDescription,
1714} from 'lib/proxy';
18−import MiniBackButton from 'components/MiniBackButton';
15+import * as need from 'lib/need';
16+import { useLocalRouter } from 'lib/LocalRouter';
17+import { ETH_ZERO_ADDR, eqAddr } from 'lib/wallet';
1918import capitalize from 'lib/capitalize';
20−import { usePointCache } from 'store/pointCache';
21−import { GenerateButton } from 'components/Buttons';
2219import { useAddressInput } from 'lib/useInputs';
20+import useEthereumTransaction from 'lib/useEthereumTransaction';
21+
22+import ViewHeader from 'components/ViewHeader';
23+import MiniBackButton from 'components/MiniBackButton';
24+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
25+import { GAS_LIMITS } from 'lib/constants';
2326
2427const proxyFromDetails = (details, proxyType) => {
2528 switch (proxyType) {
@@ -36,16 +39,18 @@ const proxyFromDetails = (details, proxyType) => {
3639 }
3740};
3841
39−function useSetProxy(proxyType) {
40− // TODO: abstract eth login into higher level useTransaction()
42+function useSetProxy(proxyType, address) {
4143 const { contracts } = useNetwork();
4244 const { pointCursor } = usePointCursor();
45+ const { syncOwnedPoint } = usePointCache();
46+
47+ const _contracts = need.contracts(contracts);
48+ const _point = need.point(pointCursor);
49+
50+ const [isUnsetting, setUnsetting] = useState(false);
4351
4452 const buildUnsignedTx = useCallback(
4553 address => {
46− const _contracts = need.contracts(contracts);
47− const _point = need.point(pointCursor);
48−
4954 const txArgs = [_contracts, _point, address];
5055
5156 switch (proxyType) {
@@ -56,30 +61,55 @@ function useSetProxy(proxyType) {
5661 case PROXY_TYPE.TRANSFER:
5762 return azimuth.ecliptic.setTransferProxy(...txArgs);
5863 case PROXY_TYPE.VOTING:
59− return azimuth.ecliptic.setTransferProxy(...txArgs);
64+ return azimuth.ecliptic.setVotingProxy(...txArgs);
6065 default:
6166 throw new Error(`Unknown proxyType ${proxyType}`);
6267 }
6368 },
64− [proxyType, contracts, pointCursor]
69+ [_contracts, _point, proxyType]
6570 );
6671
67− const generate = useCallback(
68− async address => {
69− const utx = buildUnsignedTx(address);
70− console.log(utx);
71− },
72− [buildUnsignedTx]
72+ const {
73+ initializing,
74+ constructed,
75+ construct: _construct,
76+ constructAndSign,
77+ generateAndSign,
78+ sign,
79+ signed,
80+ broadcast,
81+ broadcasted,
82+ confirmed,
83+ reset,
84+ inputsLocked,
85+ bind,
86+ } = useEthereumTransaction(GAS_LIMITS.SET_PROXY);
87+
88+ // sync point details after success
89+ useEffect(() => {
90+ if (confirmed) {
91+ syncOwnedPoint(_point);
92+ }
93+ }, [_point, confirmed, syncOwnedPoint]);
94+
95+ // construct the unsigned transaction when we have a valid address
96+ const construct = useCallback(
97+ address => _construct(buildUnsignedTx(address)),
98+ [_construct, buildUnsignedTx]
7399 );
74100
75− const unset = useCallback(() => generate(ETH_ZERO_ADDR), [generate]);
76−
77− const locked = false;
101+ // force-unset
102+ const unset = useCallback(() => {
103+ setUnsetting(true);
104+ _construct(buildUnsignedTx(ETH_ZERO_ADDR));
105+ }, [_construct, buildUnsignedTx]);
78106
79107 return {
80− locked,
81− generate,
108+ construct,
82109 unset,
110+ isUnsetting,
111+ inputsLocked: inputsLocked || isUnsetting,
112+ bind,
83113 };
84114}
85115
@@ -92,14 +122,18 @@ export default function AdminSetProxy() {
92122
93123 const properProxyType = capitalize(proxyTypeToHuman(data.proxyType));
94124
95− const { generate, unset, locked } = useSetProxy(data.proxyType);
125+ const { construct, unset, inputsLocked, bind } = useSetProxy(data.proxyType);
96126 const [addressInput, { pass, data: address }] = useAddressInput({
97127 name: 'address',
98128 label: `New ${properProxyType} Address`,
99− disabled: locked,
129+ disabled: inputsLocked,
100130 });
101131
102− const _generate = useCallback(() => generate(address), [address, generate]);
132+ useEffect(() => {
133+ if (pass) {
134+ construct(address);
135+ }
136+ }, [pass, address, construct]);
103137
104138 const proxyAddress = proxyFromDetails(details, data.proxyType);
105139 const isProxySet = !eqAddr(ETH_ZERO_ADDR, proxyAddress);
@@ -117,11 +151,17 @@ export default function AdminSetProxy() {
117151 Current {properProxyType} Address
118152 </Grid.Item>
119153 <Grid.Item full as={Flex} row justify="between" align="center">
120− <Flex.Item flex as={Text} className="mono">
154+ <Flex.Item
155+ flex
156+ as={Text}
157+ className={cn({
158+ 'mono black': isProxySet,
159+ gray4: !isProxySet,
160+ })}>
121161 {isProxySet ? proxyAddress : 'Unset'}
122162 </Flex.Item>
123163 {isProxySet && (
124− <Flex.Item as={LinkButton} onClick={unset}>
164+ <Flex.Item as={LinkButton} onClick={unset} disabled={inputsLocked}>
125165 Unset
126166 </Flex.Item>
127167 )}
@@ -129,9 +169,7 @@ export default function AdminSetProxy() {
129169
130170 <Grid.Item full as={Input} {...addressInput} className="mv4" />
131171
132− <Grid.Item full as={GenerateButton} onClick={_generate} disabled={!pass}>
133− Generate & Sign Transaction
134− </Grid.Item>
172+ <Grid.Item full as={InlineEthereumTransaction} {...bind} />
135173 </Grid>
136174 );
137175}