@@ -1,14 +1,13 @@
1import { useCallback, useEffect, useMemo, useState } from 'react';
1import { useCallback, useEffect, useMemo, useState } from 'react';
2−import _ from 'lodash';
3import * as azimuth from 'azimuth-js';
2import * as azimuth from 'azimuth-js';
4import * as need from 'lib/need';
3import * as need from 'lib/need';
5−import { Just } from 'folktale/maybe';
4+import SecureLS from 'secure-ls';
7import { Invite } from 'lib/types/Invite';
6import { Invite } from 'lib/types/Invite';
8import { convertToInt } from './convertToInt';
7import { convertToInt } from './convertToInt';
9import { isDevelopment, isRopsten } from './flags';
8import { isDevelopment, isRopsten } from './flags';
10−import { hasInvite, generateInviteWallet } from './utils/roller';
9+import { generateInviteWallet, getPendingSpawns } from './utils/roller';
11−import { INVITES_PER_PAGE, ROLLER_HOSTS } from './constants';
10+import { ROLLER_HOSTS } from './constants';
13import { useNetwork } from 'store/network';
12import { useNetwork } from 'store/network';
14import { usePointCursor } from 'store/pointCursor';
13import { usePointCursor } from 'store/pointCursor';
@@ -38,8 +37,6 @@ import {
39 EthAddress,
38 EthAddress,
40 UnspawnedPoints,
39 UnspawnedPoints,
43} from '@urbit/roller-api';
40} from '@urbit/roller-api';
@@ -50,13 +47,7 @@ import {
50 registerProxyAddress,
47 registerProxyAddress,
51} from './utils/roller';
48} from './utils/roller';
53−function isSpawn(tx: L2Data | undefined): tx is SpawnParams {
50+const ONE_SECOND = 1000;
54− return (tx as SpawnParams) !== undefined;
57−function isShipNumber(ship: number | string | undefined): ship is number {
58− return (ship as number) !== undefined;
61const inviteTemplate = (
52const inviteTemplate = (
62 planet: number,
53 planet: number,
@@ -82,6 +73,7 @@ export default function useRoller() {
82 nextBatchTime,
73 nextBatchTime,
83 currentL2,
74 currentL2,
84 invitePoints,
75 invitePoints,
85 setNextBatchTime,
77 setNextBatchTime,
86 setNextRoll,
78 setNextRoll,
87 setPendingTransactions,
79 setPendingTransactions,
@@ -131,6 +123,11 @@ export default function useRoller() {
132 }, [api]); // eslint-disable-line react-hooks/exhaustive-deps
124 }, [api]); // eslint-disable-line react-hooks/exhaustive-deps
126+ const ls = new SecureLS({
127+ isCompression: false,
128+ encryptionSecret: authToken.getOrElse('default'),
134 const generateInviteCodes = useCallback(
131 const generateInviteCodes = useCallback(
135 async (numInvites: number) => {
132 async (numInvites: number) => {
136 const _point = need.point(pointCursor);
133 const _point = need.point(pointCursor);
@@ -154,25 +151,12 @@ export default function useRoller() {
155 const pendingTxs = await api.getPendingByShip(_point);
152 const pendingTxs = await api.getPendingByShip(_point);
157− const pendingSpawns = _.reduce(
154+ const pendingSpawns = getPendingSpawns(pendingTxs);
160− return isSpawn(pending.rawTx?.tx) &&
161− isShipNumber(pending.rawTx?.tx.data.ship)
162− ? acc.add(pending.rawTx?.tx.data.ship!)
168 planets = planets.filter((point: number) => !pendingSpawns.has(point));
156 planets = planets.filter((point: number) => !pendingSpawns.has(point));
170 const starInfo = await api.getPoint(_point);
158 const starInfo = await api.getPoint(_point);
171− const tickets: {
159+ const invites: Invite[] = [];
176 const requests: Promise<string>[] = [];
160 const requests: Promise<string>[] = [];
178 const proxy = getSpawnProxy(starInfo.ownership!, _wallet.address);
162 const proxy = getSpawnProxy(starInfo.ownership!, _wallet.address);
@@ -244,12 +228,15 @@ export default function useRoller() {
245 await Promise.all(requests);
229 await Promise.all(requests);
247− tickets.push({
231+ invites.push({
250 owner: inviteWallet.ownership.keys.address,
235 owner: inviteWallet.ownership.keys.address,
239+ setStoredInvites(ls, invites);
@@ -259,7 +246,7 @@ export default function useRoller() {
261 getDetails,
248 getDetails,
262− authMnemonic,
249+ ls,
263 setInviteGeneratingNum,
250 setInviteGeneratingNum,
@@ -290,23 +277,25 @@ export default function useRoller() {
290 const newPending = await api.getPendingByShip(curPoint);
277 const newPending = await api.getPendingByShip(curPoint);
292 setPendingTransactions(newPending);
279 setPendingTransactions(newPending);
294− // const allTransactions = await api.getHistory()
295 } catch (error) {
280 } catch (error) {
296 console.warn('ERROR GETTING PENDING', error);
281 console.warn('ERROR GETTING PENDING', error);
298 }, [api, setPendingTransactions, pointCursor]);
283 }, [api, setPendingTransactions, pointCursor]);
285+ const generateInviteInfo = async (planet: number, _authToken: string) => {
286+ const { ticket, inviteWallet } = await generateInviteWallet(
291+ return inviteTemplate(planet, ticket, inviteWallet.ownership.keys.address);
300 const getInvites = useCallback(
294 const getInvites = useCallback(
301− async (isL2: boolean, page: number, getAll = false) => {
295+ async (isL2: boolean, getAll = false) => {
303 const curPoint: number = Number(need.point(pointCursor));
297 const curPoint: number = Number(need.point(pointCursor));
304− const storedInvites = getStoredInvites(curPoint);
305− if (storedInvites.length) {
306− setInvites(storedInvites);
308− setInvites(invitePoints.map(p => inviteTemplate(p)));
298+ setInvites(invitePoints.map(p => inviteTemplate(p)));
311 const _authToken = authToken.getOrElse(null);
300 const _authToken = authToken.getOrElse(null);
312 const _contracts = contracts.getOrElse(null);
301 const _contracts = contracts.getOrElse(null);
@@ -332,38 +321,27 @@ export default function useRoller() {
333 const newInvites: Invite[] = [];
322 const newInvites: Invite[] = [];
334 // Iterate over all of the stored invites, generating wallet info as necessary
323 // Iterate over all of the stored invites, generating wallet info as necessary
324+ const storedInvites = getStoredInvites(ls);
335 for (let i = 0; i < invitePlanets.length; i++) {
326 for (let i = 0; i < invitePlanets.length; i++) {
336 setInviteGeneratingNum(i + 1);
327 setInviteGeneratingNum(i + 1);
337 const planet = invitePlanets[i];
328 const planet = invitePlanets[i];
338− const invite = storedInvites.find(hasInvite(planet));
329+ const invite = storedInvites[planet];
340− const start = page * INVITES_PER_PAGE;
341− const end = start + INVITES_PER_PAGE;
343− if (invite) {
331+ if (invite?.ticket) {
344 newInvites.push(invite);
332 newInvites.push(invite);
345− } else if (getAll || (i >= start && i < end)) {
333+ } else if (getAll) {
346 if (isDevelopment) {
334 if (isDevelopment) {
347 console.log('MISSING INVITE INFO', planet);
335 console.log('MISSING INVITE INFO', planet);
349− const { ticket, inviteWallet } = await generateInviteWallet(
337+ const newInvite = await generateInviteInfo(planet, _authToken);
354− newInvites.push(
338+ newInvites.push(newInvite);
358− inviteWallet.ownership.keys.address
362 newInvites.push(inviteTemplate(planet));
340 newInvites.push(inviteTemplate(planet));
366− setStoredInvites(curPoint, newInvites);
344+ setStoredInvites(ls, newInvites);
367 setInvites(newInvites);
345 setInvites(newInvites);
369 return newInvites;
347 return newInvites;
@@ -380,11 +358,28 @@ export default function useRoller() {
380 getDetails,
358 getDetails,
381 pointCursor,
359 pointCursor,
382 invitePoints,
360 invitePoints,
383 setInvites,
362 setInvites,
384 setInviteGeneratingNum,
363 setInviteGeneratingNum,
367+ const showInvite = useCallback(
368+ async (planet: number) => {
369+ const _authToken = authToken.getOrElse(null);
372+ const newInvite = await generateInviteInfo(planet, _authToken);
373+ const newInvites = invites.map(invite =>
374+ invite.planet === planet ? newInvite : invite
376+ setInvites(newInvites);
377+ setStoredInvites(ls, newInvites);
380+ [authToken, invites, ls, setInvites]
388 const getNumInvites = useCallback(
383 const getNumInvites = useCallback(
389 async (isL2: boolean) => {
384 async (isL2: boolean) => {
@@ -400,12 +395,22 @@ export default function useRoller() {
398+ const newPending = await api.getPendingByShip(curPoint);
399+ const pendingSpawns = getPendingSpawns(newPending);
403 const outgoingPoints = getOutgoingPoints(
401 const outgoingPoints = getOutgoingPoints(
404 controlledPoints,
402 controlledPoints,
405 getDetails
403 getDetails
406 ).filter((p: number) => isPlanet(p) && availablePoints.includes(p));
404 ).filter((p: number) => isPlanet(p) && availablePoints.includes(p));
406+ console.log(pendingSpawns, outgoingPoints, invitePoints)
408+ setPendingTransactions(newPending);
408− setInvitePoints(invitePoints.concat(outgoingPoints));
411+ .concat(outgoingPoints)
412+ .filter(p => !pendingSpawns.has(p))
410 } catch (e) {
415 } catch (e) {
411 if (isDevelopment) {
416 if (isDevelopment) {
@@ -416,11 +421,12 @@ export default function useRoller() {
418 pointCursor,
423 pointCursor,
420 authToken,
424 authToken,
421 contracts,
425 contracts,
422 controlledPoints,
426 controlledPoints,
423 getDetails,
427 getDetails,
429+ setPendingTransactions,
@@ -645,12 +651,11 @@ export default function useRoller() {
645 const nextRoll = getTimeToNextBatch(nextBatchTime, new Date().getTime());
651 const nextRoll = getTimeToNextBatch(nextBatchTime, new Date().getTime());
646 setNextRoll(nextRoll);
652 setNextRoll(nextRoll);
648− if (nextBatchTime <= new Date().getTime()) {
654+ if (nextBatchTime - ONE_SECOND <= new Date().getTime()) {
649 api.getRollerConfig().then(response => {
655 api.getRollerConfig().then(response => {
650 setNextBatchTime(response.nextBatch);
656 setNextBatchTime(response.nextBatch);
657+ getNumInvites(currentL2);
653− getInvites(currentL2, 0);
655 }, 1000);
660 }, 1000);
@@ -669,5 +674,7 @@ export default function useRoller() {
669 setProxyAddress,
674 setProxyAddress,
670 configureNetworkingKeys,
675 configureNetworkingKeys,
671 getNumInvites,
676 getNumInvites,