8import { Just } from 'folktale/maybe';
9import { Grid, Button } from 'indigo-react';
10import * as azimuth from 'azimuth-js';
11import { randomHex } from 'web3-utils';
12import { Box, Checkbox, Icon, Row, Text } from '@tlon/indigo-react';
14import { usePointCache } from 'store/pointCache';
15import { useNetwork } from 'store/network';
16import { useWallet } from 'store/wallet';
17import { useRollerStore } from 'store/rollerStore';
19import useRoller from 'lib/useRoller';
20import { useLocalRouter } from 'lib/LocalRouter';
21import * as need from 'lib/need';
23 attemptNetworkSeedDerivation,
27import useEthereumTransaction from 'lib/useEthereumTransaction';
28import { GAS_LIMITS, ONE_SECOND } from 'lib/constants';
29import { addHexPrefix } from 'lib/utils/address';
30import { useSingleKeyfileGenerator } from 'lib/useKeyfileGenerator';
32import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
33import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
34import NoticeBox from 'components/NoticeBox';
36import { HexInput } from 'form/Inputs';
39 buildCheckboxValidator,
41} from 'form/validators';
42import BridgeForm from 'form/BridgeForm';
43import FormError from 'form/FormError';
44import Window from 'components/L2/Window/Window';
45import HeaderPane from 'components/L2/Window/HeaderPane';
46import BodyPane from 'components/L2/Window/BodyPane';
48import './NetworkKeys.scss';
49import { L1TxnType } from 'lib/types/PendingL1Transaction';
50import { PointField } from 'lib/types/Point';
53 manualNetworkSeed: string,
54 setManualNetworkSeed: (seed: string) => void
56 const { urbitWallet, wallet, authMnemonic, authToken }: any = useWallet();
57 const { point } = useRollerStore();
58 const { syncDetails, syncRekeyDate }: any = usePointCache();
59 const { contracts }: any = useNetwork();
61 const _contracts = need.contracts(contracts);
63 const networkRevision = Number(point.keyRevisionNumber);
64 const randomSeed = useRef<string | null>();
67 generating: keyfileGenerating,
70 } = useSingleKeyfileGenerator({ seed: manualNetworkSeed });
72 const buildNetworkSeed = useCallback(
74 if (manualSeed !== undefined) {
75 setManualNetworkSeed(manualSeed);
78 const newNetworkRevision = networkRevision + 1;
79 console.log(`deriving seed with revision ${newNetworkRevision}`);
81 const networkSeed = await attemptNetworkSeedDerivation({
88 revision: newNetworkRevision,
91 if (Just.hasInstance(networkSeed)) {
92 return networkSeed.value;
95 randomSeed.current = randomSeed.current || randomHex(32); // 32 bytes
96 setManualNetworkSeed(randomSeed.current);
98 return randomSeed.current;
103 setManualNetworkSeed,
112 const { completed: _completed, ...rest } = useEthereumTransaction(
114 async (manualSeed: string, isDiscontinuity: boolean) => {
115 const seed = await buildNetworkSeed(manualSeed);
116 const pair = deriveNetworkKeys(seed);
118 return azimuth.ecliptic.configureKeys(
121 addHexPrefix(pair.crypt.public),
122 addHexPrefix(pair.auth.public),
123 CRYPTO_SUITE_VERSION,
127 [_contracts, point, buildNetworkSeed]
130 () => Promise.all([syncDetails(point.value), syncRekeyDate(point.value)]),
131 [point, syncDetails, syncRekeyDate]
133 GAS_LIMITS.CONFIGURE_KEYS
136 // only treat the transaction as completed once we also have keys to download
137 const completed = _completed && !keyfileGenerating;
147export default function UrbitOSNetworkKeys({
149 setManualNetworkSeed,
151 manualNetworkSeed: string;
152 setManualNetworkSeed: (seed: string) => void;
154 const { pop }: any = useLocalRouter();
155 const { point, setLoading } = useRollerStore();
157 configureNetworkKeys,
158 getPendingTransactions,
161 const [breach, setBreach] = useState(false);
162 const [useCustomSeed, setUseCustomSeed] = useState(false);
163 const [l2Completed, setL2Completed] = useState(false);
165 const hasKeys = point.networkKeysSet;
175 } = useSetKeys(manualNetworkSeed, setManualNetworkSeed);
181 field: PointField.keyRevisionNumber,
182 message: `${point.patp}'s Network Keys have been set!`,
184 id: `${point.keyRevisionNumber}-network-keys-${point.value}`,
186 type: L1TxnType.setNetworkKeys,
188 time: new Date().getTime(),
190 intervalTime: ONE_SECOND,
193 }, [completed]); // eslint-disable-line react-hooks/exhaustive-deps
195 const validateForm = useCallback((values, errors) => {
196 if (values.useNetworkSeed && errors.networkSeed) {
201 const validate = useMemo(
205 useNetworkSeed: buildCheckboxValidator(),
206 networkSeed: buildHexValidator(64), // 64 chars
207 useDiscontinuity: buildCheckboxValidator(),
214 const onValues = useCallback(
215 ({ valid, values, form }) => {
217 const networkSeed = useCustomSeed ? values.networkSeed : undefined;
218 construct(networkSeed, breach);
219 setManualNetworkSeed(networkSeed);
224 if (!useCustomSeed && values.networkSeed) {
225 form.change('networkSeed', '');
227 setManualNetworkSeed('');
234 setManualNetworkSeed,
240 const setNetworkKeys = useCallback(async () => {
243 await configureNetworkKeys({
245 customNetworkSeed: manualNetworkSeed,
247 // TODO: just use the tx hash instead?
248 getPendingTransactions();
249 // TODO: this is just so we get visual feedback that the tx has gone through
250 // but this should be addressed with the new UI flow (-> download keyfile)
252 // A question here is how to deal with the modals/messages about the keys not being
253 // set since they are in pending in the Roller...
254 // we could inspect if there's a changeKeys in the local list of pending txs,...
258 message: `${point.patp}'s Network Keys have been set!`,
259 intervalTime: ONE_SECOND,
261 setTimeout(() => setL2Completed(true), ONE_SECOND);
270 getPendingTransactions,
272 configureNetworkKeys,
277 const initialValues = useMemo(() => ({}), []);
279 const viewTitle = completed
280 ? 'Network Keys have been set'
283 : 'Initiate Network Keys';
285 const bootMessage = () => (
286 <Text as="p" textAlign={'center'}>
287 Download your new Network Key to boot your ship. Be sure to delete your
288 old pier before booting with this new key.
292 const resetMessage = () => (
294 <Text as="p" textAlign={'center'}>
295 Copy the contents of the Network Key file and run
303 textAlign={'center'}>
304 |rekey 'keyfile_contents'
306 <Text as="p" textAlign={'center'}>
307 using the dojo on your running ship.
312 const waitMessage = () => (
313 <Text as="p" textAlign={'center'}>
314 <strong>Important:</strong> you will need to wait until the next L2 batch
315 is submitted to the roller to boot your ship. If you do not wait, then you
316 will not be able to boot your ship.
320 const buttonText = `${hasKeys ? 'Reset' : 'Set'} Network Keys`;
322 const isComplete = completed || l2Completed;
325 <Window className="network-keys">
331 <Box className="flex-col col justify-between h-full">
332 <Box className="flex-col h-full justify-center">
333 <Icon icon="Download" className="download" />
334 {breach ? bootMessage() : resetMessage()}
335 {breach && point.isL2 ? waitMessage() : null}
343 onClick={keyfileBind.download}>
349 as={DownloadKeyfileButton}
362 initialValues={initialValues}>
364 <Box className="contents">
368 className="check-row"
369 onClick={() => setBreach(!breach)}>
373 disabled={inputsLocked}
377 <Box className="info-text">
378 Use if your ship is corrupted, you lost your files, or
380 you want to erase your data
383 className="check-row"
384 onClick={() => setUseCustomSeed(!useCustomSeed)}>
387 selected={useCustomSeed}
388 disabled={inputsLocked}
392 <Box className="info-text">
393 Enter your own custom network seed to derive from
397 <Grid.Item full as={NoticeBox} className="mb2">
398 When using a custom network seed, you'll need to
399 download your Arvo keyfile immediately after this
400 transaction as Bridge does not store your seed.
406 label="Network Seed (32 bytes)"
407 disabled={inputsLocked}
412 <Grid.Item full as={FormError} />
423 onClick={setNetworkKeys}>
429 as={InlineEthereumTransaction}
432 onReturn={() => pop()}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list