mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 10:56:24 +00:00
Merge pull request #1480 from RoboSats/fix-file-cache-problem-and-static-files-management
Fix file cache problem and static files management
This commit is contained in:
commit
54d98f9169
24
.github/workflows/coordinator-image.yml
vendored
24
.github/workflows/coordinator-image.yml
vendored
@ -21,31 +21,15 @@ jobs:
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-main-js
|
||||
path: frontend/static/frontend/
|
||||
name: django-main-static
|
||||
path: frontend
|
||||
|
||||
- name: 'Download Basic main.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-main-js
|
||||
path: frontend/static/frontend/
|
||||
|
||||
- name: 'Download pro.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-pro-js
|
||||
path: frontend/static/frontend/
|
||||
|
||||
- name: 'Download pro.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-pro-js
|
||||
path: frontend/static/frontend/
|
||||
name: django-main-static
|
||||
path: frontend
|
||||
|
||||
- name: 'Log in to Docker Hub'
|
||||
uses: docker/login-action@v3
|
||||
|
20
.github/workflows/desktop-build.yml
vendored
20
.github/workflows/desktop-build.yml
vendored
@ -27,11 +27,21 @@ jobs:
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Set up frontend dependencies
|
||||
run: |
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build
|
||||
- name: 'Download Basic main.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: desktop-main-static
|
||||
path: desktopApp
|
||||
|
||||
- name: 'Download Basic main.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: desktop-main-static
|
||||
path: desktopApp
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
30
.github/workflows/frontend-build.yml
vendored
30
.github/workflows/frontend-build.yml
vendored
@ -50,20 +50,34 @@ jobs:
|
||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||
cd frontend
|
||||
npm run build
|
||||
- name: 'Archive Web Basic Build Results'
|
||||
- name: 'Archive Django Static Build Results'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: web-main-js
|
||||
name: django-main-static
|
||||
path: |
|
||||
frontend/static/frontend/*main.js
|
||||
frontend/static/frontend/*.wasm
|
||||
- name: 'Archive Web PRO Build Results'
|
||||
frontend/static
|
||||
frontend/templates/frontend/*.html
|
||||
- name: 'Archive Node App Static Build Results'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: web-pro-js
|
||||
name: nodeapp-main-static
|
||||
path: |
|
||||
frontend/static/frontend/*pro.js
|
||||
frontend/static/frontend/*.wasm
|
||||
nodeapp/static
|
||||
nodeapp/*.html
|
||||
- name: 'Archive Desktop App Static Build Results'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: desktop-main-static
|
||||
path: |
|
||||
desktopApp/static
|
||||
desktopApp/*.html
|
||||
- name: 'Archive Django Static Build Results'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: web-main-static
|
||||
path: |
|
||||
web/static
|
||||
web/*.html
|
||||
- name: 'Archive Mobile Build Results'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
8
.github/workflows/integration-tests.yml
vendored
8
.github/workflows/integration-tests.yml
vendored
@ -30,6 +30,14 @@ jobs:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Download static files Artifact'
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: django-main-static
|
||||
path: frontend
|
||||
|
||||
- name: Patch Dockerfile and .env-sample
|
||||
run: |
|
||||
sed -i "1s/FROM python:.*/FROM python:${{ matrix.python-tag }}/" Dockerfile
|
||||
|
31
.github/workflows/selfhosted-client-image.yml
vendored
31
.github/workflows/selfhosted-client-image.yml
vendored
@ -21,40 +21,21 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Copy Static' # Needed since Github actions does not support symlinks
|
||||
run: cp -r frontend/static nodeapp/static
|
||||
|
||||
- name: 'Download basic.selfhosted.js Artifact'
|
||||
- name: 'Download Basic main.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-main-js
|
||||
path: nodeapp/static/frontend/
|
||||
name: nodeapp-main-static
|
||||
path: nodeapp
|
||||
|
||||
- name: 'Download main.js Artifact for a release'
|
||||
- name: 'Download Basic main.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-main-js
|
||||
path: nodeapp/static/frontend/
|
||||
|
||||
- name: 'Download pro.selfhosted.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-pro-js
|
||||
path: nodeapp/static/frontend/
|
||||
|
||||
- name: 'Download pro.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-pro-js
|
||||
path: nodeapp/static/frontend/
|
||||
name: nodeapp-main-static
|
||||
path: nodeapp
|
||||
|
||||
- name: 'Log in to Docker Hub'
|
||||
uses: docker/login-action@v3
|
||||
|
31
.github/workflows/web-client-image.yml
vendored
31
.github/workflows/web-client-image.yml
vendored
@ -21,40 +21,21 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Copy Static' # Needed since Github actions does not support symlinks
|
||||
run: cp -r frontend/static web/static
|
||||
|
||||
- name: 'Download main.js Artifact'
|
||||
- name: 'Download Basic main.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-main-js
|
||||
path: web/static/frontend/
|
||||
name: web-main-static
|
||||
path: web
|
||||
|
||||
- name: 'Download main.js Artifact for a release'
|
||||
- name: 'Download Basic main.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-main-js
|
||||
path: web/static/frontend/
|
||||
|
||||
- name: 'Download pro.js Artifact'
|
||||
if: inputs.semver == '' # Only if workflow fired from frontend-build.yml
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: frontend-build.yml
|
||||
workflow_conclusion: success
|
||||
name: web-pro-js
|
||||
path: web/static/frontend/
|
||||
|
||||
- name: 'Download pro.js Artifact for a release'
|
||||
if: inputs.semver != '' # Only if fired as job in release.yml
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: web-pro-js
|
||||
path: web/static/frontend/
|
||||
name: web-main-static
|
||||
path: web
|
||||
|
||||
- name: 'Log in to Docker Hub'
|
||||
uses: docker/login-action@v3
|
||||
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -634,6 +634,7 @@ frontend/static/assets/avatars*
|
||||
api/lightning/*_grpc.py
|
||||
api/lightning/*_pb2.py
|
||||
api/lightning/pymp*
|
||||
api/lightning/pip*
|
||||
frontend/static/locales/collected_phrases.json
|
||||
frontend/static/admin*
|
||||
frontend/static/rest_framework*
|
||||
@ -641,15 +642,21 @@ frontend/static/import_export*
|
||||
frontend/static/drf_spectacular_sidecar/
|
||||
frontend/src/components/PaymentMethods/Icons/code*
|
||||
frontend/src/components/PaymentMethods/Icons/webp*
|
||||
frontend/static/frontend/**
|
||||
frontend/static/frontend
|
||||
docs/.jekyll-cache*
|
||||
docs/_site*
|
||||
node
|
||||
desktopApp/release-builds
|
||||
|
||||
# mobile frontend statics
|
||||
mobile/html/Web.bundle/js*
|
||||
mobile/html/Web.bundle/css*
|
||||
mobile/html/Web.bundle/assets*
|
||||
# frontend statics
|
||||
frontend/templates/frontend/*.html
|
||||
mobile/html/Web.bundle
|
||||
desktopApp/static
|
||||
desktopApp/*.html
|
||||
web/static
|
||||
web/*.html
|
||||
nodeapp/static
|
||||
nodeapp/*.html
|
||||
|
||||
# Protocol Buffers
|
||||
api/lightning/*.proto
|
||||
|
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="shortcut icon" type="image/png" href="./static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="./static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="./static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="./static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./static/css/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./static/css/leaflet.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.RobosatsSettings = 'web-basic'
|
||||
window.RobosatsClient = 'desktop-app'
|
||||
</script>
|
||||
<script src="./static/frontend/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
../frontend/static
|
1292
frontend/package-lock.json
generated
1292
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,6 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.35.1",
|
||||
"@typescript-eslint/parser": "^5.35.1",
|
||||
"babel-loader": "^9.1.3",
|
||||
"copy-webpack-plugin": "^12.0.1",
|
||||
"eslint": "^8.45.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard-with-typescript": "^36.1.0",
|
||||
@ -40,6 +39,8 @@
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.34.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"filemanager-webpack-plugin": "^8.0.0",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"jest": "^29.6.1",
|
||||
"prettier": "^3.3.3",
|
||||
"ts-node": "^10.9.2",
|
||||
|
@ -15,6 +15,7 @@ import { GarageContextProvider } from './contexts/GarageContext';
|
||||
import { FederationContextProvider } from './contexts/FederationContext';
|
||||
|
||||
const App = (): JSX.Element => {
|
||||
const [client, _view] = window.RobosatsSettings.split('-');
|
||||
return (
|
||||
<StrictMode>
|
||||
<ErrorBoundary>
|
||||
@ -24,11 +25,7 @@ const App = (): JSX.Element => {
|
||||
<FederationContextProvider>
|
||||
<GarageContextProvider>
|
||||
<CssBaseline />
|
||||
{window.NativeRobosats === undefined && window.RobosatsClient === undefined ? (
|
||||
<HostAlert />
|
||||
) : (
|
||||
<TorConnectionBadge />
|
||||
)}
|
||||
{client !== 'mobile' ? <HostAlert /> : <TorConnectionBadge />}
|
||||
<Main />
|
||||
</GarageContextProvider>
|
||||
</FederationContextProvider>
|
||||
|
@ -12,9 +12,10 @@ import { GarageContext, type UseGarageStoreType } from '../contexts/GarageContex
|
||||
import Routes from './Routes';
|
||||
|
||||
const getRouter = (): any => {
|
||||
if (window.NativeRobosats === undefined && window.RobosatsClient === undefined) {
|
||||
const [client, _view] = window.RobosatsSettings.split('-');
|
||||
if (client === 'web') {
|
||||
return BrowserRouter;
|
||||
} else if (window.RobosatsClient === 'desktop-app') {
|
||||
} else if (client === 'desktop') {
|
||||
return HashRouter;
|
||||
} else {
|
||||
return MemoryRouter;
|
||||
|
@ -43,7 +43,7 @@ const RobotProfile = ({
|
||||
setView,
|
||||
width,
|
||||
}: RobotProfileProps): JSX.Element => {
|
||||
const { windowSize } = useContext<UseAppStoreType>(AppContext);
|
||||
const { windowSize, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
|
||||
|
||||
const { t } = useTranslation();
|
||||
@ -317,7 +317,7 @@ const RobotProfile = ({
|
||||
</LoadingButton>
|
||||
</Grid>
|
||||
|
||||
{window.NativeRobosats === undefined ? (
|
||||
{client !== 'mobile' ? (
|
||||
<Grid item>
|
||||
<Button
|
||||
color='primary'
|
||||
|
@ -24,7 +24,7 @@ import { FederationContext, type UseFederationStoreType } from '../../contexts/F
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
|
||||
const RobotPage = (): JSX.Element => {
|
||||
const { torStatus, windowSize, settings, page } = useContext<UseAppStoreType>(AppContext);
|
||||
const { torStatus, windowSize, settings, page, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { federation, sortedCoordinators } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { t } = useTranslation();
|
||||
@ -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' || !settings.useProxy) {
|
||||
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
||||
setView('profile');
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ const RobotPage = (): JSX.Element => {
|
||||
garage.deleteSlot();
|
||||
};
|
||||
|
||||
if (settings.useProxy && !(window.NativeRobosats === undefined) && !(torStatus === 'ON')) {
|
||||
if (settings.useProxy && client === 'mobile' && !(torStatus === 'ON')) {
|
||||
return (
|
||||
<Paper
|
||||
elevation={12}
|
||||
|
@ -4,8 +4,8 @@ import SelfhostedAlert from './SelfhostedAlert';
|
||||
import UnsafeAlert from './UnsafeAlert';
|
||||
|
||||
const HostAlert = (): JSX.Element => {
|
||||
const { settings } = useContext<UseAppStoreType>(AppContext);
|
||||
const component = settings.selfhostedClient ? SelfhostedAlert : UnsafeAlert;
|
||||
const { client } = useContext<UseAppStoreType>(AppContext);
|
||||
const component = client === 'selfhosted' || client === 'desktop' ? SelfhostedAlert : UnsafeAlert;
|
||||
return component();
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@ const RobotAvatar: React.FC<Props> = ({
|
||||
}) => {
|
||||
const [avatarSrc, setAvatarSrc] = useState<string>('');
|
||||
const [activeBackground, setActiveBackground] = useState<boolean>(true);
|
||||
const { hostUrl } = useContext<UseAppStoreType>(AppContext);
|
||||
const { hostUrl, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const backgroundFadeTime = 3000;
|
||||
|
||||
const [backgroundData] = useState<BackgroundData>(placeholder.loading);
|
||||
@ -71,7 +71,7 @@ const RobotAvatar: React.FC<Props> = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (shortAlias && shortAlias !== '') {
|
||||
if (!window.NativeRobosats) {
|
||||
if (client !== 'mobile') {
|
||||
setAvatarSrc(
|
||||
`${hostUrl}/static/federation/avatars/${shortAlias}${small ? '.small' : ''}.webp`,
|
||||
);
|
||||
|
@ -37,7 +37,7 @@ interface SettingsFormProps {
|
||||
}
|
||||
|
||||
const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
||||
const { fav, setFav, settings, setSettings } = useContext<UseAppStoreType>(AppContext);
|
||||
const { fav, setFav, settings, setSettings, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const fontSizes = [
|
||||
@ -237,7 +237,7 @@ const SettingsForm = ({ dense = false }: SettingsFormProps): JSX.Element => {
|
||||
</ToggleButtonGroup>
|
||||
</ListItem>
|
||||
|
||||
{window.NativeRobosats !== undefined && (
|
||||
{client === 'mobile' && (
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<TorIcon />
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Box,
|
||||
@ -33,6 +33,7 @@ import { apiClient } from '../../../services/api';
|
||||
import { systemClient } from '../../../services/System';
|
||||
|
||||
import lnproxies from '../../../../static/lnproxies.json';
|
||||
import { UseAppStoreType, AppContext } from '../../../contexts/AppContext';
|
||||
let filteredProxies: Array<Record<string, any>> = [];
|
||||
export interface LightningForm {
|
||||
invoice: string;
|
||||
@ -89,6 +90,7 @@ export const LightningPayoutForm = ({
|
||||
setLightning,
|
||||
settings,
|
||||
}: LightningPayoutFormProps): JSX.Element => {
|
||||
const { client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
@ -153,7 +155,7 @@ export const LightningPayoutForm = ({
|
||||
bitcoinNetwork = settings?.network ?? 'mainnet';
|
||||
if (settings.host?.includes('.i2p') === true) {
|
||||
internetNetwork = 'I2P';
|
||||
} else if (settings.host?.includes('.onion') === true || window.NativeRobosats !== undefined) {
|
||||
} else if (settings.host?.includes('.onion') === true || client === 'mobile') {
|
||||
internetNetwork = 'TOR';
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { format } from 'date-fns';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@ -37,6 +37,7 @@ import {
|
||||
} from '../Icons';
|
||||
import { type TradeCoordinatorSummary, type TradeRobotSummary } from '../../models/Order.model';
|
||||
import { systemClient } from '../../services/System';
|
||||
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
|
||||
interface Props {
|
||||
isMaker: boolean;
|
||||
@ -61,6 +62,7 @@ const TradeSummary = ({
|
||||
platformSummary,
|
||||
orderId,
|
||||
}: Props): JSX.Element => {
|
||||
const { client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
@ -81,7 +83,7 @@ const TradeSummary = ({
|
||||
taker: takerSummary,
|
||||
platform: platformSummary,
|
||||
};
|
||||
if (window.NativeRobosats === undefined) {
|
||||
if (client !== 'mobile') {
|
||||
saveAsJson(`order${orderId}-summary.json`, summary);
|
||||
} else {
|
||||
systemClient.copyToClipboard(JSON.stringify(summary));
|
||||
|
@ -40,7 +40,6 @@ export interface SlideDirection {
|
||||
export type TorStatus = 'ON' | 'STARTING' | 'STOPPING' | 'OFF';
|
||||
|
||||
export const isNativeRoboSats = !(window.NativeRobosats === undefined);
|
||||
export const isDesktopRoboSats = !(window.RobosatsClient === undefined);
|
||||
|
||||
const pageFromPath = window.location.pathname.split('/')[1];
|
||||
const isPagePathEmpty = pageFromPath === '';
|
||||
@ -76,13 +75,14 @@ const makeTheme = function (settings: Settings): Theme {
|
||||
};
|
||||
|
||||
const getHostUrl = (network = 'mainnet'): string => {
|
||||
const [client, _view] = window.RobosatsSettings.split('-');
|
||||
const randomAlias =
|
||||
Object.keys(defaultFederation)[
|
||||
Math.floor(Math.random() * Object.keys(defaultFederation).length)
|
||||
];
|
||||
let host = defaultFederation[randomAlias][network].onion;
|
||||
let protocol = 'http:';
|
||||
if (window.NativeRobosats === undefined) {
|
||||
if (client !== 'mobile') {
|
||||
host = getHost();
|
||||
protocol = location.protocol;
|
||||
}
|
||||
@ -93,8 +93,9 @@ const getHostUrl = (network = 'mainnet'): string => {
|
||||
const getOrigin = (network = 'mainnet'): Origin => {
|
||||
const host = getHostUrl(network);
|
||||
let origin: Origin = 'onion';
|
||||
const [client, _view] = window.RobosatsSettings.split('-');
|
||||
|
||||
if (window.NativeRobosats !== undefined || host.includes('.onion')) {
|
||||
if (client === 'mobile' || client === 'desktop' || host.includes('.onion')) {
|
||||
origin = 'onion';
|
||||
} else if (host.includes('i2p')) {
|
||||
origin = 'i2p';
|
||||
@ -106,13 +107,13 @@ const getOrigin = (network = 'mainnet'): Origin => {
|
||||
};
|
||||
|
||||
const getSettings = (): Settings => {
|
||||
let settings = new Settings();
|
||||
if (window.RobosatsSettings === 'selfhosted-basic') {
|
||||
settings = new SettingsSelfhosted();
|
||||
} else if (window.RobosatsSettings === 'selfhosted-pro') {
|
||||
settings = new SettingsSelfhostedPro();
|
||||
} else if (window.RobosatsSettings === 'web-pro') {
|
||||
settings = new SettingsPro();
|
||||
let settings;
|
||||
|
||||
const [client, view] = window.RobosatsSettings.split('-');
|
||||
if (client === 'selfhosted') {
|
||||
settings = view === 'pro' ? new SettingsSelfhostedPro() : new SettingsSelfhosted();
|
||||
} else {
|
||||
settings = view === 'pro' ? new SettingsPro() : new Settings();
|
||||
}
|
||||
|
||||
return settings;
|
||||
@ -152,6 +153,8 @@ export interface UseAppStoreType {
|
||||
fav: Favorites;
|
||||
setFav: Dispatch<SetStateAction<Favorites>>;
|
||||
worldmap?: GeoJsonObject;
|
||||
client: 'mobile' | 'web' | 'desktop' | string;
|
||||
view: 'basic' | 'pro' | string;
|
||||
}
|
||||
|
||||
export const initialAppContext: UseAppStoreType = {
|
||||
@ -178,6 +181,8 @@ export const initialAppContext: UseAppStoreType = {
|
||||
fav: { type: null, currency: 0, mode: 'fiat', coordinator: 'any' },
|
||||
setFav: () => {},
|
||||
worldmap: undefined,
|
||||
client: 'web',
|
||||
view: 'basic',
|
||||
};
|
||||
|
||||
export const AppContext = createContext<UseAppStoreType>(initialAppContext);
|
||||
@ -191,6 +196,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
const clientVersion = initialAppContext.clientVersion;
|
||||
const hostUrl = initialAppContext.hostUrl;
|
||||
const origin = initialAppContext.origin;
|
||||
const [client, view] = window.RobosatsSettings.split('-');
|
||||
|
||||
const [settings, setSettings] = useState<Settings>(getSettings());
|
||||
const [theme, setTheme] = useState<Theme>(() => {
|
||||
@ -286,6 +292,8 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
fav,
|
||||
setFav,
|
||||
worldmap,
|
||||
client,
|
||||
view,
|
||||
}}
|
||||
>
|
||||
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
||||
|
@ -46,7 +46,7 @@ export const FederationContext = createContext<UseFederationStoreType>(initialFe
|
||||
export const FederationContextProvider = ({
|
||||
children,
|
||||
}: FederationContextProviderProps): JSX.Element => {
|
||||
const { settings, page, origin, hostUrl, open, torStatus } =
|
||||
const { settings, page, origin, hostUrl, open, torStatus, client } =
|
||||
useContext<UseAppStoreType>(AppContext);
|
||||
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const [federation] = useState(new Federation(origin, settings, hostUrl));
|
||||
@ -66,7 +66,7 @@ export const FederationContextProvider = ({
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
||||
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
||||
void federation.updateUrl(origin, settings, hostUrl);
|
||||
void federation.update();
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ export const GarageContext = createContext<UseGarageStoreType>(initialGarageCont
|
||||
|
||||
export const GarageContextProvider = ({ children }: GarageContextProviderProps): JSX.Element => {
|
||||
// All garage data structured
|
||||
const { settings, torStatus, open, page } = useContext<UseAppStoreType>(AppContext);
|
||||
const { settings, torStatus, open, page, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const pageRef = useRef(page);
|
||||
const { federation, sortedCoordinators } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const [garage] = useState<Garage>(initialGarageContext.garage);
|
||||
@ -93,14 +93,14 @@ export const GarageContextProvider = ({ children }: GarageContextProviderProps):
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
||||
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
||||
const token = garage.getSlot()?.token;
|
||||
if (token) void garage.fetchRobot(federation, token);
|
||||
}
|
||||
}, [settings.network, settings.useProxy, torStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.NativeRobosats !== undefined && !systemClient.loading) {
|
||||
if (client === 'mobile' && !systemClient.loading) {
|
||||
garage.loadSlots();
|
||||
}
|
||||
}, [systemClient.loading]);
|
||||
|
@ -47,7 +47,9 @@ class BaseSettings {
|
||||
this.host = getHost();
|
||||
|
||||
const useProxy = systemClient.getItem('settings_use_proxy');
|
||||
this.useProxy = window.NativeRobosats !== undefined && useProxy !== 'false';
|
||||
|
||||
const [client, _view] = window.RobosatsSettings.split('-');
|
||||
this.useProxy = client === 'mobile' && useProxy !== 'false';
|
||||
|
||||
apiClient.useProxy = this.useProxy;
|
||||
}
|
||||
|
1
frontend/src/services/Native/index.d.ts
vendored
1
frontend/src/services/Native/index.d.ts
vendored
@ -5,7 +5,6 @@ declare global {
|
||||
ReactNativeWebView?: ReactNativeWebView;
|
||||
NativeRobosats?: NativeRobosats;
|
||||
RobosatsSettings: 'web-basic' | 'web-pro' | 'selfhosted-basic' | 'selfhosted-pro';
|
||||
RobosatsClient: 'desktop-app' | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="onion-location" content="{{ ONION_LOCATION }}" />
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static "css/fonts.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/loader.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/leaflet.css" %}"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{% static "frontend/main.js" %}"></script>
|
||||
</body>
|
||||
</html>
|
@ -2,23 +2,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="onion-location" content="{{ ONION_LOCATION }}" />
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
<link rel="shortcut icon" href="<%= htmlWebpackPlugin.options.basePath %>static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="<%= htmlWebpackPlugin.options.basePath %>static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="<%= htmlWebpackPlugin.options.basePath %>static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="<%= htmlWebpackPlugin.options.basePath %>static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<% if (pro) { %>
|
||||
<title>RoboSats PRO - Simple and Private Bitcoin Exchange</title>
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static "css/fonts.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/loader.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/leaflet.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css_pro/react-grid-layout.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css_pro/react-resizable.css" %}"/>
|
||||
|
||||
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.basePath %>static/css_pro/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.basePath %>static/css_pro/react-grid-layout.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.basePath %>static/css_pro/react-resizable.css"/>
|
||||
<% } else { %>
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.basePath %>static/css/fonts.css"/>
|
||||
<% } %>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.basePath %>static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.basePath %>static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.basePath %>static/css/leaflet.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
@ -57,7 +63,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{% static "frontend/pro.js" %}"></script>
|
||||
<script>
|
||||
window.RobosatsSettings = '<%= htmlWebpackPlugin.options.robosatsSettings %>'
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,6 +1,8 @@
|
||||
import path from 'path';
|
||||
import { Configuration } from 'webpack';
|
||||
import CopyPlugin from 'copy-webpack-plugin';
|
||||
import FileManagerPlugin from 'filemanager-webpack-plugin';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
import { version } from './package.json';
|
||||
|
||||
const config: Configuration = {
|
||||
entry: './src/index.js',
|
||||
@ -24,12 +26,126 @@ const config: Configuration = {
|
||||
},
|
||||
};
|
||||
|
||||
const configWeb: Configuration = {
|
||||
const configNode: Configuration = {
|
||||
...config,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'static/frontend'),
|
||||
filename: 'main.js',
|
||||
filename: `main.v${version}.[contenthash].js`,
|
||||
clean: true,
|
||||
publicPath: '/static/frontend/',
|
||||
},
|
||||
plugins: [
|
||||
// Django
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: false,
|
||||
},
|
||||
filename: path.resolve(__dirname, 'templates/frontend/basic.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'web-basic',
|
||||
basePath: '/',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: true,
|
||||
},
|
||||
filename: path.resolve(__dirname, 'templates/frontend/pro.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'web-pro',
|
||||
basePath: '/',
|
||||
}),
|
||||
// Node App
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: false,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../nodeapp/basic.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'selfhosted-basic',
|
||||
basePath: '/',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: true,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../nodeapp/pro.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'selfhosted-pro',
|
||||
basePath: '/',
|
||||
}),
|
||||
new FileManagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
copy: [
|
||||
{
|
||||
source: path.resolve(__dirname, 'static'),
|
||||
destination: path.resolve(__dirname, '../nodeapp/static'),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
// Desktop App
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: false,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../desktopApp/index.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'desktop-basic',
|
||||
basePath: '/',
|
||||
}),
|
||||
new FileManagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
copy: [
|
||||
{
|
||||
source: path.resolve(__dirname, 'static'),
|
||||
destination: path.resolve(__dirname, '../desktopApp/static'),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
// Web App
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: false,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../web/basic.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'web-basic',
|
||||
basePath: '/',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: true,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../web/pro.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'web-pro',
|
||||
basePath: '/',
|
||||
}),
|
||||
new FileManagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
copy: [
|
||||
{
|
||||
source: path.resolve(__dirname, 'static'),
|
||||
destination: path.resolve(__dirname, '../web/static'),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
const configMobile: Configuration = {
|
||||
@ -79,28 +195,44 @@ const configMobile: Configuration = {
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../mobile/html/Web.bundle/static/frontend'),
|
||||
filename: `main.v${version}.[contenthash].js`,
|
||||
clean: true,
|
||||
publicPath: './static/frontend/',
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, 'static/css'),
|
||||
to: path.resolve(__dirname, '../mobile/html/Web.bundle/css'),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, 'templates/frontend/index.ejs'),
|
||||
templateParameters: {
|
||||
pro: false,
|
||||
},
|
||||
filename: path.resolve(__dirname, '../mobile/html/Web.bundle/index.html'),
|
||||
inject: 'body',
|
||||
robosatsSettings: 'mobile-basic',
|
||||
basePath: './',
|
||||
}),
|
||||
new FileManagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
copy: [
|
||||
{
|
||||
source: path.resolve(__dirname, 'static/css'),
|
||||
destination: path.resolve(__dirname, '../mobile/html/Web.bundle/static/css'),
|
||||
},
|
||||
{
|
||||
source: path.resolve(__dirname, 'static/assets/sounds'),
|
||||
destination: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/sounds'),
|
||||
},
|
||||
{
|
||||
source: path.resolve(__dirname, 'static/federation'),
|
||||
destination: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/federation'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, 'static/assets/sounds'),
|
||||
to: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/sounds'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, 'static/federation'),
|
||||
to: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/federation'),
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../mobile/html/Web.bundle/js'),
|
||||
filename: 'main.js',
|
||||
},
|
||||
};
|
||||
|
||||
export default [configWeb, configMobile];
|
||||
export default [configNode, configMobile];
|
||||
|
3
mobile/.gitignore
vendored
3
mobile/.gitignore
vendored
@ -63,5 +63,4 @@ buck-out/
|
||||
/vendor/bundle/
|
||||
|
||||
# frontend js
|
||||
/html/Web.bundle/js*
|
||||
/html/Web.bundle/css*
|
||||
/html/Web.bundle/static*
|
||||
|
@ -1,55 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="css/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="css/leaflet.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/leaflet.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.RobosatsSettings = 'selfhosted-basic'
|
||||
</script>
|
||||
<script src="/static/frontend/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,19 +1,16 @@
|
||||
version: '3.9'
|
||||
# Frontend and node client development orchestration
|
||||
name: robosats-frontend
|
||||
name: robosats-nodeapp-frontend
|
||||
services:
|
||||
frontend:
|
||||
build: ../frontend
|
||||
container_name: npm-dev-frontend
|
||||
container_name: nodeapp-dev-frontend
|
||||
restart: always
|
||||
command: npm run dev
|
||||
volumes:
|
||||
- ../frontend:/usr/src/frontend
|
||||
- ../mobile:/usr/src/mobile
|
||||
|
||||
nodeapp:
|
||||
nginx:
|
||||
build: .
|
||||
container_name: nodeapp-dev-frontend
|
||||
container_name: nodeapp-dev-nginx
|
||||
restart: always
|
||||
environment:
|
||||
TOR_PROXY_IP: 127.0.0.1
|
||||
@ -23,11 +20,10 @@ services:
|
||||
- ./:/usr/src/robosats/
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./coordinators/:/etc/nginx/conf.d/
|
||||
- ../frontend/static:/usr/src/robosats/static
|
||||
|
||||
tor:
|
||||
build: ../docker/tor
|
||||
container_name: tor-dev-frontend
|
||||
container_name: nodeapp-dev-tor
|
||||
restart: always
|
||||
environment:
|
||||
LOCAL_USER_ID: 1000
|
||||
|
@ -64,14 +64,6 @@ http {
|
||||
autoindex on;
|
||||
}
|
||||
|
||||
location /nostr {
|
||||
proxy_pass http://127.0.0.1:7777;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location = /favicon.ico {
|
||||
alias /usr/src/robosats/static/assets/images/favicon-96x96.png;
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats PRO - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/css_pro/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/leaflet.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/css_pro/react-grid-layout.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/css_pro/react-resizable.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.RobosatsSettings = 'selfhosted-pro'
|
||||
</script>
|
||||
<script src="/static/frontend/main.js"></script>
|
||||
</body>
|
||||
</html>
|
192
package-lock.json
generated
192
package-lock.json
generated
@ -6,6 +6,25 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ejs": "^3.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
@ -13,6 +32,153 @@
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
"bin": {
|
||||
"ejs": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
|
||||
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"minimatch": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/jake": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
|
||||
"integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"async": "^3.2.3",
|
||||
"chalk": "^4.0.2",
|
||||
"filelist": "^1.0.4",
|
||||
"minimatch": "^3.1.2"
|
||||
},
|
||||
"bin": {
|
||||
"jake": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
@ -23,6 +189,32 @@
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ejs": "^3.1.10"
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,11 @@ class FrontendFetchTest(TestCase):
|
||||
path = reverse("basic")
|
||||
response = self.client.get(path)
|
||||
self.assertContains(response, "<html>")
|
||||
self.assertContains(response, "main.js")
|
||||
self.assertContains(response, "RoboSats -")
|
||||
self.assertContains(response, "static/frontend/main.v")
|
||||
|
||||
def test_pro_frontend_url_content(self):
|
||||
path = reverse("pro")
|
||||
response = self.client.get(path)
|
||||
self.assertContains(response, "<html>")
|
||||
self.assertContains(response, "pro.js")
|
||||
self.assertContains(response, "static/frontend/main.v")
|
||||
|
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/leaflet.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.RobosatsSettings = 'web-basic'
|
||||
</script>
|
||||
<script src="/static/frontend/main.js"></script>
|
||||
</body>
|
||||
</html>
|
20
web/docker-compose.yml
Normal file
20
web/docker-compose.yml
Normal file
@ -0,0 +1,20 @@
|
||||
version: '3.9'
|
||||
# Frontend and node client development orchestration
|
||||
name: robosats-web-frontend
|
||||
services:
|
||||
frontend:
|
||||
build: ../frontend
|
||||
container_name: web-dev-frontend
|
||||
restart: always
|
||||
command: npm run dev
|
||||
|
||||
nginx:
|
||||
build: .
|
||||
container_name: web-dev-nginx
|
||||
restart: always
|
||||
volumes:
|
||||
- ./:/usr/src/robosats/
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./coordinators/:/etc/nginx/conf.d/
|
||||
ports:
|
||||
- 80:80
|
65
web/pro.html
65
web/pro.html
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<link rel="shortcut icon" href="/static/assets/images/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/static/assets/images/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
|
||||
|
||||
<title>RoboSats PRO - Simple and Private Bitcoin Exchange</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/css_pro/fonts.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/loader.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/index.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/leaflet.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/css_pro/react-grid-layout.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/css_pro/react-resizable.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>
|
||||
This site requires JavaScript. This message is only visible if you have it disabled. <br/><br/>
|
||||
If you are using TOR browser set the "Security Level" to "Standard". If you keep seeing this message clear cache and storage of TOR browser app and retry.<br/><br/>
|
||||
If the problem persists, ask for support in the RoboSats telegram group<a href="https://t.me/robosats"> (t.me/robosats)</a>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="main">
|
||||
<div id="app">
|
||||
<div class="loaderCenter">
|
||||
<div class="loaderSpinner"></div>
|
||||
<div class="content-slider">
|
||||
<div class="slider">
|
||||
<div class="mask">
|
||||
<ul>
|
||||
<li class="anim1">
|
||||
<div class="quote">Looking for robot parts ...</div>
|
||||
</li>
|
||||
<li class="anim2">
|
||||
<div class="quote">Adding layers to the onion ...</div>
|
||||
</li>
|
||||
<li class="anim3">
|
||||
<div class="quote">Winning at game theory ...</div>
|
||||
</li>
|
||||
<li class="anim4">
|
||||
<div class="quote">Moving Sats at light speed ...</div>
|
||||
</li>
|
||||
<li class="anim5">
|
||||
<div class="quote">Hiding in 2^256 bits of entropy...</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.RobosatsSettings = 'web-pro'
|
||||
</script>
|
||||
<script src="/static/frontend/main.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user