mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-31 10:31:35 +00:00
More fixes
This commit is contained in:
parent
4eb46f1e16
commit
7f78f69df6
@ -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 />
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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}
|
||||||
|
@ -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)
|
||||||
|
@ -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 (
|
||||||
|
@ -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>
|
||||||
|
@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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';
|
||||||
|
@ -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]);
|
||||||
|
@ -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]);
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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');
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user