on master help sign in
reticket: add support for L2
6b5f7ebyosoyubik
src/lib/useRoller.ts+45−22
@@ -80,6 +80,7 @@ export default function useRoller() {
80 currentL2,
80 currentL2,
81 nonces,
81 nonces,
82 increaseNonce,
82 increaseNonce,
83+ setNonce,
83 } = useRollerStore();
84 } = useRollerStore();
84 const [config, setConfig] = useState<Config | null>(null);
85 const [config, setConfig] = useState<Config | null>(null);
85
86
@@ -463,7 +464,7 @@ export default function useRoller() {
463 return pendingTx;
464 return pendingTx;
464 };
465 };
465
466
466− interface AcceptInviteParams {
467+ interface ReticketParams {
467 point: Ship;
468 point: Ship;
468 to: EthAddress;
469 to: EthAddress;
469 manager: EthAddress;
470 manager: EthAddress;
@@ -471,25 +472,30 @@ export default function useRoller() {
471 toWallet: any; // TODO: wallet type
472 toWallet: any; // TODO: wallet type
472 }
473 }
473
474
474− const acceptInvite = async ({
475+ const performL2Reticket = async ({
475 point,
476 point,
476 to,
477 to,
477 manager,
478 manager,
478 fromWallet,
479 fromWallet,
479 toWallet,
480 toWallet,
480− }: AcceptInviteParams) => {
481+ }: ReticketParams) => {
482+ let pointDetails = nonces[point];
481 const azimuthPoint = await api.getPoint(point);
483 const azimuthPoint = await api.getPoint(point);
482− console.log('azimuthPoint', azimuthPoint);
483− const ownerAddress = azimuthPoint?.ownership?.owner?.address!;
484
484
485− const operator =
485+ console.log(pointDetails);
486− azimuthPoint.ownership &&
486+ if (pointDetails === undefined) {
487+ // This is an invite acceptance
488+ pointDetails = azimuthPoint.ownership!;
489+ console.log(pointDetails);
490+ }
491+ const ownerAddress = pointDetails.owner?.address!;
487− getOwnerNonce(azimuthPoint.ownership, ownerAddress);
492+ const operator = pointDetails && getOwnerNonce(pointDetails, ownerAddress);
488
493
489 if (operator === undefined)
494 if (operator === undefined)
490 throw new Error("Error: Address doesn't match proxy");
495 throw new Error("Error: Address doesn't match proxy");
491
496
492− const nonce = operator.nonce!;
497+ let nonce = operator.nonce!;
498+ let requests = [];
493
499
494 // 1. Update networking keys
500 // 1. Update networking keys
495 const networkRevision = convertToInt(azimuthPoint.network.keys.life, 10);
501 const networkRevision = convertToInt(azimuthPoint.network.keys.life, 10);
@@ -506,36 +512,53 @@ export default function useRoller() {
506 nonce,
512 nonce,
507 networkSeed
513 networkSeed
508 );
514 );
509−
515+ nonce = nonce + 1;
510− // TODO: not needed? next time we operate with this point we will login, and get
511− // the latest nonce (updated with any nonce increase from possible pending txs)
512 // increaseNonce(point, operator.proxy!);
516 // increaseNonce(point, operator.proxy!);
517+ requests.push(configureKeysRequest);
513
518
514 // 2. Set Management Proxy
519 // 2. Set Management Proxy
515− const registerProxyAddressRequest = await registerProxyAddress(
520+ const registerMgmtRequest = await registerProxyAddress(
516 api,
521 api,
517 fromWallet,
522 fromWallet,
518 point,
523 point,
519 operator.proxy!,
524 operator.proxy!,
520 'manage',
525 'manage',
521− nonce + 1,
526+ nonce,
522 manager
527 manager
523 );
528 );
529+ nonce = nonce + 1;
530+ // increaseNonce(point, operator.proxy!);
531+ requests.push(registerMgmtRequest);
524
532
533+ // 3. Set Spawn Proxy
534+ if (!isPlanet(Number(point))) {
535+ const registerSpawnRequest = await registerProxyAddress(
536+ api,
537+ fromWallet,
538+ point,
539+ operator.proxy!,
540+ 'spawn',
541+ nonce,
542+ toWallet.spawn.keys.address
543+ );
544+ nonce = nonce + 1;
545+ // increaseNonce(point, operator.proxy!);
546+ requests.push(registerSpawnRequest);
547+ }
525− // 3. Transfer point
548+ // 4. Transfer point
526 const transferTxRequest = await transferPointRequest(
549 const transferTxRequest = await transferPointRequest(
527 api,
550 api,
528 fromWallet,
551 fromWallet,
529 point,
552 point,
530 operator.proxy!,
553 operator.proxy!,
531− nonce + 2,
554+ nonce,
532 to
555 to
533 );
556 );
557+ // increaseNonce(point, operator.proxy!);
558+ setNonce(point, pointDetails, operator.proxy!, nonce);
559+ requests.push(transferTxRequest);
560+
534− const hashes = await Promise.all([
561+ const hashes = await Promise.all(requests);
535− configureKeysRequest,
536− registerProxyAddressRequest,
537− transferTxRequest,
538− ]);
539 return hashes;
562 return hashes;
540 };
563 };
541
564
@@ -636,7 +659,7 @@ export default function useRoller() {
636
659
637 return {
660 return {
638 api,
661 api,
639− acceptInvite,
662+ performL2Reticket,
640 config,
663 config,
641 getPoints,
664 getPoints,
642 getInvites,
665 getInvites,
src/lib/utils/roller.ts+25−23
@@ -23,6 +23,9 @@ export const HOUR = MINUTE * 60;
23export const padZero = (amount: number) =>
23export const padZero = (amount: number) =>
24 `${amount < 10 && amount > 0 ? '0' : ''}${amount}`;
24 `${amount < 10 && amount > 0 ? '0' : ''}${amount}`;
25
25
26+export const hasPoint = (point: number) => (invite: Invite) =>
27+ invite.planet === point;
28+
26export const getTimeToNextBatch = (nextBatch: number, now: number) => {
29export const getTimeToNextBatch = (nextBatch: number, now: number) => {
27 const toNext = nextBatch - now;
30 const toNext = nextBatch - now;
28 const hours = Math.floor(toNext / HOUR);
31 const hours = Math.floor(toNext / HOUR);
@@ -98,7 +101,7 @@ export const configureKeys = async (
98 encrypt: addHexPrefix(pair.crypt.public),
101 encrypt: addHexPrefix(pair.crypt.public),
99 auth: addHexPrefix(pair.auth.public),
102 auth: addHexPrefix(pair.auth.public),
100 cryptoSuite: String(CRYPTO_SUITE_VERSION),
103 cryptoSuite: String(CRYPTO_SUITE_VERSION),
101− breach,
104+ breach: breach || false,
102 };
105 };
103
106
104 const hash = await api.hashTransaction(nonce, from, 'configureKeys', data);
107 const hash = await api.hashTransaction(nonce, from, 'configureKeys', data);
@@ -142,6 +145,26 @@ const proxyType = (proxy: Proxy) => {
142 }
145 }
143};
146};
144
147
148+const setProxy = async (
149+ api: any,
150+ proxyAddressType: string,
151+ sig: Signature,
152+ from: From,
153+ address: EthAddress,
154+ data: AddressParams
155+) => {
156+ switch (proxyAddressType) {
157+ case 'manage':
158+ return await api.setManagementProxy(sig, from, address, data);
159+ case 'spawn':
160+ return await api.setSpawnProxy(sig, from, address, data);
161+ case 'transfer':
162+ return await api.setTrasferProxy(sig, from, address, data);
163+ default:
164+ throw new Error(`Unknown proxyType ${proxyAddressType}`);
165+ }
166+};
167+
145export const registerProxyAddress = async (
168export const registerProxyAddress = async (
146 api: any,
169 api: any,
147 _wallet: any,
170 _wallet: any,
@@ -172,25 +195,4 @@ export const registerProxyAddress = async (
172 );
195 );
173};
196};
174
197
175−const setProxy = async (
198+export const reticketL2Point = async () => {};
176− api: any,
177− proxyAddressType: string,
178− sig: Signature,
179− from: From,
180− address: EthAddress,
181− data: AddressParams
182−) => {
183− switch (proxyAddressType) {
184− case 'manage':
185− return await api.setManagementProxy(sig, from, address, data);
186− case 'spawn':
187− return await api.setSpawnProxy(sig, from, address, data);
188− case 'transfer':
189− return await api.setTrasferProxy(sig, from, address, data);
190− default:
191− throw new Error(`Unknown proxyType ${proxyAddressType}`);
192− }
193−};
194−
195−export const hasPoint = (point: number) => (invite: Invite) =>
196− invite.planet === point;
src/store/roller.ts+12−7
@@ -1,5 +1,10 @@
1import create from 'zustand';
1import create from 'zustand';
2+import {
3+ L2Point,
2−import { L2Point, PendingTransaction, Ownership } from '@urbit/roller-api';
4+ PendingTransaction,
5+ Ownership,
6+ Ship,
7+} from '@urbit/roller-api';
3
8
4import { HOUR, isL2, isL2Spawn } from 'lib/utils/roller';
9import { HOUR, isL2, isL2Spawn } from 'lib/utils/roller';
5import { increaseProxyNonce, setProxyNonce } from 'lib/utils/nonce';
10import { increaseProxyNonce, setProxyNonce } from 'lib/utils/nonce';
@@ -13,11 +18,11 @@ export interface RollerStore {
13 currentL2: boolean;
18 currentL2: boolean;
14 currentL2Spawn: boolean;
19 currentL2Spawn: boolean;
15 nonces: {
20 nonces: {
16− [point: number]: Ownership;
21+ [point: Ship]: Ownership;
17 };
22 };
18− increaseNonce: (point: number, proxy: string) => void;
23+ increaseNonce: (point: Ship, proxy: string) => void;
19 setNonce: (
24 setNonce: (
20− point: number,
25+ point: Ship,
21 owner: Ownership,
26 owner: Ownership,
22 proxy: string,
27 proxy: string,
23 nonce: number
28 nonce: number
@@ -42,14 +47,14 @@ export const useRollerStore = create<RollerStore>(set => ({
42 invites: [],
47 invites: [],
43 recentlyCompleted: 0,
48 recentlyCompleted: 0,
44 nonces: {},
49 nonces: {},
45− increaseNonce: (point: number, proxy: string) =>
50+ increaseNonce: (point: Ship, proxy: string) =>
46 set(state => {
51 set(state => {
47 const owner = increaseProxyNonce(state.nonces[point], proxy);
52 const owner = increaseProxyNonce(state.nonces[point], proxy);
48 console.log(point, proxy, owner);
53 console.log(point, proxy, owner);
49 if (!owner) throw new Error("Can't increase nonce for this proxy");
54 if (!owner) throw new Error("Can't increase nonce for this proxy");
50 return { ...state, nonces: { ...state.nonces, [point]: owner } };
55 return { ...state, nonces: { ...state.nonces, [point]: owner } };
51 }),
56 }),
52− setNonce: (point: number, owner: Ownership, proxy: string, nonce: number) =>
57+ setNonce: (point: Ship, owner: Ownership, proxy: string, nonce: number) =>
53 set(state => {
58 set(state => {
54 const updatedOwner = setProxyNonce(owner, proxy, nonce);
59 const updatedOwner = setProxyNonce(owner, proxy, nonce);
55 if (!updatedOwner) throw new Error("Can't set nonce for this proxy");
60 if (!updatedOwner) throw new Error("Can't set nonce for this proxy");
@@ -58,7 +63,7 @@ export const useRollerStore = create<RollerStore>(set => ({
58 nonces: { ...state.nonces, [point]: updatedOwner },
63 nonces: { ...state.nonces, [point]: updatedOwner },
59 };
64 };
60 }),
65 }),
61− setNonces: (point: number, owner: Ownership) =>
66+ setNonces: (point: Ship, owner: Ownership) =>
62 set(state => {
67 set(state => {
63 return { ...state, nonces: { ...state.nonces, [point]: owner } };
68 return { ...state, nonces: { ...state.nonces, [point]: owner } };
64 }),
69 }),
src/views/Activate/MasterKeyTransfer.tsx+8−3
@@ -14,7 +14,7 @@ import DangerBox from './DangerBox';
14import View from 'components/View';
14import View from 'components/View';
15
15
16const MasterKeyTransfer = () => {
16const MasterKeyTransfer = () => {
17− const { acceptInvite } = useRoller();
17+ const { performL2Reticket } = useRoller();
18 const {
18 const {
19 derivedPatp,
19 derivedPatp,
20 derivedPoint,
20 derivedPoint,
@@ -27,7 +27,7 @@ const MasterKeyTransfer = () => {
27 setError(undefined);
27 setError(undefined);
28
28
29 try {
29 try {
30− await acceptInvite({
30+ await performL2Reticket({
31 point: derivedPoint.value,
31 point: derivedPoint.value,
32 to: derivedWallet.value.ownership.keys.address,
32 to: derivedWallet.value.ownership.keys.address,
33 manager: derivedWallet.value.management.keys.address,
33 manager: derivedWallet.value.management.keys.address,
@@ -38,7 +38,12 @@ const MasterKeyTransfer = () => {
38 console.error(error);
38 console.error(error);
39 setError(error);
39 setError(error);
40 }
40 }
41+ }, [
42+ derivedWallet,
43+ performL2Reticket,
41− }, [derivedWallet, acceptInvite, derivedPoint.value, inviteWallet.value]);
44+ derivedPoint.value,
45+ inviteWallet.value,
46+ ]);
42
47
43 useFadeIn();
48 useFadeIn();
44
49
src/views/UrbitID/ResetKeys/ResetExecute.js+31−14
@@ -16,7 +16,9 @@ import { useWallet } from 'store/wallet';
16import { usePointCursor } from 'store/pointCursor';
16import { usePointCursor } from 'store/pointCursor';
17import { usePointCache } from 'store/pointCache';
17import { usePointCache } from 'store/pointCache';
18import { useHistory } from 'store/history';
18import { useHistory } from 'store/history';
19+import { useRollerStore } from 'store/roller';
19
20
21+import useRoller from 'lib/useRoller';
20import { useWalletConnect } from 'lib/useWalletConnect';
22import { useWalletConnect } from 'lib/useWalletConnect';
21
23
22import { RestartButton, ForwardButton } from 'components/Buttons';
24import { RestartButton, ForwardButton } from 'components/Buttons';
@@ -53,6 +55,8 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
53 walletType,
55 walletType,
54 walletHdPath,
56 walletHdPath,
55 } = useWallet();
57 } = useWallet();
58+ const { performL2Reticket } = useRoller();
59+ const { currentL2 } = useRollerStore();
56 const { pointCursor } = usePointCursor();
60 const { pointCursor } = usePointCursor();
57 const { getDetails } = usePointCache();
61 const { getDetails } = usePointCache();
58 const {
62 const {
@@ -92,20 +96,33 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
92 walletType === WALLET_TYPES.WALLET_CONNECT ? wcSend : undefined;
96 walletType === WALLET_TYPES.WALLET_CONNECT ? wcSend : undefined;
93
97
94 try {
98 try {
99+ if (currentL2) {
100+ console.log(newWallet.value);
101+ // FIXME: the useEffect is called twice, which is fine since the duplicate
102+ // L2 txs will be discarded
103+ //
104+ await performL2Reticket({
105+ point,
106+ to: newWallet.value.wallet.ownership.keys.address,
107+ manager: newWallet.value.wallet.management.keys.address,
108+ toWallet: newWallet.value.wallet,
109+ fromWallet: need.wallet(wallet),
110+ });
111+ } else
95− await reticketPointBetweenWallets({
112+ await reticketPointBetweenWallets({
96− fromWallet: need.wallet(wallet),
113+ fromWallet: need.wallet(wallet),
97− fromWalletType: walletType,
114+ fromWalletType: walletType,
98− fromWalletHdPath: walletHdPath,
115+ fromWalletHdPath: walletHdPath,
99− toWallet: newWallet.value.wallet,
116+ toWallet: newWallet.value.wallet,
100− point: point,
117+ point: point,
101− web3: need.web3(web3),
118+ web3: need.web3(web3),
102− contracts: need.contracts(contracts),
119+ contracts: need.contracts(contracts),
103− networkType,
120+ networkType,
104− onUpdate: handleUpdate,
121+ onUpdate: handleUpdate,
105− nextRevision: networkRevision + 1,
122+ nextRevision: networkRevision + 1,
106− txnSigner,
123+ txnSigner,
107− txnSender,
124+ txnSender,
108− });
125+ });
109 } catch (err) {
126 } catch (err) {
110 console.error(err);
127 console.error(err);
111 setGeneralError(err);
128 setGeneralError(err);