on master help sign in
wip: configure keys + transfer point
commitea93e0c3f8f3f4ec1de66ca1f5852c0d772a287a authortomholford <tomholford@users.noreply.github.com> dateMon 13 Sep 2021, 21:30 (5 years ago) parent1268c9f
3 files changed+93−136
src/lib/useRoller.ts+73−17 src/views/Activate/ActivateButton.tsx+1 src/views/Activate/MasterKeyTransfer.tsx+19−119
src/lib/useRoller.ts+73−17
@@ -43,6 +43,12 @@ import {
4343import { usePointCache } from 'store/pointCache';
4444import { getOutgoingPoints, maybeGetResult } from 'views/Points';
4545import { isPlanet } from './utils/point';
46+import {
47+ CRYPTO_SUITE_VERSION,
48+ deriveNetworkKeys,
49+ deriveNetworkSeedFromUrbitWallet,
50+} from './keys';
51+import { convertToInt } from './convertToInt';
4652
4753const spawn = async (
4854 api: any,
@@ -140,8 +146,8 @@ const hasPoint = (point: number) => (invite: Invite) => invite.planet === point;
140146const getProxyAndNonce = (
141147 point: L2Point,
142148 address: string
143−): { proxy?: string; nonce?: number } =>
144− point.ownership?.managementProxy?.address === address
149+): { proxy?: string; nonce?: number } => {
150+ return point.ownership?.managementProxy?.address === address
145151 ? { proxy: 'manage', nonce: point.ownership?.managementProxy.nonce }
146152 : point.ownership?.owner?.address === address
147153 ? { proxy: 'own', nonce: point.ownership?.owner.nonce }
@@ -155,6 +161,7 @@ const getProxyAndNonce = (
155161 nonce: point.transferProxy?.votingProxy?.owner.nonce,
156162 }
157163 : { proxy: undefined, nonce: undefined };
164+};
158165
159166export default function useRoller() {
160167 const { wallet, authToken, authMnemonic, urbitWallet }: any = useWallet();
@@ -466,40 +473,89 @@ export default function useRoller() {
466473 ]
467474 );
468475
476+ // TODO: extract from #transferPoint
477+ // interface ConfigureKeysParams {
478+
479+ // }
480+
481+ // const configureKeys = async () => {
482+
483+ // }
484+
469485 interface TransferPointParams {
470486 point: Ship;
471− from: From;
472487 to: EthAddress;
473− fromAddress: EthAddress;
474− signingKey: string;
488+ ownerAddress: EthAddress;
489+ wallet: any; // TODO: wallet type
475490 }
476491
477492 const transferPoint = async ({
478493 point,
479− from,
480494 to,
481− fromAddress,
482− signingKey,
495+ ownerAddress,
496+ wallet,
483497 }: TransferPointParams) => {
484− const pointInfo = await api.getPoint(point);
498+ const patp = ob.patp(point);
499+ const signingKey = wallet.ownership.keys.private;
500+ const azimuthPoint = await api.getPoint(point);
485501
486− const { nonce } = getProxyAndNonce(pointInfo, fromAddress);
502+ const { nonce } = getProxyAndNonce(azimuthPoint, ownerAddress);
487503 if (nonce === undefined) {
488504 throw new Error('Nonce unavailable');
489505 }
490− const transferData = { address: fromAddress, reset: true };
491− const transferHash: Hash = await api.hashTransaction(
506+
507+ // update networking keys
508+ // TODO: extract this to a useRoller#configureKeys function?
509+ const networkRevision = convertToInt(azimuthPoint.network.keys.life, 10);
510+ const nextRevision = networkRevision + 1;
511+ const seed = await deriveNetworkSeedFromUrbitWallet(wallet, nextRevision);
512+ const keys = deriveNetworkKeys(seed.value);
513+ const keysData = {
514+ address: ownerAddress,
515+ encrypt: keys.crypt.public,
516+ breach: false,
517+ auth: keys.auth.public,
518+ cryptoSuite: CRYPTO_SUITE_VERSION,
519+ };
520+ const keysFrom: From = {
521+ ship: patp,
522+ proxy: 'own',
523+ };
524+
525+ const keysHash: Hash = await api.hashTransaction(
492526 nonce,
493− from,
527+ keysFrom,
528+ 'configureKeys',
529+ keysData
530+ );
531+
532+ await api.configureKeys(
533+ signTransactionHash(keysHash, Buffer.from(signingKey, 'hex')),
534+ keysFrom,
535+ ownerAddress,
536+ keysData
537+ );
538+
539+ // transfer point
540+ const transferFrom: From = {
541+ ship: patp,
542+ proxy: 'transfer',
543+ };
544+
545+ const transferData = { address: ownerAddress, reset: false };
546+ const transferHash: Hash = await api.hashTransaction(
547+ nonce + 1,
548+ transferFrom,
494549 'transferPoint',
495550 transferData
496551 );
497552
498− const sig = signTransactionHash(
499− transferHash,
500− Buffer.from(signingKey, 'hex')
553+ const transferTxHash = await api.transferPoint(
554+ signTransactionHash(transferHash, Buffer.from(signingKey, 'hex')),
555+ transferFrom,
556+ to,
557+ transferData
501558 );
502− const transferTxHash = await api.transferPoint(sig, from, to, transferData);
503559
504560 return transferTxHash;
505561 };
src/views/Activate/ActivateButton.tsx+1
@@ -28,6 +28,7 @@ const ActivateButton = ({
2828 height={'50px'}
2929 fontWeight={'400'}
3030 fontSize={'18px'}
31+ disabled={disabled}
3132 opacity={disabled ? 0.2 : 1.0}
3233 {...rest}>
3334 {children}
src/views/Activate/MasterKeyTransfer.tsx+19−119
@@ -1,141 +1,39 @@
1−import React, { useState, useCallback, useMemo, useEffect } from 'react';
1+import React, { useState, useCallback, useMemo } from 'react';
22
3−import { useNetwork } from 'store/network';
4−import { useWallet } from 'store/wallet';
5−import { useHistory } from 'store/history';
6−import { usePointCursor } from 'store/pointCursor';
7−
8−import * as need from 'lib/need';
93import useLifecycle from 'lib/useLifecycle';
10−import useBlockWindowClose from 'lib/useBlockWindowClose';
11−import { reticketPointBetweenWallets } from 'lib/reticket';
124
135import { Anchor, Box, Text } from '@tlon/indigo-react';
146import { useActivateFlow } from './ActivateFlow';
157import ActivateView from './ActivateView';
16−import { POINT_DOMINIONS } from 'lib/constants';
17−import { From } from '@urbit/roller-api';
188import useRoller from 'lib/useRoller';
199import { FadeableActivateHeader as ActivateHeader } from './ActivateHeader';
2010import { FadeableActivateButton as ActivateButton } from './ActivateButton';
2111import useFadeIn from './useFadeIn';
2212import PointPresenter from './PointPresenter';
13+import DangerBox from './DangerBox';
2314
24−const MasterKeyTransfer = ({ className, resetActivateRouter }) => {
25− const { replaceWith, names } = useHistory();
26− const { setUrbitWallet } = useWallet();
27− const { setPointCursor } = usePointCursor();
28− const { web3, contracts, networkType } = useNetwork();
15+const MasterKeyTransfer = () => {
2916 const { api, transferPoint } = useRoller();
30− const {
31− derivedPatp,
32− derivedPoint,
33− derivedPointDominion,
34− derivedWallet,
35− inviteWallet,
36− reset: resetActivateFlow,
37− } = useActivateFlow();
38− const [generalError, setGeneralError] = useState();
39− const [progress, setProcesss] = useState(0);
40− const [needFunds, setNeedFunds] = useState();
41−
42− // const [transferTxHash, setTransferTxHash] = useState<string | null>(null);
43−
44− const _inviteWallet = need.wallet(inviteWallet);
45− const _wallet = need.wallet(derivedWallet);
46− const _point = need.point(derivedPoint);
47− const _web3 = need.web3(web3);
48− const _contracts = need.contracts(contracts);
49−
50− const goToLogin = useCallback(
51− () => replaceWith([{ key: names.LOGIN }, { key: names.POINT }]),
52− [replaceWith, names]
53− );
54−
55− const goToRestart = useCallback(() => {
56− // NOTE: because we're already on the ACTIVATE view in the history,
57− // react (intelligently) doesn't trigger a re-render and that means the
58− // current state of the two nested routers (activate & passport) stick
59− // around unless we manually clear them.
60− // we only need to clear activate because that will unmount the passport
61− // router (which will be set to initialRoutes when mounted again)
62−
63− // 2) reset local router
64− resetActivateRouter();
65− // 3) clear the state
66− resetActivateFlow();
67− }, [resetActivateRouter, resetActivateFlow]);
68−
69− const claimL2Point = useCallback(async () => {
70− console.log('claiming l2 point:');
71− const transferFrom: From = {
72− ship: derivedPatp.value,
73− proxy: 'transfer',
74− };
75−
76− const l2point = await api.getPoint(derivedPoint.value);
77− const fromAddress = l2point.ownership?.owner?.address!;
78− const txHash = await transferPoint({
79− point: derivedPoint.value,
80− from: transferFrom,
81− to: _inviteWallet.address,
82− fromAddress: fromAddress,
83− signingKey: derivedWallet.value.ownership.keys.private,
84− });
85−
86− // setTransferTxHash(txHash);
87− }, [
88− _inviteWallet.address,
89− api,
90− derivedPatp.value,
91− derivedPoint.value,
92− derivedWallet.value,
93− transferPoint,
94− ]);
95−
96− // const claimL1Point = useCallback(async () => {
97− // await reticketPointBetweenWallets({
98− // fromWallet: _inviteWallet,
99− // toWallet: _wallet,
100− // point: _point,
101− // web3: _web3,
102− // contracts: _contracts,
103− // networkType,
104− // onUpdate: handleUpdate,
105− // transferEth: true,
106− // //NOTE not passing wc function, we always have invite ticket wallet
107− // });
108− // }, [_contracts, _inviteWallet, _point, _wallet, _web3, networkType]);
17+ const { derivedPatp, derivedPoint, derivedWallet } = useActivateFlow();
18+ const [error, setError] = useState();
10919
11020 const claimPoint = useCallback(async () => {
111− setGeneralError(false);
21+ setError(undefined);
11222
11323 try {
114− // If L2
115− if (derivedPointDominion.value === POINT_DOMINIONS.L2) {
116− await claimL2Point();
117− } else {
118− // await claimL1Point();
119− console.log('do nothing for now');
120− }
121−
122− // If L1
123−
124− // set the global wallet
125− // setUrbitWallet(derivedWallet);
126− // setPointCursor(derivedPoint);
127−
128− // and redirect to login
129− // await timeout(3000);
130− // goToLogin();
24+ const l2point = await api.getPoint(derivedPoint.value);
25+ await transferPoint({
26+ point: derivedPoint.value,
27+ to: derivedWallet.value.ownership.address,
28+ ownerAddress: l2point.ownership?.owner?.address!,
29+ wallet: derivedWallet.value,
30+ });
13131 } catch (error) {
13232 console.error(error);
133− // some generic error
134− setGeneralError(error);
33+ setError(error);
13534 }
136− }, [derivedPointDominion, claimL2Point]);
35+ }, [api, derivedPoint.value, derivedWallet.value, transferPoint]);
13736
138− // useBlockWindowClose();
13937 useFadeIn();
14038
14139 useLifecycle(() => {
@@ -165,13 +63,15 @@ const MasterKeyTransfer = ({ className, resetActivateRouter }) => {
16563 flexDirection={'column'}
16664 flexWrap={'nowrap'}
16765 justifyContent={'space-between'}>
66+ {error && <DangerBox>{error.toString()}</DangerBox>}
16867 <ActivateButton
16968 onClick={() =>
17069 window.open(
17170 'https://github.com/urbit/port/releases/latest/download/Port.dmg'
17271 )
17372 }
174− success={true}>
73+ success={true}
74+ disabled={error}>
17575 Download the Client for Mac
17676 </ActivateButton>
17777 <Anchor
@@ -188,7 +88,7 @@ const MasterKeyTransfer = ({ className, resetActivateRouter }) => {
18888 </Anchor>
18989 </Box>
19090 );
191− }, []);
91+ }, [error]);
19292
19393 return (
19494 <ActivateView header={header} footer={footer}>