@@ -4,36 +4,39 @@ import * as need from 'lib/need';
4import SecureLS from 'secure-ls';
4import SecureLS from 'secure-ls';
6import { Invite } from 'lib/types/Invite';
6import { Invite } from 'lib/types/Invite';
7−import { convertToInt } from './convertToInt';
8−import { isDevelopment, isRopsten } from './flags';
10− adopt,
8+ deriveNetworkSeedFromUrbitWallet,
11− detach,
9+ attemptNetworkSeedDerivation,
12− generateInviteWallet,
10+} from 'lib/keys';
15−} from './utils/roller';
16−import { ROLLER_HOSTS } from './constants';
18import { useNetwork } from 'store/network';
12import { useNetwork } from 'store/network';
19import { usePointCursor } from 'store/pointCursor';
13import { usePointCursor } from 'store/pointCursor';
20−import { useRollerStore } from 'store/roller';
14+import { EMPTY_POINT, useRollerStore } from 'store/rollerStore';
21import { useWallet } from 'store/wallet';
15import { useWallet } from 'store/wallet';
22import { getStoredInvites, setStoredInvites } from 'store/storage/roller';
16import { getStoredInvites, setStoredInvites } from 'store/storage/roller';
23import { usePointCache } from 'store/pointCache';
17import { usePointCache } from 'store/pointCache';
24import { getOutgoingPoints } from 'views/Points';
18import { getOutgoingPoints } from 'views/Points';
26 getSpawnProxy,
21 getSpawnProxy,
27 getManagerProxy,
22 getManagerProxy,
28 getAddressProxy,
23 getAddressProxy,
29 getTransferProxy,
24 getTransferProxy,
30} from './utils/proxy';
25} from './utils/proxy';
31−import { isPlanet } from './utils/point';
26+import { isPlanet, toL1Details } from './utils/point';
32−
27+import { convertToInt } from './convertToInt';
28+import { isDevelopment, isRopsten } from './flags';
34− deriveNetworkSeedFromUrbitWallet,
30+ generateInviteWallet,
35− attemptNetworkSeedDerivation,
31+ getPendingSpawns,
36−} from 'lib/keys';
32+ submitL2Transaction,
34+ registerProxyAddress,
38+} from './utils/roller';
39+import { ROLLER_HOSTS } from './constants';
@@ -45,13 +48,9 @@ import {
45 UnspawnedPoints,
48 UnspawnedPoints,
46} from '@urbit/roller-api';
49} from '@urbit/roller-api';
48−import {
51+import Point, { Points, Relationship } from './types/Point';
49− configureKeys,
52+import { useTimerStore } from 'store/timerStore';
50− getTimeToNextBatch,
53+import { ReticketParams, SendL2Params } from './types/L2Transaction';
52− transferPointRequest,
53− registerProxyAddress,
54−} from './utils/roller';
56const ONE_SECOND = 1000;
55const ONE_SECOND = 1000;
@@ -81,17 +80,19 @@ export default function useRoller() {
81 const controlledPoints = allPoints?.controlledPoints;
80 const controlledPoints = allPoints?.controlledPoints;
82 const getDetails = allPoints?.getDetails;
81 const getDetails = allPoints?.getDetails;
83+ const { setNextRoll } = useTimerStore();
85 nextBatchTime,
86 nextBatchTime,
87 invitePoints,
88 invitePoints,
89 setNextBatchTime,
90 setNextBatchTime,
91 setPendingTransactions,
91 setPendingTransactions,
92 setInvites,
92 setInvites,
93 setInvitePoints,
93 setInvitePoints,
94 setInviteGeneratingNum,
94 setInviteGeneratingNum,
95 } = useRollerStore();
96 } = useRollerStore();
96 const [config, setConfig] = useState<Config | null>(null);
97 const [config, setConfig] = useState<Config | null>(null);
@@ -158,6 +159,7 @@ export default function useRoller() {
158 throw new Error('Internal Error: Missing Contracts/Web3/Wallet');
159 throw new Error('Internal Error: Missing Contracts/Web3/Wallet');
162+ // TODO: remove when UI disables management proxy from spawning invites
161 // if (Just.hasInstance(authMnemonic)) {
163 // if (Just.hasInstance(authMnemonic)) {
162 // throw new Error(
164 // throw new Error(
163 // "Auth key Error: A management mnemonic can't create invite codes"
165 // "Auth key Error: A management mnemonic can't create invite codes"
@@ -173,7 +175,6 @@ export default function useRoller() {
174 const starInfo = await api.getPoint(_point);
176 const starInfo = await api.getPoint(_point);
175 const invites: Invite[] = [];
177 const invites: Invite[] = [];
176− const requests: Promise<string>[] = [];
178 const proxy = getSpawnProxy(starInfo.ownership!, _wallet.address);
179 const proxy = getSpawnProxy(starInfo.ownership!, _wallet.address);
@@ -195,33 +196,36 @@ export default function useRoller() {
195 _authToken
196 _authToken
198− const spawnRequest = spawn(
199+ await submitL2Transaction({
200− _wallet,
201+ address: _wallet.address,
201− _point,
203+ ship: _point,
203− nonceInc,
205+ nonce: nonceInc,
204− planet,
206+ pointToSpawn: planet,
205 walletType,
208 walletType,
206− _web3
209+ web3: _web3,
209 const networkSeed = await deriveNetworkSeedFromUrbitWallet(
212 const networkSeed = await deriveNetworkSeedFromUrbitWallet(
210 inviteWallet,
213 inviteWallet,
213− const configureKeysRequest = configureKeys(
216+ await submitL2Transaction({
215− _wallet,
218+ wallet: _wallet,
216− planet,
219+ ship: planet,
217− 'own',
220+ proxy: 'own',
219 networkSeed,
222 networkSeed,
223+ type: 'configureKeys',
220 walletType,
224 walletType,
221− _web3
225+ web3: _web3,
224− const setManagementProxyRequest = registerProxyAddress(
228+ await registerProxyAddress(
@@ -233,24 +237,17 @@ export default function useRoller() {
236− const transferRequest = transferPointRequest(
240+ await submitL2Transaction({
238− _wallet,
242+ wallet: _wallet,
239− planet,
243+ ship: planet,
240− 'own',
244+ proxy: 'own',
241− 2,
245+ type: 'transferPoint',
242− inviteWallet.ownership.keys.address,
247+ address: inviteWallet.ownership.keys.address,
243 walletType,
248 walletType,
244− _web3
249+ web3: _web3,
249− configureKeysRequest,
250− setManagementProxyRequest,
253− await Promise.all(requests);
255 invites.push({
252 invites.push({
256 hash: '',
253 hash: '',
@@ -497,30 +494,23 @@ export default function useRoller() {
497 authToken,
494 authToken,
498 revision: nextRevision,
495 revision: nextRevision,
500− const txHash = await configureKeys(
497+ const txHash = await submitL2Transaction({
502− _wallet,
499+ wallet: _wallet,
503− _point,
500+ ship: _point,
504− proxy!,
501+ proxy: proxy!,
506 networkSeed,
503 networkSeed,
504+ type: 'configureKeys',
507 walletType,
505 walletType,
508− _web3,
506+ web3: _web3,
511 const pendingTx = await api.getPendingTx(txHash);
509 const pendingTx = await api.getPendingTx(txHash);
513 return pendingTx;
511 return pendingTx;
516− interface ReticketParams {
519− manager: EthAddress;
520− fromWallet: any; // TODO: wallet type
521− toWallet: any; // TODO: wallet type
524 const performL2Reticket = async ({
514 const performL2Reticket = async ({
@@ -542,16 +532,17 @@ export default function useRoller() {
542 toWallet,
532 toWallet,
543 nextRevision
533 nextRevision
545− const configureKeysRequest = await configureKeys(
535+ const configureKeysRequest = await submitL2Transaction({
547− fromWallet,
537+ wallet: fromWallet,
548− point,
538+ ship: point,
551 networkSeed,
541 networkSeed,
552 walletType,
542 walletType,
543+ type: 'configureKeys',
553− _web3
544+ web3: _web3,
555 nonce = nonce + 1;
546 nonce = nonce + 1;
556 requests.push(configureKeysRequest);
547 requests.push(configureKeysRequest);
@@ -587,16 +578,17 @@ export default function useRoller() {
587 requests.push(registerSpawnRequest);
578 requests.push(registerSpawnRequest);
589 // 4. Transfer point
580 // 4. Transfer point
590− const transferTxRequest = await transferPointRequest(
581+ const transferTxRequest = await submitL2Transaction({
592− fromWallet,
583+ wallet: fromWallet,
593− point,
584+ ship: point,
594− proxy,
585+ proxy: 'own',
586+ type: 'transferPoint',
596− to,
588+ address: to,
597 walletType,
589 walletType,
598− _web3
590+ web3: _web3,
600 requests.push(transferTxRequest);
592 requests.push(transferTxRequest);
602 const hashes = await Promise.all(requests);
594 const hashes = await Promise.all(requests);
@@ -724,17 +716,19 @@ export default function useRoller() {
725 const nonce = await api.getNonce({ ship: _point, proxy });
717 const nonce = await api.getNonce({ ship: _point, proxy });
727− const txHash = await transferPointRequest(
719+ const txHash = await submitL2Transaction({
729− _wallet,
721+ wallet: _wallet,
730− _point,
722+ ship: _point,
726+ type: 'transferPoint',
734 walletType,
727 walletType,
735− _web3,
728+ web3: _web3,
736− reset || false
729+ reset,
738 const pendingTx = await api.getPendingTx(txHash);
732 const pendingTx = await api.getPendingTx(txHash);
740 return pendingTx;
734 return pendingTx;
@@ -742,6 +736,114 @@ export default function useRoller() {
742 [api, pointCursor, wallet, web3, walletType]
736 [api, pointCursor, wallet, web3, walletType]
739+ const sendL2Transaction = useCallback(
740+ async (params: SendL2Params) => {
741+ const _point = need.point(pointCursor);
742+ const _wallet = wallet.getOrElse(null);
743+ const _web3 = web3.getOrElse(null);
746+ // not using need because we want a custom error
747+ throw new Error('Internal Error: Missing Wallet');
750+ return submitL2Transaction({
759+ [api, pointCursor, wallet, web3, walletType]
762+ const changeSponsor = useCallback(
763+ async (newSponsor: number) => {
764+ const _wallet = wallet.getOrElse(null);
765+ const _point = need.point(pointCursor);
768+ // not using need because we want a custom error
769+ throw new Error('Internal Error: Missing Wallet');
772+ const pointDetails = await api.getPoint(_point);
773+ const proxy = getManagerProxy(pointDetails.ownership!, _wallet.address);
775+ if (proxy === undefined)
776+ throw new Error("Error: Address doesn't match proxy");
778+ const nonce = await api.getNonce({ ship: _point, proxy });
788+ [api, sendL2Transaction, wallet, pointCursor]
791+ const initPoint = useCallback(
792+ (relationship: Relationship) => async (point: string | number) => {
793+ const _wallet = wallet.getOrElse(null);
799+ const pointNum = Number(point);
800+ const rawDetails = await api.getPoint(pointNum);
801+ const details = toL1Details(rawDetails);
803+ return new Point(pointNum, relationship, details, _wallet.address);
811+ const getPointDetails = useCallback(
813+ ownedPoints: number[],
814+ incomingPoints: number[],
815+ managingPoints: number[],
816+ votingPoints: number[],
817+ spawningPoints: number[]
821+ await Promise.all(ownedPoints.map(initPoint(Relationship.own))),
823+ incomingPoints.map(initPoint(Relationship.transfer))
825+ await Promise.all(managingPoints.map(initPoint(Relationship.manage))),
826+ await Promise.all(votingPoints.map(initPoint(Relationship.vote))),
827+ await Promise.all(spawningPoints.map(initPoint(Relationship.spawn))),
831+ allPoints.reduce((acc: Points, cur: (Point | undefined)[]) => {
844+ [setPoints, initPoint]
745 // On load, get initial config
847 // On load, get initial config
746 useEffect(() => {
848 useEffect(() => {
747 if (config) {
849 if (config) {
@@ -759,30 +861,32 @@ export default function useRoller() {
759 if (nextBatchTime - ONE_SECOND <= new Date().getTime()) {
861 if (nextBatchTime - ONE_SECOND <= new Date().getTime()) {
760 api.getRollerConfig().then(response => {
862 api.getRollerConfig().then(response => {
761 setNextBatchTime(response.nextBatch);
863 setNextBatchTime(response.nextBatch);
762− getNumInvites(currentL2);
864+ getNumInvites(!!point?.isL2);
765 }, 10000000);
867 }, 10000000);
767 return () => clearInterval(interval);
869 return () => clearInterval(interval);
768− }, [nextBatchTime, getPendingTransactions, currentL2]); // eslint-disable-line react-hooks/exhaustive-deps
870+ }, [nextBatchTime, getPendingTransactions, point]); // eslint-disable-line react-hooks/exhaustive-deps
771 adoptPoint,
873 adoptPoint,
773− performL2Reticket,
875+ changeSponsor,
775− getPoints,
877+ configureNetworkingKeys,
776 getInvites,
878 getInvites,
777 getPendingTransactions,
882 getPendingTransactions,
778 generateInviteCodes,
883 generateInviteCodes,
779 kickPoint,
884 kickPoint,
780 rejectPoint,
885 rejectPoint,
781 transferPoint,
886 transferPoint,
782 setProxyAddress,
889 setProxyAddress,
783− configureNetworkingKeys,
785 showInvite,
890 showInvite,