on 09c9394 help sign in
bridge/src/lib/useKeyfileGenerator.ts
138 lines 3.5 kB history raw
1import { useCallback, useMemo, useEffect, useState } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
3import saveAs from 'file-saver';
5import { useWallet } from 'store/wallet';
6import { useRollerStore } from 'store/rollerStore';
8import { generateCode } from 'lib/networkCode';
10import {
11 attemptNetworkSeedDerivation,
12 keysMatchChain,
13 deriveNetworkKeys,
14 compileNetworkKey,
15} from './keys';
16import { stripSigPrefix } from 'form/formatters';
18// overrideable defaults:
19// seed - derived from wallet, mnemonic, or token (if posisble)
20// point - the current pointCursor
21interface useKeyfileGeneratorArgs {
22 seed?: string;
23 point?: number;
26/**
27 * @deprecated
28 * Use `useMultikeyFileGenerator` instead
29 */
30export default function useKeyfileGenerator({ seed }: useKeyfileGeneratorArgs) {
31 const { urbitWallet, wallet, authMnemonic, authToken }: any = useWallet();
32 const { point } = useRollerStore();
34 const [notice, setNotice] = useState('Deriving networking keys...');
35 const [downloaded, setDownloaded] = useState(false);
36 const [generating, setGenerating] = useState(true);
37 const [keyfile, setKeyfile] = useState<boolean | string>(false);
38 const [code, setCode] = useState(false);
40 const networkRevision = Number(point.keyRevisionNumber);
41 const canManage = point.isOwner || point.isManagementProxy;
43 const hasNetworkKeys = networkRevision > 0;
44 const available = canManage && hasNetworkKeys && !!keyfile;
46 const generate = useCallback(async () => {
47 if (!hasNetworkKeys) {
48 setGenerating(false);
49 setNotice('Network keys not yet set.');
50 console.log(
51 `no networking keys available for revision ${networkRevision}`
52 );
53 return;
54 }
56 const networkSeed = seed
57 ? Just(seed)
58 : await attemptNetworkSeedDerivation({
59 urbitWallet,
60 wallet,
61 authMnemonic,
62 details: point,
63 authToken,
64 point: point.value,
65 revision: networkRevision,
66 });
68 if (Nothing.hasInstance(networkSeed)) {
69 setGenerating(false);
70 setNotice(
71 'Custom or nondeterministic networking keys cannot be re-downloaded.'
72 );
73 console.log(`seed is nondeterminable for revision ${networkRevision}`);
74 return;
75 }
77 const _networkSeed = networkSeed.value;
79 const pair = deriveNetworkKeys(_networkSeed);
81 if (!keysMatchChain(pair, point)) {
82 setGenerating(false);
83 setNotice('Derived networking keys do not match on-chain details.');
84 console.log(`keys do not match details for revision ${networkRevision}`);
85 return;
86 }
88 setNotice('');
89 setCode(generateCode(pair));
90 setKeyfile(compileNetworkKey(pair, point.value, networkRevision));
91 setGenerating(false);
92 }, [
93 networkRevision,
94 hasNetworkKeys,
95 seed,
96 urbitWallet,
97 wallet,
98 authMnemonic,
99 setCode,
100 point,
101 authToken,
102 ]);
104 const filename = useMemo(() => {
105 return `${stripSigPrefix(point.patp)}-${networkRevision}.key`;
106 }, [point, networkRevision]);
108 const download = useCallback(() => {
109 if (typeof keyfile !== 'string') {
110 return;
111 }
113 saveAs(
114 new Blob([keyfile], {
115 type: 'text/plain;charset=utf-8',
116 }),
117 filename
118 );
119 setDownloaded(true);
120 }, [filename, keyfile]);
122 useEffect(() => {
123 generate();
124 }, [generate]);
126 const values = {
127 generating,
128 available,
129 downloaded,
130 download,
131 filename,
132 notice,
133 keyfile,
134 code,
135 };
137 return { ...values, bind: values };