More fixes

This commit is contained in:
Reckless_Satoshi 2023-11-02 14:15:18 +00:00 committed by Reckless_Satoshi
parent 4eb46f1e16
commit 7f78f69df6
20 changed files with 113 additions and 100 deletions

View File

@ -835,7 +835,7 @@ const BookTable = ({
<Grid item xs={6}> <Grid item xs={6}>
<IconButton <IconButton
onClick={() => { onClick={() => {
federation.update(); void federation.update();
}} }}
> >
<Refresh /> <Refresh />

View File

@ -81,7 +81,7 @@ const Map = ({
} }
eventHandlers={{ eventHandlers={{
click: (_event: LeafletMouseEvent) => { click: (_event: LeafletMouseEvent) => {
order?.id && onOrderClicked(order.id); order?.id != null && onOrderClicked(order.id);
}, },
}} }}
> >
@ -111,7 +111,7 @@ const Map = ({
return ( return (
<MarkerClusterGroup showCoverageOnHover={true} disableClusteringAtZoom={14}> <MarkerClusterGroup showCoverageOnHover={true} disableClusteringAtZoom={14}>
{orders.map((order) => { {orders.map((order) => {
if (!order?.latitude || !order?.longitude) return <></>; if (!(order?.latitude != null) || !(order?.longitude != null)) return <></>;
return RobotMarker(order.id, [order.latitude, order.longitude], order.type ?? 0, order); return RobotMarker(order.id, [order.latitude, order.longitude], order.type ?? 0, order);
})} })}
</MarkerClusterGroup> </MarkerClusterGroup>

View File

@ -82,7 +82,9 @@ const TakeButton = ({
}, [orderUpdatedAt, takeAmount, info]); }, [orderUpdatedAt, takeAmount, info]);
const currencyCode: string = const currencyCode: string =
garage.getOrder()?.currency === 1000 ? 'Sats' : currencies[`${garage.getOrder()?.currency}`]; garage.getOrder()?.currency === 1000
? 'Sats'
: currencies[`${Number(garage.getOrder()?.currency)}`];
const InactiveMakerDialog = function (): JSX.Element { const InactiveMakerDialog = function (): JSX.Element {
return ( return (
@ -188,7 +190,7 @@ const TakeButton = ({
}, [takeAmount, orderUpdatedAt]); }, [takeAmount, orderUpdatedAt]);
const takeOrderButton = function (): JSX.Element { const takeOrderButton = function (): JSX.Element {
if (garage.getOrder()?.has_range) { if (garage.getOrder()?.has_range === true) {
return ( return (
<Box <Box
sx={{ sx={{
@ -315,7 +317,7 @@ const TakeButton = ({
}; };
const takeOrder = function (): void { const takeOrder = function (): void {
if (!focusedCoordinator) return; if (!(focusedCoordinator != null)) return;
setLoadingTake(true); setLoadingTake(true);
const { url } = federation const { url } = federation

View File

@ -36,7 +36,7 @@ import { PaymentStringAsIcons } from '../../components/PaymentMethods';
import { FlagWithProps, SendReceiveIcon } from '../Icons'; import { FlagWithProps, SendReceiveIcon } from '../Icons';
import LinearDeterminate from './LinearDeterminate'; import LinearDeterminate from './LinearDeterminate';
import type { Order, Coordinator } from '../../models'; import type Coordinator from '../../models';
import { statusBadgeColor, pn, amountToString, computeSats } from '../../utils'; import { statusBadgeColor, pn, amountToString, computeSats } from '../../utils';
import TakeButton from './TakeButton'; import TakeButton from './TakeButton';
import { F2fMapDialog } from '../Dialogs'; import { F2fMapDialog } from '../Dialogs';
@ -291,7 +291,7 @@ const OrderDetails = ({
/> />
</ListItemAvatar> </ListItemAvatar>
<ListItemText <ListItemText
primary={`${currentOrder.order?.maker_nick} (${ primary={`${String(currentOrder.order?.maker_nick)} (${
currentOrder.order?.type === 1 currentOrder.order?.type === 1
? t(currentOrder.order?.currency === 1000 ? 'Swapping Out' : 'Seller') ? t(currentOrder.order?.currency === 1000 ? 'Swapping Out' : 'Seller')
: t(currentOrder.order?.currency === 1000 ? 'Swapping In' : 'Buyer') : t(currentOrder.order?.currency === 1000 ? 'Swapping In' : 'Buyer')
@ -301,12 +301,15 @@ const OrderDetails = ({
</ListItem> </ListItem>
<Collapse <Collapse
in={currentOrder.order?.is_participant && currentOrder.order?.taker_nick !== 'None'} in={
currentOrder.order?.is_participant === true &&
currentOrder.order?.taker_nick !== 'None'
}
> >
<Divider /> <Divider />
<ListItem> <ListItem>
<ListItemText <ListItemText
primary={`${currentOrder.order?.taker_nick} (${ primary={`${String(currentOrder.order?.taker_nick)} (${
currentOrder.order?.type === 1 currentOrder.order?.type === 1
? t(currentOrder.order?.currency === 1000 ? 'Swapping In' : 'Buyer') ? t(currentOrder.order?.currency === 1000 ? 'Swapping In' : 'Buyer')
: t(currentOrder.order?.currency === 1000 ? 'Swapping Out' : 'Seller') : t(currentOrder.order?.currency === 1000 ? 'Swapping Out' : 'Seller')
@ -422,7 +425,7 @@ const OrderDetails = ({
: t('Accepted payment methods') : t('Accepted payment methods')
} }
/> />
{currentOrder.order?.payment_method.includes('Cash F2F') && ( {currentOrder.order?.payment_method.includes('Cash F2F') === true && (
<ListItemIcon> <ListItemIcon>
<Tooltip enterTouchDelay={0} title={t('F2F location')}> <Tooltip enterTouchDelay={0} title={t('F2F location')}>
<div> <div>
@ -457,14 +460,16 @@ const OrderDetails = ({
/> />
) : null} ) : null}
{currentOrder.order?.price_now === undefined && currentOrder.order?.is_explicit ? ( {currentOrder.order?.price_now === undefined &&
currentOrder.order?.is_explicit === true ? (
<ListItemText <ListItemText
primary={pn(currentOrder.order?.satoshis)} primary={pn(currentOrder.order?.satoshis)}
secondary={t('Amount of Satoshis')} secondary={t('Amount of Satoshis')}
/> />
) : null} ) : null}
{currentOrder.order?.price_now === undefined && !currentOrder.order?.is_explicit ? ( {currentOrder.order?.price_now === undefined &&
!(currentOrder.order?.is_explicit === true) ? (
<ListItemText <ListItemText
primary={`${parseFloat(Number(currentOrder.order?.premium).toFixed(2))}%`} primary={`${parseFloat(Number(currentOrder.order?.premium).toFixed(2))}%`}
secondary={t('Premium over market price')} secondary={t('Premium over market price')}
@ -537,7 +542,7 @@ const OrderDetails = ({
<></> <></>
)} )}
{!currentOrder.order?.is_participant ? ( {!(currentOrder.order?.is_participant === true) ? (
<Grid item xs={12}> <Grid item xs={12}>
<TakeButton <TakeButton
baseUrl={baseUrl} baseUrl={baseUrl}

View File

@ -66,7 +66,7 @@ const RobotAvatar: React.FC<Props> = ({
if (window.NativeRobosats === undefined) { if (window.NativeRobosats === undefined) {
setAvatarSrc(`${baseUrl}${path}${nickname}${small ? '.small' : ''}.webp`); setAvatarSrc(`${baseUrl}${path}${nickname}${small ? '.small' : ''}.webp`);
setNicknameReady(true); setNicknameReady(true);
} else if (focusedCoordinator) { } else if (focusedCoordinator != null) {
setNicknameReady(true); setNicknameReady(true);
const { url } = federation const { url } = federation
.getCoordinator(focusedCoordinator) .getCoordinator(focusedCoordinator)

View File

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useMemo, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { import {
Tooltip, Tooltip,
@ -66,7 +66,7 @@ const RobotInfo: React.FC<Props> = ({ robot, slotIndex, coordinator, onClose }:
}; };
useEffect(() => { useEffect(() => {
handleWebln(); void handleWebln();
}, []); }, []);
const handleWeblnInvoiceClicked = async (e: MouseEvent<HTMLButtonElement, MouseEvent>): void => { const handleWeblnInvoiceClicked = async (e: MouseEvent<HTMLButtonElement, MouseEvent>): void => {
@ -87,10 +87,10 @@ const RobotInfo: React.FC<Props> = ({ robot, slotIndex, coordinator, onClose }:
const robot = garage.getRobot(slotIndex); const robot = garage.getRobot(slotIndex);
if (robot.encPrivKey && robot.token) { if (robot.encPrivKey != null && robot.token != null) {
void signCleartextMessage(rewardInvoice, robot.encPrivKey, robot.token).then( void signCleartextMessage(rewardInvoice, robot.encPrivKey, robot.token).then(
(signedInvoice) => { (signedInvoice) => {
coordinator.fetchReward(signedInvoice, garage, slotIndex).then((data) => { void coordinator.fetchReward(signedInvoice, garage, slotIndex).then((data) => {
setBadInvoice(data.bad_invoice ?? ''); setBadInvoice(data.bad_invoice ?? '');
setShowRewardsSpinner(false); setShowRewardsSpinner(false);
setWithdrawn(data.successful_withdrawal); setWithdrawn(data.successful_withdrawal);
@ -103,7 +103,7 @@ const RobotInfo: React.FC<Props> = ({ robot, slotIndex, coordinator, onClose }:
}; };
const setStealthInvoice = (wantsStealth: boolean): void => { const setStealthInvoice = (wantsStealth: boolean): void => {
coordinator.fetchStealth(wantsStealth, garage, slotIndex); void coordinator.fetchStealth(wantsStealth, garage, slotIndex);
}; };
return ( return (

View File

@ -22,12 +22,13 @@ const CancelButton = ({
const { t } = useTranslation(); const { t } = useTranslation();
const showCancelButton = const showCancelButton =
(order?.is_maker && [0, 1, 2].includes(order?.status)) || (order?.is_maker === true && [0, 1, 2].includes(order?.status)) ??
[3, 6, 7].includes(order?.status ?? -1); [3, 6, 7].includes(order?.status ?? -1);
const showCollabCancelButton = [8, 9].includes(order?.status ?? -1) && !order?.asked_for_cancel; const showCollabCancelButton =
[8, 9].includes(order?.status ?? -1) && !(order?.asked_for_cancel === true);
const noConfirmation = const noConfirmation =
(order?.is_maker && [0, 1, 2].includes(order?.status ?? -1)) || (order?.is_maker === true && [0, 1, 2].includes(order?.status ?? -1)) ??
(order?.is_taker && order?.status === 3); (order?.is_taker === true && order?.status === 3);
return ( return (
<Box> <Box>

View File

@ -10,11 +10,11 @@ interface CollabCancelAlertProps {
const CollabCancelAlert = ({ order }: CollabCancelAlertProps): JSX.Element => { const CollabCancelAlert = ({ order }: CollabCancelAlertProps): JSX.Element => {
const { t } = useTranslation(); const { t } = useTranslation();
let text = ''; let text = '';
if (order?.pending_cancel) { if (order?.pending_cancel === true) {
text = t('{{nickname}} is asking for a collaborative cancel', { text = t('{{nickname}} is asking for a collaborative cancel', {
nickname: order?.is_maker ? order?.taker_nick : order?.maker_nick, nickname: order?.is_maker ? order?.taker_nick : order?.maker_nick,
}); });
} else if (order?.asked_for_cancel) { } else if (order?.asked_for_cancel === true) {
text = t('You asked for a collaborative cancellation'); text = t('You asked for a collaborative cancellation');
} }

View File

@ -8,7 +8,6 @@ import {
DialogContentText, DialogContentText,
Button, Button,
} from '@mui/material'; } from '@mui/material';
import { type Order } from '../../../models';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
interface ConfirmUndoFiatSentDialogProps { interface ConfirmUndoFiatSentDialogProps {

View File

@ -1,10 +1,11 @@
import React, { useEffect, useLayoutEffect, useState } from 'react'; import React, { useEffect, useLayoutEffect, useState, useContext } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Button, TextField, Grid, Paper, Typography } from '@mui/material'; import { Button, TextField, Grid, Paper, Typography } from '@mui/material';
import { encryptMessage, decryptMessage } from '../../../../pgp'; import { encryptMessage, decryptMessage } from '../../../../pgp';
import { AuditPGPDialog } from '../../../Dialogs'; import { AuditPGPDialog } from '../../../Dialogs';
import { websocketClient, type WebsocketConnection } from '../../../../services/Websocket'; import { websocketClient, type WebsocketConnection } from '../../../../services/Websocket';
import { type Robot } from '../../../../models'; import { type Robot } from '../../../../models';
import { GarageContext, type UseGarageStoreType } from '../../../../contexts/GarageContext';
// Icons // Icons
import CircularProgress from '@mui/material/CircularProgress'; import CircularProgress from '@mui/material/CircularProgress';

View File

@ -58,6 +58,7 @@ interface loadingButtonsProps {
cancel: boolean; cancel: boolean;
fiatSent: boolean; fiatSent: boolean;
fiatReceived: boolean; fiatReceived: boolean;
undoFiatSent: boolean;
submitInvoice: boolean; submitInvoice: boolean;
submitAddress: boolean; submitAddress: boolean;
submitStatement: boolean; submitStatement: boolean;
@ -70,6 +71,7 @@ const noLoadingButtons: loadingButtonsProps = {
cancel: false, cancel: false,
fiatSent: false, fiatSent: false,
fiatReceived: false, fiatReceived: false,
undoFiatSent: false,
submitInvoice: false, submitInvoice: false,
submitAddress: false, submitAddress: false,
submitStatement: false, submitStatement: false,
@ -167,7 +169,7 @@ const TradeBox = ({
void apiClient void apiClient
.post( .post(
url, url,
`/api/order/?order_id=${currentOrder.id}`, `/api/order/?order_id=${Number(currentOrder.id)}`,
{ {
action, action,
invoice, invoice,
@ -234,7 +236,7 @@ const TradeBox = ({
const updateInvoice = function (invoice: string): void { const updateInvoice = function (invoice: string): void {
const robot = garage.getRobot(); const robot = garage.getRobot();
if (robot !== null && robot.encPrivKey && robot.token) { if (robot?.encPrivKey != null && robot?.token != null) {
setLoadingButtons({ ...noLoadingButtons, submitInvoice: true }); setLoadingButtons({ ...noLoadingButtons, submitInvoice: true });
void signCleartextMessage(invoice, robot.encPrivKey, robot.token).then((signedInvoice) => { void signCleartextMessage(invoice, robot.encPrivKey, robot.token).then((signedInvoice) => {
submitAction({ submitAction({
@ -249,7 +251,7 @@ const TradeBox = ({
const updateAddress = function (): void { const updateAddress = function (): void {
const robot = garage.getRobot(); const robot = garage.getRobot();
if (robot !== null && robot.encPrivKey && robot.token) { if (robot?.encPrivKey != null && robot?.token != null) {
setLoadingButtons({ ...noLoadingButtons, submitAddress: true }); setLoadingButtons({ ...noLoadingButtons, submitAddress: true });
void signCleartextMessage(onchain.address, robot.encPrivKey, robot.token).then( void signCleartextMessage(onchain.address, robot.encPrivKey, robot.token).then(
(signedAddress) => { (signedAddress) => {
@ -287,6 +289,7 @@ const TradeBox = ({
}); });
// If Webln implements locked payments compatibility, this logic might be simplier // If Webln implements locked payments compatibility, this logic might be simplier
if (webln === undefined) { if (webln === undefined) {
console.log('WebLN dialog will not be shown');
} else if (order.is_maker && order.status === 0) { } else if (order.is_maker && order.status === 0) {
webln.sendPayment(order.bond_invoice); webln.sendPayment(order.bond_invoice);
setWaitingWebln(true); setWaitingWebln(true);
@ -324,7 +327,7 @@ const TradeBox = ({
useEffect(() => { useEffect(() => {
if (currentOrder.order !== null && currentOrder.order.status !== lastOrderStatus) { if (currentOrder.order !== null && currentOrder.order.status !== lastOrderStatus) {
setLastOrderStatus(currentOrder.order.status); setLastOrderStatus(currentOrder.order.status);
handleWebln(currentOrder.order); void handleWebln(currentOrder.order);
} }
// FIXME this should trigger with current order, not garage order // FIXME this should trigger with current order, not garage order
}, [orderUpdatedAt]); }, [orderUpdatedAt]);

View File

@ -16,27 +16,29 @@ import { AppContext, type UseAppStoreType } from './AppContext';
import { GarageContext, type UseGarageStoreType } from './GarageContext'; import { GarageContext, type UseGarageStoreType } from './GarageContext';
// Refresh delays (ms) according to Order status // Refresh delays (ms) according to Order status
const statusToDelay = [
3000, // 'Waiting for maker bond' // FIXME statusToDelay is never used. On order received, we should setDelay according to new received status.
35000, // 'Public' // const statusToDelay = [
180000, // 'Paused' // 3000, // 'Waiting for maker bond'
3000, // 'Waiting for taker bond' // 35000, // 'Public'
999999, // 'Cancelled' // 180000, // 'Paused'
999999, // 'Expired' // 3000, // 'Waiting for taker bond'
8000, // 'Waiting for trade collateral and buyer invoice' // 999999, // 'Cancelled'
8000, // 'Waiting only for seller trade collateral' // 999999, // 'Expired'
8000, // 'Waiting only for buyer invoice' // 8000, // 'Waiting for trade collateral and buyer invoice'
10000, // 'Sending fiat - In chatroom' // 8000, // 'Waiting only for seller trade collateral'
10000, // 'Fiat sent - In chatroom' // 8000, // 'Waiting only for buyer invoice'
100000, // 'In dispute' // 10000, // 'Sending fiat - In chatroom'
999999, // 'Collaboratively cancelled' // 10000, // 'Fiat sent - In chatroom'
10000, // 'Sending satoshis to buyer' // 100000, // 'In dispute'
60000, // 'Sucessful trade' // 999999, // 'Collaboratively cancelled'
30000, // 'Failed lightning network routing' // 10000, // 'Sending satoshis to buyer'
300000, // 'Wait for dispute resolution' // 60000, // 'Sucessful trade'
300000, // 'Maker lost dispute' // 30000, // 'Failed lightning network routing'
300000, // 'Taker lost dispute' // 300000, // 'Wait for dispute resolution'
]; // 300000, // 'Maker lost dispute'
// 300000, // 'Taker lost dispute'
// ];
export interface fetchRobotProps { export interface fetchRobotProps {
coordinator?: Coordinator; coordinator?: Coordinator;
@ -128,14 +130,14 @@ export const useFederationStore = (): UseFederationStoreType => {
newFed.registerHook('onCoordinatorUpdate', () => { newFed.registerHook('onCoordinatorUpdate', () => {
setFederationUpdatedAt(new Date().toISOString()); setFederationUpdatedAt(new Date().toISOString());
}); });
newFed.start(origin, settings, hostUrl); void newFed.start(origin, settings, hostUrl);
return newFed; return newFed;
}); });
}, [settings.network, torStatus]); }, [settings.network, torStatus]);
const fetchCurrentOrder = () => { const fetchCurrentOrder = (): void => {
if (currentOrder.id != null && (page === 'order' || badOrder === undefined)) { if (currentOrder.id != null && (page === 'order' || badOrder === undefined)) {
federation.fetchOrder(currentOrder, garage.getRobot()); void federation.fetchOrder(currentOrder, garage.getRobot());
} }
}; };
@ -157,14 +159,14 @@ export const useFederationStore = (): UseFederationStoreType => {
if (robot !== null) { if (robot !== null) {
if (open.profile && robot?.avatarLoaded) { if (open.profile && robot?.avatarLoaded) {
federation.fetchRobot(garage, garage.currentSlot); // refresh/update existing robot void federation.fetchRobot(garage, garage.currentSlot); // refresh/update existing robot
} else if ( } else if (
!robot.avatarLoaded && !robot.avatarLoaded &&
robot.token !== undefined && robot.token !== undefined &&
robot.encPrivKey !== undefined && robot.encPrivKey !== undefined &&
robot.pubKey !== undefined robot.pubKey !== undefined
) { ) {
federation.fetchRobot(garage, garage.currentSlot); // create new robot with existing token and keys (on network and coordinator change) void federation.fetchRobot(garage, garage.currentSlot); // create new robot with existing token and keys (on network and coordinator change)
} }
} }
}, [open.profile, hostUrl, robotUpdatedAt]); }, [open.profile, hostUrl, robotUpdatedAt]);

View File

@ -1,4 +1,3 @@
import { sha256 } from 'js-sha256';
import { import {
type Robot, type Robot,
type LimitList, type LimitList,
@ -8,9 +7,8 @@ import {
type Garage, type Garage,
} from '.'; } from '.';
import { apiClient } from '../services/api'; import { apiClient } from '../services/api';
import { hexToBase91, validateTokenEntropy } from '../utils'; import { validateTokenEntropy } from '../utils';
import { compareUpdateLimit } from './Limit.model'; import { compareUpdateLimit } from './Limit.model';
import { signCleartextMessage } from '../pgp';
export interface Contact { export interface Contact {
nostr?: string | undefined; nostr?: string | undefined;
@ -132,7 +130,7 @@ export class Coordinator {
hostUrl: string, hostUrl: string,
onStarted: (shortAlias: string) => void = () => {}, onStarted: (shortAlias: string) => void = () => {},
): Promise<void> => { ): Promise<void> => {
if (!this.enabled) return; if (this.enabled !== true) return;
if (settings.selfhostedClient && this.shortAlias !== 'local') { if (settings.selfhostedClient && this.shortAlias !== 'local') {
this.url = hostUrl; this.url = hostUrl;
@ -142,13 +140,13 @@ export class Coordinator {
this.basePath = ''; this.basePath = '';
} }
this.update(() => { void this.update(() => {
onStarted(this.shortAlias); onStarted(this.shortAlias);
}); });
}; };
update = async (onUpdate: (shortAlias: string) => void = () => {}): Promise<void> => { update = async (onUpdate: (shortAlias: string) => void = () => {}): Promise<void> => {
const onDataLoad = () => { const onDataLoad = (): void => {
if (this.isUpdated()) onUpdate(this.shortAlias); if (this.isUpdated()) onUpdate(this.shortAlias);
}; };
@ -157,7 +155,7 @@ export class Coordinator {
this.loadInfo(onDataLoad); this.loadInfo(onDataLoad);
}; };
loadBook = (onDataLoad: () => void = () => {}) => { loadBook = (onDataLoad: () => void = () => {}): void => {
if (this.loadingBook) return; if (this.loadingBook) return;
this.loadingBook = true; this.loadingBook = true;
@ -181,7 +179,7 @@ export class Coordinator {
}); });
}; };
loadLimits = (onDataLoad: () => void = () => {}) => { loadLimits = (onDataLoad: () => void = () => {}): void => {
if (this.loadingLimits) return; if (this.loadingLimits) return;
this.loadingLimits = true; this.loadingLimits = true;
@ -208,7 +206,7 @@ export class Coordinator {
}); });
}; };
loadInfo = (onDataLoad: () => void = () => {}) => { loadInfo = (onDataLoad: () => void = () => {}): void => {
if (this.loadingInfo) return; if (this.loadingInfo) return;
this.loadingInfo = true; this.loadingInfo = true;
@ -227,25 +225,25 @@ export class Coordinator {
}); });
}; };
enable = (onEnabled: () => void = () => {}) => { enable = (onEnabled: () => void = () => {}): void => {
this.enabled = true; this.enabled = true;
this.update(() => { void this.update(() => {
onEnabled(); onEnabled();
}); });
}; };
disable = () => { disable = (): void => {
this.enabled = false; this.enabled = false;
this.info = undefined; this.info = undefined;
this.limits = {}; this.limits = {};
this.book = []; this.book = [];
}; };
isUpdated = () => { isUpdated = (): boolean => {
return !((this.loadingBook === this.loadingInfo) === this.loadingLimits); return !((this.loadingBook === this.loadingInfo) === this.loadingLimits);
}; };
getBaseUrl = () => { getBaseUrl = (): string => {
return this.url + this.basePath; return this.url + this.basePath;
}; };
@ -265,7 +263,7 @@ export class Coordinator {
fecthRobot = async (garage: Garage, index: number): Promise<Robot | null> => { fecthRobot = async (garage: Garage, index: number): Promise<Robot | null> => {
const robot = garage?.getRobot(index); const robot = garage?.getRobot(index);
if (!robot?.token) return null; if (robot?.token == null) return null;
const authHeaders = robot.getAuthHeaders(); const authHeaders = robot.getAuthHeaders();
@ -313,7 +311,7 @@ export class Coordinator {
}; };
fetchOrder = async (orderId: number, robot: Robot): Promise<Order | null> => { fetchOrder = async (orderId: number, robot: Robot): Promise<Order | null> => {
if (!robot.token) return null; if (!(robot.token != null)) return null;
const authHeaders = robot.getAuthHeaders(); const authHeaders = robot.getAuthHeaders();
@ -340,7 +338,7 @@ export class Coordinator {
}> => { }> => {
const robot = garage.getRobot(index); const robot = garage.getRobot(index);
if (!robot?.token || !robot.encPrivKey) return null; if (!(robot?.token != null) || !(robot.encPrivKey != null)) return null;
const data = await apiClient.post( const data = await apiClient.post(
this.url, this.url,
@ -352,7 +350,7 @@ export class Coordinator {
); );
const newRobot = { const newRobot = {
...robot, ...robot,
earnedRewards: data?.successful_withdrawal ? 0 : robot.earnedRewards, earnedRewards: data?.successful_withdrawal === true ? 0 : robot.earnedRewards,
}; };
garage.updateRobot(newRobot, index); garage.updateRobot(newRobot, index);
@ -362,7 +360,7 @@ export class Coordinator {
fetchStealth = async (wantsStealth: boolean, garage: Garage, index: number): Promise<null> => { fetchStealth = async (wantsStealth: boolean, garage: Garage, index: number): Promise<null> => {
const robot = garage?.getRobot(index); const robot = garage?.getRobot(index);
if (!robot?.token || !robot.encPrivKey) return null; if (!(robot?.token != null) || !(robot.encPrivKey != null)) return null;
await apiClient.post( await apiClient.post(
this.url, this.url,

View File

@ -45,7 +45,7 @@ export const updateExchangeInfo = (federation: Federation): ExchangeInfo => {
highestVersion = getHigherVer(highestVersion, coordinator.info.version); highestVersion = getHigherVer(highestVersion, coordinator.info.version);
aggregations.forEach((key: any) => { aggregations.forEach((key: any) => {
info[key] = info[key] + Number(coordinator.info[key]); info[key] = Number(info[key]) + Number(coordinator.info[key]);
}); });
} }
return null; return null;

View File

@ -53,7 +53,7 @@ export class Federation {
}); });
}; };
onCoordinatorSaved = (shortAlias: string) => { onCoordinatorSaved = (shortAlias: string): void => {
this.book = [...this.book, ...this.getCoordinator(shortAlias).book]; this.book = [...this.book, ...this.getCoordinator(shortAlias).book];
this.loading = false; this.loading = false;
this.triggerHook('onCoordinatorUpdate'); this.triggerHook('onCoordinatorUpdate');
@ -64,46 +64,48 @@ export class Federation {
}; };
// Setup // Setup
start = (origin: Origin, settings: Settings, hostUrl: string): void => { start = async (origin: Origin, settings: Settings, hostUrl: string): Promise<void> => {
const onCoordinatorStarted = (shortAlias: string) => { const onCoordinatorStarted = (shortAlias: string): void => {
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1; this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
this.onCoordinatorSaved(shortAlias); this.onCoordinatorSaved(shortAlias);
}; };
this.loading = true; this.loading = true;
Object.values(this.coordinators).forEach(async (coor) => { // Object.values(this.coordinators).forEach(async (coor) => {
for (const coor of Object.values(this.coordinators)) {
await coor.start(origin, settings, hostUrl, onCoordinatorStarted); await coor.start(origin, settings, hostUrl, onCoordinatorStarted);
}); }
}; };
update = (): void => { update = async (): Promise<void> => {
this.loading = false; this.loading = false;
Object.values(this.coordinators).forEach(async (coor) => { // Object.values(this.coordinators).forEach(async (coor) => {
for (const coor of Object.values(this.coordinators)) {
await coor.update(() => { await coor.update(() => {
this.onCoordinatorSaved(coor.shortAlias); this.onCoordinatorSaved(coor.shortAlias);
}); });
}); }
}; };
updateExchange = () => { updateExchange = (): void => {
this.exchange.info = updateExchangeInfo(this); this.exchange.info = updateExchangeInfo(this);
}; };
// Fetchs // Fetchs
fetchRobot = async (garage: Garage, slot: number): Promise<void> => { fetchRobot = async (garage: Garage, slot: number): Promise<void> => {
Object.values(this.coordinators).forEach((coor) => { Object.values(this.coordinators).forEach((coor) => {
coor.fecthRobot(garage, slot); void coor.fecthRobot(garage, slot);
}); });
}; };
fetchOrder = async (currentOrder: CurrentOrder, robot: Robot): Promise<CurrentOrder | null> => { fetchOrder = async (currentOrder: CurrentOrder, robot: Robot): Promise<CurrentOrder | null> => {
if (currentOrder.shortAlias !== null) { if (currentOrder.shortAlias !== null) {
const coordinator = this.coordinators[currentOrder.shortAlias]; const coordinator = this.coordinators[currentOrder.shortAlias];
if (coordinator && currentOrder.id !== null) { if (coordinator != null && currentOrder.id !== null) {
const newOrber = await coordinator.fetchOrder(currentOrder.id, robot); const newOrder = await coordinator.fetchOrder(currentOrder.id, robot);
return { return {
...currentOrder, ...currentOrder,
order: newOrber, order: newOrder,
}; };
} }
} }
@ -115,12 +117,12 @@ export class Federation {
return this.coordinators[shortAlias]; return this.coordinators[shortAlias];
}; };
disableCoordinator = (shortAlias: string) => { disableCoordinator = (shortAlias: string): void => {
this.coordinators[shortAlias].disable(); this.coordinators[shortAlias].disable();
this.triggerHook('onCoordinatorUpdate'); this.triggerHook('onCoordinatorUpdate');
}; };
enableCoordinator = (shortAlias: string) => { enableCoordinator = (shortAlias: string): void => {
this.coordinators[shortAlias].enable(() => { this.coordinators[shortAlias].enable(() => {
this.triggerHook('onCoordinatorUpdate'); this.triggerHook('onCoordinatorUpdate');
}); });

View File

@ -93,7 +93,7 @@ class Garage {
index = this.currentSlot, index = this.currentSlot,
) => { ) => {
const robot = this.getSlot(index).robot; const robot = this.getSlot(index).robot;
if (robot) { if (robot != null) {
robot.update(attributes); robot.update(attributes);
this.triggerHook('onRobotUpdate'); this.triggerHook('onRobotUpdate');
this.save(); this.save();

View File

@ -1,5 +1,5 @@
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import { hexToBase91, validateTokenEntropy } from '../utils'; import { hexToBase91 } from '../utils';
interface AuthHeaders { interface AuthHeaders {
tokenSHA256: string; tokenSHA256: string;
@ -14,7 +14,7 @@ class Robot {
if (garageRobot != null) { if (garageRobot != null) {
this.token = garageRobot?.token ?? undefined; this.token = garageRobot?.token ?? undefined;
this.tokenSHA256 = this.tokenSHA256 =
garageRobot?.tokenSHA256 ?? (this.token ? hexToBase91(sha256(this.token)) : ''); garageRobot?.tokenSHA256 ?? (this.token != null ? hexToBase91(sha256(this.token)) : '');
this.pubKey = garageRobot?.pubKey ?? undefined; this.pubKey = garageRobot?.pubKey ?? undefined;
this.encPrivKey = garageRobot?.encPrivKey ?? undefined; this.encPrivKey = garageRobot?.encPrivKey ?? undefined;
} }
@ -40,7 +40,7 @@ class Robot {
public copiedToken: boolean = false; public copiedToken: boolean = false;
public avatarLoaded: boolean = false; public avatarLoaded: boolean = false;
update = (attributes: Record<string, any>) => { update = (attributes: Record<string, any>): void => {
Object.assign(this, attributes); Object.assign(this, attributes);
}; };

View File

@ -44,7 +44,7 @@ const BookWidget = React.forwardRef(function Component(
/> />
</Paper> </Paper>
); );
}, [book, layout, windowSize, fav]); }, [layout, windowSize, fav, federation.book]);
}); });
export default BookWidget; export default BookWidget;

View File

@ -40,7 +40,7 @@ const DepthChartWidget = React.forwardRef(function Component(
/> />
</Paper> </Paper>
); );
}, [fav.currency, book, limits, exchange, layout]); }, [fav.currency, layout, federation.exchange]);
}); });
export default DepthChartWidget; export default DepthChartWidget;

View File

@ -27,7 +27,7 @@ const MakerWidget = React.forwardRef(function Component(
<MakerForm /> <MakerForm />
</Paper> </Paper>
); );
}, [maker, limits, fav]); }, [maker, fav, federation]);
}); });
export default MakerWidget; export default MakerWidget;