mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-31 02:21:35 +00:00
Merge branch 'main' into android-notification-system
This commit is contained in:
commit
e9863417dd
@ -50,16 +50,16 @@ class Command(BaseCommand):
|
|||||||
parts = message.split(" ")
|
parts = message.split(" ")
|
||||||
if len(parts) < 2:
|
if len(parts) < 2:
|
||||||
self.notifications.send_telegram_message(
|
self.notifications.send_telegram_message(
|
||||||
chat_id=result["message"]["from"]["id"],
|
result["message"]["from"]["id"],
|
||||||
text='You must enable the notifications bot using the RoboSats client. Click on your "Robot robot" -> "Enable Telegram" and follow the link or scan the QR code.',
|
'You must enable the notifications bot using the RoboSats client. Click on your "Robot robot" -> "Enable Telegram" and follow the link or scan the QR code.',
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
token = parts[-1]
|
token = parts[-1]
|
||||||
robot = Robot.objects.filter(telegram_token=token).first()
|
robot = Robot.objects.filter(telegram_token=token).first()
|
||||||
if not robot:
|
if not robot:
|
||||||
self.notifications.send_telegram_message(
|
self.notifications.send_telegram_message(
|
||||||
chat_id=result["message"]["from"]["id"],
|
result["message"]["from"]["id"],
|
||||||
text=f'Wops, invalid token! There is no Robot with telegram chat token "{token}"',
|
f'Wops, invalid token! There is no Robot with telegram chat token "{token}"',
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -37,13 +37,13 @@ class Notifications:
|
|||||||
if robot.telegram_enabled:
|
if robot.telegram_enabled:
|
||||||
self.send_telegram_message(robot.telegram_chat_id, title, description)
|
self.send_telegram_message(robot.telegram_chat_id, title, description)
|
||||||
|
|
||||||
def save_message(self, order, robot, title, description):
|
def save_message(self, order, robot, title, description=""):
|
||||||
"""Save a message for a user"""
|
"""Save a message for a user"""
|
||||||
Notification.objects.create(
|
Notification.objects.create(
|
||||||
title=title, description=description, robot=robot, order=order
|
title=title, description=description, robot=robot, order=order
|
||||||
)
|
)
|
||||||
|
|
||||||
def send_telegram_message(self, chat_id, title, description):
|
def send_telegram_message(self, chat_id, title, description=""):
|
||||||
"""sends a message to a user with telegram notifications enabled"""
|
"""sends a message to a user with telegram notifications enabled"""
|
||||||
|
|
||||||
bot_token = config("TELEGRAM_TOKEN")
|
bot_token = config("TELEGRAM_TOKEN")
|
||||||
|
@ -141,7 +141,7 @@ def get_devfund_pubkey(network: str) -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
session = get_session()
|
session = get_session()
|
||||||
url = "https://raw.githubusercontent.com/RoboSats/robosats/main/devfund_pubey.json"
|
url = "https://raw.githubusercontent.com/RoboSats/robosats/main/devfund_pubkey.json"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = session.get(url)
|
response = session.get(url)
|
||||||
|
24
frontend/package-lock.json
generated
24
frontend/package-lock.json
generated
@ -23,11 +23,11 @@
|
|||||||
"@nivo/core": "^0.86.0",
|
"@nivo/core": "^0.86.0",
|
||||||
"@nivo/line": "^0.86.0",
|
"@nivo/line": "^0.86.0",
|
||||||
"base-ex": "^0.8.1",
|
"base-ex": "^0.8.1",
|
||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.13",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"file-replace-loader": "^1.4.0",
|
"file-replace-loader": "^1.4.0",
|
||||||
"i18next": "^23.2.11",
|
"i18next": "^23.2.11",
|
||||||
"i18next-browser-languagedetector": "^7.2.1",
|
"i18next-browser-languagedetector": "^8.0.0",
|
||||||
"i18next-http-backend": "^2.5.0",
|
"i18next-http-backend": "^2.5.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
"js-sha256": "^0.11.0",
|
"js-sha256": "^0.11.0",
|
||||||
@ -81,7 +81,7 @@
|
|||||||
"jest": "^29.6.1",
|
"jest": "^29.6.1",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.3.2",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.5.4",
|
||||||
"webpack": "^5.89.0",
|
"webpack": "^5.89.0",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
@ -6411,9 +6411,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/country-flag-icons": {
|
"node_modules/country-flag-icons": {
|
||||||
"version": "1.5.11",
|
"version": "1.5.13",
|
||||||
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.11.tgz",
|
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.13.tgz",
|
||||||
"integrity": "sha512-B+mvFywunkRJs270k7kCBjhogvIA0uNn6GAXv6m2cPn3rrwqZzZVr2gBWcz+Cz7OGVWlcbERlYRIX0S6OGr8Bw=="
|
"integrity": "sha512-4JwHNqaKZ19doQoNcBjsoYA+I7NqCH/mC/6f5cBWvdKzcK5TMmzLpq3Z/syVHMHJuDGFwJ+rPpGizvrqJybJow=="
|
||||||
},
|
},
|
||||||
"node_modules/create-require": {
|
"node_modules/create-require": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@ -8823,9 +8823,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i18next-browser-languagedetector": {
|
"node_modules/i18next-browser-languagedetector": {
|
||||||
"version": "7.2.1",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz",
|
||||||
"integrity": "sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==",
|
"integrity": "sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.23.2"
|
"@babel/runtime": "^7.23.2"
|
||||||
}
|
}
|
||||||
@ -16730,9 +16730,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.4.2",
|
"version": "5.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||||
"integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
|
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
"jest": "^29.6.1",
|
"jest": "^29.6.1",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.3.2",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.5.4",
|
||||||
"webpack": "^5.89.0",
|
"webpack": "^5.89.0",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
@ -62,11 +62,11 @@
|
|||||||
"@nivo/core": "^0.86.0",
|
"@nivo/core": "^0.86.0",
|
||||||
"@nivo/line": "^0.86.0",
|
"@nivo/line": "^0.86.0",
|
||||||
"base-ex": "^0.8.1",
|
"base-ex": "^0.8.1",
|
||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.13",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"file-replace-loader": "^1.4.0",
|
"file-replace-loader": "^1.4.0",
|
||||||
"i18next": "^23.2.11",
|
"i18next": "^23.2.11",
|
||||||
"i18next-browser-languagedetector": "^7.2.1",
|
"i18next-browser-languagedetector": "^8.0.0",
|
||||||
"i18next-http-backend": "^2.5.0",
|
"i18next-http-backend": "^2.5.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
"js-sha256": "^0.11.0",
|
"js-sha256": "^0.11.0",
|
||||||
|
@ -40,14 +40,14 @@ const OrderPage = (): JSX.Element => {
|
|||||||
const shortAlias = params.shortAlias;
|
const shortAlias = params.shortAlias;
|
||||||
const coordinator = federation.getCoordinator(shortAlias ?? '');
|
const coordinator = federation.getCoordinator(shortAlias ?? '');
|
||||||
if (coordinator) {
|
if (coordinator) {
|
||||||
const { url, basePath } = coordinator?.getEndpoint(
|
const endpoint = coordinator?.getEndpoint(
|
||||||
settings.network,
|
settings.network,
|
||||||
origin,
|
origin,
|
||||||
settings.selfhostedClient,
|
settings.selfhostedClient,
|
||||||
hostUrl,
|
hostUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
setBaseUrl(`${url}${basePath}`);
|
if (endpoint) setBaseUrl(`${endpoint?.url}${endpoint?.basePath}`);
|
||||||
|
|
||||||
const orderId = Number(params.orderId);
|
const orderId = Number(params.orderId);
|
||||||
if (
|
if (
|
||||||
|
@ -156,7 +156,7 @@ const RobotProfile = ({
|
|||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{loadingCoordinators > 0 && !Boolean(robot?.activeOrderId) ? (
|
{loadingCoordinators > 0 && !robot?.activeOrderId ? (
|
||||||
<Grid>
|
<Grid>
|
||||||
<b>{t('Looking for orders!')}</b>
|
<b>{t('Looking for orders!')}</b>
|
||||||
<LinearProgress />
|
<LinearProgress />
|
||||||
@ -210,9 +210,9 @@ const RobotProfile = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!Boolean(robot?.activeOrderId) &&
|
{!robot?.activeOrderId &&
|
||||||
slot?.hashId &&
|
slot?.hashId &&
|
||||||
!Boolean(robot?.lastOrderId) &&
|
!robot?.lastOrderId &&
|
||||||
loadingCoordinators === 0 ? (
|
loadingCoordinators === 0 ? (
|
||||||
<Grid item>{t('No existing orders found')}</Grid>
|
<Grid item>{t('No existing orders found')}</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -4,7 +4,7 @@ import SettingsForm from '../../components/SettingsForm';
|
|||||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||||
import FederationTable from '../../components/FederationTable';
|
import FederationTable from '../../components/FederationTable';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { FederationContext, UseFederationStoreType } from '../../contexts/FederationContext';
|
import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext';
|
||||||
|
|
||||||
const SettingsPage = (): JSX.Element => {
|
const SettingsPage = (): JSX.Element => {
|
||||||
const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
|
const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
|
||||||
@ -16,7 +16,7 @@ const SettingsPage = (): JSX.Element => {
|
|||||||
// Regular expression to match a valid .onion URL
|
// Regular expression to match a valid .onion URL
|
||||||
const onionUrlPattern = /^((http|https):\/\/)?[a-zA-Z2-7]{16,56}\.onion$/;
|
const onionUrlPattern = /^((http|https):\/\/)?[a-zA-Z2-7]{16,56}\.onion$/;
|
||||||
|
|
||||||
const addCoordinator = () => {
|
const addCoordinator: () => void = () => {
|
||||||
if (federation.coordinators[newAlias]) {
|
if (federation.coordinators[newAlias]) {
|
||||||
setError(t('Alias already exists'));
|
setError(t('Alias already exists'));
|
||||||
} else {
|
} else {
|
||||||
@ -65,7 +65,9 @@ const SettingsPage = (): JSX.Element => {
|
|||||||
variant='outlined'
|
variant='outlined'
|
||||||
size='small'
|
size='small'
|
||||||
value={newAlias}
|
value={newAlias}
|
||||||
onChange={(e) => setNewAlias(e.target.value)}
|
onChange={(e) => {
|
||||||
|
setNewAlias(e.target.value);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
id='outlined-basic'
|
id='outlined-basic'
|
||||||
@ -73,7 +75,9 @@ const SettingsPage = (): JSX.Element => {
|
|||||||
variant='outlined'
|
variant='outlined'
|
||||||
size='small'
|
size='small'
|
||||||
value={newUrl}
|
value={newUrl}
|
||||||
onChange={(e) => setNewUrl(e.target.value)}
|
onChange={(e) => {
|
||||||
|
setNewUrl(e.target.value);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
sx={{ maxHeight: 38 }}
|
sx={{ maxHeight: 38 }}
|
||||||
|
@ -14,7 +14,6 @@ import {
|
|||||||
LinearProgress,
|
LinearProgress,
|
||||||
IconButton,
|
IconButton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
type LinearProgressProps,
|
|
||||||
styled,
|
styled,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
@ -24,7 +23,7 @@ import {
|
|||||||
type GridPaginationModel,
|
type GridPaginationModel,
|
||||||
type GridColDef,
|
type GridColDef,
|
||||||
type GridValidRowModel,
|
type GridValidRowModel,
|
||||||
GridSlotsComponent,
|
type GridSlotsComponent,
|
||||||
} from '@mui/x-data-grid';
|
} from '@mui/x-data-grid';
|
||||||
import currencyDict from '../../../static/assets/currencies.json';
|
import currencyDict from '../../../static/assets/currencies.json';
|
||||||
import { type PublicOrder } from '../../models';
|
import { type PublicOrder } from '../../models';
|
||||||
@ -831,14 +830,6 @@ const BookTable = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface GridComponentProps {
|
|
||||||
LoadingOverlay: (props: LinearProgressProps) => JSX.Element;
|
|
||||||
NoResultsOverlay?: (props: any) => JSX.Element;
|
|
||||||
NoRowsOverlay?: (props: any) => JSX.Element;
|
|
||||||
Footer?: (props: any) => JSX.Element;
|
|
||||||
Toolbar?: (props: any) => JSX.Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NoResultsOverlay = function (): JSX.Element {
|
const NoResultsOverlay = function (): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -409,9 +409,8 @@ const AutocompletePayments: React.FC<AutocompletePaymentsProps> = (props) => {
|
|||||||
))}
|
))}
|
||||||
{qttHiddenTags > 0 ? (
|
{qttHiddenTags > 0 ? (
|
||||||
<StyledChip
|
<StyledChip
|
||||||
sx={{ borderRadius: 1 }}
|
|
||||||
label={`+${qttHiddenTags}`}
|
label={`+${qttHiddenTags}`}
|
||||||
sx={{ height: '1.6rem' }}
|
sx={{ borderRadius: 1, height: '1.6rem' }}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useMemo } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Select,
|
Select,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||||
import {
|
import {
|
||||||
@ -26,13 +26,10 @@ import {
|
|||||||
AccountBalance,
|
AccountBalance,
|
||||||
AttachMoney,
|
AttachMoney,
|
||||||
QrCode,
|
QrCode,
|
||||||
ControlPoint,
|
|
||||||
} 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 SwapCalls from '@mui/icons-material/SwapCalls';
|
||||||
import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext';
|
|
||||||
import { GarageContext, UseGarageStoreType } from '../../contexts/GarageContext';
|
|
||||||
import { apiClient } from '../../services/api';
|
import { apiClient } from '../../services/api';
|
||||||
|
|
||||||
interface SettingsFormProps {
|
interface SettingsFormProps {
|
||||||
@ -41,8 +38,6 @@ interface SettingsFormProps {
|
|||||||
|
|
||||||
const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
||||||
const { fav, setFav, settings, setSettings } = useContext<UseAppStoreType>(AppContext);
|
const { fav, setFav, settings, setSettings } = useContext<UseAppStoreType>(AppContext);
|
||||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
|
||||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const fontSizes = [
|
const fontSizes = [
|
||||||
|
@ -4,19 +4,17 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
type SetStateAction,
|
type SetStateAction,
|
||||||
useMemo,
|
|
||||||
useContext,
|
useContext,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { type Order, Federation, Settings, Coordinator } from '../models';
|
import { type Order, Federation, Settings } from '../models';
|
||||||
|
|
||||||
import { federationLottery } from '../utils';
|
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 NativeRobosats from '../services/Native';
|
import { type Origin, type Origins } from '../models/Coordinator.model';
|
||||||
import { Origins } from '../models/Coordinator.model';
|
|
||||||
|
|
||||||
// Refresh delays (ms) according to Order status
|
// Refresh delays (ms) according to Order status
|
||||||
const defaultDelay = 5000;
|
const defaultDelay = 5000;
|
||||||
@ -175,14 +173,15 @@ export const FederationContextProvider = ({
|
|||||||
federated: false,
|
federated: false,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
};
|
};
|
||||||
|
const origins: Origins = {
|
||||||
|
clearnet: undefined,
|
||||||
|
onion: url as Origin,
|
||||||
|
i2p: undefined,
|
||||||
|
};
|
||||||
if (settings.network === 'mainnet') {
|
if (settings.network === 'mainnet') {
|
||||||
attributes.mainnet = {
|
attributes.mainnet = origins;
|
||||||
onion: url,
|
|
||||||
} as Origins;
|
|
||||||
} else {
|
} else {
|
||||||
attributes.testnet = {
|
attributes.testnet = origins;
|
||||||
onion: url,
|
|
||||||
} as Origins;
|
|
||||||
}
|
}
|
||||||
federation.addCoordinator(origin, settings, hostUrl, attributes);
|
federation.addCoordinator(origin, settings, hostUrl, attributes);
|
||||||
const newCoordinator = federation.coordinators[alias];
|
const newCoordinator = federation.coordinators[alias];
|
||||||
|
@ -210,7 +210,7 @@ export class Coordinator {
|
|||||||
|
|
||||||
generateAllMakerAvatars = async (data: [PublicOrder]): Promise<void> => {
|
generateAllMakerAvatars = async (data: [PublicOrder]): Promise<void> => {
|
||||||
for (const order of data) {
|
for (const order of data) {
|
||||||
roboidentitiesClient.generateRobohash(order.maker_hash_id, 'small');
|
void roboidentitiesClient.generateRobohash(order.maker_hash_id, 'small');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export class Federation {
|
|||||||
settings: Settings,
|
settings: Settings,
|
||||||
hostUrl: string,
|
hostUrl: string,
|
||||||
attributes: Record<any, any>,
|
attributes: Record<any, any>,
|
||||||
) => {
|
): void => {
|
||||||
const value = {
|
const value = {
|
||||||
...coordinatorDefaultValues,
|
...coordinatorDefaultValues,
|
||||||
...attributes,
|
...attributes,
|
||||||
@ -115,7 +115,7 @@ export class Federation {
|
|||||||
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
||||||
this.updateEnabledCoordinators();
|
this.updateEnabledCoordinators();
|
||||||
for (const coor of Object.values(this.coordinators)) {
|
for (const coor of Object.values(this.coordinators)) {
|
||||||
coor.update(() => {
|
void coor.update(() => {
|
||||||
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
||||||
this.onCoordinatorSaved();
|
this.onCoordinatorSaved();
|
||||||
});
|
});
|
||||||
@ -128,7 +128,7 @@ export class Federation {
|
|||||||
this.triggerHook('onCoordinatorUpdate');
|
this.triggerHook('onCoordinatorUpdate');
|
||||||
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)) {
|
||||||
coor.updateBook(() => {
|
void coor.updateBook(() => {
|
||||||
this.onCoordinatorSaved();
|
this.onCoordinatorSaved();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Coordinator, type Order } from '.';
|
import { type Coordinator, type Order } from '.';
|
||||||
import { systemClient } from '../services/System';
|
import { systemClient } from '../services/System';
|
||||||
import { saveAsJson } from '../utils';
|
import { saveAsJson } from '../utils';
|
||||||
import Slot from './Slot.model';
|
import Slot from './Slot.model';
|
||||||
@ -59,8 +59,13 @@ class Garage {
|
|||||||
const rawSlots = JSON.parse(slotsDump);
|
const rawSlots = JSON.parse(slotsDump);
|
||||||
Object.values(rawSlots).forEach((rawSlot: Record<any, any>) => {
|
Object.values(rawSlots).forEach((rawSlot: Record<any, any>) => {
|
||||||
if (rawSlot?.token) {
|
if (rawSlot?.token) {
|
||||||
this.slots[rawSlot.token] = new Slot(rawSlot.token, Object.keys(rawSlot.robots), {}, () =>
|
this.slots[rawSlot.token] = new Slot(
|
||||||
this.triggerHook('onRobotUpdate'),
|
rawSlot.token,
|
||||||
|
Object.keys(rawSlot.robots),
|
||||||
|
{},
|
||||||
|
() => {
|
||||||
|
this.triggerHook('onRobotUpdate');
|
||||||
|
},
|
||||||
);
|
);
|
||||||
Object.keys(rawSlot.robots).forEach((shortAlias) => {
|
Object.keys(rawSlot.robots).forEach((shortAlias) => {
|
||||||
const rawRobot = rawSlot.robots[shortAlias];
|
const rawRobot = rawSlot.robots[shortAlias];
|
||||||
@ -132,9 +137,9 @@ class Garage {
|
|||||||
if (!token || !shortAliases) return;
|
if (!token || !shortAliases) return;
|
||||||
|
|
||||||
if (this.getSlot(token) === null) {
|
if (this.getSlot(token) === null) {
|
||||||
this.slots[token] = new Slot(token, shortAliases, attributes, () =>
|
this.slots[token] = new Slot(token, shortAliases, 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 { Coordinator, Garage, Robot, type Order } from '.';
|
import { type Coordinator, type Garage, Robot, type Order } from '.';
|
||||||
import { roboidentitiesClient } from '../services/Roboidentities/Web';
|
import { roboidentitiesClient } from '../services/Roboidentities/Web';
|
||||||
|
|
||||||
class Slot {
|
class Slot {
|
||||||
@ -13,12 +13,12 @@ class Slot {
|
|||||||
|
|
||||||
this.hashId = sha256(sha256(this.token));
|
this.hashId = sha256(sha256(this.token));
|
||||||
this.nickname = null;
|
this.nickname = null;
|
||||||
roboidentitiesClient.generateRoboname(this.hashId).then((nickname) => {
|
void roboidentitiesClient.generateRoboname(this.hashId).then((nickname) => {
|
||||||
this.nickname = nickname;
|
this.nickname = nickname;
|
||||||
onRobotUpdate();
|
onRobotUpdate();
|
||||||
});
|
});
|
||||||
roboidentitiesClient.generateRobohash(this.hashId, 'small');
|
void roboidentitiesClient.generateRobohash(this.hashId, 'small');
|
||||||
roboidentitiesClient.generateRobohash(this.hashId, 'large');
|
void roboidentitiesClient.generateRobohash(this.hashId, 'large');
|
||||||
|
|
||||||
this.robots = shortAliases.reduce((acc: Record<string, Robot>, shortAlias: string) => {
|
this.robots = shortAliases.reduce((acc: Record<string, Robot>, shortAlias: string) => {
|
||||||
acc[shortAlias] = new Robot(robotAttributes);
|
acc[shortAlias] = new Robot(robotAttributes);
|
||||||
@ -82,7 +82,7 @@ class Slot {
|
|||||||
pubKey: defaultRobot.pubKey,
|
pubKey: defaultRobot.pubKey,
|
||||||
encPrivKey: defaultRobot.encPrivKey,
|
encPrivKey: defaultRobot.encPrivKey,
|
||||||
});
|
});
|
||||||
coordinator.fetchRobot(garage, defaultRobot.token);
|
void coordinator.fetchRobot(garage, defaultRobot.token);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import RoboidentitiesClientNativeClient from './RoboidentitiesNativeClient';
|
import RoboidentitiesClientNativeClient from './RoboidentitiesNativeClient';
|
||||||
import { RoboidentitiesClient } from './type';
|
import { type RoboidentitiesClient } from './type';
|
||||||
|
|
||||||
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientNativeClient();
|
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientNativeClient();
|
||||||
|
@ -31,8 +31,8 @@ class RoboidentitiesNativeClient implements RoboidentitiesClient {
|
|||||||
type: 'robohash',
|
type: 'robohash',
|
||||||
detail: key,
|
detail: key,
|
||||||
});
|
});
|
||||||
const result = response ? Object.values(response)[0] : '';
|
const result: string = response ? Object.values(response)[0] : '';
|
||||||
const image = `data:image/png;base64,${result}`;
|
const image: string = `data:image/png;base64,${result}`;
|
||||||
this.robohashes[key] = image;
|
this.robohashes[key] = image;
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,14 @@ import { robohash } from './RobohashGenerator';
|
|||||||
|
|
||||||
class RoboidentitiesClientWebClient implements RoboidentitiesClient {
|
class RoboidentitiesClientWebClient implements RoboidentitiesClient {
|
||||||
public generateRoboname: (initialString: string) => Promise<string> = async (initialString) => {
|
public generateRoboname: (initialString: string) => Promise<string> = async (initialString) => {
|
||||||
return new Promise<string>(async (resolve, _reject) => {
|
return await new Promise<string>((resolve, _reject) => {
|
||||||
resolve(generate_roboname(initialString));
|
resolve(generate_roboname(initialString));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public generateRobohash: (initialString: string, size: 'small' | 'large') => Promise<string> =
|
public generateRobohash: (initialString: string, size: 'small' | 'large') => Promise<string> =
|
||||||
async (initialString, size) => {
|
async (initialString, size) => {
|
||||||
return robohash.generate(initialString, size);
|
return await robohash.generate(initialString, size);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import RoboidentitiesClientWebClient from './RoboidentitiesWebClient';
|
import RoboidentitiesClientWebClient from './RoboidentitiesWebClient';
|
||||||
import { RoboidentitiesClient } from './type';
|
import { type RoboidentitiesClient } from './type';
|
||||||
|
|
||||||
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientWebClient();
|
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientWebClient();
|
||||||
|
@ -5,7 +5,7 @@ import ApiWebClient from '../ApiWebClient';
|
|||||||
class ApiNativeClient implements ApiClient {
|
class ApiNativeClient implements ApiClient {
|
||||||
public useProxy = true;
|
public useProxy = true;
|
||||||
|
|
||||||
private webClient: ApiClient = new ApiWebClient();
|
private readonly webClient: ApiClient = new ApiWebClient();
|
||||||
|
|
||||||
private readonly assetsPromises = new Map<string, Promise<string | undefined>>();
|
private readonly assetsPromises = new Map<string, Promise<string | undefined>>();
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class ApiNativeClient implements ApiClient {
|
|||||||
|
|
||||||
public delete: (baseUrl: string, path: string, auth?: Auth) => Promise<object | undefined> =
|
public delete: (baseUrl: string, path: string, auth?: Auth) => Promise<object | undefined> =
|
||||||
async (baseUrl, path, auth) => {
|
async (baseUrl, path, auth) => {
|
||||||
if (!this.useProxy) return this.webClient.delete(baseUrl, path, auth);
|
if (!this.useProxy) return await this.webClient.delete(baseUrl, path, auth);
|
||||||
return await window.NativeRobosats?.postMessage({
|
return await window.NativeRobosats?.postMessage({
|
||||||
category: 'http',
|
category: 'http',
|
||||||
type: 'delete',
|
type: 'delete',
|
||||||
@ -71,7 +71,7 @@ class ApiNativeClient implements ApiClient {
|
|||||||
body: object,
|
body: object,
|
||||||
auth?: Auth,
|
auth?: Auth,
|
||||||
) => Promise<object | undefined> = async (baseUrl, path, body, auth) => {
|
) => Promise<object | undefined> = async (baseUrl, path, body, auth) => {
|
||||||
if (!this.useProxy) return this.webClient.post(baseUrl, path, body, auth);
|
if (!this.useProxy) return await this.webClient.post(baseUrl, path, body, auth);
|
||||||
return await window.NativeRobosats?.postMessage({
|
return await window.NativeRobosats?.postMessage({
|
||||||
category: 'http',
|
category: 'http',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
@ -87,7 +87,7 @@ class ApiNativeClient implements ApiClient {
|
|||||||
path,
|
path,
|
||||||
auth,
|
auth,
|
||||||
) => {
|
) => {
|
||||||
if (!this.useProxy) return this.webClient.get(baseUrl, path, auth);
|
if (!this.useProxy) return await this.webClient.get(baseUrl, path, auth);
|
||||||
return await window.NativeRobosats?.postMessage({
|
return await window.NativeRobosats?.postMessage({
|
||||||
category: 'http',
|
category: 'http',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
|
@ -16,14 +16,6 @@ export interface AggregatedInfo {
|
|||||||
version: Version;
|
version: Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
type toAdd =
|
|
||||||
| 'num_public_buy_orders'
|
|
||||||
| 'num_public_sell_orders'
|
|
||||||
| 'book_liquidity'
|
|
||||||
| 'active_robots_today'
|
|
||||||
| 'last_day_volume'
|
|
||||||
| 'lifetime_volume';
|
|
||||||
|
|
||||||
export const weightedMean = (arrValues: number[], arrWeights: number[]): number => {
|
export const weightedMean = (arrValues: number[], arrWeights: number[]): number => {
|
||||||
if (arrValues.length === 0) {
|
if (arrValues.length === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
2229
mobile/package-lock.json
generated
2229
mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
|||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/react-native": "^0.71.3",
|
"@types/react-native": "^0.71.3",
|
||||||
"@types/react-test-renderer": "^18.0.0",
|
"@types/react-test-renderer": "^18.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
"@typescript-eslint/eslint-plugin": "^8.0.1",
|
||||||
"@typescript-eslint/parser": "^5.59.6",
|
"@typescript-eslint/parser": "^5.59.6",
|
||||||
"babel-jest": "^29.7.0",
|
"babel-jest": "^29.7.0",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.39.0",
|
||||||
@ -35,13 +35,13 @@
|
|||||||
"eslint-import-resolver-typescript": "^3.6.0",
|
"eslint-import-resolver-typescript": "^3.6.0",
|
||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-n": "^15.7.0",
|
"eslint-plugin-n": "^15.7.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.6.0",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.35.0",
|
||||||
"eslint-plugin-react-hooks": "^4.6.2",
|
"eslint-plugin-react-hooks": "^4.6.2",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"metro-react-native-babel-preset": "^0.75.1",
|
"metro-react-native-babel-preset": "^0.75.1",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.3.3",
|
||||||
"react-test-renderer": "18.2.0",
|
"react-test-renderer": "18.2.0",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
django==5.0.6
|
django==5.0.8
|
||||||
django-admin-relation-links==0.2.5
|
django-admin-relation-links==0.2.5
|
||||||
django-celery-beat==2.6.0
|
django-celery-beat==2.6.0
|
||||||
django-celery-results==2.5.1
|
django-celery-results==2.5.1
|
||||||
@ -19,7 +19,7 @@ ring==0.10.1
|
|||||||
gunicorn==22.0.0
|
gunicorn==22.0.0
|
||||||
psycopg2==2.9.9
|
psycopg2==2.9.9
|
||||||
SQLAlchemy==2.0.16
|
SQLAlchemy==2.0.16
|
||||||
django-import-export==4.1.0
|
django-import-export==4.1.1
|
||||||
requests[socks]
|
requests[socks]
|
||||||
shapely==2.0.4
|
shapely==2.0.4
|
||||||
python-gnupg==0.5.2
|
python-gnupg==0.5.2
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
coverage==7.5.0
|
coverage==7.6.0
|
||||||
ruff==0.5.1
|
ruff==0.5.1
|
||||||
git+https://github.com/Reckless-Satoshi/drf-openapi-tester.git@soften-django-requirements
|
git+https://github.com/Reckless-Satoshi/drf-openapi-tester.git@soften-django-requirements
|
||||||
pre-commit==3.7.0
|
pre-commit==3.7.0
|
Loading…
Reference in New Issue
Block a user