Frontend eslint fixes

This commit is contained in:
koalasat 2024-10-19 15:57:20 +02:00
parent 1cc79890cd
commit 3f882db902
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
28 changed files with 93 additions and 91 deletions

View File

@ -1,7 +1,7 @@
import React, { StrictMode, Suspense } from 'react'; import React, { StrictMode, Suspense } from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import Main from './basic/Main'; import Main from './basic/Main';
import { CssBaseline, Grid } from '@mui/material'; import { CssBaseline } from '@mui/material';
import HostAlert from './components/HostAlert'; import HostAlert from './components/HostAlert';
import TorConnectionBadge from './components/TorConnection'; import TorConnectionBadge from './components/TorConnection';
@ -16,7 +16,7 @@ import { FederationContextProvider } from './contexts/FederationContext';
import NotificationSwitchBadge from './components/NotificationSwitch'; import NotificationSwitchBadge from './components/NotificationSwitch';
const App = (): JSX.Element => { const App = (): JSX.Element => {
const [client, _view] = window.RobosatsSettings.split('-'); const [client] = window.RobosatsSettings.split('-');
return ( return (
<StrictMode> <StrictMode>
<ErrorBoundary> <ErrorBoundary>

View File

@ -12,7 +12,7 @@ import { GarageContext, type UseGarageStoreType } from '../contexts/GarageContex
import Routes from './Routes'; import Routes from './Routes';
const getRouter = (): any => { const getRouter = (): any => {
const [client, _view] = window.RobosatsSettings.split('-'); const [client] = window.RobosatsSettings.split('-');
if (client === 'web') { if (client === 'web') {
return BrowserRouter; return BrowserRouter;
} else if (client === 'desktop') { } else if (client === 'desktop') {

View File

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useMemo, useState } from 'react'; import React, { useContext, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Grid, Paper, Collapse, Typography } from '@mui/material'; import { Grid, Paper, Collapse, Typography } from '@mui/material';
@ -13,7 +13,7 @@ import { FederationContext, type UseFederationStoreType } from '../../contexts/F
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext'; import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
const MakerPage = (): JSX.Element => { const MakerPage = (): JSX.Element => {
const { fav, windowSize, navbarHeight, page } = useContext<UseAppStoreType>(AppContext); const { fav, windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
const { federation } = useContext<UseFederationStoreType>(FederationContext); const { federation } = useContext<UseFederationStoreType>(FederationContext);
const { garage, maker } = useContext<UseGarageStoreType>(GarageContext); const { garage, maker } = useContext<UseGarageStoreType>(GarageContext);
const { t } = useTranslation(); const { t } = useTranslation();

View File

@ -23,7 +23,7 @@ import { genBase62Token } from '../../utils';
import { NewTabIcon } from '../../components/Icons'; import { NewTabIcon } from '../../components/Icons';
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext'; import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
import { UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
interface OnboardingProps { interface OnboardingProps {
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void; setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;

View File

@ -13,8 +13,7 @@ import {
useTheme, useTheme,
type SelectChangeEvent, type SelectChangeEvent,
} from '@mui/material'; } from '@mui/material';
import { Key } from '@mui/icons-material'; import { Key, Bolt, Add, DeleteSweep, Download } from '@mui/icons-material';
import { Bolt, Add, DeleteSweep, Download } from '@mui/icons-material';
import RobotAvatar from '../../components/RobotAvatar'; import RobotAvatar from '../../components/RobotAvatar';
import TokenInput from './TokenInput'; import TokenInput from './TokenInput';
import { type Slot, type Robot } from '../../models'; import { type Slot, type Robot } from '../../models';
@ -22,7 +21,7 @@ import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
import { genBase62Token } from '../../utils'; import { genBase62Token } from '../../utils';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext'; import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
import { UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
interface RobotProfileProps { interface RobotProfileProps {
robot: Robot; robot: Robot;

View File

@ -4,10 +4,10 @@ import { Box, Button, Grid, Typography, useTheme } from '@mui/material';
import { RoboSatsTextIcon } from '../../components/Icons'; import { RoboSatsTextIcon } from '../../components/Icons';
import { FastForward, RocketLaunch, Key } from '@mui/icons-material'; import { FastForward, RocketLaunch, Key } from '@mui/icons-material';
import { genBase62Token } from '../../utils'; import { genBase62Token } from '../../utils';
import { UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
import { UseGarageStoreType, GarageContext } from '../../contexts/GarageContext'; import { type UseGarageStoreType, GarageContext } from '../../contexts/GarageContext';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext'; import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
interface WelcomeProps { interface WelcomeProps {
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void; setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;

View File

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useState } from 'react';
import { Box, Button, Grid, List, ListItem, Paper, TextField, Typography } from '@mui/material'; import { Box, Button, Grid, List, ListItem, Paper, TextField, Typography } from '@mui/material';
import SettingsForm from '../../components/SettingsForm'; import SettingsForm from '../../components/SettingsForm';
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
@ -8,7 +8,7 @@ import { FederationContext, type UseFederationStoreType } from '../../contexts/F
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext'; import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
const SettingsPage = (): JSX.Element => { const SettingsPage = (): JSX.Element => {
const { windowSize, navbarHeight, page } = useContext<UseAppStoreType>(AppContext); const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
const { federation, addNewCoordinator } = useContext<UseFederationStoreType>(FederationContext); const { federation, addNewCoordinator } = useContext<UseFederationStoreType>(FederationContext);
const { garage } = useContext<UseGarageStoreType>(GarageContext); const { garage } = useContext<UseGarageStoreType>(GarageContext);
const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3; const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3;

View File

@ -581,9 +581,10 @@ const BookTable = ({
width: width * fontSize, width: width * fontSize,
renderCell: (params: any) => { renderCell: (params: any) => {
const coordinator = federation.getCoordinator(params.row.coordinatorShortAlias); const coordinator = federation.getCoordinator(params.row.coordinatorShortAlias);
const amount = Boolean(params.row.has_range) const amount =
? parseFloat(params.row.max_amount) params.row.has_range === true
: parseFloat(params.row.amount); ? parseFloat(params.row.max_amount)
: parseFloat(params.row.amount);
const premium = parseFloat(params.row.premium); const premium = parseFloat(params.row.premium);
const price = const price =
(coordinator.limits[params.row.currency.toString()]?.price ?? 1) * (1 + premium / 100); (coordinator.limits[params.row.currency.toString()]?.price ?? 1) * (1 + premium / 100);

View File

@ -68,9 +68,9 @@ import {
} from '../Icons'; } from '../Icons';
import { AppContext } from '../../contexts/AppContext'; import { AppContext } from '../../contexts/AppContext';
import { systemClient } from '../../services/System'; import { systemClient } from '../../services/System';
import Coordinator, { type Badges } from '../../models/Coordinator.model'; import type Coordinator from '../../models/Coordinator.model';
import { type Badges } from '../../models/Coordinator.model';
import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
import { width } from '@mui/system';
interface Props { interface Props {
open: boolean; open: boolean;

View File

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
@ -34,7 +34,7 @@ interface Props {
const ExchangeDialog = ({ open = false, onClose }: Props): JSX.Element => { const ExchangeDialog = ({ open = false, onClose }: Props): JSX.Element => {
const { t } = useTranslation(); const { t } = useTranslation();
const { federation, federationUpdatedAt } = useContext(FederationContext); const { federation } = useContext(FederationContext);
return ( return (
<Dialog open={open} onClose={onClose}> <Dialog open={open} onClose={onClose}>

View File

@ -3,9 +3,9 @@ import { useTranslation } from 'react-i18next';
import { Dialog, DialogContent, Typography, Button, Grid } from '@mui/material'; import { Dialog, DialogContent, Typography, Button, Grid } from '@mui/material';
import TokenInput from '../../basic/RobotPage/TokenInput'; import TokenInput from '../../basic/RobotPage/TokenInput';
import Key from '@mui/icons-material/Key'; import Key from '@mui/icons-material/Key';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext'; import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
import { UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
import { UseGarageStoreType, GarageContext } from '../../contexts/GarageContext'; import { type UseGarageStoreType, GarageContext } from '../../contexts/GarageContext';
interface Props { interface Props {
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void; setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;
@ -24,7 +24,7 @@ const RecoveryDialog = ({ setInputToken, setView }: Props): JSX.Element => {
setRecoveryToken(''); setRecoveryToken('');
}, [open.recovery]); }, [open.recovery]);
const onClickRecover = () => { const onClickRecover = (): void => {
garage.createRobot(federation, recoveryToken); garage.createRobot(federation, recoveryToken);
setInputToken(recoveryToken.trim()); setInputToken(recoveryToken.trim());
setView('profile'); setView('profile');

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState, useContext, useMemo } from 'react'; import React, { useCallback, useEffect, useState, useContext } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Box, useTheme, Checkbox, CircularProgress, Typography, Grid } from '@mui/material'; import { Box, useTheme, Checkbox, CircularProgress, Typography, Grid } from '@mui/material';
import { DataGrid, type GridColDef, type GridValidRowModel } from '@mui/x-data-grid'; import { DataGrid, type GridColDef, type GridValidRowModel } from '@mui/x-data-grid';
@ -22,7 +22,7 @@ const FederationTable = ({
}: FederationTableProps): JSX.Element => { }: FederationTableProps): JSX.Element => {
const { t } = useTranslation(); const { t } = useTranslation();
const { federation, federationUpdatedAt } = useContext<UseFederationStoreType>(FederationContext); const { federation, federationUpdatedAt } = useContext<UseFederationStoreType>(FederationContext);
const { setOpen, settings } = useContext<UseAppStoreType>(AppContext); const { setOpen } = useContext<UseAppStoreType>(AppContext);
const theme = useTheme(); const theme = useTheme();
const [pageSize, setPageSize] = useState<number>(0); const [pageSize, setPageSize] = useState<number>(0);

View File

@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { Box, CircularProgress, useTheme } from '@mui/material'; import { Box, CircularProgress, useTheme } from '@mui/material';
import { NotificationsActive, NotificationsOff } from '@mui/icons-material'; import { NotificationsActive, NotificationsOff } from '@mui/icons-material';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
import { systemClient } from '../../services/System'; import { systemClient } from '../../services/System';
const NotificationSwitchBadge = (): JSX.Element => { const NotificationSwitchBadge = (): JSX.Element => {
@ -14,7 +14,7 @@ const NotificationSwitchBadge = (): JSX.Element => {
setStopNotifications(settings.stopNotifications); setStopNotifications(settings.stopNotifications);
}, [settings.stopNotifications]); }, [settings.stopNotifications]);
const onClick = () => { const onClick = (): void => {
if (torStatus === 'ON' || !settings.useProxy) { if (torStatus === 'ON' || !settings.useProxy) {
setSettings({ ...settings, stopNotifications: !settings.stopNotifications }); setSettings({ ...settings, stopNotifications: !settings.stopNotifications });
systemClient.setItem('settings_stop_notifications', String(!settings.stopNotifications)); systemClient.setItem('settings_stop_notifications', String(!settings.stopNotifications));

View File

@ -23,16 +23,12 @@ import {
DarkMode, DarkMode,
SettingsOverscan, SettingsOverscan,
Link, Link,
AttachMoney,
QrCode, QrCode,
SettingsInputAntenna, SettingsInputAntenna,
Dns,
} from '@mui/icons-material'; } from '@mui/icons-material';
import { systemClient } from '../../services/System'; import { systemClient } from '../../services/System';
import { TorIcon } from '../Icons'; import { TorIcon } from '../Icons';
import SwapCalls from '@mui/icons-material/SwapCalls';
import { apiClient } from '../../services/api'; import { apiClient } from '../../services/api';
import Nostr from '../Icons/Nostr';
interface SettingsFormProps { interface SettingsFormProps {
dense?: boolean; dense?: boolean;

View File

@ -2,7 +2,7 @@ import React, { useContext } from 'react';
import { Box, CircularProgress, Tooltip } from '@mui/material'; import { Box, CircularProgress, Tooltip } from '@mui/material';
import { TorIcon } from '../Icons'; import { TorIcon } from '../Icons';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
interface TorIndicatorProps { interface TorIndicatorProps {
color: 'inherit' | 'error' | 'warning' | 'success' | 'primary' | 'secondary' | 'info' | undefined; color: 'inherit' | 'error' | 'warning' | 'success' | 'primary' | 'secondary' | 'info' | undefined;

View File

@ -33,7 +33,7 @@ import { apiClient } from '../../../services/api';
import { systemClient } from '../../../services/System'; import { systemClient } from '../../../services/System';
import lnproxies from '../../../../static/lnproxies.json'; import lnproxies from '../../../../static/lnproxies.json';
import { UseAppStoreType, AppContext } from '../../../contexts/AppContext'; import { type UseAppStoreType, AppContext } from '../../../contexts/AppContext';
let filteredProxies: Array<Record<string, any>> = []; let filteredProxies: Array<Record<string, any>> = [];
export interface LightningForm { export interface LightningForm {
invoice: string; invoice: string;

View File

@ -37,7 +37,7 @@ import {
} from '../Icons'; } from '../Icons';
import { type TradeCoordinatorSummary, type TradeRobotSummary } from '../../models/Order.model'; import { type TradeCoordinatorSummary, type TradeRobotSummary } from '../../models/Order.model';
import { systemClient } from '../../services/System'; import { systemClient } from '../../services/System';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext'; import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
interface Props { interface Props {
isMaker: boolean; isMaker: boolean;

View File

@ -76,13 +76,13 @@ const makeTheme = function (settings: Settings): Theme {
}; };
const getHostUrl = (network = 'mainnet'): string => { const getHostUrl = (network = 'mainnet'): string => {
const [client, _view] = window.RobosatsSettings.split('-'); const [client] = window.RobosatsSettings.split('-');
const randomAlias = const randomAlias =
Object.keys(defaultFederation)[ Object.keys(defaultFederation)[
Math.floor(Math.random() * Object.keys(defaultFederation).length) Math.floor(Math.random() * Object.keys(defaultFederation).length)
]; ];
let host = defaultFederation[randomAlias][network].onion; let host: string = defaultFederation[randomAlias][network].onion;
let protocol = 'http:'; let protocol: string = 'http:';
if (client !== 'mobile') { if (client !== 'mobile') {
host = getHost(); host = getHost();
protocol = location.protocol; protocol = location.protocol;
@ -94,7 +94,7 @@ const getHostUrl = (network = 'mainnet'): string => {
const getOrigin = (network = 'mainnet'): Origin => { const getOrigin = (network = 'mainnet'): Origin => {
const host = getHostUrl(network); const host = getHostUrl(network);
let origin: Origin = 'onion'; let origin: Origin = 'onion';
const [client, _view] = window.RobosatsSettings.split('-'); const [client] = window.RobosatsSettings.split('-');
if (client === 'mobile' || client === 'desktop' || host.includes('.onion')) { if (client === 'mobile' || client === 'desktop' || host.includes('.onion')) {
origin = 'onion'; origin = 'onion';
@ -209,8 +209,9 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
initialAppContext.slideDirection, initialAppContext.slideDirection,
); );
const [open, setOpen] = useState<OpenDialogs>(initialAppContext.open); const [open, setOpen] = useState<OpenDialogs>(initialAppContext.open);
const [windowSize, setWindowSize] = useState<WindowSize>(() => const [windowSize, setWindowSize] = useState<WindowSize>(
getWindowSize(theme.typography.fontSize), () => getWindowSize(theme.typography.fontSize),
O,
); );
const [fav, setFav] = useState<Favorites>(initialAppContext.fav); const [fav, setFav] = useState<Favorites>(initialAppContext.fav);
const [acknowledgedWarning, setAcknowledgedWarning] = useState<boolean>( const [acknowledgedWarning, setAcknowledgedWarning] = useState<boolean>(

View File

@ -1,12 +1,4 @@
import React, { import React, { createContext, useEffect, useState, useContext, type ReactNode } from 'react';
createContext,
type Dispatch,
useEffect,
useState,
type SetStateAction,
useContext,
type ReactNode,
} from 'react';
import { Federation, Settings } from '../models'; import { Federation, Settings } from '../models';
@ -14,7 +6,8 @@ import { federationLottery } from '../utils';
import { AppContext, type UseAppStoreType } from './AppContext'; import { AppContext, type UseAppStoreType } from './AppContext';
import { GarageContext, type UseGarageStoreType } from './GarageContext'; import { GarageContext, type UseGarageStoreType } from './GarageContext';
import Coordinator, { type Origin, type Origins } from '../models/Coordinator.model'; import type Coordinator from '../models/Coordinator.model';
import { type Origin, type Origins } from '../models/Coordinator.model';
export interface CurrentOrderIdProps { export interface CurrentOrderIdProps {
id: number | null; id: number | null;

View File

@ -13,7 +13,6 @@ import { defaultMaker, type Maker, Garage } from '../models';
import { systemClient } from '../services/System'; import { systemClient } from '../services/System';
import { type UseAppStoreType, AppContext } from './AppContext'; import { type UseAppStoreType, AppContext } from './AppContext';
import { type UseFederationStoreType, FederationContext } from './FederationContext'; import { type UseFederationStoreType, FederationContext } from './FederationContext';
import { genKey } from '../pgp';
export interface GarageContextProviderProps { export interface GarageContextProviderProps {
children: ReactNode; children: ReactNode;
@ -90,7 +89,9 @@ export const GarageContextProvider = ({ children }: GarageContextProviderProps):
clearInterval(timer); clearInterval(timer);
fetchSlotActiveOrder(); fetchSlotActiveOrder();
return () => clearTimeout(timer); return () => {
clearTimeout(timer);
};
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -143,7 +144,11 @@ export const GarageContextProvider = ({ children }: GarageContextProviderProps):
const resetInterval = (): void => { const resetInterval = (): void => {
clearInterval(timer); clearInterval(timer);
setDelay(defaultDelay); setDelay(defaultDelay);
setTimer(setTimeout(() => fetchSlotActiveOrder(), defaultDelay)); setTimer(
setTimeout(() => {
fetchSlotActiveOrder();
}, defaultDelay),
);
}; };
return ( return (

View File

@ -202,7 +202,7 @@ export class Coordinator {
if (!data?.not_found) { if (!data?.not_found) {
this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => { this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => {
order.coordinatorShortAlias = this.shortAlias; order.coordinatorShortAlias = this.shortAlias;
return { ...book, [this.shortAlias + order.id]: order }; return { ...book, [`${this.shortAlias}${order.id}`]: order };
}, {}); }, {});
void this.generateAllMakerAvatars(); void this.generateAllMakerAvatars();
onDataLoad(); onDataLoad();
@ -272,7 +272,7 @@ export class Coordinator {
enable = (onEnabled: () => void = () => {}): void => { enable = (onEnabled: () => void = () => {}): void => {
this.enabled = true; this.enabled = true;
void this.loadLimits(() => { this.loadLimits(() => {
onEnabled(); onEnabled();
}); });
}; };

View File

@ -12,7 +12,6 @@ import { federationLottery, getHost } from '../utils';
import { coordinatorDefaultValues } from './Coordinator.model'; import { coordinatorDefaultValues } from './Coordinator.model';
import { updateExchangeInfo } from './Exchange.model'; import { updateExchangeInfo } from './Exchange.model';
import eventToPublicOrder from '../utils/nostr'; import eventToPublicOrder from '../utils/nostr';
import { SubCloser } from 'nostr-tools/lib/types/pool';
import RoboPool from '../services/RoboPool'; import RoboPool from '../services/RoboPool';
type FederationHooks = 'onFederationUpdate'; type FederationHooks = 'onFederationUpdate';
@ -71,7 +70,7 @@ export class Federation {
public coordinators: Record<string, Coordinator>; public coordinators: Record<string, Coordinator>;
public exchange: Exchange; public exchange: Exchange;
public book: Record<string, PublicOrder>; public book: Record<string, PublicOrder | undefined>;
public loading: boolean; public loading: boolean;
public connection: 'api' | 'nostr' | null; public connection: 'api' | 'nostr' | null;
@ -87,7 +86,7 @@ export class Federation {
this.loadBookNostr(); this.loadBookNostr();
} else { } else {
this.roboPool.close(); this.roboPool.close();
this.loadBook(); void this.loadBook();
} }
}; };
@ -103,7 +102,7 @@ export class Federation {
if (publicOrder) { if (publicOrder) {
this.book[dTag] = publicOrder; this.book[dTag] = publicOrder;
} else { } else {
delete this.book[dTag]; this.book[dTag] = undefined;
} }
}, },
oneose: () => { oneose: () => {
@ -181,7 +180,7 @@ export class Federation {
this.updateEnabledCoordinators(); this.updateEnabledCoordinators();
for (const coor of Object.values(this.coordinators)) { for (const coor of Object.values(this.coordinators)) {
void coor.loadInfo(() => { coor.loadInfo(() => {
this.onCoordinatorSaved(); this.onCoordinatorSaved();
}); });
} }
@ -194,7 +193,7 @@ export class Federation {
this.updateEnabledCoordinators(); this.updateEnabledCoordinators();
for (const coor of Object.values(this.coordinators)) { for (const coor of Object.values(this.coordinators)) {
void coor.loadLimits(() => { coor.loadLimits(() => {
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1; this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
this.onCoordinatorSaved(); this.onCoordinatorSaved();
}); });
@ -209,7 +208,7 @@ export class Federation {
this.triggerHook('onFederationUpdate'); this.triggerHook('onFederationUpdate');
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length; this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
for (const coor of Object.values(this.coordinators)) { for (const coor of Object.values(this.coordinators)) {
void coor.loadBook(() => { coor.loadBook(() => {
this.onCoordinatorSaved(); this.onCoordinatorSaved();
this.triggerHook('onFederationUpdate'); this.triggerHook('onFederationUpdate');
}); });

View File

@ -219,7 +219,7 @@ class Order {
slot, slot,
takeAmount, takeAmount,
) => { ) => {
return this.submitAction(federation, slot, { return await this.submitAction(federation, slot, {
action: 'take', action: 'take',
amount: this?.currency === 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount), amount: this?.currency === 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount),
}); });

View File

@ -49,7 +49,7 @@ class BaseSettings {
this.network = networkCookie && networkCookie !== '' ? networkCookie : 'mainnet'; this.network = networkCookie && networkCookie !== '' ? networkCookie : 'mainnet';
this.host = getHost(); this.host = getHost();
const [client, _view] = window.RobosatsSettings.split('-'); const [client] = window.RobosatsSettings.split('-');
const stopNotifications = systemClient.getItem('settings_stop_notifications'); const stopNotifications = systemClient.getItem('settings_stop_notifications');
this.stopNotifications = client === 'mobile' && stopNotifications === 'true'; this.stopNotifications = client === 'mobile' && stopNotifications === 'true';

View File

@ -1,7 +1,6 @@
import { Event } from 'nostr-tools'; import { type Event } from 'nostr-tools';
import { Settings } from '../../models'; import { type Settings } from '../../models';
import defaultFederation from '../../../static/federation.json'; import defaultFederation from '../../../static/federation.json';
import { Origins } from '../../models/Coordinator.model';
interface RoboPoolEvents { interface RoboPoolEvents {
onevent: (event: Event) => void; onevent: (event: Event) => void;
@ -13,9 +12,9 @@ class RoboPool {
this.network = settings.network ?? 'mainnet'; this.network = settings.network ?? 'mainnet';
this.relays = Object.values(defaultFederation) this.relays = Object.values(defaultFederation)
.map((coord) => { .map((coord) => {
const url = coord[this.network][settings.selfhostedClient ? 'onion' : origin]; const url: string = coord[this.network][settings.selfhostedClient ? 'onion' : origin];
if (!url) return; if (!url) return undefined;
return `ws://${url.replace(/^https?:\/\//, '')}/nostr`; return `ws://${url.replace(/^https?:\/\//, '')}/nostr`;
}) })
@ -26,15 +25,15 @@ class RoboPool {
public network: string; public network: string;
public webSockets: WebSocket[] = []; public webSockets: WebSocket[] = [];
private messageHandlers: Array<(url: string, event: MessageEvent) => void> = []; private readonly messageHandlers: Array<(url: string, event: MessageEvent) => void> = [];
connect = () => { connect = (): void => {
this.relays.forEach((url) => { this.relays.forEach((url) => {
if (this.webSockets.find((w: WebSocket) => w.url === url)) return; if (this.webSockets.find((w: WebSocket) => w.url === url)) return;
let ws: WebSocket; let ws: WebSocket;
const connect = () => { const connect = (): void => {
ws = new WebSocket(url); ws = new WebSocket(url);
// Add event listeners for the WebSocket // Add event listeners for the WebSocket
@ -43,7 +42,9 @@ class RoboPool {
}; };
ws.onmessage = (event) => { ws.onmessage = (event) => {
this.messageHandlers.forEach((handler) => handler(url, event)); this.messageHandlers.forEach((handler) => {
handler(url, event);
});
}; };
ws.onerror = (error) => { ws.onerror = (error) => {
@ -61,12 +62,14 @@ class RoboPool {
}); });
}; };
close = () => { close = (): void => {
this.webSockets.forEach((ws) => ws.close()); this.webSockets.forEach((ws) => {
ws.close();
});
}; };
sendMessage = (message: string) => { sendMessage = (message: string): void => {
const send = (index: number, message: string) => { const send = (index: number, message: string): void => {
const ws = this.webSockets[index]; const ws = this.webSockets[index];
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
@ -76,10 +79,12 @@ class RoboPool {
} }
}; };
this.webSockets.forEach((_ws, index) => send(index, message)); this.webSockets.forEach((_ws, index) => {
send(index, message);
});
}; };
subscribeBook = (events: RoboPoolEvents) => { subscribeBook = (events: RoboPoolEvents): void => {
const authors = Object.values(defaultFederation) const authors = Object.values(defaultFederation)
.map((f) => f.nostrHexPubkey) .map((f) => f.nostrHexPubkey)
.filter((item) => item !== undefined); .filter((item) => item !== undefined);

View File

@ -19,11 +19,11 @@ class RoboGenerator {
private readonly workers: RoboWorker[] = []; private readonly workers: RoboWorker[] = [];
private readonly taskQueue: Task[] = []; private readonly taskQueue: Task[] = [];
private numberOfWorkers: number = 8; private readonly numberOfWorkers: number = 8;
private waitingForLibrary: boolean = true; private waitingForLibrary: boolean = true;
private resolves: Record<string, ((result: string) => void)[]> = {}; private resolves: Record<string, Array<(result: string) => void>> = {};
private rejects: Record<string, ((reason?: Error) => void)[]> = {}; private rejects: Record<string, Array<(reason?: Error) => void>> = {};
constructor() { constructor() {
for (let i = 0; i < this.numberOfWorkers; i++) { for (let i = 0; i < this.numberOfWorkers; i++) {
@ -86,7 +86,7 @@ class RoboGenerator {
return { id, worker, busy: false }; return { id, worker, busy: false };
}; };
addTask = (task: any) => { addTask = (task: any): void => {
const availableWorker = this.workers.find((w) => !w.busy); const availableWorker = this.workers.find((w) => !w.busy);
if (availableWorker && !this.waitingForLibrary) { if (availableWorker && !this.waitingForLibrary) {
availableWorker.worker.postMessage(task); availableWorker.worker.postMessage(task);

View File

@ -1,4 +1,4 @@
import { type PublicOrder, type Favorites, Federation } from '../models'; import { type PublicOrder, type Favorites, type Federation } from '../models';
interface AmountFilter { interface AmountFilter {
amount: string; amount: string;

View File

@ -1,5 +1,5 @@
import { Event } from 'nostr-tools'; import { type Event } from 'nostr-tools';
import { Federation, PublicOrder } from '../models'; import { type PublicOrder } from '../models';
import { fromUnixTime } from 'date-fns'; import { fromUnixTime } from 'date-fns';
import Geohash from 'latlon-geohash'; import Geohash from 'latlon-geohash';
import currencyDict from '../../static/assets/currencies.json'; import currencyDict from '../../static/assets/currencies.json';
@ -69,18 +69,20 @@ const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOr
tag.shift(); tag.shift();
publicOrder.payment_method = tag.join(' '); publicOrder.payment_method = tag.join(' ');
break; break;
case 'g': case 'g': {
const { lat, lon } = Geohash.decode(tag[1]); const { lat, lon } = Geohash.decode(tag[1]);
publicOrder.latitude = lat; publicOrder.latitude = lat;
publicOrder.longitude = lon; publicOrder.longitude = lon;
break; break;
case 'f': }
case 'f': {
const currencyNumber = Object.entries(currencyDict).find( const currencyNumber = Object.entries(currencyDict).find(
([_key, value]) => value === tag[1], ([_key, value]) => value === tag[1],
); );
publicOrder.currency = currencyNumber?.[0] ? parseInt(currencyNumber[0], 10) : null; publicOrder.currency = currencyNumber?.[0] ? parseInt(currencyNumber[0], 10) : null;
break; break;
case 'source': }
case 'source': {
const orderUrl = tag[1].split('/'); const orderUrl = tag[1].split('/');
publicOrder.id = parseInt(orderUrl[orderUrl.length - 1] ?? '0'); publicOrder.id = parseInt(orderUrl[orderUrl.length - 1] ?? '0');
const coordinatorIdentifier = orderUrl[orderUrl.length - 2] ?? ''; const coordinatorIdentifier = orderUrl[orderUrl.length - 2] ?? '';
@ -88,6 +90,7 @@ const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOr
([key, value]) => value.identifier === coordinatorIdentifier, ([key, value]) => value.identifier === coordinatorIdentifier,
)?.[0]; )?.[0];
break; break;
}
default: default:
break; break;
} }