@@ -1,14 +1,13 @@
11import { useCallback, useEffect, useMemo, useState } from 'react';
2−import _ from 'lodash';
32import * as azimuth from 'azimuth-js';
43import * as need from 'lib/need';
5−import { Just } from 'folktale/maybe';
4+import SecureLS from 'secure-ls';
65
76import { Invite } from 'lib/types/Invite';
87import { convertToInt } from './convertToInt';
98import { isDevelopment, isRopsten } from './flags';
10−import { hasInvite, generateInviteWallet } from './utils/roller';
11−import { INVITES_PER_PAGE, ROLLER_HOSTS } from './constants';
9+import { generateInviteWallet, getPendingSpawns } from './utils/roller';
10+import { ROLLER_HOSTS } from './constants';
1211
1312import { useNetwork } from 'store/network';
1413import { usePointCursor } from 'store/pointCursor';
@@ -38,8 +37,6 @@ import {
3837 Options,
3938 EthAddress,
4039 UnspawnedPoints,
41− SpawnParams,
42− L2Data,
4340} from '@urbit/roller-api';
4441
4542import {
@@ -50,13 +47,7 @@ import {
5047 registerProxyAddress,
5148} from './utils/roller';
5249
53−function isSpawn(tx: L2Data | undefined): tx is SpawnParams {
54− return (tx as SpawnParams) !== undefined;
55−}
56−
57−function isShipNumber(ship: number | string | undefined): ship is number {
58− return (ship as number) !== undefined;
59−}
50+const ONE_SECOND = 1000;
6051
6152const inviteTemplate = (
6253 planet: number,
@@ -82,6 +73,7 @@ export default function useRoller() {
8273 nextBatchTime,
8374 currentL2,
8475 invitePoints,
76+ invites,
8577 setNextBatchTime,
8678 setNextRoll,
8779 setPendingTransactions,
@@ -131,6 +123,11 @@ export default function useRoller() {
131123 });
132124 }, [api]); // eslint-disable-line react-hooks/exhaustive-deps
133125
126+ const ls = new SecureLS({
127+ isCompression: false,
128+ encryptionSecret: authToken.getOrElse('default'),
129+ });
130+
134131 const generateInviteCodes = useCallback(
135132 async (numInvites: number) => {
136133 const _point = need.point(pointCursor);
@@ -154,25 +151,12 @@ export default function useRoller() {
154151
155152 const pendingTxs = await api.getPendingByShip(_point);
156153
157− const pendingSpawns = _.reduce(
158− pendingTxs,
159− (acc, pending) => {
160− return isSpawn(pending.rawTx?.tx) &&
161− isShipNumber(pending.rawTx?.tx.data.ship)
162− ? acc.add(pending.rawTx?.tx.data.ship!)
163− : acc;
164− },
165− new Set<number>()
166− );
154+ const pendingSpawns = getPendingSpawns(pendingTxs);
167155
168156 planets = planets.filter((point: number) => !pendingSpawns.has(point));
169157
170158 const starInfo = await api.getPoint(_point);
171− const tickets: {
172− ticket: string;
173− planet: number;
174− owner: string;
175− }[] = [];
159+ const invites: Invite[] = [];
176160 const requests: Promise<string>[] = [];
177161
178162 const proxy = getSpawnProxy(starInfo.ownership!, _wallet.address);
@@ -244,12 +228,15 @@ export default function useRoller() {
244228 );
245229 await Promise.all(requests);
246230
247− tickets.push({
231+ invites.push({
232+ hash: '',
248233 ticket,
249234 planet,
250235 owner: inviteWallet.ownership.keys.address,
251236 });
252237 }
238+
239+ setStoredInvites(ls, invites);
253240 },
254241 [
255242 api,
@@ -259,7 +246,7 @@ export default function useRoller() {
259246 wallet,
260247 web3,
261248 getDetails,
262− authMnemonic,
249+ ls,
263250 setInviteGeneratingNum,
264251 ]
265252 );
@@ -290,23 +277,25 @@ export default function useRoller() {
290277 const newPending = await api.getPendingByShip(curPoint);
291278
292279 setPendingTransactions(newPending);
293−
294− // const allTransactions = await api.getHistory()
295280 } catch (error) {
296281 console.warn('ERROR GETTING PENDING', error);
297282 }
298283 }, [api, setPendingTransactions, pointCursor]);
299284
285+ const generateInviteInfo = async (planet: number, _authToken: string) => {
286+ const { ticket, inviteWallet } = await generateInviteWallet(
287+ planet,
288+ _authToken
289+ );
290+
291+ return inviteTemplate(planet, ticket, inviteWallet.ownership.keys.address);
292+ };
293+
300294 const getInvites = useCallback(
301− async (isL2: boolean, page: number, getAll = false) => {
295+ async (isL2: boolean, getAll = false) => {
302296 try {
303297 const curPoint: number = Number(need.point(pointCursor));
304− const storedInvites = getStoredInvites(curPoint);
305− if (storedInvites.length) {
306− setInvites(storedInvites);
307− } else {
308− setInvites(invitePoints.map(p => inviteTemplate(p)));
309− }
298+ setInvites(invitePoints.map(p => inviteTemplate(p)));
310299
311300 const _authToken = authToken.getOrElse(null);
312301 const _contracts = contracts.getOrElse(null);
@@ -332,38 +321,27 @@ export default function useRoller() {
332321
333322 const newInvites: Invite[] = [];
334323 // Iterate over all of the stored invites, generating wallet info as necessary
324+ const storedInvites = getStoredInvites(ls);
325+
335326 for (let i = 0; i < invitePlanets.length; i++) {
336327 setInviteGeneratingNum(i + 1);
337328 const planet = invitePlanets[i];
338− const invite = storedInvites.find(hasInvite(planet));
339−
340− const start = page * INVITES_PER_PAGE;
341− const end = start + INVITES_PER_PAGE;
329+ const invite = storedInvites[planet];
342330
343− if (invite) {
331+ if (invite?.ticket) {
344332 newInvites.push(invite);
345− } else if (getAll || (i >= start && i < end)) {
333+ } else if (getAll) {
346334 if (isDevelopment) {
347335 console.log('MISSING INVITE INFO', planet);
348336 }
349− const { ticket, inviteWallet } = await generateInviteWallet(
350− planet,
351− _authToken
352− );
353−
354− newInvites.push(
355− inviteTemplate(
356− planet,
357− ticket,
358− inviteWallet.ownership.keys.address
359− )
360− );
337+ const newInvite = await generateInviteInfo(planet, _authToken);
338+ newInvites.push(newInvite);
361339 } else {
362340 newInvites.push(inviteTemplate(planet));
363341 }
364342 }
365343
366− setStoredInvites(curPoint, newInvites);
344+ setStoredInvites(ls, newInvites);
367345 setInvites(newInvites);
368346
369347 return newInvites;
@@ -380,11 +358,28 @@ export default function useRoller() {
380358 getDetails,
381359 pointCursor,
382360 invitePoints,
361+ ls,
383362 setInvites,
384363 setInviteGeneratingNum,
385364 ]
386365 );
387366
367+ const showInvite = useCallback(
368+ async (planet: number) => {
369+ const _authToken = authToken.getOrElse(null);
370+
371+ if (_authToken) {
372+ const newInvite = await generateInviteInfo(planet, _authToken);
373+ const newInvites = invites.map(invite =>
374+ invite.planet === planet ? newInvite : invite
375+ );
376+ setInvites(newInvites);
377+ setStoredInvites(ls, newInvites);
378+ }
379+ },
380+ [authToken, invites, ls, setInvites]
381+ );
382+
388383 const getNumInvites = useCallback(
389384 async (isL2: boolean) => {
390385 try {
@@ -400,12 +395,22 @@ export default function useRoller() {
400395 curPoint
401396 );
402397
398+ const newPending = await api.getPendingByShip(curPoint);
399+ const pendingSpawns = getPendingSpawns(newPending);
400+
403401 const outgoingPoints = getOutgoingPoints(
404402 controlledPoints,
405403 getDetails
406404 ).filter((p: number) => isPlanet(p) && availablePoints.includes(p));
407405
408− setInvitePoints(invitePoints.concat(outgoingPoints));
406+ console.log(pendingSpawns, outgoingPoints, invitePoints)
407+
408+ setPendingTransactions(newPending);
409+ setInvitePoints(
410+ invitePoints
411+ .concat(outgoingPoints)
412+ .filter(p => !pendingSpawns.has(p))
413+ );
409414 }
410415 } catch (e) {
411416 if (isDevelopment) {
@@ -416,11 +421,12 @@ export default function useRoller() {
416421 [
417422 api,
418423 pointCursor,
419− setInvitePoints,
420424 authToken,
421425 contracts,
422426 controlledPoints,
423427 getDetails,
428+ setInvitePoints,
429+ setPendingTransactions,
424430 ]
425431 );
426432
@@ -645,12 +651,11 @@ export default function useRoller() {
645651 const nextRoll = getTimeToNextBatch(nextBatchTime, new Date().getTime());
646652 setNextRoll(nextRoll);
647653
648− if (nextBatchTime <= new Date().getTime()) {
654+ if (nextBatchTime - ONE_SECOND <= new Date().getTime()) {
649655 api.getRollerConfig().then(response => {
650656 setNextBatchTime(response.nextBatch);
657+ getNumInvites(currentL2);
651658 });
652−
653− getInvites(currentL2, 0);
654659 }
655660 }, 1000);
656661
@@ -669,5 +674,7 @@ export default function useRoller() {
669674 setProxyAddress,
670675 configureNetworkingKeys,
671676 getNumInvites,
677+ showInvite,
678+ ls,
672679 };
673680}