mirror of
https://github.com/Reckless-Satoshi/robosats.git
synced 2024-09-11 11:55:26 +03:00
Merge branch 'main' into update-order-nav-bar-on-time
This commit is contained in:
commit
34738e8a51
@ -1,5 +1,6 @@
|
||||
import json
|
||||
|
||||
from decimal import Decimal
|
||||
from django.core.validators import MinValueValidator
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
@ -18,7 +19,7 @@ class Currency(models.Model):
|
||||
decimal_places=4,
|
||||
default=None,
|
||||
null=True,
|
||||
validators=[MinValueValidator(0)],
|
||||
validators=[MinValueValidator(Decimal(0))],
|
||||
)
|
||||
timestamp = models.DateTimeField(default=timezone.now)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
from decouple import config
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from django.db import models
|
||||
@ -27,21 +28,24 @@ class MarketTick(models.Model):
|
||||
decimal_places=2,
|
||||
default=None,
|
||||
null=True,
|
||||
validators=[MinValueValidator(0)],
|
||||
validators=[MinValueValidator(Decimal(0))],
|
||||
)
|
||||
volume = models.DecimalField(
|
||||
max_digits=8,
|
||||
decimal_places=8,
|
||||
default=None,
|
||||
null=True,
|
||||
validators=[MinValueValidator(0)],
|
||||
validators=[MinValueValidator(Decimal(0))],
|
||||
)
|
||||
premium = models.DecimalField(
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
default=None,
|
||||
null=True,
|
||||
validators=[MinValueValidator(-100), MaxValueValidator(999)],
|
||||
validators=[
|
||||
MinValueValidator(Decimal(-100)),
|
||||
MaxValueValidator(Decimal(999))
|
||||
],
|
||||
blank=True,
|
||||
)
|
||||
currency = models.ForeignKey("api.Currency", null=True, on_delete=models.SET_NULL)
|
||||
@ -52,7 +56,10 @@ class MarketTick(models.Model):
|
||||
max_digits=4,
|
||||
decimal_places=4,
|
||||
default=0,
|
||||
validators=[MinValueValidator(0), MaxValueValidator(1)],
|
||||
validators=[
|
||||
MinValueValidator(Decimal(0)),
|
||||
MaxValueValidator(Decimal(1))
|
||||
],
|
||||
)
|
||||
|
||||
def log_a_tick(order):
|
||||
|
@ -1,3 +1,4 @@
|
||||
from decimal import Decimal
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
@ -58,7 +59,10 @@ class OnchainPayment(models.Model):
|
||||
default=2.05,
|
||||
null=False,
|
||||
blank=False,
|
||||
validators=[MinValueValidator(1), MaxValueValidator(999)],
|
||||
validators=[
|
||||
MinValueValidator(Decimal(1)),
|
||||
MaxValueValidator(Decimal(999))
|
||||
],
|
||||
)
|
||||
mining_fee_rate = models.DecimalField(
|
||||
max_digits=6,
|
||||
@ -66,7 +70,10 @@ class OnchainPayment(models.Model):
|
||||
default=2.05,
|
||||
null=False,
|
||||
blank=False,
|
||||
validators=[MinValueValidator(1), MaxValueValidator(999)],
|
||||
validators=[
|
||||
MinValueValidator(Decimal(1)),
|
||||
MaxValueValidator(Decimal(999))
|
||||
],
|
||||
)
|
||||
mining_fee_sats = models.PositiveBigIntegerField(default=0, null=False, blank=False)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# We use custom seeded UUID generation during testing
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
from decouple import config
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
@ -90,7 +91,10 @@ class Order(models.Model):
|
||||
decimal_places=2,
|
||||
default=0,
|
||||
null=True,
|
||||
validators=[MinValueValidator(-100), MaxValueValidator(999)],
|
||||
validators=[
|
||||
MinValueValidator(Decimal(-100)),
|
||||
MaxValueValidator(Decimal(999))
|
||||
],
|
||||
blank=True,
|
||||
)
|
||||
# explicit
|
||||
@ -135,8 +139,8 @@ class Order(models.Model):
|
||||
default=settings.DEFAULT_BOND_SIZE,
|
||||
null=False,
|
||||
validators=[
|
||||
MinValueValidator(settings.MIN_BOND_SIZE), # 2 %
|
||||
MaxValueValidator(settings.MAX_BOND_SIZE), # 15 %
|
||||
MinValueValidator(Decimal(settings.MIN_BOND_SIZE)), # 2 %
|
||||
MaxValueValidator(Decimal(settings.MAX_BOND_SIZE)), # 15 %
|
||||
],
|
||||
blank=False,
|
||||
)
|
||||
@ -147,8 +151,8 @@ class Order(models.Model):
|
||||
decimal_places=6,
|
||||
null=True,
|
||||
validators=[
|
||||
MinValueValidator(-90),
|
||||
MaxValueValidator(90),
|
||||
MinValueValidator(Decimal(-90)),
|
||||
MaxValueValidator(Decimal(90)),
|
||||
],
|
||||
blank=True,
|
||||
)
|
||||
@ -157,8 +161,8 @@ class Order(models.Model):
|
||||
decimal_places=6,
|
||||
null=True,
|
||||
validators=[
|
||||
MinValueValidator(-180),
|
||||
MaxValueValidator(180),
|
||||
MinValueValidator(Decimal(-180)),
|
||||
MaxValueValidator(Decimal(180)),
|
||||
],
|
||||
blank=True,
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: RoboSats REST API
|
||||
version: 0.6.0
|
||||
version: 0.6.2
|
||||
x-logo:
|
||||
url: https://raw.githubusercontent.com/Reckless-Satoshi/robosats/main/frontend/static/assets/images/robosats-0.1.1-banner.png
|
||||
backgroundColor: '#FFFFFF'
|
||||
|
8
frontend/package-lock.json
generated
8
frontend/package-lock.json
generated
@ -79,7 +79,7 @@
|
||||
"eslint-plugin-react": "^7.34.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"jest": "^29.6.1",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.3.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.2",
|
||||
"webpack": "^5.89.0",
|
||||
@ -15096,9 +15096,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
|
||||
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
|
@ -41,7 +41,7 @@
|
||||
"eslint-plugin-react": "^7.34.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"jest": "^29.6.1",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.3.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.2",
|
||||
"webpack": "^5.89.0",
|
||||
|
@ -44,7 +44,7 @@ const RobotPage = (): JSX.Element => {
|
||||
const token = urlToken ?? garage.currentSlot;
|
||||
if (token !== undefined && token !== null && page === 'robot') {
|
||||
setInputToken(token);
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON') {
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
||||
getGenerateRobot(token);
|
||||
setView('profile');
|
||||
}
|
||||
@ -83,7 +83,7 @@ const RobotPage = (): JSX.Element => {
|
||||
garage.deleteSlot();
|
||||
};
|
||||
|
||||
if (!(window.NativeRobosats === undefined) && !(torStatus === 'ON')) {
|
||||
if (settings.useProxy && !(window.NativeRobosats === undefined) && !(torStatus === 'ON')) {
|
||||
return (
|
||||
<Paper
|
||||
elevation={12}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useAutocomplete from '@mui/base/useAutocomplete';
|
||||
import { useAutocomplete } from '@mui/base/useAutocomplete';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import {
|
||||
Button,
|
||||
|
@ -90,12 +90,6 @@ const MakerForm = ({
|
||||
const minRangeAmountMultiple = 1.6;
|
||||
const amountSafeThresholds = [1.03, 0.98];
|
||||
|
||||
useEffect(() => {
|
||||
// Why?
|
||||
// const slot = garage.getSlot();
|
||||
// if (slot?.token) void federation.fetchRobot(garage, slot?.token);
|
||||
}, [garage.currentSlot]);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrencyCode(currencyDict[fav.currency === 0 ? 1 : fav.currency]);
|
||||
}, [coordinatorUpdatedAt]);
|
||||
|
@ -178,7 +178,7 @@ const OrderDetails = ({
|
||||
: coordinator.info?.taker_fee ?? 0;
|
||||
const defaultRoutingBudget = 0.001;
|
||||
const btc_now = order.satoshis_now / 100000000;
|
||||
const rate = order.amount > 0 ? order.amount / btc_now : Number(order.max_amount) / btc_now;
|
||||
const rate = Number(order.max_amount ?? order.amount) / btc_now;
|
||||
|
||||
if (isBuyer) {
|
||||
if (order.amount > 0) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import {
|
||||
@ -28,17 +28,19 @@ import {
|
||||
QrCode,
|
||||
} from '@mui/icons-material';
|
||||
import { systemClient } from '../../services/System';
|
||||
import { TorIcon } from '../Icons';
|
||||
import SwapCalls from '@mui/icons-material/SwapCalls';
|
||||
import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext';
|
||||
import { GarageContext, UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
|
||||
interface SettingsFormProps {
|
||||
dense?: boolean;
|
||||
}
|
||||
|
||||
const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
||||
const { fav, setFav, origin, hostUrl, 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 { t } = useTranslation();
|
||||
const fontSizes = [
|
||||
@ -237,6 +239,29 @@ const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</ListItem>
|
||||
|
||||
{window.NativeRobosats !== undefined && (
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<TorIcon />
|
||||
</ListItemIcon>
|
||||
<ToggleButtonGroup
|
||||
exclusive={true}
|
||||
value={settings.useProxy}
|
||||
onChange={(_e, useProxy) => {
|
||||
setSettings({ ...settings, useProxy });
|
||||
systemClient.setItem('settings_use_proxy', String(useProxy));
|
||||
}}
|
||||
>
|
||||
<ToggleButton value={true} color='primary'>
|
||||
{t('Build-in')}
|
||||
</ToggleButton>
|
||||
<ToggleButton value={false} color='secondary'>
|
||||
{t('Disabled')}
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</ListItem>
|
||||
)}
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
@ -55,10 +55,10 @@ const TorIndicator = ({
|
||||
};
|
||||
|
||||
const TorConnectionBadge = (): JSX.Element => {
|
||||
const { torStatus } = useContext<UseAppStoreType>(AppContext);
|
||||
const { torStatus, settings } = useContext<UseAppStoreType>(AppContext);
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (window?.NativeRobosats == null) {
|
||||
if (window?.NativeRobosats == null || !settings.useProxy) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
@ -222,6 +222,7 @@ export const SuccessfulPrompt = ({
|
||||
takerSummary={order.taker_summary}
|
||||
platformSummary={order.platform_summary}
|
||||
orderId={order.id}
|
||||
coordinatorLongAlias={federation.getCoordinator(order.shortAlias)?.longAlias}
|
||||
/>
|
||||
</Grid>
|
||||
) : (
|
||||
|
@ -43,6 +43,7 @@ interface Props {
|
||||
makerHashId: string;
|
||||
takerHashId: string;
|
||||
currencyCode: string;
|
||||
coordinatorLongAlias: string;
|
||||
makerSummary: TradeRobotSummary;
|
||||
takerSummary: TradeRobotSummary;
|
||||
platformSummary: TradeCoordinatorSummary;
|
||||
@ -54,6 +55,7 @@ const TradeSummary = ({
|
||||
makerHashId,
|
||||
takerHashId,
|
||||
currencyCode,
|
||||
coordinatorLongAlias,
|
||||
makerSummary,
|
||||
takerSummary,
|
||||
platformSummary,
|
||||
@ -72,6 +74,7 @@ const TradeSummary = ({
|
||||
|
||||
const onClickExport = function (): void {
|
||||
const summary = {
|
||||
coordinator: coordinatorLongAlias,
|
||||
order_id: orderId,
|
||||
currency: currencyCode,
|
||||
maker: makerSummary,
|
||||
|
@ -111,12 +111,14 @@ export const FederationContextProvider = ({
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// On bitcoin network change we reset book, limits and federation info and fetch everything again
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON') {
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
||||
void federation.updateUrl(origin, settings, hostUrl);
|
||||
void federation.update();
|
||||
|
||||
const token = garage.getSlot()?.getRobot()?.token;
|
||||
if (token) void federation.fetchRobot(garage, token);
|
||||
}
|
||||
}, [settings.network, torStatus]);
|
||||
}, [settings.network, settings.useProxy, torStatus]);
|
||||
|
||||
const onOrderReceived = (order: Order): void => {
|
||||
let newDelay = defaultDelay;
|
||||
@ -178,15 +180,6 @@ export const FederationContextProvider = ({
|
||||
if (page === 'offers') void federation.updateBook();
|
||||
}, [page]);
|
||||
|
||||
// use effects to fetchRobots on app start and network change
|
||||
useEffect(() => {
|
||||
const slot = garage.getSlot();
|
||||
const robot = slot?.getRobot();
|
||||
|
||||
if (robot && garage.currentSlot && slot?.token && robot.encPrivKey && robot.pubKey) {
|
||||
void federation.fetchRobot(garage, slot.token);
|
||||
}
|
||||
}, [settings.network]);
|
||||
// use effects to fetchRobots on Profile open
|
||||
useEffect(() => {
|
||||
const slot = garage.getSlot();
|
||||
|
@ -145,7 +145,7 @@ export class Coordinator {
|
||||
public loadingInfo: boolean = false;
|
||||
public limits: LimitList = {};
|
||||
public loadingLimits: boolean = false;
|
||||
public loadingRobot: boolean = true;
|
||||
public loadingRobot: string | null;
|
||||
|
||||
updateUrl = (origin: Origin, settings: Settings, hostUrl: string): void => {
|
||||
if (settings.selfhostedClient && this.shortAlias !== 'local') {
|
||||
@ -185,6 +185,7 @@ export class Coordinator {
|
||||
if (this.loadingBook) return;
|
||||
|
||||
this.loadingBook = true;
|
||||
this.book = [];
|
||||
|
||||
apiClient
|
||||
.get(this.url, `${this.basePath}/api/book/`)
|
||||
@ -297,7 +298,7 @@ export class Coordinator {
|
||||
};
|
||||
|
||||
fetchRobot = async (garage: Garage, token: string): Promise<Robot | null> => {
|
||||
if (!this.enabled || !token) return null;
|
||||
if (!this.enabled || !token || this.loadingRobot === token) return null;
|
||||
|
||||
const robot = garage?.getSlot(token)?.getRobot() ?? null;
|
||||
const authHeaders = robot?.getAuthHeaders();
|
||||
@ -308,6 +309,8 @@ export class Coordinator {
|
||||
|
||||
if (!hasEnoughEntropy) return null;
|
||||
|
||||
this.loadingRobot = token;
|
||||
|
||||
garage.updateRobot(token, this.shortAlias, { loading: true });
|
||||
|
||||
const newAttributes = await apiClient
|
||||
@ -330,7 +333,8 @@ export class Coordinator {
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
})
|
||||
.finally(() => (this.loadingRobot = null));
|
||||
|
||||
garage.updateRobot(token, this.shortAlias, {
|
||||
...newAttributes,
|
||||
|
@ -100,7 +100,7 @@ export class Federation {
|
||||
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
||||
this.updateEnabledCoordinators();
|
||||
for (const coor of Object.values(this.coordinators)) {
|
||||
await coor.update(() => {
|
||||
coor.update(() => {
|
||||
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
||||
this.onCoordinatorSaved();
|
||||
});
|
||||
@ -109,10 +109,11 @@ export class Federation {
|
||||
|
||||
updateBook = async (): Promise<void> => {
|
||||
this.loading = true;
|
||||
this.book = [];
|
||||
this.triggerHook('onCoordinatorUpdate');
|
||||
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
||||
for (const coor of Object.values(this.coordinators)) {
|
||||
await coor.updateBook(() => {
|
||||
coor.updateBook(() => {
|
||||
this.onCoordinatorSaved();
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import i18n from '../i18n/Web';
|
||||
import { systemClient } from '../services/System';
|
||||
import { apiClient } from '../services/api';
|
||||
import { getHost } from '../utils';
|
||||
|
||||
export type Language =
|
||||
@ -42,8 +43,13 @@ class BaseSettings {
|
||||
: i18n.resolvedLanguage.substring(0, 2);
|
||||
|
||||
const networkCookie = systemClient.getItem('settings_network');
|
||||
this.network = networkCookie !== '' ? networkCookie : 'mainnet';
|
||||
this.network = networkCookie && networkCookie !== '' ? networkCookie : 'mainnet';
|
||||
this.host = getHost();
|
||||
|
||||
const useProxy = systemClient.getItem('settings_use_proxy');
|
||||
this.useProxy = window.NativeRobosats !== undefined && useProxy !== 'false';
|
||||
|
||||
apiClient.useProxy = this.useProxy;
|
||||
}
|
||||
|
||||
public frontend: 'basic' | 'pro' = 'basic';
|
||||
@ -56,6 +62,7 @@ class BaseSettings {
|
||||
public host?: string;
|
||||
public unsafeClient: boolean = false;
|
||||
public selfhostedClient: boolean = false;
|
||||
public useProxy: boolean;
|
||||
}
|
||||
|
||||
export default BaseSettings;
|
||||
|
@ -28,7 +28,7 @@ class SystemNativeClient implements SystemClient {
|
||||
};
|
||||
|
||||
public setCookie: (key: string, value: string) => void = (key, value) => {
|
||||
delete window.NativeRobosats?.cookies[key];
|
||||
window.NativeRobosats?.loadCookie({ key, value });
|
||||
void window.NativeRobosats?.postMessage({
|
||||
category: 'system',
|
||||
type: 'setCookie',
|
||||
|
@ -1,8 +1,12 @@
|
||||
import { type ApiClient, type Auth } from '..';
|
||||
import { systemClient } from '../../System';
|
||||
import ApiWebClient from '../ApiWebClient';
|
||||
|
||||
class ApiNativeClient implements ApiClient {
|
||||
private assetsCache: Record<string, string> = {};
|
||||
public useProxy = true;
|
||||
|
||||
private webClient: ApiClient = new ApiWebClient();
|
||||
|
||||
private readonly assetsPromises = new Map<string, Promise<string | undefined>>();
|
||||
|
||||
private readonly getHeaders: (auth?: Auth) => HeadersInit = (auth) => {
|
||||
@ -51,6 +55,7 @@ class ApiNativeClient implements ApiClient {
|
||||
|
||||
public delete: (baseUrl: string, path: string, auth?: Auth) => Promise<object | undefined> =
|
||||
async (baseUrl, path, auth) => {
|
||||
if (!this.proxy) this.webClient.delete(baseUrl, path, auth);
|
||||
return await window.NativeRobosats?.postMessage({
|
||||
category: 'http',
|
||||
type: 'delete',
|
||||
@ -66,6 +71,7 @@ class ApiNativeClient implements ApiClient {
|
||||
body: object,
|
||||
auth?: Auth,
|
||||
) => Promise<object | undefined> = async (baseUrl, path, body, auth) => {
|
||||
if (!this.proxy) this.webClient.post(baseUrl, path, body, auth);
|
||||
return await window.NativeRobosats?.postMessage({
|
||||
category: 'http',
|
||||
type: 'post',
|
||||
@ -81,6 +87,7 @@ class ApiNativeClient implements ApiClient {
|
||||
path,
|
||||
auth,
|
||||
) => {
|
||||
if (!this.proxy) this.webClient.get(baseUrl, path, auth);
|
||||
return await window.NativeRobosats?.postMessage({
|
||||
category: 'http',
|
||||
type: 'get',
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { type ApiClient, type Auth } from '..';
|
||||
|
||||
class ApiWebClient implements ApiClient {
|
||||
public useProxy = false;
|
||||
|
||||
private readonly getHeaders: (auth?: Auth) => HeadersInit = (auth) => {
|
||||
let headers = {
|
||||
'Content-Type': 'application/json',
|
||||
|
@ -7,6 +7,7 @@ export interface Auth {
|
||||
}
|
||||
|
||||
export interface ApiClient {
|
||||
useProxy: boolean;
|
||||
post: (baseUrl: string, path: string, body: object, auth?: Auth) => Promise<object | undefined>;
|
||||
put: (baseUrl: string, path: string, body: object, auth?: Auth) => Promise<object | undefined>;
|
||||
get: (baseUrl: string, path: string, auth?: Auth) => Promise<object | undefined>;
|
||||
|
@ -45,7 +45,6 @@ export default function federationLottery(federation: Federation): string[] {
|
||||
// federation[shortAlias] = { badges:{ donatesToDevFund }};
|
||||
// }
|
||||
|
||||
// console.log(federation)
|
||||
// return federation;
|
||||
// }
|
||||
|
||||
@ -58,5 +57,4 @@ export default function federationLottery(federation: Federation): string[] {
|
||||
// results.push(rankedCoordinators);
|
||||
// }
|
||||
|
||||
// console.log(results)
|
||||
// }
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "La teva última ordre #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Fosc",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Clar",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Tvá poslední nabídka #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Deine letzte Order #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Your last order #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Tu última orden #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Oscuro",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Claro",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Zure azken eskaera #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Votre dernière commande #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Sombre",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Il tuo ultimo ordine #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Scuro",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Chiaro",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "前回のオーダー #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "ダーク",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "フィアット",
|
||||
"Light": "ライト",
|
||||
"Mainnet": "メインネット",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Your last order #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Sua última ordem #{{orderID}}",
|
||||
"finished order": "ordem finalizada",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Ваш последний ордер #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Темный",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Фиат",
|
||||
"Light": "Светлый",
|
||||
"Mainnet": "Основная сеть",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Din senaste order #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "Amri yako ya mwisho #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Giza",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Nuru",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "รายการล่าสุดของคุณ #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "Dark",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "Fiat",
|
||||
"Light": "Light",
|
||||
"Mainnet": "Mainnet",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "你的上一笔交易 #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "深色",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "法币",
|
||||
"Light": "浅色",
|
||||
"Mainnet": "主网",
|
||||
|
@ -489,7 +489,9 @@
|
||||
"Your last order #{{orderID}}": "你的上一筆交易 #{{orderID}}",
|
||||
"finished order": "finished order",
|
||||
"#43": "Phrases in components/SettingsForm/index.tsx",
|
||||
"Build-in": "Build-in",
|
||||
"Dark": "深色",
|
||||
"Disabled": "Disabled",
|
||||
"Fiat": "法幣",
|
||||
"Light": "淺色",
|
||||
"Mainnet": "主網",
|
||||
|
@ -71,6 +71,7 @@ const App = () => {
|
||||
loadCookie('settings_mode');
|
||||
loadCookie('settings_light_qr');
|
||||
loadCookie('settings_network');
|
||||
loadCookie('settings_use_proxy');
|
||||
loadCookie('garage_slots').then(() => injectMessageResolve(responseId));
|
||||
};
|
||||
|
||||
|
10
mobile/package-lock.json
generated
10
mobile/package-lock.json
generated
@ -6,7 +6,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "robosats",
|
||||
"version": "0.6.1",
|
||||
"version": "0.6.2",
|
||||
"dependencies": {
|
||||
"@react-native-clipboard/clipboard": "^1.13.2",
|
||||
"@react-native-community/netinfo": "^11.3.0",
|
||||
@ -37,7 +37,7 @@
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"jest": "^29.7.0",
|
||||
"metro-react-native-babel-preset": "^0.75.1",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.3.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
@ -12714,9 +12714,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
|
||||
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
|
@ -41,7 +41,7 @@
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"jest": "^29.7.0",
|
||||
"metro-react-native-babel-preset": "^0.75.1",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.3.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
|
7
tests/README.md
Normal file
7
tests/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Run e2e tests
|
||||
|
||||
```
|
||||
docker compose -f docker-tests.yml --env-file tests/compose.env up -d
|
||||
docker exec coordinator coverage run manage.py test
|
||||
docker exec coordinator coverage report
|
||||
```
|
2013
tests/api_specs.yaml
2013
tests/api_specs.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user