@@ -1,214 +0,0 @@
1−import * as need from 'lib/need';
2−import saveAs from 'file-saver';
3−import ob from 'urbit-ob';
4−import { Just, Nothing } from 'folktale/maybe';
5−
6−import { useCallback, useEffect, useMemo, useState } from 'react';
7−import { usePointCache } from 'store/pointCache';
8−import { usePointCursor } from 'store/pointCursor';
9−import { useWallet } from 'store/wallet';
10−import { deriveNetworkKeys } from 'urbit-key-generation';
11−import { convertToInt } from './convertToInt';
12−import {
13− attemptNetworkSeedDerivation,
14− compileMultiKey,
15− keysMatchChain,
16−} from './keys';
17−import { generateCode } from './networkCode';
18−import { L1Point } from './types/L1Point';
19−import useCurrentPermissions from './useCurrentPermissions';
20−import { stripSigPrefix } from 'form/formatters';
21−import { useRollerStore } from 'store/rollerStore';
22−
23−interface useMultikeyFileGeneratorArgs {
24− seed?: string;
25− point?: number;
26− seedWallet?: any;
27− inviteMasterTicketWallet?: any;
28−}
29−
30−/**
31− * defaults:
32− * - seed: derived from wallet, mnemonic, or token (if posisble)
33− * - point: the current pointCursor
34− */
35−export default function useMultikeyFileGenerator({
36− seed,
37− point,
38− seedWallet,
39− inviteMasterTicketWallet,
40−}: useMultikeyFileGeneratorArgs) {
41− const { urbitWallet, wallet, authMnemonic, authToken }: any = useWallet();
42− const { pointCursor }: any = usePointCursor();
43− const { syncDetails, getDetails }: any = usePointCache();
44− const { isOwner, isManagementProxy } = useCurrentPermissions();
45− const rollerStore = useRollerStore();
46−
47− const [notice, setNotice] = useState('Deriving networking keys...');
48− const [downloaded, setDownloaded] = useState(false);
49− const [generating, setGenerating] = useState(true);
50− const [keyfile, setKeyfile] = useState<boolean | string>(false);
51− const [code, setCode] = useState(false);
52−
53− const _point = useMemo(() => point || need.point(pointCursor), [
54− point,
55− pointCursor,
56− ]);
57− const details = getDetails(_point);
58− const _details: L1Point | null = useMemo(
59− () =>
60− rollerStore?.point?.isL2
61− ? rollerStore.point
62− : details.matchWith({
63− Just: (d: any) => need.details(d),
64− Nothing: () => null,
65− }),
66− [details, rollerStore.point]
67− );
68−
69− const currentRevision: number = useMemo(
70− () => convertToInt(_details?.keyRevisionNumber || 0, 10),
71− [_details]
72− );
73− const nextRevision = useMemo(() => currentRevision + 1, [currentRevision]);
74−
75− const pairFromRevision = useCallback(
76− async (revision: number, useInviteMasterTicketWallet = false) => {
77− if (!_details) {
78− return;
79− }
80−
81− // During the activation flow, we pass in the
82− // inviteMasterTicketWallet to derive the multikey
83− const derivationWallet =
84− useInviteMasterTicketWallet && inviteMasterTicketWallet
85− ? inviteMasterTicketWallet
86− : seedWallet || urbitWallet;
87−
88− const networkSeed = seed
89− ? Just(seed)
90− : await attemptNetworkSeedDerivation({
91− urbitWallet: derivationWallet,
92− wallet,
93− authMnemonic,
94− details: _details,
95− authToken,
96− point: _point,
97− revision: revision,
98− });
99−
100− if (Nothing.hasInstance(networkSeed)) {
101− setGenerating(false);
102− setNotice(
103− 'Custom or nondeterministic networking keys cannot be re-downloaded.'
104− );
105− console.log(`seed is nondeterminable for revision ${revision}`);
106− return;
107− }
108−
109− const _networkSeed = networkSeed.value;
110−
111− return deriveNetworkKeys(_networkSeed);
112− },
113− [
114− _details,
115− inviteMasterTicketWallet,
116− seedWallet,
117− urbitWallet,
118− seed,
119− wallet,
120− authMnemonic,
121− authToken,
122− _point,
123− ]
124− );
125−
126− const hasNetworkKeys = currentRevision > 0;
127− const available =
128− (isOwner || isManagementProxy) && hasNetworkKeys && !!keyfile;
129−
130− const generate = useCallback(async () => {
131− if (!hasNetworkKeys) {
132− setGenerating(false);
133− setNotice('Network keys not yet set.');
134− console.log(
135− `no networking keys available for revision ${currentRevision}`
136− );
137− return;
138− }
139−
140− const currentPair = await pairFromRevision(currentRevision);
141−
142− if (!currentPair || !keysMatchChain(currentPair, _details || {})) {
143− setGenerating(false);
144− setNotice('Derived networking keys do not match on-chain details.');
145− console.log(`keys do not match details for revision ${currentRevision}`);
146− return;
147− }
148−
149− // During the activation flow, we want to use the invite wallet for the next pair
150− const nextPair = await pairFromRevision(nextRevision, true);
151−
152− setNotice('');
153− setCode(generateCode(currentPair));
154− setKeyfile(
155− compileMultiKey(_point, [
156− {
157− revision: currentRevision,
158− pair: currentPair,
159− },
160− {
161− revision: nextRevision,
162− pair: nextPair,
163− },
164− ])
165− );
166− setGenerating(false);
167− }, [
168− _details,
169− _point,
170− currentRevision,
171− hasNetworkKeys,
172− nextRevision,
173− pairFromRevision,
174− ]);
175−
176− const filename = useMemo(() => {
177− return `${stripSigPrefix(ob.patp(_point))}-${currentRevision}.key`;
178− }, [_point, currentRevision]);
179−
180− const download = useCallback(() => {
181− if (typeof keyfile !== 'string') {
182− return;
183− }
184−
185− saveAs(
186− new Blob([keyfile], {
187− type: 'text/plain;charset=utf-8',
188− }),
189− filename
190− );
191− setDownloaded(true);
192− }, [filename, keyfile]);
193−
194− useEffect(() => {
195− syncDetails(_point);
196− }, [_point, syncDetails]);
197−
198− useEffect(() => {
199− generate();
200− }, [generate]);
201−
202− const output = {
203− generating,
204− available,
205− downloaded,
206− download,
207− filename,
208− notice,
209− keyfile,
210− code,
211− };
212−
213− return { ...output, bind: output };
214−}