Fix order autoupdate and chat (#1047)

* Fix Order autoupdate and chat

* Remove console.log
This commit is contained in:
KoalaSat 2024-01-06 12:33:57 +00:00 committed by GitHub
parent 399671d709
commit 94af0b2afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 110 additions and 82 deletions

View File

@ -67,7 +67,7 @@ const OrderPage = (): JSX.Element => {
if (robot != null && slot?.token != null) { if (robot != null && slot?.token != null) {
void federation.fetchRobot(garage, slot.token); void federation.fetchRobot(garage, slot.token);
coordinator coordinator
.fetchOrder(currentOrderId, robot) .fetchOrder(currentOrderId, robot, slot.token)
.then((order) => { .then((order) => {
if (order?.bad_request !== undefined) { if (order?.bad_request !== undefined) {
setBadOrder(order.bad_request); setBadOrder(order.bad_request);

View File

@ -69,7 +69,7 @@ const RobotProfile = ({
const handleChangeSlot = (e: SelectChangeEvent<number | 'loading'>): void => { const handleChangeSlot = (e: SelectChangeEvent<number | 'loading'>): void => {
garage.currentSlot = e.target.value; garage.currentSlot = e.target.value;
setInputToken(garage.getSlot()?.getRobot()?.token ?? ''); setInputToken(garage.getSlot()?.token ?? '');
setLoading(true); setLoading(true);
}; };

View File

@ -98,6 +98,13 @@ const MakerForm = ({
useEffect(() => { useEffect(() => {
setCurrencyCode(currencyDict[fav.currency === 0 ? 1 : fav.currency]); setCurrencyCode(currencyDict[fav.currency === 0 ? 1 : fav.currency]);
}, [coordinatorUpdatedAt]);
useEffect(() => {
updateCoordinatorInfo();
}, [maker.coordinator]);
const updateCoordinatorInfo = () => {
if (maker.coordinator != null) { if (maker.coordinator != null) {
const newLimits = federation.getCoordinator(maker.coordinator).limits; const newLimits = federation.getCoordinator(maker.coordinator).limits;
if (Object.keys(newLimits).length !== 0) { if (Object.keys(newLimits).length !== 0) {
@ -107,7 +114,7 @@ const MakerForm = ({
setLimits(newLimits); setLimits(newLimits);
} }
} }
}, [coordinatorUpdatedAt]); };
const updateAmountLimits = function ( const updateAmountLimits = function (
limitList: LimitList, limitList: LimitList,

View File

@ -87,8 +87,8 @@ const RobotInfo: React.FC<Props> = ({ coordinator, onClose }: Props) => {
const slot = garage.getSlot(); const slot = garage.getSlot();
const robot = slot?.getRobot(coordinator.shortAlias); const robot = slot?.getRobot(coordinator.shortAlias);
if (robot != null && slot?.token != null && robot.encPrivKey != null && robot.token != null) { if (robot != null && slot?.token != null && robot.encPrivKey != null) {
void signCleartextMessage(rewardInvoice, robot.encPrivKey, robot.token).then( void signCleartextMessage(rewardInvoice, robot.encPrivKey, slot?.token).then(
(signedInvoice) => { (signedInvoice) => {
void coordinator.fetchReward(signedInvoice, garage, slot?.token).then((data) => { void coordinator.fetchReward(signedInvoice, garage, slot?.token).then((data) => {
setBadInvoice(data.bad_invoice ?? ''); setBadInvoice(data.bad_invoice ?? '');

View File

@ -15,6 +15,9 @@ import ChatHeader from '../ChatHeader';
import { type EncryptedChatMessage, type ServerMessage } from '..'; import { type EncryptedChatMessage, type ServerMessage } from '..';
import ChatBottom from '../ChatBottom'; import ChatBottom from '../ChatBottom';
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import { Order } from '../../../../models';
import { UseFederationStoreType, FederationContext } from '../../../../contexts/FederationContext';
import { UseAppStoreType, AppContext } from '../../../../contexts/AppContext';
const audioPath = const audioPath =
window.NativeRobosats === undefined window.NativeRobosats === undefined
@ -22,7 +25,7 @@ const audioPath =
: 'file:///android_asset/Web.bundle/assets/sounds'; : 'file:///android_asset/Web.bundle/assets/sounds';
interface Props { interface Props {
orderId: number; order: Order;
status: number; status: number;
userNick: string; userNick: string;
takerNick: string; takerNick: string;
@ -34,7 +37,7 @@ interface Props {
} }
const EncryptedSocketChat: React.FC<Props> = ({ const EncryptedSocketChat: React.FC<Props> = ({
orderId, order,
status, status,
userNick, userNick,
takerNick, takerNick,
@ -46,7 +49,9 @@ const EncryptedSocketChat: React.FC<Props> = ({
}: Props): JSX.Element => { }: Props): JSX.Element => {
const { t } = useTranslation(); const { t } = useTranslation();
const theme = useTheme(); const theme = useTheme();
const { origin, hostUrl, settings } = useContext<UseAppStoreType>(AppContext);
const { garage, robotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext); const { garage, robotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
const { federation } = useContext<UseFederationStoreType>(FederationContext);
const [audio] = useState(() => new Audio(`${audioPath}/chat-open.mp3`)); const [audio] = useState(() => new Audio(`${audioPath}/chat-open.mp3`));
const [connected, setConnected] = useState<boolean>(false); const [connected, setConnected] = useState<boolean>(false);
@ -98,13 +103,20 @@ const EncryptedSocketChat: React.FC<Props> = ({
}, [serverMessages]); }, [serverMessages]);
const connectWebsocket = (): void => { const connectWebsocket = (): void => {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (!robot) return; if (!slot?.token) return;
const { url, basePath } = federation
.getCoordinator(order.shortAlias)
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
websocketClient websocketClient
.open( .open(
`ws://${window.location.host}/ws/chat/${orderId}/?token_sha256_hex=${sha256(robot?.token)}`, `${url.replace(/^https?:\/\//, 'ws://') + basePath}/ws/chat/${
order.id
}/?token_sha256_hex=${sha256(slot?.token)}`,
) )
.then((connection) => { .then((connection) => {
setConnection(connection); setConnection(connection);
@ -144,7 +156,8 @@ const EncryptedSocketChat: React.FC<Props> = ({
const onMessage: (message: any) => void = (message) => { const onMessage: (message: any) => void = (message) => {
const dataFromServer = JSON.parse(message.data); const dataFromServer = JSON.parse(message.data);
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (dataFromServer != null && !receivedIndexes.includes(dataFromServer.index)) { if (dataFromServer != null && !receivedIndexes.includes(dataFromServer.index)) {
setReceivedIndexes((prev) => [...prev, dataFromServer.index]); setReceivedIndexes((prev) => [...prev, dataFromServer.index]);
setPeerConnected(dataFromServer.peer_connected); setPeerConnected(dataFromServer.peer_connected);
@ -166,7 +179,7 @@ const EncryptedSocketChat: React.FC<Props> = ({
dataFromServer.message.split('\\').join('\n'), dataFromServer.message.split('\\').join('\n'),
dataFromServer.user_nick === userNick ? robot.pubKey : peerPubKey, dataFromServer.user_nick === userNick ? robot.pubKey : peerPubKey,
robot.encPrivKey, robot.encPrivKey,
robot.token, slot.token,
).then((decryptedData) => { ).then((decryptedData) => {
setWaitingEcho(waitingEcho ? decryptedData.decryptedMessage !== lastSent : false); setWaitingEcho(waitingEcho ? decryptedData.decryptedMessage !== lastSent : false);
setLastSent(decryptedData.decryptedMessage === lastSent ? '----BLANK----' : lastSent); setLastSent(decryptedData.decryptedMessage === lastSent ? '----BLANK----' : lastSent);
@ -214,8 +227,9 @@ const EncryptedSocketChat: React.FC<Props> = ({
}; };
const onButtonClicked = (e: React.FormEvent<HTMLFormElement>): void => { const onButtonClicked = (e: React.FormEvent<HTMLFormElement>): void => {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
if (robot?.token !== undefined && value.includes(robot.token)) { const robot = slot?.getRobot();
if (slot?.token !== undefined && value.includes(slot.token)) {
alert( alert(
`Aye! You just sent your own robot robot.token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`, `Aye! You just sent your own robot robot.token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`,
); );
@ -235,7 +249,7 @@ const EncryptedSocketChat: React.FC<Props> = ({
setValue(''); setValue('');
setWaitingEcho(true); setWaitingEcho(true);
setLastSent(value); setLastSent(value);
encryptMessage(value, robot.pubKey, peerPubKey, robot.encPrivKey, robot.token) encryptMessage(value, robot.pubKey, peerPubKey, robot.encPrivKey, slot.token)
.then((encryptedMessage) => { .then((encryptedMessage) => {
if (connection != null) { if (connection != null) {
connection.send({ connection.send({
@ -264,12 +278,12 @@ const EncryptedSocketChat: React.FC<Props> = ({
onClose={() => { onClose={() => {
setAudit(false); setAudit(false);
}} }}
orderId={Number(orderId)} orderId={Number(order.id)}
messages={messages} messages={messages}
ownPubKey={garage.getSlot()?.getRobot()?.pubKey ?? ''} ownPubKey={garage.getSlot()?.getRobot()?.pubKey ?? ''}
ownEncPrivKey={garage.getSlot()?.getRobot()?.encPrivKey ?? ''} ownEncPrivKey={garage.getSlot()?.getRobot()?.encPrivKey ?? ''}
peerPubKey={peerPubKey ?? 'Not received yet'} peerPubKey={peerPubKey ?? 'Not received yet'}
passphrase={garage.getSlot()?.getRobot()?.token ?? ''} passphrase={garage.getSlot()?.token ?? ''}
onClickBack={() => { onClickBack={() => {
setAudit(false); setAudit(false);
}} }}
@ -381,7 +395,7 @@ const EncryptedSocketChat: React.FC<Props> = ({
</Grid> </Grid>
<Grid item> <Grid item>
<ChatBottom <ChatBottom
orderId={orderId} orderId={order.id}
audit={audit} audit={audit}
setAudit={setAudit} setAudit={setAudit}
createJsonFile={createJsonFile} createJsonFile={createJsonFile}

View File

@ -19,9 +19,10 @@ import {
FederationContext, FederationContext,
} from '../../../../contexts/FederationContext'; } from '../../../../contexts/FederationContext';
import { type UseGarageStoreType, GarageContext } from '../../../../contexts/GarageContext'; import { type UseGarageStoreType, GarageContext } from '../../../../contexts/GarageContext';
import { Order } from '../../../../models';
interface Props { interface Props {
orderId: number; order: Order;
userNick: string; userNick: string;
takerNick: string; takerNick: string;
chatOffset: number; chatOffset: number;
@ -38,7 +39,7 @@ const audioPath =
: 'file:///android_asset/Web.bundle/assets/sounds'; : 'file:///android_asset/Web.bundle/assets/sounds';
const EncryptedTurtleChat: React.FC<Props> = ({ const EncryptedTurtleChat: React.FC<Props> = ({
orderId, order,
userNick, userNick,
takerNick, takerNick,
chatOffset, chatOffset,
@ -94,7 +95,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
.getCoordinator(shortAlias) .getCoordinator(shortAlias)
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl); .getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
apiClient apiClient
.get(url + basePath, `/api/chat/?order_id=${orderId}&offset=${lastIndex}`, { .get(url + basePath, `/api/chat/?order_id=${order.id}&offset=${lastIndex}`, {
tokenSHA256: garage.getSlot()?.getRobot()?.tokenSHA256 ?? '', tokenSHA256: garage.getSlot()?.getRobot()?.tokenSHA256 ?? '',
}) })
.then((results: any) => { .then((results: any) => {
@ -122,7 +123,8 @@ const EncryptedTurtleChat: React.FC<Props> = ({
}; };
const onMessage = (dataFromServer: ServerMessage): void => { const onMessage = (dataFromServer: ServerMessage): void => {
const robot = garage.getSlot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (robot && dataFromServer != null) { if (robot && dataFromServer != null) {
// If we receive an encrypted message // If we receive an encrypted message
if (dataFromServer.message.substring(0, 27) === `-----BEGIN PGP MESSAGE-----`) { if (dataFromServer.message.substring(0, 27) === `-----BEGIN PGP MESSAGE-----`) {
@ -130,7 +132,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
dataFromServer.message.split('\\').join('\n'), dataFromServer.message.split('\\').join('\n'),
dataFromServer.nick === userNick ? robot.pubKey : peerPubKey, dataFromServer.nick === userNick ? robot.pubKey : peerPubKey,
robot.encPrivKey, robot.encPrivKey,
robot.token, slot.token,
).then((decryptedData) => { ).then((decryptedData) => {
setLastSent(decryptedData.decryptedMessage === lastSent ? '----BLANK----' : lastSent); setLastSent(decryptedData.decryptedMessage === lastSent ? '----BLANK----' : lastSent);
setLastIndex(lastIndex < dataFromServer.index ? dataFromServer.index : lastIndex); setLastIndex(lastIndex < dataFromServer.index ? dataFromServer.index : lastIndex);
@ -178,11 +180,12 @@ const EncryptedTurtleChat: React.FC<Props> = ({
}; };
const onButtonClicked = (e: React.FormEvent<HTMLFormElement>): void => { const onButtonClicked = (e: React.FormEvent<HTMLFormElement>): void => {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (!robot) return; if (!robot) return;
if (robot?.token && value.includes(robot.token)) { if (slot?.token && value.includes(slot.token)) {
alert( alert(
`Aye! You just sent your own robot robot.token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`, `Aye! You just sent your own robot robot.token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`,
); );
@ -199,7 +202,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
`/api/chat/`, `/api/chat/`,
{ {
PGP_message: value, PGP_message: value,
order_id: orderId, order_id: order.id,
offset: lastIndex, offset: lastIndex,
}, },
{ tokenSHA256: robot?.tokenSHA256 ?? '' }, { tokenSHA256: robot?.tokenSHA256 ?? '' },
@ -221,7 +224,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
else if (value !== '' && Boolean(robot?.pubKey)) { else if (value !== '' && Boolean(robot?.pubKey)) {
setWaitingEcho(true); setWaitingEcho(true);
setLastSent(value); setLastSent(value);
encryptMessage(value, robot?.pubKey, peerPubKey ?? '', robot?.encPrivKey, robot?.token) encryptMessage(value, robot?.pubKey, peerPubKey ?? '', robot?.encPrivKey, slot?.token)
.then((encryptedMessage) => { .then((encryptedMessage) => {
const { url, basePath } = federation const { url, basePath } = federation
.getCoordinator(garage.getSlot()?.activeShortAlias ?? '') .getCoordinator(garage.getSlot()?.activeShortAlias ?? '')
@ -232,7 +235,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
`/api/chat/`, `/api/chat/`,
{ {
PGP_message: String(encryptedMessage).split('\n').join('\\'), PGP_message: String(encryptedMessage).split('\n').join('\\'),
order_id: orderId, order_id: order.id,
offset: lastIndex, offset: lastIndex,
}, },
{ tokenSHA256: robot?.tokenSHA256 }, { tokenSHA256: robot?.tokenSHA256 },
@ -270,7 +273,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
onClose={() => { onClose={() => {
setAudit(false); setAudit(false);
}} }}
orderId={Number(orderId)} orderId={Number(order.id)}
messages={messages} messages={messages}
ownPubKey={garage.getSlot()?.getRobot()?.pubKey ?? ''} ownPubKey={garage.getSlot()?.getRobot()?.pubKey ?? ''}
ownEncPrivKey={garage.getSlot()?.getRobot()?.encPrivKey ?? ''} ownEncPrivKey={garage.getSlot()?.getRobot()?.encPrivKey ?? ''}
@ -382,7 +385,7 @@ const EncryptedTurtleChat: React.FC<Props> = ({
<Grid item> <Grid item>
<ChatBottom <ChatBottom
orderId={orderId} orderId={order.id}
audit={audit} audit={audit}
setAudit={setAudit} setAudit={setAudit}
createJsonFile={createJsonFile} createJsonFile={createJsonFile}

View File

@ -1,10 +1,10 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { type Robot } from '../../../models'; import { Order, type Robot } from '../../../models';
import EncryptedSocketChat from './EncryptedSocketChat'; import EncryptedSocketChat from './EncryptedSocketChat';
import EncryptedTurtleChat from './EncryptedTurtleChat'; import EncryptedTurtleChat from './EncryptedTurtleChat';
interface Props { interface Props {
orderId: number; order: Order;
status: number; status: number;
takerNick: string; takerNick: string;
makerNick: string; makerNick: string;
@ -33,7 +33,7 @@ export interface ServerMessage {
} }
const EncryptedChat: React.FC<Props> = ({ const EncryptedChat: React.FC<Props> = ({
orderId, order,
takerNick, takerNick,
userNick, userNick,
chatOffset, chatOffset,
@ -48,7 +48,7 @@ const EncryptedChat: React.FC<Props> = ({
<EncryptedTurtleChat <EncryptedTurtleChat
messages={messages} messages={messages}
setMessages={setMessages} setMessages={setMessages}
orderId={orderId} order={order}
takerNick={takerNick} takerNick={takerNick}
userNick={userNick} userNick={userNick}
chatOffset={chatOffset} chatOffset={chatOffset}
@ -61,7 +61,7 @@ const EncryptedChat: React.FC<Props> = ({
status={status} status={status}
messages={messages} messages={messages}
setMessages={setMessages} setMessages={setMessages}
orderId={orderId} order={order}
takerNick={takerNick} takerNick={takerNick}
userNick={userNick} userNick={userNick}
baseUrl={baseUrl} baseUrl={baseUrl}

View File

@ -132,7 +132,7 @@ export const ChatPrompt = ({
<EncryptedChat <EncryptedChat
status={order.status} status={order.status}
chatOffset={order.chat_last_index} chatOffset={order.chat_last_index}
orderId={order.id} order={order}
takerNick={order.taker_nick} takerNick={order.taker_nick}
makerNick={order.maker_nick} makerNick={order.maker_nick}
userNick={order.ur_nick} userNick={order.ur_nick}

View File

@ -269,11 +269,12 @@ const TradeBox = ({ baseUrl, onStartAgain }: TradeBoxProps): JSX.Element => {
}; };
const updateInvoice = function (invoice: string): void { const updateInvoice = function (invoice: string): void {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (robot?.encPrivKey != null && robot?.token != null) { if (robot?.encPrivKey != null && slot?.token != null) {
setLoadingButtons({ ...noLoadingButtons, submitInvoice: true }); setLoadingButtons({ ...noLoadingButtons, submitInvoice: true });
void signCleartextMessage(invoice, robot.encPrivKey, robot.token).then((signedInvoice) => { void signCleartextMessage(invoice, robot.encPrivKey, slot.token).then((signedInvoice) => {
submitAction({ submitAction({
action: 'update_invoice', action: 'update_invoice',
invoice: signedInvoice, invoice: signedInvoice,
@ -284,11 +285,12 @@ const TradeBox = ({ baseUrl, onStartAgain }: TradeBoxProps): JSX.Element => {
}; };
const updateAddress = function (): void { const updateAddress = function (): void {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
const robot = slot?.getRobot();
if (robot?.encPrivKey != null && robot?.token != null) { if (robot?.encPrivKey != null && slot?.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, slot.token).then(
(signedAddress) => { (signedAddress) => {
submitAction({ submitAction({
action: 'update_address', action: 'update_address',
@ -306,10 +308,10 @@ const TradeBox = ({ baseUrl, onStartAgain }: TradeBoxProps): JSX.Element => {
}; };
const submitStatement = function (): void { const submitStatement = function (): void {
const robot = garage.getSlot()?.getRobot(); const slot = garage.getSlot();
let statement = dispute.statement; let statement = dispute.statement;
if (dispute.attachLogs) { if (dispute.attachLogs) {
const payload = { statement, messages, token: robot?.token }; const payload = { statement, messages, token: slot?.token };
statement = JSON.stringify(payload, null, 2); statement = JSON.stringify(payload, null, 2);
} }
setLoadingButtons({ ...noLoadingButtons, submitStatement: true }); setLoadingButtons({ ...noLoadingButtons, submitStatement: true });

View File

@ -119,14 +119,18 @@ export const useFederationStore = (): UseFederationStoreType => {
} }
}; };
const fetchCurrentOrder = (): void => { const fetchCurrentOrder: () => void = () => {
const activeSlot = garage.getSlot(); const slot = garage?.getSlot();
const robot = activeSlot?.getRobot(activeSlot?.activeShortAlias ?? ''); const robot = slot?.getRobot();
if (robot?.activeOrderId && activeSlot?.activeShortAlias) { console.log('slot?.token', slot?.token);
const coordinator = federation.getCoordinator(activeSlot?.activeShortAlias ?? ''); console.log('slot?.activeShortAlias', slot?.activeShortAlias);
console.log('robot?.activeOrderId', robot?.activeOrderId);
if (slot?.token && slot?.activeShortAlias && robot?.activeOrderId) {
const coordinator = federation.getCoordinator(slot.activeShortAlias);
coordinator coordinator
?.fetchOrder(robot.activeOrderId, robot) ?.fetchOrder(robot.activeOrderId, robot, slot.token)
.then((order) => { .then((order) => {
console.log('order', order);
onOrderReceived(order as Order); onOrderReceived(order as Order);
}) })
.finally(() => { .finally(() => {
@ -156,8 +160,8 @@ export const useFederationStore = (): UseFederationStoreType => {
if (robot && garage.currentSlot) { if (robot && garage.currentSlot) {
if (open.profile && Boolean(slot?.hashId) && slot?.token) { if (open.profile && Boolean(slot?.hashId) && slot?.token) {
void federation.fetchRobot(garage, slot?.token); // refresh/update existing robot void federation.fetchRobot(garage, slot?.token); // refresh/update existing robot
} else if (robot.token && robot.encPrivKey && robot.pubKey) { } else if (slot?.token && robot.encPrivKey && robot.pubKey) {
void federation.fetchRobot(garage, robot.token); // create new robot with existing token and keys (on network and coordinator change) void federation.fetchRobot(garage, slot.token); // create new robot with existing token and keys (on network and coordinator change)
} }
} }
}, [open.profile, hostUrl, robotUpdatedAt]); }, [open.profile, hostUrl, robotUpdatedAt]);

View File

@ -291,17 +291,14 @@ export class Coordinator {
}; };
fecthRobot = async (garage: Garage, token: string): Promise<Robot | null> => { fecthRobot = async (garage: Garage, token: string): Promise<Robot | null> => {
if (!this.enabled) return null; if (!this.enabled || !token) return null;
const robot = garage?.getSlot(token)?.getRobot() ?? null; const robot = garage?.getSlot(token)?.getRobot() ?? null;
const authHeaders = robot?.getAuthHeaders();
if (robot?.token !== token) return null; if (!authHeaders) return null;
const authHeaders = robot.getAuthHeaders(); const { hasEnoughEntropy, bitsEntropy, shannonEntropy } = validateTokenEntropy(token);
if (authHeaders === null) return null;
const { hasEnoughEntropy, bitsEntropy, shannonEntropy } = validateTokenEntropy(robot.token);
if (!hasEnoughEntropy) return null; if (!hasEnoughEntropy) return null;
@ -339,17 +336,17 @@ export class Coordinator {
return garage.getSlot(this.shortAlias)?.getRobot() ?? null; return garage.getSlot(this.shortAlias)?.getRobot() ?? null;
}; };
fetchOrder = async (orderId: number, robot: Robot): Promise<Order | null> => { fetchOrder = async (orderId: number, robot: Robot, token: string): Promise<Order | null> => {
if (!this.enabled) return null; if (!this.enabled) return null;
if (!(robot.token != null)) return null; if (!token) return null;
const authHeaders = robot.getAuthHeaders(); const authHeaders = robot.getAuthHeaders();
if (!authHeaders) return null;
if (authHeaders === null) return null;
return await apiClient return await apiClient
.get(this.url, `${this.basePath}/api/order/?order_id=${orderId}`, authHeaders) .get(this.url, `${this.basePath}/api/order/?order_id=${orderId}`, authHeaders)
.then((data) => { .then((data) => {
console.log('data', data);
const order: Order = { const order: Order = {
...defaultOrder, ...defaultOrder,
...data, ...data,
@ -373,9 +370,10 @@ export class Coordinator {
}> => { }> => {
if (!this.enabled) return null; if (!this.enabled) return null;
const robot = garage.getSlot(index)?.getRobot(); const slot = garage.getSlot(index);
const robot = slot?.getRobot();
if (!(robot?.token != null) || !(robot.encPrivKey != null)) return null; if (!slot?.token || !robot?.encPrivKey) return null;
const data = await apiClient.post( const data = await apiClient.post(
this.url, this.url,
@ -385,7 +383,7 @@ export class Coordinator {
}, },
{ tokenSHA256: robot.tokenSHA256 }, { tokenSHA256: robot.tokenSHA256 },
); );
garage.upsertRobot(robot?.token, this.shortAlias, { garage.upsertRobot(slot?.token, this.shortAlias, {
earnedRewards: data?.successful_withdrawal === true ? 0 : robot.earnedRewards, earnedRewards: data?.successful_withdrawal === true ? 0 : robot.earnedRewards,
}); });
@ -395,9 +393,10 @@ export class Coordinator {
fetchStealth = async (wantsStealth: boolean, garage: Garage, index: string): Promise<null> => { fetchStealth = async (wantsStealth: boolean, garage: Garage, index: string): Promise<null> => {
if (!this.enabled) return null; if (!this.enabled) return null;
const robot = garage?.getSlot(index)?.getRobot(); const slot = garage.getSlot(index);
const robot = slot?.getRobot();
if (!(robot?.token != null) || !(robot.encPrivKey != null)) return null; if (!(slot?.token != null) || !(robot?.encPrivKey != null)) return null;
await apiClient.post( await apiClient.post(
this.url, this.url,
@ -406,7 +405,7 @@ export class Coordinator {
{ tokenSHA256: robot.tokenSHA256 }, { tokenSHA256: robot.tokenSHA256 },
); );
garage.upsertRobot(robot?.token, this.shortAlias, { garage.upsertRobot(slot?.token, this.shortAlias, {
stealthInvoices: wantsStealth, stealthInvoices: wantsStealth,
}); });

View File

@ -120,12 +120,12 @@ class Garage {
let slot = this.getSlot(token); let slot = this.getSlot(token);
if (slot === null && attributes.token != null) { if (slot === null && token) {
slot = this.createSlot(attributes.token); slot = this.createSlot(token);
} }
if (slot != null) { if (slot != null) {
slot.upsertRobot(shortAlias, attributes); slot.upsertRobot(shortAlias, { token, ...attributes });
this.triggerHook('onRobotUpdate'); this.triggerHook('onRobotUpdate');
this.save(); this.save();
} }

View File

@ -10,13 +10,13 @@ interface AuthHeaders {
} }
class Robot { class Robot {
constructor(garageRobot?: Robot) { constructor(attributes?: Record<any, any>) {
if (garageRobot != null) { if (attributes != null) {
this.token = garageRobot?.token ?? undefined; this.token = attributes?.token ?? undefined;
this.tokenSHA256 = this.tokenSHA256 =
garageRobot?.tokenSHA256 ?? (this.token != null ? hexToBase91(sha256(this.token)) : ''); attributes?.tokenSHA256 ?? (this.token != null ? hexToBase91(sha256(this.token)) : '');
this.pubKey = garageRobot?.pubKey ?? undefined; this.pubKey = attributes?.pubKey ?? undefined;
this.encPrivKey = garageRobot?.encPrivKey ?? undefined; this.encPrivKey = attributes?.encPrivKey ?? undefined;
} }
} }
@ -43,9 +43,7 @@ class Robot {
}; };
getAuthHeaders = (): AuthHeaders | null => { getAuthHeaders = (): AuthHeaders | null => {
if (this.token === undefined) return null; const tokenSHA256 = this.tokenSHA256 ?? '';
const tokenSHA256 = hexToBase91(sha256(this.token));
const encPrivKey = this.encPrivKey ?? ''; const encPrivKey = this.encPrivKey ?? '';
const pubKey = this.pubKey ?? ''; const pubKey = this.pubKey ?? '';

View File

@ -48,7 +48,8 @@ class Slot {
}; };
upsertRobot = (shortAlias: string, attributes: Record<any, any>): Robot | null => { upsertRobot = (shortAlias: string, attributes: Record<any, any>): Robot | null => {
if (this.robots[shortAlias] === undefined) this.robots[shortAlias] = new Robot(); if (this.robots[shortAlias] === undefined)
this.robots[shortAlias] = new Robot(attributes ?? {});
this.robots[shortAlias].update(attributes); this.robots[shortAlias].update(attributes);