@@ -1,4 +1,4 @@
1−import React, { useCallback, useEffect, useState } from 'react';
1+import React, { useCallback, useEffect, useRef, useState } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
2import { Just, Nothing } from 'folktale/maybe';
@@ -39,6 +39,7 @@ import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
39import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
39import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
40import NoticeBox from 'components/NoticeBox';
40import NoticeBox from 'components/NoticeBox';
41import { useHexInput, useCheckboxInput } from 'lib/useInputs';
41import { useHexInput, useCheckboxInput } from 'lib/useInputs';
42+import useKeyfileGenerator from 'lib/useKeyfileGenerator';
43const chainKeyProp = name => d =>
44const chainKeyProp = name => d =>
44 d[name] === CURVE_ZERO_ADDR ? Nothing() : Just(d[name]);
45 d[name] === CURVE_ZERO_ADDR ? Nothing() : Just(d[name]);
@@ -61,19 +62,29 @@ function useSetKeys() {
61 const _point = need.point(pointCursor);
62 const _point = need.point(pointCursor);
62 const _contracts = need.contracts(contracts);
63 const _contracts = need.contracts(contracts);
65+ const randomSeed = useRef();
64 // NOTE: nd = 'nondeterministic' (can also be a 'manual' seed)
67 // NOTE: nd = 'nondeterministic' (can also be a 'manual' seed)
65 const [ndNetworkSeed, setNdNetworkSeed] = useState();
68 const [ndNetworkSeed, setNdNetworkSeed] = useState();
71+ available: keyfileAvailable,
73+ } = useKeyfileGenerator(ndNetworkSeed);
68 isDefaultState,
76 isDefaultState,
69 construct: _construct,
77 construct: _construct,
70 unconstruct,
78 unconstruct,
71 broadcasting,
79 broadcasting,
72− confirmed,
80+ confirmed: _confirmed,
73 inputsLocked,
81 inputsLocked,
75 } = useEthereumTransaction(GAS_LIMITS.CONFIGURE_KEYS);
83 } = useEthereumTransaction(GAS_LIMITS.CONFIGURE_KEYS);
85+ // only treat the transaction as confirmed once we also have keys to download
86+ const confirmed = _confirmed && keyfileAvailable;
77 // sync point details after success
88 // sync point details after success
78 useEffect(() => {
89 useEffect(() => {
79 if (confirmed) {
90 if (confirmed) {
@@ -98,14 +109,14 @@ function useSetKeys() {
98 revision: networkRevision + 1,
109 revision: networkRevision + 1,
101− return networkSeed.matchWith({
112+ if (Just.hasInstance(networkSeed)) {
102− Nothing: () => {
113+ return networkSeed.value;
103− const ndSeed = randomHex(64);
114+ }
116+ randomSeed.current = randomSeed.current || randomHex(64);
104− setNdNetworkSeed(ndSeed);
117+ setNdNetworkSeed(randomSeed.current);
106− },
119+ return randomSeed.current;
111 [_point, authMnemonic, getDetails, urbitWallet, wallet]
122 [_point, authMnemonic, getDetails, urbitWallet, wallet]
@@ -139,6 +150,7 @@ function useSetKeys() {
139 ndNetworkSeed,
150 ndNetworkSeed,
140 inputsLocked,
151 inputsLocked,
@@ -162,8 +174,8 @@ export default function AdminNetworkingKeys() {
162 broadcasting,
174 broadcasting,
163 confirmed,
175 confirmed,
164 inputsLocked,
176 inputsLocked,
167 } = useSetKeys();
179 } = useSetKeys();
169 const [showNetworkSeedInput, { data: showNetworkSeed }] = useCheckboxInput({
181 const [showNetworkSeedInput, { data: showNetworkSeed }] = useCheckboxInput({
@@ -205,10 +217,10 @@ export default function AdminNetworkingKeys() {
207 construct,
219 construct,
208 isDiscontinuity,
221 isDiscontinuity,
209 networkSeed,
222 networkSeed,
210 showNetworkSeed,
223 showNetworkSeed,
212 validDiscontinuity,
224 validDiscontinuity,
213 validNetworkSeed,
225 validNetworkSeed,
@@ -334,12 +346,7 @@ export default function AdminNetworkingKeys() {
334 <Grid.Item full as={NoticeBox} className="mb3">
346 <Grid.Item full as={NoticeBox} className="mb3">
335 You need this keyfile to authenticate with Arvo.
347 You need this keyfile to authenticate with Arvo.
336 </Grid.Item>
348 </Grid.Item>
339− as={DownloadKeyfileButton}
349+ <Grid.Item full as={DownloadKeyfileButton} solid {...keyfileBind} />
341− networkSeed={ndNetworkSeed}