Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ced248345d |
@@ -5,8 +5,6 @@ on:
|
||||
branches:
|
||||
- release/*
|
||||
- develop
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
@@ -99,13 +97,15 @@ jobs:
|
||||
- name: See affected apps
|
||||
run: |
|
||||
echo ">>>> debug"
|
||||
echo "NX Version: $nx_version"
|
||||
echo "NX_BASE: ${{ env.NX_BASE }}"
|
||||
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
||||
echo ">>>> eof debug"
|
||||
|
||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
||||
echo -n "Affected projects: $affected"
|
||||
|
||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
branch_slug="$(echo ${{ github.head_ref || github.ref_name }} | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
projects_e2e=""
|
||||
preview_governance="not deployed"
|
||||
preview_trading="not deployed"
|
||||
|
||||
@@ -30,21 +30,13 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Log in to the Container registry (ghcr)
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Log in to the Container registry (docker hub)
|
||||
uses: docker/login-action@v2
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
with:
|
||||
# registry: registry.hub.docker.com
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -62,24 +54,30 @@ jobs:
|
||||
- name: Define variables
|
||||
run: |
|
||||
envName=''
|
||||
dockerfile="dist.Dockerfile"
|
||||
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||
domain="vega.rocks"
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
if [[ "${{ github.ref }}" =~ .*mainnet.* ]]; then
|
||||
domain="vega.community"
|
||||
if [[ "${{ matrix.app }}" = "trading" ]]; then
|
||||
dockerfile="ipfs.Dockerfile"
|
||||
fi
|
||||
fi
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
||||
envName="mainnet"
|
||||
fi
|
||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
fi
|
||||
nodeVersion=$(cat .nvmrc | head -n 1)
|
||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||
echo NODE_VERSION=${nodeVersion} >> $GITHUB_ENV
|
||||
echo DOCKERFILE=docker/${dockerfile} >> $GITHUB_ENV
|
||||
|
||||
- name: Build local dist
|
||||
if: ${{ env.DOCKERFILE != 'docker/ipfs.Dockerfile' }}
|
||||
run: |
|
||||
flags=""
|
||||
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
|
||||
@@ -100,59 +98,62 @@ jobs:
|
||||
|
||||
- name: Build and export to local Docker
|
||||
id: docker_build
|
||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
file: ${{ env.DOCKERFILE }}
|
||||
load: true
|
||||
build-args: |
|
||||
APP=${{ matrix.app }}
|
||||
NODE_VERSION=${{ env.NODE_VERSION }}
|
||||
ENV_NAME=${{ env.ENV_NAME }}
|
||||
tags: |
|
||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
|
||||
|
||||
- name: Image digest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
- name: Sanity check docker image
|
||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
||||
run: |
|
||||
echo "Check ipfs-hash"
|
||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matirx.app }}-ipfs-hash
|
||||
echo "List html directory"
|
||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
||||
if [[ "${{ env.DOCKERFILE }}" = "docker/ipfs.Dockerfile" ]]; then
|
||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
||||
fi
|
||||
|
||||
- name: Publish dist as docker image (ghcr)
|
||||
echo "List html directory"
|
||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree .'
|
||||
|
||||
- name: Copy dist to local filesystem
|
||||
if: ${{ env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' }}
|
||||
run: |
|
||||
docker create --name=dist ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
|
||||
docker cp dist:/usr/share/nginx/html dist
|
||||
|
||||
echo "check local dist files"
|
||||
tree dist/html
|
||||
mv dist/html dist-result
|
||||
|
||||
- name: Publish dist as docker image
|
||||
uses: docker/build-push-action@v3
|
||||
if: ${{ github.event_name == 'pull_request' || (matrix.app == 'trading' && github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') ) }}
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
file: ${{ env.DOCKERFILE }}
|
||||
push: true
|
||||
build-args: |
|
||||
APP=${{ matrix.app }}
|
||||
NODE_VERSION=${{ env.NODE_VERSION }}
|
||||
ENV_NAME=${{ env.ENV_NAME }}
|
||||
tags: |
|
||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Publish dist as docker image (docker hub)
|
||||
uses: docker/build-push-action@v3
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
push: true
|
||||
build-args: |
|
||||
APP=${{ matrix.app }}
|
||||
ENV_NAME=${{ env.ENV_NAME }}
|
||||
tags: |
|
||||
vegaprotocol/${{ matrix.app }}:${{ github.ref_name }}
|
||||
|
||||
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||
- name: Publish dist to s3
|
||||
uses: jakejarvis/s3-sync-action@master
|
||||
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') }}
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
with:
|
||||
args: --acl private --follow-symlinks --delete
|
||||
env:
|
||||
@@ -168,9 +169,3 @@ jobs:
|
||||
with:
|
||||
labels: ${{ matrix.app }}-preview
|
||||
number: ${{ github.event.number }}
|
||||
|
||||
- name: Add ipfs hash to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
with:
|
||||
files: ${{ matrix.app }}-ipfs-hash
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/dist-result
|
||||
/tmp
|
||||
/out-tsc
|
||||
/tools/executors/**/*.js
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
.PHONY: latest-release
|
||||
latest-release:
|
||||
gh release list | head -n 1 | awk '{print $1}'
|
||||
|
||||
.PHONY: show-latest-release
|
||||
show-latest-release:
|
||||
gh release view `gh release list | head -n 1 | awk '{print $1}'`
|
||||
|
||||
.PHONY: recalculate-ipfs
|
||||
recalculate-ipfs:
|
||||
echo "ipfs hash inside the image"
|
||||
docker run --rm ${TAG} cat /ipfs-hash
|
||||
echo "recalculating ipfs hash"
|
||||
docker run --rm ${TAG} ipfs add -rw /usr/share/nginx/html
|
||||
|
||||
.PHONY: eject-ipfs-hash
|
||||
unpack:
|
||||
docker create --name=dist ${TAG}
|
||||
docker cp dist:/usr/share/nginx/html dist
|
||||
docker rm dist
|
||||
@@ -103,68 +103,25 @@ In CI linting, formatting and also run. These checks can be seen in the [CI work
|
||||
|
||||
Visit the [Nx Documentation](https://nx.dev/getting-started/intro) to learn more.
|
||||
|
||||
# 🐋 Hosting a console
|
||||
# Docker & Vegacapsule
|
||||
|
||||
To host a console there are two possible build scenarios for running the frontends: nx performed **outside** or **inside** docker build. For specific build instructions follow [build instructions](#build-instructions).
|
||||
## Docker
|
||||
|
||||
In order to run a container on port 3000:
|
||||
The [Dockerfile](./dockerfiles) for running the frontends is pretty basic, merely building the application with the APP arg that is passed in and serving the application from [nginx](./nginx/nginx.conf). The only complexity that exists is that there is a script which allows the passing of run time environment variables to the containers. See configuration below for how to do this.
|
||||
|
||||
You can build any of the containers locally with the following command:
|
||||
|
||||
```bash
|
||||
docker build --dockerfile dockerfiles/Dockerfile.cra . --build-arg APP=[YOUR APP] --tag=[TAG]
|
||||
```
|
||||
|
||||
In order to run a container:
|
||||
|
||||
```bash
|
||||
docker run -p 3000:80 [TAG]
|
||||
```
|
||||
|
||||
## Build instructions
|
||||
|
||||
The [`docker`](./docker) subfolder has some docker configurations for easily setting up your own hosted version of console either for the web, or ready for pinning on IPFS
|
||||
|
||||
### nx build outside the docker
|
||||
|
||||
Packaging prepared dist into [`nginx`](https://hub.docker.com/_/nginx)([server configuration](./nginx/nginx.conf)) docker image involves building the application on docker host machine from source.
|
||||
|
||||
As a prerequisite you need to perform build of `dist` directory and move its content for specific application to `dist-result` directory. Use following script to do it with a single command:
|
||||
|
||||
```bash
|
||||
./docker/prepare-dist.sh
|
||||
```
|
||||
|
||||
You can build any of the containers locally with the following command:
|
||||
|
||||
```bash
|
||||
docker build --dockerfile docker/node-outside-docker.Dockerfile . --tag=[TAG]
|
||||
```
|
||||
|
||||
### nx build inside the docker
|
||||
|
||||
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build) example.
|
||||
|
||||
```bash
|
||||
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=$(cat .nvmrc) --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
|
||||
```
|
||||
|
||||
### Computing ipfs-hash of the build
|
||||
|
||||
At the moment this feature is important only for `trading` (console) releases.
|
||||
|
||||
Each docker build finishes with hash calculation for dist directory. Resulting hash is added to file named as `/ipfs-hash`. Once docker image is produced you can run following commad to display ipfs-hash:
|
||||
|
||||
```bash
|
||||
make recalculate-ipfs TAG=vegaprotocol/trading:{YOUR_VERSION}
|
||||
```
|
||||
|
||||
**updating hash:** recompiling dist directory (even if there are no changed to source code) results in different hash computed by ipfs command.
|
||||
|
||||
### Verifying ipfs-hash of existing current application version
|
||||
|
||||
An IPFS CID will be attached to every [release](https://github.com/vegaprotocol/frontend-monorepo/releases). If you are intending to pin an application on IPFS, you can check that your build matches by running the following steps:
|
||||
|
||||
1. Show latest release by runnning: `make latest-release`. You need to configure [`gh`](https://cli.github.com/) for this step to work, otherwise please provide release manually from [github](https://github.com/vegaprotocol/frontend-monorepo/releases) or [dockerhub](https://hub.docker.com/r/vegaprotocol/trading)
|
||||
2. Set RELEASE environment variable to value that you want to validate: `export RELEASE=$(make latest-release)` or `export RELEASE=vXX.XX.XX`
|
||||
3. Set TAG environment variable to image that you want to validate: `export TAG=vegaprotocol/trading:$RELEASE`
|
||||
4. Download docker image with the desired release `docker pull $TAG`.
|
||||
5. Recalculate hash: `make recalculate-ipfs`
|
||||
6. You should see exactly same hash produced by ipfs command as one placed with the release notes: `make show-latest-release`
|
||||
7. If you want to extract dist from docker image to your local filesystem you can run following command: `make unpack`
|
||||
8. Now `dist` directory contains valid application build. **it is not possible to calculate same ipfs hash on files that are result of copy operation**
|
||||
Images ending with `.dist` are to pack locally created transpiled HTML files into nginx container for non-compatible with yarn architectures like M1 Mac
|
||||
|
||||
## Config
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
# .env is stagnet1, so there are no overrides required
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET3":"https://stagnet3.explorer.vega.xyz"}'
|
||||
# .env is stagnet1, so there are no overrides required
|
||||
@@ -1,18 +1,9 @@
|
||||
import {
|
||||
AppFailure,
|
||||
NetworkLoader,
|
||||
NodeGuard,
|
||||
NodeSwitcherDialog,
|
||||
useEnvironment,
|
||||
useInitializeEnv,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment';
|
||||
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { router } from './routes/router-config';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
const splashLoading = (
|
||||
<Splash>
|
||||
@@ -21,23 +12,10 @@ const splashLoading = (
|
||||
);
|
||||
|
||||
function App() {
|
||||
const { VEGA_URL } = useEnvironment();
|
||||
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useNodeSwitcherStore(
|
||||
(store) => [store.dialogOpen, store.setDialogOpen]
|
||||
);
|
||||
return (
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
||||
<NodeGuard
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
</NodeGuard>
|
||||
<NodeSwitcherDialog
|
||||
open={nodeSwitcherOpen}
|
||||
setOpen={setNodeSwitcherOpen}
|
||||
/>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
</NetworkLoader>
|
||||
</TendermintWebsocketProvider>
|
||||
);
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
import {
|
||||
useEnvironment,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { ENV } from '../../config/env';
|
||||
|
||||
export const Footer = () => {
|
||||
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
||||
const setNodeSwitcherOpen = useNodeSwitcherStore(
|
||||
(store) => store.setDialogOpen
|
||||
);
|
||||
|
||||
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
||||
const { screenSize } = useScreenDimensions();
|
||||
const showFullFeedbackLabel = useMemo(
|
||||
() => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
|
||||
@@ -21,40 +15,46 @@ export const Footer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<div className="flex justify-between gap-2 align-middle">
|
||||
{GIT_COMMIT_HASH && (
|
||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
<p data-testid="git-commit-hash">
|
||||
{t('Version')}:{' '}
|
||||
<Link
|
||||
href={
|
||||
GIT_ORIGIN_URL
|
||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||
: undefined
|
||||
}
|
||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||
>
|
||||
{GIT_COMMIT_HASH}
|
||||
</Link>
|
||||
</p>
|
||||
<>
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<div className="flex justify-between gap-2 align-middle">
|
||||
{GIT_COMMIT_HASH && (
|
||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
<p data-testid="git-commit-hash">
|
||||
{t('Version')}:{' '}
|
||||
<Link
|
||||
href={
|
||||
GIT_ORIGIN_URL
|
||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||
: undefined
|
||||
}
|
||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||
>
|
||||
{GIT_COMMIT_HASH}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
|
||||
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
|
||||
{t('Change')}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
|
||||
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
|
||||
{t('Change')}
|
||||
</Link>
|
||||
<div className="flex pl-2 content-center">
|
||||
<ExternalLink href={ENV.addresses.feedback}>
|
||||
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex pl-2 content-center">
|
||||
<ExternalLink href={ENV.addresses.feedback}>
|
||||
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</footer>
|
||||
<NodeSwitcherDialog
|
||||
open={nodeSwitcherOpen}
|
||||
setOpen={setNodeSwitcherOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+14
-37
@@ -37,10 +37,6 @@ import {
|
||||
useEnvironment,
|
||||
NetworkLoader,
|
||||
useInitializeEnv,
|
||||
NodeGuard,
|
||||
AppFailure,
|
||||
NodeSwitcherDialog,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { ENV } from './config';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
@@ -52,7 +48,6 @@ import {
|
||||
TELEMETRY_ON,
|
||||
} from './components/telemetry-dialog/telemetry-dialog';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const cache: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
@@ -186,19 +181,9 @@ const ScrollToTop = () => {
|
||||
|
||||
const AppContainer = () => {
|
||||
const { config, loading, error } = useEthereumConfig();
|
||||
const {
|
||||
VEGA_ENV,
|
||||
VEGA_URL,
|
||||
GIT_COMMIT_HASH,
|
||||
GIT_BRANCH,
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
} = useEnvironment();
|
||||
const { VEGA_ENV, GIT_COMMIT_HASH, GIT_BRANCH, ETHEREUM_PROVIDER_URL } =
|
||||
useEnvironment();
|
||||
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
|
||||
const { t } = useTranslation();
|
||||
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
|
||||
store.dialogOpen,
|
||||
store.setDialogOpen,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (ENV.dsn && telemetryOn) {
|
||||
@@ -234,29 +219,21 @@ const AppContainer = () => {
|
||||
<ScrollToTop />
|
||||
<AppStateProvider>
|
||||
<div className="grid min-h-full text-white">
|
||||
<NodeGuard
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={
|
||||
<AppFailure title={t('NodeUnsuitable', { url: VEGA_URL })} />
|
||||
<AsyncRenderer<EthereumConfig | null>
|
||||
loading={loading}
|
||||
data={config}
|
||||
error={error}
|
||||
render={(cnf) =>
|
||||
cnf && (
|
||||
<Web3Container
|
||||
chainId={Number(cnf.chain_id)}
|
||||
providerUrl={ETHEREUM_PROVIDER_URL}
|
||||
/>
|
||||
)
|
||||
}
|
||||
>
|
||||
<AsyncRenderer<EthereumConfig | null>
|
||||
loading={loading}
|
||||
data={config}
|
||||
error={error}
|
||||
render={(cnf) =>
|
||||
cnf && (
|
||||
<Web3Container
|
||||
chainId={Number(cnf.chain_id)}
|
||||
providerUrl={ETHEREUM_PROVIDER_URL}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</NodeGuard>
|
||||
/>
|
||||
</div>
|
||||
</AppStateProvider>
|
||||
<NodeSwitcherDialog open={nodeSwitcherOpen} setOpen={setNodeSwitcher} />
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -811,6 +811,5 @@
|
||||
"OptOutOfTelemetry": "You can opt out any time via settings",
|
||||
"NoThanks": "No thanks",
|
||||
"ShareData": "Share data",
|
||||
"ContinueSharingData": "Continue sharing data",
|
||||
"NodeUnsuitable": "Node: {{url}} is unsuitable"
|
||||
"ContinueSharingData": "Continue sharing data"
|
||||
}
|
||||
|
||||
+1
-7
@@ -34,7 +34,6 @@ import {
|
||||
formatNumberPercentage,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { VALIDATOR_LOGO_MAP } from './logo-map';
|
||||
|
||||
interface CanonisedConsensusNodeProps {
|
||||
id: string;
|
||||
@@ -162,11 +161,6 @@ export const ConsensusValidatorsTable = ({
|
||||
pendingUserStake,
|
||||
userStakeShare,
|
||||
}) => {
|
||||
const logo = VALIDATOR_LOGO_MAP[id]
|
||||
? VALIDATOR_LOGO_MAP[id]
|
||||
: avatarUrl
|
||||
? avatarUrl
|
||||
: null;
|
||||
const {
|
||||
rawValidatorScore: previousEpochValidatorScore,
|
||||
performanceScore: previousEpochPerformanceScore,
|
||||
@@ -177,7 +171,7 @@ export const ConsensusValidatorsTable = ({
|
||||
id,
|
||||
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
||||
[ValidatorFields.VALIDATOR]: {
|
||||
avatarUrl: logo,
|
||||
avatarUrl,
|
||||
name,
|
||||
},
|
||||
[ValidatorFields.STAKE]: stakedTotal,
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export const VALIDATOR_LOGO_MAP: { [key: string]: string } = {
|
||||
'55504e9bfd914a7bbefa342c82f59a2f4dee344e5b6863a14c02a812f4fbde32':
|
||||
'https://pbs.twimg.com/profile_images/1586047492629712897/ZVMWBE94_400x400.jpg',
|
||||
efbdf943443bd7595e83b0d7e88f37b7932d487d1b94aab3d004997273bb43fc:
|
||||
'https://pbs.twimg.com/profile_images/1026823609979949057/3e-LCHHm_400x400.jpg',
|
||||
'126751c5830b50d39eb85412fb2964f46338cce6946ff455b73f1b1be3f5e8cc':
|
||||
'https://pbs.twimg.com/profile_images/1228627868542029824/9aoaLiIx_400x400.jpg',
|
||||
'43697a3e911d8b70c0ce672adde17a5c38ca8f6a0486bf85ed0546e1b9a82887':
|
||||
'https://pbs.twimg.com/profile_images/1352167987478843392/XzX82gIb_400x400.jpg',
|
||||
ac735acc9ab11cf1d8c59c2df2107e00092b4ac96451cb137a1629af5b66242a:
|
||||
'https://pbs.twimg.com/profile_images/1159254945885016064/vhhp1wL4_400x400.jpg',
|
||||
'74023df02b8afc9eaf3e3e2e8b07eab1d2122ac3e74b1b0222daf4af565ad3dd':
|
||||
'https://cdn4.telegram-cdn.org/file/n_OJ6upnglNG95E7u5FyfLmqqBUhf25LqtyZD0UM27gMM_WWi8rywrp9JaAA83quP7vx-WU9Q86quvIRdk9wuUrC2tdD08cYxah4dXHa4OgphFg7Vm5UYFjuGxuHn916OIlzIuVOjJWK_nricGdlPcZQK_T4kBJ_5v4pp94j76_DQ1eSy8DjUxnchZxqpGFv-lGN8U4SjRMK0RC_6DusNaRYEn9Ni2ZQHig7nMiqud-nkK5RgUrClfXFwyhoMFVfhHpGUzwpSv1pSEVLXVh7E1mVmWYrW9hzdQGGrouWCGRqtf_hRa9enS2fv0P9mAB23BcURWuLOVtMdJTF4wfc-w.jpg',
|
||||
};
|
||||
@@ -16,7 +16,6 @@ import type { PreviousEpochQuery } from '../../__generated__/PreviousEpoch';
|
||||
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
||||
import type { StakingDelegationFieldsFragment } from '../../__generated__/Staking';
|
||||
import type { ValidatorsView } from './validator-tables';
|
||||
import { VALIDATOR_LOGO_MAP } from './logo-map';
|
||||
|
||||
export enum ValidatorFields {
|
||||
RANKING_INDEX = 'rankingIndex',
|
||||
@@ -103,18 +102,13 @@ interface ValidatorRendererProps {
|
||||
export const ValidatorRenderer = ({ data }: ValidatorRendererProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { avatarUrl, name } = data.validator;
|
||||
const logo = VALIDATOR_LOGO_MAP[data.id]
|
||||
? VALIDATOR_LOGO_MAP[data.id]
|
||||
: avatarUrl
|
||||
? avatarUrl
|
||||
: null;
|
||||
return (
|
||||
<div className="w-[238px] grid grid-cols-[1fr_auto] gap-2 items-center">
|
||||
<span className="flex overflow-hidden">
|
||||
{logo && (
|
||||
{avatarUrl && (
|
||||
<img
|
||||
className="h-6 w-6 rounded-full mr-2"
|
||||
src={logo}
|
||||
src={avatarUrl}
|
||||
alt={`Avatar icon for ${name}`}
|
||||
onError={(e) => (e.currentTarget.style.display = 'none')}
|
||||
/>
|
||||
|
||||
@@ -78,38 +78,37 @@ export const ValidatorTables = ({
|
||||
const nextDelegation = delegations?.find(
|
||||
(d) => d.node.id === validatorId && d.epoch === Number(epochId) + 1
|
||||
);
|
||||
if (validator.stakedByOperator !== '0') {
|
||||
switch (validator.rankingScore?.status) {
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_TENDERMINT:
|
||||
acc.consensusValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
break;
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_ERSATZ:
|
||||
acc.standbyValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
break;
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_PENDING:
|
||||
acc.pendingValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
switch (validator.rankingScore?.status) {
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_TENDERMINT:
|
||||
acc.consensusValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
break;
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_ERSATZ:
|
||||
acc.standbyValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
break;
|
||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_PENDING:
|
||||
acc.pendingValidators.push(
|
||||
addUserDataToValidator(
|
||||
validator,
|
||||
currentDelegation,
|
||||
nextDelegation,
|
||||
currentUserStakeAvailable
|
||||
)
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"tranche_end": "2023-05-20T00:00:00.000Z",
|
||||
"total_added": "19242.125",
|
||||
"total_removed": "1523.8177488329475",
|
||||
"locked_amount": "6570.0201729841825026125",
|
||||
"locked_amount": "6891.9471601080244395475",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "188",
|
||||
@@ -4861,7 +4861,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "86666.297",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "49683.1009092296761910951",
|
||||
"locked_amount": "49802.2753121154213651374",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "86666.297",
|
||||
@@ -4927,7 +4927,7 @@
|
||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||
"total_added": "2500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "305.538226241351125",
|
||||
"locked_amount": "312.4325905575906",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2500",
|
||||
@@ -4960,7 +4960,7 @@
|
||||
"tranche_end": "2023-11-01T00:00:00.000Z",
|
||||
"total_added": "15000.000000000000015",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "14286.1290383454105142861290383454105",
|
||||
"locked_amount": "14327.0455917874395143270455917874395",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1.5e-14",
|
||||
@@ -5048,7 +5048,7 @@
|
||||
"tranche_end": "2023-09-01T00:00:00.000Z",
|
||||
"total_added": "17500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "10865.52010995370325",
|
||||
"locked_amount": "10913.25608896940375",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "12500",
|
||||
@@ -5315,7 +5315,7 @@
|
||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||
"total_added": "37500",
|
||||
"total_removed": "18077.0118744",
|
||||
"locked_amount": "17246.515788060160125",
|
||||
"locked_amount": "17350.5026089625535",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -5734,7 +5734,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "49637.7713310174637779075",
|
||||
"locked_amount": "49756.837002255673748325",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -5767,7 +5767,7 @@
|
||||
"tranche_end": "2024-04-01T00:00:00.000Z",
|
||||
"total_added": "54144.7663",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "48411.21764968406449080437",
|
||||
"locked_amount": "48485.46842731635829207292",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "54144.7663",
|
||||
@@ -5800,7 +5800,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "62600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "19936.502048452562182",
|
||||
"locked_amount": "20022.5830035514954",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10000",
|
||||
@@ -5993,7 +5993,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1784.15319000507335",
|
||||
"locked_amount": "1791.028665651953",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -7062,7 +7062,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "1709370.7872515768348",
|
||||
"locked_amount": "123534.5481966065072434858",
|
||||
"locked_amount": "126202.1342632826843379468",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -40934,7 +40934,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "715655.108029600523393",
|
||||
"locked_amount": "214330.915145972181008792886",
|
||||
"locked_amount": "218430.066175628697078272948",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -42326,8 +42326,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "872635.89843522227071852",
|
||||
"locked_amount": "6059691.24938843042043456221192312067585835",
|
||||
"total_removed": "871680.07831804700259352",
|
||||
"locked_amount": "6074226.5757489411253544394273819693295485",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -42836,11 +42836,6 @@
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
||||
},
|
||||
{
|
||||
"amount": "955.820117175268125",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
|
||||
},
|
||||
{
|
||||
"amount": "10150.87581603206683",
|
||||
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
|
||||
@@ -45015,12 +45010,6 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
||||
},
|
||||
{
|
||||
"amount": "955.820117175268125",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
|
||||
},
|
||||
{
|
||||
"amount": "913.910324501590625",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -46577,8 +46566,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "259998.8875",
|
||||
"withdrawn_tokens": "160546.342221561692",
|
||||
"remaining_tokens": "99452.545278438308"
|
||||
"withdrawn_tokens": "159590.522104386423875",
|
||||
"remaining_tokens": "100408.365395613576125"
|
||||
},
|
||||
{
|
||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||
@@ -48959,7 +48948,7 @@
|
||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "6246751.954791069035514289",
|
||||
"total_removed": "6170228.182342542771392682",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -49169,11 +49158,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "76523.772448526264121607",
|
||||
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
|
||||
},
|
||||
{
|
||||
"amount": "1257.7360413991436375",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -56373,12 +56357,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "76523.772448526264121607",
|
||||
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
|
||||
},
|
||||
{
|
||||
"amount": "466184.354416277260082874",
|
||||
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||
@@ -56393,8 +56371,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "575536.79731735",
|
||||
"withdrawn_tokens": "575536.79731735",
|
||||
"remaining_tokens": "0"
|
||||
"withdrawn_tokens": "499013.024868823735878393",
|
||||
"remaining_tokens": "76523.772448526264121607"
|
||||
},
|
||||
{
|
||||
"address": "0xaAeD573103e3f981867C4cd31c6674DE1c8a13c3",
|
||||
@@ -56886,7 +56864,7 @@
|
||||
"tranche_start": "2021-10-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "5778205.3912159303",
|
||||
"total_removed": "3492469.400132244009296769",
|
||||
"total_removed": "3480901.398845846498418769",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -57031,11 +57009,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "11568.001286397510878",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
|
||||
},
|
||||
{
|
||||
"amount": "58898.87608135458795",
|
||||
"user": "0x83b1a48376E045D26420200345414e6b93066396",
|
||||
@@ -58006,12 +57979,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "11568.001286397510878",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
"tranche_id": 4,
|
||||
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
|
||||
},
|
||||
{
|
||||
"amount": "209431.056913602489122",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
@@ -58020,8 +57987,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "220999.0582",
|
||||
"withdrawn_tokens": "220999.0582",
|
||||
"remaining_tokens": "0"
|
||||
"withdrawn_tokens": "209431.056913602489122",
|
||||
"remaining_tokens": "11568.001286397510878"
|
||||
},
|
||||
{
|
||||
"address": "0x9058e12e2F32cB1cD4D3123359963D77786477FC",
|
||||
@@ -59102,8 +59069,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "44544.1737890903416",
|
||||
"locked_amount": "33961.958672622378193436739320136",
|
||||
"total_removed": "44479.0535455583416",
|
||||
"locked_amount": "34611.49258501772999518148756976",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
@@ -65727,11 +65694,6 @@
|
||||
"user": "0x0436E2E4EA467f9958403dc56635404EE1bb1E94",
|
||||
"tx": "0x97f5b5ec5ac839a8d182b9267b5d052cb70f9a18b648874337e3d5360b21a5fb"
|
||||
},
|
||||
{
|
||||
"amount": "65.120243532",
|
||||
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
|
||||
},
|
||||
{
|
||||
"amount": "182.662252664",
|
||||
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
|
||||
@@ -86325,12 +86287,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "65.120243532",
|
||||
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||
"tranche_id": 5,
|
||||
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
|
||||
},
|
||||
{
|
||||
"amount": "120.24984145",
|
||||
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||
@@ -86339,8 +86295,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200",
|
||||
"withdrawn_tokens": "185.370084982",
|
||||
"remaining_tokens": "14.629915018"
|
||||
"withdrawn_tokens": "120.24984145",
|
||||
"remaining_tokens": "79.75015855"
|
||||
},
|
||||
{
|
||||
"address": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
|
||||
@@ -144445,11 +144401,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "0",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
|
||||
},
|
||||
{
|
||||
"amount": "0",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
@@ -144745,12 +144696,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "0",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
"tranche_id": 9,
|
||||
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
|
||||
},
|
||||
{
|
||||
"amount": "0",
|
||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
createMarketsDataFragment,
|
||||
assetQuery,
|
||||
networkParamsQuery,
|
||||
nodeGuardQuery,
|
||||
} from '@vegaprotocol/mock';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
@@ -159,7 +158,6 @@ describe('Closed markets', { tags: '@smoke' }, () => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||
aliasGQLQuery(req, 'NetworkParams', networkParamsQuery());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
marketsDataQuery,
|
||||
marketsQuery,
|
||||
networkParamsQuery,
|
||||
nodeGuardQuery,
|
||||
ordersQuery,
|
||||
positionsQuery,
|
||||
proposalListQuery,
|
||||
@@ -83,7 +82,6 @@ const mockTradingPage = (
|
||||
) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
'Markets',
|
||||
|
||||
+7
-3
@@ -1,6 +1,6 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
|
||||
export const AppFailure = ({
|
||||
title,
|
||||
@@ -9,13 +9,17 @@ export const AppFailure = ({
|
||||
title: string;
|
||||
error?: string | null;
|
||||
}) => {
|
||||
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||
const { setNodeSwitcher } = useGlobalStore((store) => ({
|
||||
nodeSwitcherOpen: store.nodeSwitcherDialog,
|
||||
setNodeSwitcher: (open: boolean) =>
|
||||
store.update({ nodeSwitcherDialog: open }),
|
||||
}));
|
||||
const nonIdealWrapperClasses =
|
||||
'h-full min-h-screen flex items-center justify-center';
|
||||
return (
|
||||
<div className={nonIdealWrapperClasses}>
|
||||
<div className="text-center">
|
||||
<p className="text-xl mb-4">{title}</p>
|
||||
<h1 className="text-xl mb-4">{title}</h1>
|
||||
{error && <p className="text-sm mb-8">{error}</p>}
|
||||
<Button onClick={() => setNodeSwitcher(true)}>
|
||||
{t('Change node')}
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
import {
|
||||
AppFailure,
|
||||
NetworkLoader,
|
||||
NodeGuard,
|
||||
useEnvironment,
|
||||
@@ -10,6 +9,7 @@ import { MaintenancePage } from '@vegaprotocol/ui-toolkit';
|
||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||
import dynamic from 'next/dynamic';
|
||||
import type { ReactNode } from 'react';
|
||||
import { AppFailure } from './app-failure';
|
||||
import { Web3Provider } from './web3-provider';
|
||||
|
||||
export const DynamicLoader = dynamic(() => import('../preloader/preloader'), {
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './app-failure';
|
||||
export * from './app-loader';
|
||||
export * from './web3-provider';
|
||||
|
||||
@@ -4,15 +4,18 @@ import { NodeHealth, NodeUrl, HealthIndicator } from './footer';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { Intent } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const mockSetNodeSwitcher = jest.fn();
|
||||
|
||||
jest.mock('@vegaprotocol/environment', () => ({
|
||||
...jest.requireActual('@vegaprotocol/environment'),
|
||||
useEnvironment: jest.fn().mockImplementation(() => ({
|
||||
VEGA_URL: 'https://vega-url.wtf',
|
||||
VEGA_INCIDENT_URL: 'https://blog.vega.community',
|
||||
})),
|
||||
useNodeSwitcherStore: jest.fn(() => mockSetNodeSwitcher),
|
||||
}));
|
||||
|
||||
const mockSetNodeSwitcher = jest.fn();
|
||||
jest.mock('../../stores', () => ({
|
||||
...jest.requireActual('../../stores'),
|
||||
useGlobalStore: () => mockSetNodeSwitcher,
|
||||
}));
|
||||
|
||||
describe('NodeHealth', () => {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
useEnvironment,
|
||||
useNodeHealth,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { useEnvironment, useNodeHealth } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { Indicator, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import classNames from 'classnames';
|
||||
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
|
||||
export const Footer = () => {
|
||||
return (
|
||||
@@ -23,7 +20,9 @@ export const Footer = () => {
|
||||
|
||||
export const NodeHealth = () => {
|
||||
const { VEGA_URL, VEGA_INCIDENT_URL } = useEnvironment();
|
||||
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||
const setNodeSwitcher = useGlobalStore(
|
||||
(store) => (open: boolean) => store.update({ nodeSwitcherDialog: open })
|
||||
);
|
||||
const { datanodeBlockHeight, text, intent } = useNodeHealth();
|
||||
const onClick = useCallback(() => {
|
||||
setNodeSwitcher(true);
|
||||
|
||||
@@ -7,13 +7,7 @@ import {
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { RISK_ACCEPTED_KEY } from '../constants';
|
||||
import { TelemetryApproval } from './telemetry-approval';
|
||||
import {
|
||||
DOCS_VEGA_WALLET,
|
||||
GET_VEGA_WALLET_URL,
|
||||
Networks,
|
||||
useDocsLink,
|
||||
useEnvironment,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface Props {
|
||||
@@ -52,9 +46,8 @@ export const RiskNoticeDialog = ({ onClose, network }: Props) => {
|
||||
};
|
||||
|
||||
const TestnetContent = ({ network }: { network: Networks }) => {
|
||||
const { GITHUB_FEEDBACK_URL } = useEnvironment();
|
||||
const docsLink = useDocsLink();
|
||||
|
||||
const { VEGA_DOCS_URL, GITHUB_FEEDBACK_URL, VEGA_WALLET_URL } =
|
||||
useEnvironment();
|
||||
return (
|
||||
<>
|
||||
<p className="mb-4">
|
||||
@@ -69,17 +62,17 @@ const TestnetContent = ({ network }: { network: Networks }) => {
|
||||
[network]
|
||||
)}
|
||||
</p>
|
||||
{GITHUB_FEEDBACK_URL && GET_VEGA_WALLET_URL && docsLink && (
|
||||
{VEGA_DOCS_URL && GITHUB_FEEDBACK_URL && VEGA_WALLET_URL && (
|
||||
<ul className="list-disc pl-4">
|
||||
<li className="mb-1">
|
||||
<Link href={GET_VEGA_WALLET_URL} target="_blank">
|
||||
<span className="underline">{t('Get a Vega Wallet')}</span>{' '}
|
||||
<Link href={VEGA_WALLET_URL} target="_blank">
|
||||
<span className="underline">{t('Learn about Vega wallet')}</span>{' '}
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
</Link>
|
||||
</li>
|
||||
<li className="mb-1">
|
||||
<Link href={docsLink(DOCS_VEGA_WALLET)} target="_blank">
|
||||
<span className="underline">{t('Learn about Vega Wallet')}</span>{' '}
|
||||
<Link href={VEGA_DOCS_URL} target="_blank">
|
||||
<span className="underline">{t('View documentation')}</span>{' '}
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
@@ -21,10 +21,9 @@ import {
|
||||
NodeSwitcherDialog,
|
||||
useEnvironment,
|
||||
useInitializeEnv,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import './styles.css';
|
||||
import { usePageTitleStore } from '../stores';
|
||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
||||
import { Footer } from '../components/footer';
|
||||
import DialogsContainer from './dialogs-container';
|
||||
import ToastsManager from './toasts-manager';
|
||||
@@ -116,10 +115,11 @@ function AppBody({ Component }: AppProps) {
|
||||
|
||||
function VegaTradingApp(props: AppProps) {
|
||||
const status = useEnvironment((store) => store.status);
|
||||
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
|
||||
store.dialogOpen,
|
||||
store.setDialogOpen,
|
||||
]);
|
||||
const { nodeSwitcherOpen, setNodeSwitcher } = useGlobalStore((store) => ({
|
||||
nodeSwitcherOpen: store.nodeSwitcherDialog,
|
||||
setNodeSwitcher: (open: boolean) =>
|
||||
store.update({ nodeSwitcherDialog: open }),
|
||||
}));
|
||||
|
||||
useInitializeEnv();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { create } from 'zustand';
|
||||
import produce from 'immer';
|
||||
|
||||
interface GlobalStore {
|
||||
nodeSwitcherDialog: boolean;
|
||||
marketId: string | null;
|
||||
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
|
||||
shouldDisplayWelcomeDialog: boolean;
|
||||
@@ -14,6 +15,7 @@ interface PageTitleStore {
|
||||
}
|
||||
|
||||
export const useGlobalStore = create<GlobalStore>()((set) => ({
|
||||
nodeSwitcherDialog: false,
|
||||
marketId: LocalStorage.getItem('marketId') || null,
|
||||
shouldDisplayWelcomeDialog: false,
|
||||
update: (newState) => {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# Build container
|
||||
ARG NODE_VERSION
|
||||
FROM --platform=amd64 node:${NODE_VERSION}-alpine3.16 as build
|
||||
WORKDIR /app
|
||||
# Argument to allow building of different apps
|
||||
ARG APP
|
||||
ARG ENV_NAME=""
|
||||
RUN apk add --update --no-cache \
|
||||
python3==3.10.11-r0 \
|
||||
make==4.3-r0 \
|
||||
gcc==11.2.1_git20220219-r2 \
|
||||
g++==11.2.1_git20220219-r2
|
||||
COPY . ./
|
||||
RUN yarn --network-timeout 100000 --pure-lockfile
|
||||
# work around for different build process in trading
|
||||
RUN sh docker/docker-build.sh
|
||||
|
||||
# Server environment
|
||||
# if this fails you need to docker pull nginx:1.23-alpine and pin new SHA
|
||||
# this is to ensure that we run always same version of alpine to make sure ipfs is indempotent
|
||||
FROM --platform=amd64 nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
|
||||
# configuration of system
|
||||
EXPOSE 80
|
||||
# Copy dist
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
COPY --from=build /app/dist/apps/${APP}/* /usr/share/nginx/html
|
||||
RUN apk add --no-cache go-ipfs==0.16.0-r6 \
|
||||
&& ipfs init \
|
||||
&& echo "$(ipfs add -rwQ /usr/share/nginx/html)" > /ipfs-hash \
|
||||
&& echo "ipfs hash of this build: $(cat /ipfs-hash)"
|
||||
@@ -1,10 +0,0 @@
|
||||
FROM --platform=amd64 nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
|
||||
EXPOSE 80
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
COPY ./dist-result/ /usr/share/nginx/html/
|
||||
RUN apk add --no-cache go-ipfs==0.16.0-r6 \
|
||||
&& ipfs init \
|
||||
&& echo "$(ipfs add -rwQ /usr/share/nginx/html)" > /ipfs-hash \
|
||||
&& echo "ipfs hash of this build: $(cat /ipfs-hash)"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
yarn --pure-lockfile
|
||||
app={$1:-trading}
|
||||
flags="--env=${$2:-mainnet}"
|
||||
yarn install
|
||||
if [ "${app}" = "trading" ]; then
|
||||
yarn nx export trading $flags
|
||||
DIST_LOCATION=dist/apps/trading/exported
|
||||
else
|
||||
yarn nx build ${app} $flags
|
||||
DIST_LOCATION=dist/apps/${app}
|
||||
fi
|
||||
cp -r $DIST_LOCATION dist-result
|
||||
@@ -7,7 +7,6 @@ export * from '../candles-chart/src/lib/chart.mock';
|
||||
export * from '../deal-ticket/src/hooks/estimate-order.mock';
|
||||
export * from '../deposits/src/lib/deposit.mock';
|
||||
export * from '../environment/src/utils/node.mock';
|
||||
export * from '../environment/src/components/node-guard/node-guard.mock';
|
||||
export * from '../fills/src/lib/fills.mock';
|
||||
export * from '../proposals/src/lib/proposals-data-provider/proposals.mock';
|
||||
export * from '../ledger/src/lib/ledger-entries.mock';
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './app-failure';
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './app-failure';
|
||||
export * from './network-loader';
|
||||
export * from './network-switcher';
|
||||
export * from './node-guard';
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
query NodeGuard {
|
||||
lastBlockHeight
|
||||
networkParametersConnection {
|
||||
edges {
|
||||
node {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type NodeGuardQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type NodeGuardQuery = { __typename?: 'Query', lastBlockHeight: string, networkParametersConnection: { __typename?: 'NetworkParametersConnection', edges?: Array<{ __typename?: 'NetworkParameterEdge', node: { __typename?: 'NetworkParameter', key: string, value: string } } | null> | null } };
|
||||
|
||||
|
||||
export const NodeGuardDocument = gql`
|
||||
query NodeGuard {
|
||||
lastBlockHeight
|
||||
networkParametersConnection {
|
||||
edges {
|
||||
node {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useNodeGuardQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useNodeGuardQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useNodeGuardQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useNodeGuardQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useNodeGuardQuery(baseOptions?: Apollo.QueryHookOptions<NodeGuardQuery, NodeGuardQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<NodeGuardQuery, NodeGuardQueryVariables>(NodeGuardDocument, options);
|
||||
}
|
||||
export function useNodeGuardLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NodeGuardQuery, NodeGuardQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<NodeGuardQuery, NodeGuardQueryVariables>(NodeGuardDocument, options);
|
||||
}
|
||||
export type NodeGuardQueryHookResult = ReturnType<typeof useNodeGuardQuery>;
|
||||
export type NodeGuardLazyQueryHookResult = ReturnType<typeof useNodeGuardLazyQuery>;
|
||||
export type NodeGuardQueryResult = Apollo.QueryResult<NodeGuardQuery, NodeGuardQueryVariables>;
|
||||
@@ -1,53 +0,0 @@
|
||||
import type { NodeGuardQuery } from './__generated__/NodeGuard';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const nodeGuardQuery = (
|
||||
override?: PartialDeep<NodeGuardQuery>
|
||||
): NodeGuardQuery => {
|
||||
const defaultResult: NodeGuardQuery = {
|
||||
lastBlockHeight: '11',
|
||||
networkParametersConnection: {
|
||||
__typename: 'NetworkParametersConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'NetworkParameterEdge',
|
||||
node: {
|
||||
__typename: 'NetworkParameter' as const,
|
||||
key: 'governance.proposal.market.requiredMajority',
|
||||
value: '0.66',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'NetworkParameterEdge',
|
||||
node: {
|
||||
__typename: 'NetworkParameter' as const,
|
||||
key: 'blockchains.ethereumConfig',
|
||||
value: JSON.stringify({
|
||||
network_id: '3',
|
||||
chain_id: '3',
|
||||
collateral_bridge_contract: {
|
||||
address: '0x7fe27d970bc8Afc3B11Cc8d9737bfB66B1efd799',
|
||||
},
|
||||
multisig_control_contract: {
|
||||
address: '0x6eBc32d66277D94DB8FF2ccF86E36f37F29a52D3',
|
||||
deployment_block_height: 12341882,
|
||||
},
|
||||
staking_bridge_contract: {
|
||||
address: '0xFFb0A0d4806502ceF491aF1141f66669A1Bd0D03',
|
||||
deployment_block_height: 11177313,
|
||||
},
|
||||
token_vesting_contract: {
|
||||
address: '0x680fF88252FA7071CAce7398e77872d54D781d0B',
|
||||
deployment_block_height: 11177353,
|
||||
},
|
||||
confirmations: 3,
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { useNodeGuardQuery } from './__generated__/NodeGuard';
|
||||
import { useStatisticsQuery } from '../../utils/__generated__/Node';
|
||||
|
||||
export const NodeGuard = ({
|
||||
children,
|
||||
@@ -10,19 +10,14 @@ export const NodeGuard = ({
|
||||
failure: ReactNode;
|
||||
skeleton: ReactNode;
|
||||
}) => {
|
||||
const { data, error, loading } = useNodeGuardQuery();
|
||||
const wrapperClasses =
|
||||
'h-full min-h-screen flex items-center justify-center text-black dark:text-white';
|
||||
const { error, loading } = useStatisticsQuery();
|
||||
const wrapperClasses = 'h-full min-h-screen flex items-center justify-center';
|
||||
|
||||
if (loading) {
|
||||
return <div className={wrapperClasses}>{skeleton}</div>;
|
||||
}
|
||||
|
||||
// It is possible for nodes to have a functioning datanode, but not return
|
||||
// any net params. The app cannot safely function without net params
|
||||
const netParamEdges = data?.networkParametersConnection.edges;
|
||||
|
||||
if (error || !netParamEdges || !netParamEdges.length) {
|
||||
if (error) {
|
||||
return <div className={wrapperClasses}>{failure}</div>;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,13 +96,13 @@ describe('RowData', () => {
|
||||
mockHeaders(props.url);
|
||||
render(renderComponent(props, statsQueryMock, subMock));
|
||||
|
||||
// radio should be enabled until query resolves
|
||||
// radio should be disabled until query resolves
|
||||
expect(
|
||||
screen.getByRole('radio', {
|
||||
checked: false,
|
||||
name: props.url,
|
||||
})
|
||||
).toBeEnabled();
|
||||
).toBeDisabled();
|
||||
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
||||
'Checking'
|
||||
);
|
||||
@@ -124,7 +124,7 @@ describe('RowData', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('radio button still enabled if query fails', async () => {
|
||||
it('radio button disabled if query fails', async () => {
|
||||
mockHeaders(props.url, {});
|
||||
|
||||
const failedQueryMock: MockedResponse<StatisticsQuery> = {
|
||||
@@ -149,7 +149,7 @@ describe('RowData', () => {
|
||||
checked: false,
|
||||
name: props.url,
|
||||
})
|
||||
).toBeEnabled();
|
||||
).toBeDisabled();
|
||||
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
||||
'Checking'
|
||||
);
|
||||
@@ -170,7 +170,7 @@ describe('RowData', () => {
|
||||
checked: false,
|
||||
name: props.url,
|
||||
})
|
||||
).toBeEnabled();
|
||||
).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -207,6 +207,19 @@ describe('RowData', () => {
|
||||
expect(screen.getByTestId('block-height-cell')).toHaveClass('text-danger');
|
||||
});
|
||||
|
||||
it('disables radio button if url is invalid', () => {
|
||||
mockHeaders(props.url, { blockHeight: 100 });
|
||||
|
||||
render(renderComponent(props, statsQueryMock, subMock));
|
||||
|
||||
expect(
|
||||
screen.getByRole('radio', {
|
||||
checked: false,
|
||||
name: props.url,
|
||||
})
|
||||
).toBeDisabled();
|
||||
});
|
||||
|
||||
it('doesnt render the radio if its the custom row', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
|
||||
@@ -124,6 +124,29 @@ export const RowData = ({
|
||||
return false;
|
||||
};
|
||||
|
||||
const getIsNodeDisabled = () => {
|
||||
if (!isValidUrl(url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if still waiting or query errored disable node
|
||||
if (loading || error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subLoading || subError) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if we are still waiting for a header entry for this
|
||||
// url disable the node
|
||||
if (!headers) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const getSubFailed = (
|
||||
subError: ApolloError | undefined,
|
||||
subFailed: boolean
|
||||
@@ -137,7 +160,12 @@ export const RowData = ({
|
||||
<>
|
||||
{id !== CUSTOM_NODE_KEY && (
|
||||
<div className="break-all" data-testid="node">
|
||||
<Radio id={`node-url-${id}`} value={url} label={url} />
|
||||
<Radio
|
||||
id={`node-url-${id}`}
|
||||
value={url}
|
||||
label={url}
|
||||
disabled={getIsNodeDisabled()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<LayoutCell
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export * from './use-environment';
|
||||
export * from './use-links';
|
||||
export * from './use-node-health';
|
||||
export * from './use-node-switcher-store';
|
||||
export * from './use-vega-releases';
|
||||
export * from './use-vega-release';
|
||||
|
||||
@@ -15,7 +15,6 @@ import { Networks } from '../types';
|
||||
import { compileErrors } from '../utils/compile-errors';
|
||||
import { envSchema } from '../utils/validate-environment';
|
||||
import { tomlConfigSchema } from '../utils/validate-configuration';
|
||||
import uniq from 'lodash/uniq';
|
||||
|
||||
type Client = ReturnType<typeof createClient>;
|
||||
type ClientCollection = {
|
||||
@@ -33,8 +32,7 @@ type Actions = {
|
||||
export type Env = Environment & EnvState;
|
||||
export type EnvStore = Env & Actions;
|
||||
|
||||
const VERSION = 1;
|
||||
export const STORAGE_KEY = `vega_url_${VERSION}`;
|
||||
export const STORAGE_KEY = 'vega_url';
|
||||
const SUBSCRIPTION_TIMEOUT = 3000;
|
||||
|
||||
export const useEnvironment = create<EnvStore>()((set, get) => ({
|
||||
@@ -71,10 +69,7 @@ export const useEnvironment = create<EnvStore>()((set, get) => ({
|
||||
let nodes: string[] | undefined;
|
||||
try {
|
||||
nodes = await fetchConfig(state.VEGA_CONFIG_URL);
|
||||
const enrichedNodes = uniq(
|
||||
[...nodes, state.VEGA_URL, storedUrl].filter(Boolean) as string[]
|
||||
);
|
||||
set({ nodes: enrichedNodes });
|
||||
set({ nodes });
|
||||
} catch (err) {
|
||||
console.warn(`Could not fetch node config from ${state.VEGA_CONFIG_URL}`);
|
||||
}
|
||||
|
||||
@@ -84,16 +84,6 @@ export const useEtherscanLink = () => {
|
||||
return link;
|
||||
};
|
||||
|
||||
export const useDocsLink = () => {
|
||||
const { VEGA_DOCS_URL } = useEnvironment();
|
||||
const baseUrl = trim(VEGA_DOCS_URL, '/');
|
||||
const link = useCallback(
|
||||
(url?: string) => `${baseUrl}/${trim(url, '/') || ''}`,
|
||||
[baseUrl]
|
||||
);
|
||||
return link;
|
||||
};
|
||||
|
||||
// Vega blog
|
||||
export const BLOG = 'https://blog.vega.xyz/';
|
||||
|
||||
@@ -135,9 +125,3 @@ export const CONSOLE_MARKET = '/markets/:marketId';
|
||||
export const CONSOLE_MARKETS = '/markets/all';
|
||||
export const CONSOLE_PORTFOLIO = '/portfolio';
|
||||
export const CONSOLE_LIQUIDITY = 'liquidity/:marketId';
|
||||
|
||||
// Vega XYZ
|
||||
export const GET_VEGA_WALLET_URL = 'https://vega.xyz/wallet/';
|
||||
|
||||
// Docs
|
||||
export const DOCS_VEGA_WALLET = '/tools/vega-wallet';
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export const useNodeSwitcherStore = create<{
|
||||
dialogOpen: boolean;
|
||||
setDialogOpen: (isOpen: boolean) => void;
|
||||
}>()((set) => ({
|
||||
dialogOpen: false,
|
||||
setDialogOpen: (isOpen) => {
|
||||
set({ dialogOpen: isOpen });
|
||||
},
|
||||
}));
|
||||
@@ -1,11 +1,7 @@
|
||||
import { Fragment } from 'react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Link, Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
NodeSwitcherDialog,
|
||||
useEnvironment,
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
|
||||
|
||||
const getFeedbackLinks = (gitOriginUrl?: string) =>
|
||||
[
|
||||
@@ -23,59 +19,64 @@ export const NetworkInfo = () => {
|
||||
GITHUB_FEEDBACK_URL,
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
} = useEnvironment();
|
||||
|
||||
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
||||
const feedbackLinks = getFeedbackLinks(GITHUB_FEEDBACK_URL);
|
||||
|
||||
return (
|
||||
<div data-testid="git-info">
|
||||
<p data-testid="git-network-data" className="mb-2">
|
||||
{t('Reading network data from')}{' '}
|
||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
||||
{VEGA_URL}
|
||||
</Lozenge>
|
||||
. <Link onClick={() => setNodeSwitcher(true)}>{t('Edit')}</Link>
|
||||
</p>
|
||||
<p data-testid="git-eth-data" className="mb-2 break-all">
|
||||
{t('Reading Ethereum data from')}{' '}
|
||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
||||
{ETHEREUM_PROVIDER_URL}
|
||||
</Lozenge>
|
||||
.{' '}
|
||||
</p>
|
||||
{GIT_COMMIT_HASH && (
|
||||
<p data-testid="git-commit-hash" className="mb-2">
|
||||
{t('Version/commit hash')}:{' '}
|
||||
<Link
|
||||
href={
|
||||
GIT_ORIGIN_URL
|
||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||
: undefined
|
||||
}
|
||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||
>
|
||||
{GIT_COMMIT_HASH}
|
||||
</Link>
|
||||
<>
|
||||
<div data-testid="git-info">
|
||||
<p data-testid="git-network-data" className="mb-2">
|
||||
{t('Reading network data from')}{' '}
|
||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
||||
{VEGA_URL}
|
||||
</Lozenge>
|
||||
. <Link onClick={() => setNodeSwitcherOpen(true)}>{t('Edit')}</Link>
|
||||
</p>
|
||||
)}
|
||||
{feedbackLinks.length > 0 && (
|
||||
<p>
|
||||
{t('Known issues and feedback on')}{' '}
|
||||
{feedbackLinks.map(({ name, url }, index) => (
|
||||
<Fragment key={index}>
|
||||
<Link key={index} href={url}>
|
||||
{name}
|
||||
</Link>
|
||||
{feedbackLinks.length > 1 &&
|
||||
index < feedbackLinks.length - 2 &&
|
||||
','}
|
||||
{feedbackLinks.length > 1 &&
|
||||
index === feedbackLinks.length - 1 &&
|
||||
`, ${t('and')} `}
|
||||
</Fragment>
|
||||
))}
|
||||
<p data-testid="git-eth-data" className="mb-2 break-all">
|
||||
{t('Reading Ethereum data from')}{' '}
|
||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
||||
{ETHEREUM_PROVIDER_URL}
|
||||
</Lozenge>
|
||||
.{' '}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{GIT_COMMIT_HASH && (
|
||||
<p data-testid="git-commit-hash" className="mb-2">
|
||||
{t('Version/commit hash')}:{' '}
|
||||
<Link
|
||||
href={
|
||||
GIT_ORIGIN_URL
|
||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||
: undefined
|
||||
}
|
||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||
>
|
||||
{GIT_COMMIT_HASH}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
{feedbackLinks.length > 0 && (
|
||||
<p>
|
||||
{t('Known issues and feedback on')}{' '}
|
||||
{feedbackLinks.map(({ name, url }, index) => (
|
||||
<Fragment key={index}>
|
||||
<Link key={index} href={url}>
|
||||
{name}
|
||||
</Link>
|
||||
{feedbackLinks.length > 1 &&
|
||||
index < feedbackLinks.length - 2 &&
|
||||
','}
|
||||
{feedbackLinks.length > 1 &&
|
||||
index === feedbackLinks.length - 1 &&
|
||||
`, ${t('and')} `}
|
||||
</Fragment>
|
||||
))}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<NodeSwitcherDialog
|
||||
open={nodeSwitcherOpen}
|
||||
setOpen={setNodeSwitcherOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user