Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f784bd552c | ||
|
|
bded1d32ba | ||
|
|
76ddf45f4c | ||
|
|
6a2c9004d8 | ||
|
|
77ee88b43e | ||
|
|
e4958ce3c0 | ||
|
|
ecedb879f8 | ||
|
|
89700803d6 | ||
|
|
65c9fa5df2 | ||
|
|
02399c40fc | ||
|
|
2cb3b55a3b | ||
|
|
3acc0e2401 | ||
|
|
c734556eb4 |
@@ -5,6 +5,8 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- release/*
|
- release/*
|
||||||
- develop
|
- develop
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
@@ -97,15 +99,13 @@ jobs:
|
|||||||
- name: See affected apps
|
- name: See affected apps
|
||||||
run: |
|
run: |
|
||||||
echo ">>>> debug"
|
echo ">>>> debug"
|
||||||
echo "NX Version: $nx_version"
|
|
||||||
echo "NX_BASE: ${{ env.NX_BASE }}"
|
echo "NX_BASE: ${{ env.NX_BASE }}"
|
||||||
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
||||||
echo ">>>> eof debug"
|
echo ">>>> eof debug"
|
||||||
|
|
||||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
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=""
|
projects_e2e=""
|
||||||
preview_governance="not deployed"
|
preview_governance="not deployed"
|
||||||
preview_trading="not deployed"
|
preview_trading="not deployed"
|
||||||
|
|||||||
@@ -30,13 +30,21 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Log in to the Container registry
|
- name: Log in to the Container registry (ghcr)
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
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
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
@@ -54,30 +62,24 @@ jobs:
|
|||||||
- name: Define variables
|
- name: Define variables
|
||||||
run: |
|
run: |
|
||||||
envName=''
|
envName=''
|
||||||
dockerfile="dist.Dockerfile"
|
|
||||||
if [[ "${{ github.event_name }}" = "push" ]]; then
|
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||||
domain="vega.rocks"
|
domain="vega.rocks"
|
||||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||||
if [[ "${{ github.ref }}" =~ .*mainnet.* ]]; then
|
if [[ "${{ github.ref }}" =~ .*mainnet.* ]]; then
|
||||||
domain="vega.community"
|
domain="vega.community"
|
||||||
if [[ "${{ matrix.app }}" = "trading" ]]; then
|
|
||||||
dockerfile="ipfs.Dockerfile"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||||
envName="stagnet1"
|
envName="stagnet1"
|
||||||
|
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
||||||
|
envName="mainnet"
|
||||||
fi
|
fi
|
||||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
nodeVersion=$(cat .nvmrc | head -n 1)
|
|
||||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||||
echo NODE_VERSION=${nodeVersion} >> $GITHUB_ENV
|
|
||||||
echo DOCKERFILE=docker/${dockerfile} >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Build local dist
|
- name: Build local dist
|
||||||
if: ${{ env.DOCKERFILE != 'docker/ipfs.Dockerfile' }}
|
|
||||||
run: |
|
run: |
|
||||||
flags=""
|
flags=""
|
||||||
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
|
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
|
||||||
@@ -98,62 +100,59 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and export to local Docker
|
- name: Build and export to local Docker
|
||||||
id: docker_build
|
id: docker_build
|
||||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ${{ env.DOCKERFILE }}
|
file: docker/node-outside-docker.Dockerfile
|
||||||
load: true
|
load: true
|
||||||
build-args: |
|
build-args: |
|
||||||
APP=${{ matrix.app }}
|
APP=${{ matrix.app }}
|
||||||
NODE_VERSION=${{ env.NODE_VERSION }}
|
|
||||||
ENV_NAME=${{ env.ENV_NAME }}
|
ENV_NAME=${{ env.ENV_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
|
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
|
||||||
|
|
||||||
- name: Image digest
|
- name: Image digest
|
||||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||||
|
|
||||||
- name: Sanity check docker image
|
- name: Sanity check docker image
|
||||||
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "Check ipfs-hash"
|
echo "Check ipfs-hash"
|
||||||
if [[ "${{ env.DOCKERFILE }}" = "docker/ipfs.Dockerfile" ]]; then
|
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
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matirx.app }}-ipfs-hash
|
||||||
fi
|
|
||||||
|
|
||||||
echo "List html directory"
|
echo "List html directory"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree .'
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
||||||
|
|
||||||
- name: Copy dist to local filesystem
|
- name: Publish dist as docker image (ghcr)
|
||||||
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
|
uses: docker/build-push-action@v3
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' || (matrix.app == 'trading' && github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') ) }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ${{ env.DOCKERFILE }}
|
file: docker/node-outside-docker.Dockerfile
|
||||||
push: true
|
push: true
|
||||||
build-args: |
|
build-args: |
|
||||||
APP=${{ matrix.app }}
|
APP=${{ matrix.app }}
|
||||||
NODE_VERSION=${{ env.NODE_VERSION }}
|
|
||||||
ENV_NAME=${{ env.ENV_NAME }}
|
ENV_NAME=${{ env.ENV_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ github.event.pull_request.head.sha || github.sha }}
|
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
|
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||||
- name: Publish dist to s3
|
- name: Publish dist to s3
|
||||||
uses: jakejarvis/s3-sync-action@master
|
uses: jakejarvis/s3-sync-action@master
|
||||||
if: ${{ github.event_name == 'push' }}
|
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
with:
|
with:
|
||||||
args: --acl private --follow-symlinks --delete
|
args: --acl private --follow-symlinks --delete
|
||||||
env:
|
env:
|
||||||
@@ -169,3 +168,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
labels: ${{ matrix.app }}-preview
|
labels: ${{ matrix.app }}-preview
|
||||||
number: ${{ github.event.number }}
|
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,6 +2,7 @@
|
|||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
|
/dist-result
|
||||||
/tmp
|
/tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
/tools/executors/**/*.js
|
/tools/executors/**/*.js
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
.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,25 +103,68 @@ 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.
|
Visit the [Nx Documentation](https://nx.dev/getting-started/intro) to learn more.
|
||||||
|
|
||||||
# Docker & Vegacapsule
|
# 🐋 Hosting a console
|
||||||
|
|
||||||
## Docker
|
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).
|
||||||
|
|
||||||
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.
|
In order to run a container on port 3000:
|
||||||
|
|
||||||
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
|
```bash
|
||||||
docker run -p 3000:80 [TAG]
|
docker run -p 3000:80 [TAG]
|
||||||
```
|
```
|
||||||
|
|
||||||
Images ending with `.dist` are to pack locally created transpiled HTML files into nginx container for non-compatible with yarn architectures like M1 Mac
|
## 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**
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|||||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
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_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
|
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
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
# .env is stagnet1, so there are no overrides required
|
# .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"}'
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment';
|
import {
|
||||||
|
AppFailure,
|
||||||
|
NetworkLoader,
|
||||||
|
NodeGuard,
|
||||||
|
NodeSwitcherDialog,
|
||||||
|
useEnvironment,
|
||||||
|
useInitializeEnv,
|
||||||
|
useNodeSwitcherStore,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
||||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
||||||
import { RouterProvider } from 'react-router-dom';
|
import { RouterProvider } from 'react-router-dom';
|
||||||
import { router } from './routes/router-config';
|
import { router } from './routes/router-config';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
|
||||||
const splashLoading = (
|
const splashLoading = (
|
||||||
<Splash>
|
<Splash>
|
||||||
@@ -12,10 +21,23 @@ const splashLoading = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const { VEGA_URL } = useEnvironment();
|
||||||
|
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useNodeSwitcherStore(
|
||||||
|
(store) => [store.dialogOpen, store.setDialogOpen]
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<TendermintWebsocketProvider>
|
<TendermintWebsocketProvider>
|
||||||
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
||||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
<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}
|
||||||
|
/>
|
||||||
</NetworkLoader>
|
</NetworkLoader>
|
||||||
</TendermintWebsocketProvider>
|
</TendermintWebsocketProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
|
import {
|
||||||
|
useEnvironment,
|
||||||
|
useNodeSwitcherStore,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||||
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { ENV } from '../../config/env';
|
import { ENV } from '../../config/env';
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
||||||
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
const setNodeSwitcherOpen = useNodeSwitcherStore(
|
||||||
|
(store) => store.setDialogOpen
|
||||||
|
);
|
||||||
|
|
||||||
const { screenSize } = useScreenDimensions();
|
const { screenSize } = useScreenDimensions();
|
||||||
const showFullFeedbackLabel = useMemo(
|
const showFullFeedbackLabel = useMemo(
|
||||||
() => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
|
() => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
|
||||||
@@ -15,46 +21,40 @@ export const Footer = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
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">
|
||||||
<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">
|
||||||
<div className="flex justify-between gap-2 align-middle">
|
{GIT_COMMIT_HASH && (
|
||||||
{GIT_COMMIT_HASH && (
|
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
<p data-testid="git-commit-hash">
|
||||||
<p data-testid="git-commit-hash">
|
{t('Version')}:{' '}
|
||||||
{t('Version')}:{' '}
|
<Link
|
||||||
<Link
|
href={
|
||||||
href={
|
GIT_ORIGIN_URL
|
||||||
GIT_ORIGIN_URL
|
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
: undefined
|
||||||
: undefined
|
}
|
||||||
}
|
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
>
|
||||||
>
|
{GIT_COMMIT_HASH}
|
||||||
{GIT_COMMIT_HASH}
|
</Link>
|
||||||
</Link>
|
</p>
|
||||||
</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>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex pl-2 content-center">
|
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||||
<ExternalLink href={ENV.addresses.feedback}>
|
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
|
||||||
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
|
||||||
</ExternalLink>
|
{t('Change')}
|
||||||
</div>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
|
||||||
<NodeSwitcherDialog
|
<div className="flex pl-2 content-center">
|
||||||
open={nodeSwitcherOpen}
|
<ExternalLink href={ENV.addresses.feedback}>
|
||||||
setOpen={setNodeSwitcherOpen}
|
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
||||||
/>
|
</ExternalLink>
|
||||||
</>
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,15 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => {
|
|||||||
token.decimals(),
|
token.decimals(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const totalSupply = toBigNum(supply, decimals);
|
const totalSupply = toBigNum(supply.toString(), decimals);
|
||||||
const totalWallet = toBigNum(totalAssociatedWallet, decimals);
|
const totalWallet = toBigNum(
|
||||||
const totalVesting = toBigNum(totalAssociatedVesting, decimals);
|
totalAssociatedWallet.toString(),
|
||||||
|
decimals
|
||||||
|
);
|
||||||
|
const totalVesting = toBigNum(
|
||||||
|
totalAssociatedVesting.toString(),
|
||||||
|
decimals
|
||||||
|
);
|
||||||
|
|
||||||
appDispatch({
|
appDispatch({
|
||||||
type: AppStateActionType.SET_TOKEN,
|
type: AppStateActionType.SET_TOKEN,
|
||||||
|
|||||||
+37
-14
@@ -37,6 +37,10 @@ import {
|
|||||||
useEnvironment,
|
useEnvironment,
|
||||||
NetworkLoader,
|
NetworkLoader,
|
||||||
useInitializeEnv,
|
useInitializeEnv,
|
||||||
|
NodeGuard,
|
||||||
|
AppFailure,
|
||||||
|
NodeSwitcherDialog,
|
||||||
|
useNodeSwitcherStore,
|
||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import { ENV } from './config';
|
import { ENV } from './config';
|
||||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||||
@@ -48,6 +52,7 @@ import {
|
|||||||
TELEMETRY_ON,
|
TELEMETRY_ON,
|
||||||
} from './components/telemetry-dialog/telemetry-dialog';
|
} from './components/telemetry-dialog/telemetry-dialog';
|
||||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const cache: InMemoryCacheConfig = {
|
const cache: InMemoryCacheConfig = {
|
||||||
typePolicies: {
|
typePolicies: {
|
||||||
@@ -181,9 +186,19 @@ const ScrollToTop = () => {
|
|||||||
|
|
||||||
const AppContainer = () => {
|
const AppContainer = () => {
|
||||||
const { config, loading, error } = useEthereumConfig();
|
const { config, loading, error } = useEthereumConfig();
|
||||||
const { VEGA_ENV, GIT_COMMIT_HASH, GIT_BRANCH, ETHEREUM_PROVIDER_URL } =
|
const {
|
||||||
useEnvironment();
|
VEGA_ENV,
|
||||||
|
VEGA_URL,
|
||||||
|
GIT_COMMIT_HASH,
|
||||||
|
GIT_BRANCH,
|
||||||
|
ETHEREUM_PROVIDER_URL,
|
||||||
|
} = useEnvironment();
|
||||||
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
|
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
|
||||||
|
store.dialogOpen,
|
||||||
|
store.setDialogOpen,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ENV.dsn && telemetryOn) {
|
if (ENV.dsn && telemetryOn) {
|
||||||
@@ -219,21 +234,29 @@ const AppContainer = () => {
|
|||||||
<ScrollToTop />
|
<ScrollToTop />
|
||||||
<AppStateProvider>
|
<AppStateProvider>
|
||||||
<div className="grid min-h-full text-white">
|
<div className="grid min-h-full text-white">
|
||||||
<AsyncRenderer<EthereumConfig | null>
|
<NodeGuard
|
||||||
loading={loading}
|
skeleton={<div>{t('Loading')}</div>}
|
||||||
data={config}
|
failure={
|
||||||
error={error}
|
<AppFailure title={t('NodeUnsuitable', { url: VEGA_URL })} />
|
||||||
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>
|
</div>
|
||||||
</AppStateProvider>
|
</AppStateProvider>
|
||||||
|
<NodeSwitcherDialog open={nodeSwitcherOpen} setOpen={setNodeSwitcher} />
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -811,5 +811,6 @@
|
|||||||
"OptOutOfTelemetry": "You can opt out any time via settings",
|
"OptOutOfTelemetry": "You can opt out any time via settings",
|
||||||
"NoThanks": "No thanks",
|
"NoThanks": "No thanks",
|
||||||
"ShareData": "Share data",
|
"ShareData": "Share data",
|
||||||
"ContinueSharingData": "Continue sharing data"
|
"ContinueSharingData": "Continue sharing data",
|
||||||
|
"NodeUnsuitable": "Node: {{url}} is unsuitable"
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -34,6 +34,7 @@ import {
|
|||||||
formatNumberPercentage,
|
formatNumberPercentage,
|
||||||
toBigNum,
|
toBigNum,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
|
import { VALIDATOR_LOGO_MAP } from './logo-map';
|
||||||
|
|
||||||
interface CanonisedConsensusNodeProps {
|
interface CanonisedConsensusNodeProps {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -131,7 +132,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
|
|
||||||
const nodes = useMemo(() => {
|
const nodes = useMemo(() => {
|
||||||
if (!data || !previousEpochData) return [];
|
if (!data) return [];
|
||||||
let canonisedNodes = data
|
let canonisedNodes = data
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
|
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
|
||||||
@@ -161,6 +162,11 @@ export const ConsensusValidatorsTable = ({
|
|||||||
pendingUserStake,
|
pendingUserStake,
|
||||||
userStakeShare,
|
userStakeShare,
|
||||||
}) => {
|
}) => {
|
||||||
|
const logo = VALIDATOR_LOGO_MAP[id]
|
||||||
|
? VALIDATOR_LOGO_MAP[id]
|
||||||
|
: avatarUrl
|
||||||
|
? avatarUrl
|
||||||
|
: null;
|
||||||
const {
|
const {
|
||||||
rawValidatorScore: previousEpochValidatorScore,
|
rawValidatorScore: previousEpochValidatorScore,
|
||||||
performanceScore: previousEpochPerformanceScore,
|
performanceScore: previousEpochPerformanceScore,
|
||||||
@@ -171,7 +177,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
id,
|
id,
|
||||||
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
||||||
[ValidatorFields.VALIDATOR]: {
|
[ValidatorFields.VALIDATOR]: {
|
||||||
avatarUrl,
|
avatarUrl: logo,
|
||||||
name,
|
name,
|
||||||
},
|
},
|
||||||
[ValidatorFields.STAKE]: stakedTotal,
|
[ValidatorFields.STAKE]: stakedTotal,
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
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,6 +16,7 @@ import type { PreviousEpochQuery } from '../../__generated__/PreviousEpoch';
|
|||||||
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
||||||
import type { StakingDelegationFieldsFragment } from '../../__generated__/Staking';
|
import type { StakingDelegationFieldsFragment } from '../../__generated__/Staking';
|
||||||
import type { ValidatorsView } from './validator-tables';
|
import type { ValidatorsView } from './validator-tables';
|
||||||
|
import { VALIDATOR_LOGO_MAP } from './logo-map';
|
||||||
|
|
||||||
export enum ValidatorFields {
|
export enum ValidatorFields {
|
||||||
RANKING_INDEX = 'rankingIndex',
|
RANKING_INDEX = 'rankingIndex',
|
||||||
@@ -102,13 +103,18 @@ interface ValidatorRendererProps {
|
|||||||
export const ValidatorRenderer = ({ data }: ValidatorRendererProps) => {
|
export const ValidatorRenderer = ({ data }: ValidatorRendererProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { avatarUrl, name } = data.validator;
|
const { avatarUrl, name } = data.validator;
|
||||||
|
const logo = VALIDATOR_LOGO_MAP[data.id]
|
||||||
|
? VALIDATOR_LOGO_MAP[data.id]
|
||||||
|
: avatarUrl
|
||||||
|
? avatarUrl
|
||||||
|
: null;
|
||||||
return (
|
return (
|
||||||
<div className="w-[238px] grid grid-cols-[1fr_auto] gap-2 items-center">
|
<div className="w-[238px] grid grid-cols-[1fr_auto] gap-2 items-center">
|
||||||
<span className="flex overflow-hidden">
|
<span className="flex overflow-hidden">
|
||||||
{avatarUrl && (
|
{logo && (
|
||||||
<img
|
<img
|
||||||
className="h-6 w-6 rounded-full mr-2"
|
className="h-6 w-6 rounded-full mr-2"
|
||||||
src={avatarUrl}
|
src={logo}
|
||||||
alt={`Avatar icon for ${name}`}
|
alt={`Avatar icon for ${name}`}
|
||||||
onError={(e) => (e.currentTarget.style.display = 'none')}
|
onError={(e) => (e.currentTarget.style.display = 'none')}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -78,37 +78,38 @@ export const ValidatorTables = ({
|
|||||||
const nextDelegation = delegations?.find(
|
const nextDelegation = delegations?.find(
|
||||||
(d) => d.node.id === validatorId && d.epoch === Number(epochId) + 1
|
(d) => d.node.id === validatorId && d.epoch === Number(epochId) + 1
|
||||||
);
|
);
|
||||||
|
if (validator.stakedByOperator !== '0') {
|
||||||
switch (validator.rankingScore?.status) {
|
switch (validator.rankingScore?.status) {
|
||||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_TENDERMINT:
|
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_TENDERMINT:
|
||||||
acc.consensusValidators.push(
|
acc.consensusValidators.push(
|
||||||
addUserDataToValidator(
|
addUserDataToValidator(
|
||||||
validator,
|
validator,
|
||||||
currentDelegation,
|
currentDelegation,
|
||||||
nextDelegation,
|
nextDelegation,
|
||||||
currentUserStakeAvailable
|
currentUserStakeAvailable
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_ERSATZ:
|
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_ERSATZ:
|
||||||
acc.standbyValidators.push(
|
acc.standbyValidators.push(
|
||||||
addUserDataToValidator(
|
addUserDataToValidator(
|
||||||
validator,
|
validator,
|
||||||
currentDelegation,
|
currentDelegation,
|
||||||
nextDelegation,
|
nextDelegation,
|
||||||
currentUserStakeAvailable
|
currentUserStakeAvailable
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_PENDING:
|
case Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_PENDING:
|
||||||
acc.pendingValidators.push(
|
acc.pendingValidators.push(
|
||||||
addUserDataToValidator(
|
addUserDataToValidator(
|
||||||
validator,
|
validator,
|
||||||
currentDelegation,
|
currentDelegation,
|
||||||
nextDelegation,
|
nextDelegation,
|
||||||
currentUserStakeAvailable
|
currentUserStakeAvailable
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
"tranche_end": "2023-05-20T00:00:00.000Z",
|
"tranche_end": "2023-05-20T00:00:00.000Z",
|
||||||
"total_added": "19242.125",
|
"total_added": "19242.125",
|
||||||
"total_removed": "1523.8177488329475",
|
"total_removed": "1523.8177488329475",
|
||||||
"locked_amount": "6891.9471601080244395475",
|
"locked_amount": "6570.0201729841825026125",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "188",
|
"amount": "188",
|
||||||
@@ -4861,7 +4861,7 @@
|
|||||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||||
"total_added": "86666.297",
|
"total_added": "86666.297",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "49802.2753121154213651374",
|
"locked_amount": "49683.1009092296761910951",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "86666.297",
|
"amount": "86666.297",
|
||||||
@@ -4927,7 +4927,7 @@
|
|||||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||||
"total_added": "2500",
|
"total_added": "2500",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "312.4325905575906",
|
"locked_amount": "305.538226241351125",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "2500",
|
"amount": "2500",
|
||||||
@@ -4960,7 +4960,7 @@
|
|||||||
"tranche_end": "2023-11-01T00:00:00.000Z",
|
"tranche_end": "2023-11-01T00:00:00.000Z",
|
||||||
"total_added": "15000.000000000000015",
|
"total_added": "15000.000000000000015",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "14327.0455917874395143270455917874395",
|
"locked_amount": "14286.1290383454105142861290383454105",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1.5e-14",
|
"amount": "1.5e-14",
|
||||||
@@ -5048,7 +5048,7 @@
|
|||||||
"tranche_end": "2023-09-01T00:00:00.000Z",
|
"tranche_end": "2023-09-01T00:00:00.000Z",
|
||||||
"total_added": "17500",
|
"total_added": "17500",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "10913.25608896940375",
|
"locked_amount": "10865.52010995370325",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "12500",
|
"amount": "12500",
|
||||||
@@ -5315,7 +5315,7 @@
|
|||||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||||
"total_added": "37500",
|
"total_added": "37500",
|
||||||
"total_removed": "18077.0118744",
|
"total_removed": "18077.0118744",
|
||||||
"locked_amount": "17350.5026089625535",
|
"locked_amount": "17246.515788060160125",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "7500",
|
"amount": "7500",
|
||||||
@@ -5734,7 +5734,7 @@
|
|||||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||||
"total_added": "129999.45",
|
"total_added": "129999.45",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "49756.837002255673748325",
|
"locked_amount": "49637.7713310174637779075",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "129999.45",
|
"amount": "129999.45",
|
||||||
@@ -5767,7 +5767,7 @@
|
|||||||
"tranche_end": "2024-04-01T00:00:00.000Z",
|
"tranche_end": "2024-04-01T00:00:00.000Z",
|
||||||
"total_added": "54144.7663",
|
"total_added": "54144.7663",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "48485.46842731635829207292",
|
"locked_amount": "48411.21764968406449080437",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "54144.7663",
|
"amount": "54144.7663",
|
||||||
@@ -5800,7 +5800,7 @@
|
|||||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||||
"total_added": "62600",
|
"total_added": "62600",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "20022.5830035514954",
|
"locked_amount": "19936.502048452562182",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "10000",
|
"amount": "10000",
|
||||||
@@ -5993,7 +5993,7 @@
|
|||||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||||
"total_added": "5000",
|
"total_added": "5000",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "1791.028665651953",
|
"locked_amount": "1784.15319000507335",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "5000",
|
"amount": "5000",
|
||||||
@@ -7062,7 +7062,7 @@
|
|||||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||||
"total_added": "1939928.38",
|
"total_added": "1939928.38",
|
||||||
"total_removed": "1709370.7872515768348",
|
"total_removed": "1709370.7872515768348",
|
||||||
"locked_amount": "126202.1342632826843379468",
|
"locked_amount": "123534.5481966065072434858",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1852091.69",
|
"amount": "1852091.69",
|
||||||
@@ -40934,7 +40934,7 @@
|
|||||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||||
"total_added": "3732368.4671",
|
"total_added": "3732368.4671",
|
||||||
"total_removed": "715655.108029600523393",
|
"total_removed": "715655.108029600523393",
|
||||||
"locked_amount": "218430.066175628697078272948",
|
"locked_amount": "214330.915145972181008792886",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1998.95815",
|
"amount": "1998.95815",
|
||||||
@@ -42326,8 +42326,8 @@
|
|||||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||||
"total_added": "15870102.715470999700000001",
|
"total_added": "15870102.715470999700000001",
|
||||||
"total_removed": "871680.07831804700259352",
|
"total_removed": "872635.89843522227071852",
|
||||||
"locked_amount": "6074226.5757489411253544394273819693295485",
|
"locked_amount": "6059691.24938843042043456221192312067585835",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "16249.93",
|
"amount": "16249.93",
|
||||||
@@ -42836,6 +42836,11 @@
|
|||||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"amount": "955.820117175268125",
|
||||||
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
|
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "10150.87581603206683",
|
"amount": "10150.87581603206683",
|
||||||
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
|
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
|
||||||
@@ -45010,6 +45015,12 @@
|
|||||||
"tranche_id": 2,
|
"tranche_id": 2,
|
||||||
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"amount": "955.820117175268125",
|
||||||
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
|
"tranche_id": 2,
|
||||||
|
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "913.910324501590625",
|
"amount": "913.910324501590625",
|
||||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
@@ -46566,8 +46577,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "259998.8875",
|
"total_tokens": "259998.8875",
|
||||||
"withdrawn_tokens": "159590.522104386423875",
|
"withdrawn_tokens": "160546.342221561692",
|
||||||
"remaining_tokens": "100408.365395613576125"
|
"remaining_tokens": "99452.545278438308"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||||
@@ -48948,7 +48959,7 @@
|
|||||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||||
"total_added": "14597706.0446472999",
|
"total_added": "14597706.0446472999",
|
||||||
"total_removed": "6170228.182342542771392682",
|
"total_removed": "6246751.954791069035514289",
|
||||||
"locked_amount": "0",
|
"locked_amount": "0",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
@@ -49158,6 +49169,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "76523.772448526264121607",
|
||||||
|
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||||
|
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "1257.7360413991436375",
|
"amount": "1257.7360413991436375",
|
||||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||||
@@ -56357,6 +56373,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "76523.772448526264121607",
|
||||||
|
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||||
|
"tranche_id": 3,
|
||||||
|
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "466184.354416277260082874",
|
"amount": "466184.354416277260082874",
|
||||||
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
|
||||||
@@ -56371,8 +56393,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "575536.79731735",
|
"total_tokens": "575536.79731735",
|
||||||
"withdrawn_tokens": "499013.024868823735878393",
|
"withdrawn_tokens": "575536.79731735",
|
||||||
"remaining_tokens": "76523.772448526264121607"
|
"remaining_tokens": "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0xaAeD573103e3f981867C4cd31c6674DE1c8a13c3",
|
"address": "0xaAeD573103e3f981867C4cd31c6674DE1c8a13c3",
|
||||||
@@ -56864,7 +56886,7 @@
|
|||||||
"tranche_start": "2021-10-05T00:00:00.000Z",
|
"tranche_start": "2021-10-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "5778205.3912159303",
|
"total_added": "5778205.3912159303",
|
||||||
"total_removed": "3480901.398845846498418769",
|
"total_removed": "3492469.400132244009296769",
|
||||||
"locked_amount": "0",
|
"locked_amount": "0",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
@@ -57009,6 +57031,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "11568.001286397510878",
|
||||||
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
|
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "58898.87608135458795",
|
"amount": "58898.87608135458795",
|
||||||
"user": "0x83b1a48376E045D26420200345414e6b93066396",
|
"user": "0x83b1a48376E045D26420200345414e6b93066396",
|
||||||
@@ -57979,6 +58006,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "11568.001286397510878",
|
||||||
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
|
"tranche_id": 4,
|
||||||
|
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "209431.056913602489122",
|
"amount": "209431.056913602489122",
|
||||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
@@ -57987,8 +58020,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "220999.0582",
|
"total_tokens": "220999.0582",
|
||||||
"withdrawn_tokens": "209431.056913602489122",
|
"withdrawn_tokens": "220999.0582",
|
||||||
"remaining_tokens": "11568.001286397510878"
|
"remaining_tokens": "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0x9058e12e2F32cB1cD4D3123359963D77786477FC",
|
"address": "0x9058e12e2F32cB1cD4D3123359963D77786477FC",
|
||||||
@@ -59069,8 +59102,8 @@
|
|||||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||||
"total_added": "472355.6199999996",
|
"total_added": "472355.6199999996",
|
||||||
"total_removed": "44479.0535455583416",
|
"total_removed": "44544.1737890903416",
|
||||||
"locked_amount": "34611.49258501772999518148756976",
|
"locked_amount": "33961.958672622378193436739320136",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "3000",
|
"amount": "3000",
|
||||||
@@ -65694,6 +65727,11 @@
|
|||||||
"user": "0x0436E2E4EA467f9958403dc56635404EE1bb1E94",
|
"user": "0x0436E2E4EA467f9958403dc56635404EE1bb1E94",
|
||||||
"tx": "0x97f5b5ec5ac839a8d182b9267b5d052cb70f9a18b648874337e3d5360b21a5fb"
|
"tx": "0x97f5b5ec5ac839a8d182b9267b5d052cb70f9a18b648874337e3d5360b21a5fb"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"amount": "65.120243532",
|
||||||
|
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||||
|
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "182.662252664",
|
"amount": "182.662252664",
|
||||||
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
|
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
|
||||||
@@ -86287,6 +86325,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "65.120243532",
|
||||||
|
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||||
|
"tranche_id": 5,
|
||||||
|
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "120.24984145",
|
"amount": "120.24984145",
|
||||||
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
|
||||||
@@ -86295,8 +86339,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "200",
|
"total_tokens": "200",
|
||||||
"withdrawn_tokens": "120.24984145",
|
"withdrawn_tokens": "185.370084982",
|
||||||
"remaining_tokens": "79.75015855"
|
"remaining_tokens": "14.629915018"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
|
"address": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
|
||||||
@@ -144401,6 +144445,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "0",
|
||||||
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
|
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "0",
|
"amount": "0",
|
||||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
@@ -144696,6 +144745,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "0",
|
||||||
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
|
"tranche_id": 9,
|
||||||
|
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "0",
|
"amount": "0",
|
||||||
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
createMarketsDataFragment,
|
createMarketsDataFragment,
|
||||||
assetQuery,
|
assetQuery,
|
||||||
networkParamsQuery,
|
networkParamsQuery,
|
||||||
|
nodeGuardQuery,
|
||||||
} from '@vegaprotocol/mock';
|
} from '@vegaprotocol/mock';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
@@ -158,6 +159,7 @@ describe('Closed markets', { tags: '@smoke' }, () => {
|
|||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||||
|
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||||
aliasGQLQuery(req, 'NetworkParams', networkParamsQuery());
|
aliasGQLQuery(req, 'NetworkParams', networkParamsQuery());
|
||||||
aliasGQLQuery(
|
aliasGQLQuery(
|
||||||
req,
|
req,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
marketsDataQuery,
|
marketsDataQuery,
|
||||||
marketsQuery,
|
marketsQuery,
|
||||||
networkParamsQuery,
|
networkParamsQuery,
|
||||||
|
nodeGuardQuery,
|
||||||
ordersQuery,
|
ordersQuery,
|
||||||
positionsQuery,
|
positionsQuery,
|
||||||
proposalListQuery,
|
proposalListQuery,
|
||||||
@@ -82,6 +83,7 @@ const mockTradingPage = (
|
|||||||
) => {
|
) => {
|
||||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||||
|
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||||
aliasGQLQuery(
|
aliasGQLQuery(
|
||||||
req,
|
req,
|
||||||
'Markets',
|
'Markets',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||||
import {
|
import {
|
||||||
|
AppFailure,
|
||||||
NetworkLoader,
|
NetworkLoader,
|
||||||
NodeGuard,
|
NodeGuard,
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
@@ -9,7 +10,6 @@ import { MaintenancePage } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { AppFailure } from './app-failure';
|
|
||||||
import { Web3Provider } from './web3-provider';
|
import { Web3Provider } from './web3-provider';
|
||||||
|
|
||||||
export const DynamicLoader = dynamic(() => import('../preloader/preloader'), {
|
export const DynamicLoader = dynamic(() => import('../preloader/preloader'), {
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export * from './app-failure';
|
|
||||||
export * from './app-loader';
|
export * from './app-loader';
|
||||||
export * from './web3-provider';
|
export * from './web3-provider';
|
||||||
|
|||||||
@@ -4,18 +4,15 @@ import { NodeHealth, NodeUrl, HealthIndicator } from './footer';
|
|||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import { Intent } from '@vegaprotocol/ui-toolkit';
|
import { Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
|
const mockSetNodeSwitcher = jest.fn();
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/environment', () => ({
|
jest.mock('@vegaprotocol/environment', () => ({
|
||||||
...jest.requireActual('@vegaprotocol/environment'),
|
...jest.requireActual('@vegaprotocol/environment'),
|
||||||
useEnvironment: jest.fn().mockImplementation(() => ({
|
useEnvironment: jest.fn().mockImplementation(() => ({
|
||||||
VEGA_URL: 'https://vega-url.wtf',
|
VEGA_URL: 'https://vega-url.wtf',
|
||||||
VEGA_INCIDENT_URL: 'https://blog.vega.community',
|
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', () => {
|
describe('NodeHealth', () => {
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useEnvironment, useNodeHealth } from '@vegaprotocol/environment';
|
import {
|
||||||
|
useEnvironment,
|
||||||
|
useNodeHealth,
|
||||||
|
useNodeSwitcherStore,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { Intent } from '@vegaprotocol/ui-toolkit';
|
import type { Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Indicator, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { Indicator, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||||
import { useGlobalStore } from '../../stores';
|
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
return (
|
return (
|
||||||
@@ -20,9 +23,7 @@ export const Footer = () => {
|
|||||||
|
|
||||||
export const NodeHealth = () => {
|
export const NodeHealth = () => {
|
||||||
const { VEGA_URL, VEGA_INCIDENT_URL } = useEnvironment();
|
const { VEGA_URL, VEGA_INCIDENT_URL } = useEnvironment();
|
||||||
const setNodeSwitcher = useGlobalStore(
|
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||||
(store) => (open: boolean) => store.update({ nodeSwitcherDialog: open })
|
|
||||||
);
|
|
||||||
const { datanodeBlockHeight, text, intent } = useNodeHealth();
|
const { datanodeBlockHeight, text, intent } = useNodeHealth();
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
setNodeSwitcher(true);
|
setNodeSwitcher(true);
|
||||||
|
|||||||
@@ -7,7 +7,13 @@ import {
|
|||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { RISK_ACCEPTED_KEY } from '../constants';
|
import { RISK_ACCEPTED_KEY } from '../constants';
|
||||||
import { TelemetryApproval } from './telemetry-approval';
|
import { TelemetryApproval } from './telemetry-approval';
|
||||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
import {
|
||||||
|
DOCS_VEGA_WALLET,
|
||||||
|
GET_VEGA_WALLET_URL,
|
||||||
|
Networks,
|
||||||
|
useDocsLink,
|
||||||
|
useEnvironment,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -46,8 +52,9 @@ export const RiskNoticeDialog = ({ onClose, network }: Props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TestnetContent = ({ network }: { network: Networks }) => {
|
const TestnetContent = ({ network }: { network: Networks }) => {
|
||||||
const { VEGA_DOCS_URL, GITHUB_FEEDBACK_URL, VEGA_WALLET_URL } =
|
const { GITHUB_FEEDBACK_URL } = useEnvironment();
|
||||||
useEnvironment();
|
const docsLink = useDocsLink();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className="mb-4">
|
<p className="mb-4">
|
||||||
@@ -62,17 +69,17 @@ const TestnetContent = ({ network }: { network: Networks }) => {
|
|||||||
[network]
|
[network]
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
{VEGA_DOCS_URL && GITHUB_FEEDBACK_URL && VEGA_WALLET_URL && (
|
{GITHUB_FEEDBACK_URL && GET_VEGA_WALLET_URL && docsLink && (
|
||||||
<ul className="list-disc pl-4">
|
<ul className="list-disc pl-4">
|
||||||
<li className="mb-1">
|
<li className="mb-1">
|
||||||
<Link href={VEGA_WALLET_URL} target="_blank">
|
<Link href={GET_VEGA_WALLET_URL} target="_blank">
|
||||||
<span className="underline">{t('Learn about Vega wallet')}</span>{' '}
|
<span className="underline">{t('Get a Vega Wallet')}</span>{' '}
|
||||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className="mb-1">
|
<li className="mb-1">
|
||||||
<Link href={VEGA_DOCS_URL} target="_blank">
|
<Link href={docsLink(DOCS_VEGA_WALLET)} target="_blank">
|
||||||
<span className="underline">{t('View documentation')}</span>{' '}
|
<span className="underline">{t('Learn about Vega Wallet')}</span>{' '}
|
||||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ import {
|
|||||||
NodeSwitcherDialog,
|
NodeSwitcherDialog,
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
useInitializeEnv,
|
useInitializeEnv,
|
||||||
|
useNodeSwitcherStore,
|
||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
import { usePageTitleStore } from '../stores';
|
||||||
import { Footer } from '../components/footer';
|
import { Footer } from '../components/footer';
|
||||||
import DialogsContainer from './dialogs-container';
|
import DialogsContainer from './dialogs-container';
|
||||||
import ToastsManager from './toasts-manager';
|
import ToastsManager from './toasts-manager';
|
||||||
@@ -115,11 +116,10 @@ function AppBody({ Component }: AppProps) {
|
|||||||
|
|
||||||
function VegaTradingApp(props: AppProps) {
|
function VegaTradingApp(props: AppProps) {
|
||||||
const status = useEnvironment((store) => store.status);
|
const status = useEnvironment((store) => store.status);
|
||||||
const { nodeSwitcherOpen, setNodeSwitcher } = useGlobalStore((store) => ({
|
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
|
||||||
nodeSwitcherOpen: store.nodeSwitcherDialog,
|
store.dialogOpen,
|
||||||
setNodeSwitcher: (open: boolean) =>
|
store.setDialogOpen,
|
||||||
store.update({ nodeSwitcherDialog: open }),
|
]);
|
||||||
}));
|
|
||||||
|
|
||||||
useInitializeEnv();
|
useInitializeEnv();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { create } from 'zustand';
|
|||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
|
|
||||||
interface GlobalStore {
|
interface GlobalStore {
|
||||||
nodeSwitcherDialog: boolean;
|
|
||||||
marketId: string | null;
|
marketId: string | null;
|
||||||
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
|
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
|
||||||
shouldDisplayWelcomeDialog: boolean;
|
shouldDisplayWelcomeDialog: boolean;
|
||||||
@@ -15,7 +14,6 @@ interface PageTitleStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useGlobalStore = create<GlobalStore>()((set) => ({
|
export const useGlobalStore = create<GlobalStore>()((set) => ({
|
||||||
nodeSwitcherDialog: false,
|
|
||||||
marketId: LocalStorage.getItem('marketId') || null,
|
marketId: LocalStorage.getItem('marketId') || null,
|
||||||
shouldDisplayWelcomeDialog: false,
|
shouldDisplayWelcomeDialog: false,
|
||||||
update: (newState) => {
|
update: (newState) => {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# 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)"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
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)"
|
||||||
|
|
||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/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,6 +7,7 @@ export * from '../candles-chart/src/lib/chart.mock';
|
|||||||
export * from '../deal-ticket/src/hooks/estimate-order.mock';
|
export * from '../deal-ticket/src/hooks/estimate-order.mock';
|
||||||
export * from '../deposits/src/lib/deposit.mock';
|
export * from '../deposits/src/lib/deposit.mock';
|
||||||
export * from '../environment/src/utils/node.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 '../fills/src/lib/fills.mock';
|
||||||
export * from '../proposals/src/lib/proposals-data-provider/proposals.mock';
|
export * from '../proposals/src/lib/proposals-data-provider/proposals.mock';
|
||||||
export * from '../ledger/src/lib/ledger-entries.mock';
|
export * from '../ledger/src/lib/ledger-entries.mock';
|
||||||
|
|||||||
+3
-7
@@ -1,6 +1,6 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useGlobalStore } from '../../stores';
|
import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store';
|
||||||
|
|
||||||
export const AppFailure = ({
|
export const AppFailure = ({
|
||||||
title,
|
title,
|
||||||
@@ -9,17 +9,13 @@ export const AppFailure = ({
|
|||||||
title: string;
|
title: string;
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
}) => {
|
}) => {
|
||||||
const { setNodeSwitcher } = useGlobalStore((store) => ({
|
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||||
nodeSwitcherOpen: store.nodeSwitcherDialog,
|
|
||||||
setNodeSwitcher: (open: boolean) =>
|
|
||||||
store.update({ nodeSwitcherDialog: open }),
|
|
||||||
}));
|
|
||||||
const nonIdealWrapperClasses =
|
const nonIdealWrapperClasses =
|
||||||
'h-full min-h-screen flex items-center justify-center';
|
'h-full min-h-screen flex items-center justify-center';
|
||||||
return (
|
return (
|
||||||
<div className={nonIdealWrapperClasses}>
|
<div className={nonIdealWrapperClasses}>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="text-xl mb-4">{title}</h1>
|
<p className="text-xl mb-4">{title}</p>
|
||||||
{error && <p className="text-sm mb-8">{error}</p>}
|
{error && <p className="text-sm mb-8">{error}</p>}
|
||||||
<Button onClick={() => setNodeSwitcher(true)}>
|
<Button onClick={() => setNodeSwitcher(true)}>
|
||||||
{t('Change node')}
|
{t('Change node')}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './app-failure';
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './app-failure';
|
||||||
export * from './network-loader';
|
export * from './network-loader';
|
||||||
export * from './network-switcher';
|
export * from './network-switcher';
|
||||||
export * from './node-guard';
|
export * from './node-guard';
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
query NodeGuard {
|
||||||
|
lastBlockHeight
|
||||||
|
networkParametersConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
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>;
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
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 type { ReactNode } from 'react';
|
||||||
import { useStatisticsQuery } from '../../utils/__generated__/Node';
|
import { useNodeGuardQuery } from './__generated__/NodeGuard';
|
||||||
|
|
||||||
export const NodeGuard = ({
|
export const NodeGuard = ({
|
||||||
children,
|
children,
|
||||||
@@ -10,14 +10,19 @@ export const NodeGuard = ({
|
|||||||
failure: ReactNode;
|
failure: ReactNode;
|
||||||
skeleton: ReactNode;
|
skeleton: ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const { error, loading } = useStatisticsQuery();
|
const { data, error, loading } = useNodeGuardQuery();
|
||||||
const wrapperClasses = 'h-full min-h-screen flex items-center justify-center';
|
const wrapperClasses =
|
||||||
|
'h-full min-h-screen flex items-center justify-center text-black dark:text-white';
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <div className={wrapperClasses}>{skeleton}</div>;
|
return <div className={wrapperClasses}>{skeleton}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
// 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) {
|
||||||
return <div className={wrapperClasses}>{failure}</div>;
|
return <div className={wrapperClasses}>{failure}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,13 +96,13 @@ describe('RowData', () => {
|
|||||||
mockHeaders(props.url);
|
mockHeaders(props.url);
|
||||||
render(renderComponent(props, statsQueryMock, subMock));
|
render(renderComponent(props, statsQueryMock, subMock));
|
||||||
|
|
||||||
// radio should be disabled until query resolves
|
// radio should be enabled until query resolves
|
||||||
expect(
|
expect(
|
||||||
screen.getByRole('radio', {
|
screen.getByRole('radio', {
|
||||||
checked: false,
|
checked: false,
|
||||||
name: props.url,
|
name: props.url,
|
||||||
})
|
})
|
||||||
).toBeDisabled();
|
).toBeEnabled();
|
||||||
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
||||||
'Checking'
|
'Checking'
|
||||||
);
|
);
|
||||||
@@ -124,7 +124,7 @@ describe('RowData', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('radio button disabled if query fails', async () => {
|
it('radio button still enabled if query fails', async () => {
|
||||||
mockHeaders(props.url, {});
|
mockHeaders(props.url, {});
|
||||||
|
|
||||||
const failedQueryMock: MockedResponse<StatisticsQuery> = {
|
const failedQueryMock: MockedResponse<StatisticsQuery> = {
|
||||||
@@ -149,7 +149,7 @@ describe('RowData', () => {
|
|||||||
checked: false,
|
checked: false,
|
||||||
name: props.url,
|
name: props.url,
|
||||||
})
|
})
|
||||||
).toBeDisabled();
|
).toBeEnabled();
|
||||||
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
|
||||||
'Checking'
|
'Checking'
|
||||||
);
|
);
|
||||||
@@ -170,7 +170,7 @@ describe('RowData', () => {
|
|||||||
checked: false,
|
checked: false,
|
||||||
name: props.url,
|
name: props.url,
|
||||||
})
|
})
|
||||||
).toBeDisabled();
|
).toBeEnabled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -207,19 +207,6 @@ describe('RowData', () => {
|
|||||||
expect(screen.getByTestId('block-height-cell')).toHaveClass('text-danger');
|
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', () => {
|
it('doesnt render the radio if its the custom row', () => {
|
||||||
render(
|
render(
|
||||||
renderComponent(
|
renderComponent(
|
||||||
|
|||||||
@@ -124,29 +124,6 @@ export const RowData = ({
|
|||||||
return false;
|
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 = (
|
const getSubFailed = (
|
||||||
subError: ApolloError | undefined,
|
subError: ApolloError | undefined,
|
||||||
subFailed: boolean
|
subFailed: boolean
|
||||||
@@ -160,12 +137,7 @@ export const RowData = ({
|
|||||||
<>
|
<>
|
||||||
{id !== CUSTOM_NODE_KEY && (
|
{id !== CUSTOM_NODE_KEY && (
|
||||||
<div className="break-all" data-testid="node">
|
<div className="break-all" data-testid="node">
|
||||||
<Radio
|
<Radio id={`node-url-${id}`} value={url} label={url} />
|
||||||
id={`node-url-${id}`}
|
|
||||||
value={url}
|
|
||||||
label={url}
|
|
||||||
disabled={getIsNodeDisabled()}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<LayoutCell
|
<LayoutCell
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export * from './use-environment';
|
export * from './use-environment';
|
||||||
export * from './use-links';
|
export * from './use-links';
|
||||||
export * from './use-node-health';
|
export * from './use-node-health';
|
||||||
|
export * from './use-node-switcher-store';
|
||||||
export * from './use-vega-releases';
|
export * from './use-vega-releases';
|
||||||
export * from './use-vega-release';
|
export * from './use-vega-release';
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { Networks } from '../types';
|
|||||||
import { compileErrors } from '../utils/compile-errors';
|
import { compileErrors } from '../utils/compile-errors';
|
||||||
import { envSchema } from '../utils/validate-environment';
|
import { envSchema } from '../utils/validate-environment';
|
||||||
import { tomlConfigSchema } from '../utils/validate-configuration';
|
import { tomlConfigSchema } from '../utils/validate-configuration';
|
||||||
|
import uniq from 'lodash/uniq';
|
||||||
|
|
||||||
type Client = ReturnType<typeof createClient>;
|
type Client = ReturnType<typeof createClient>;
|
||||||
type ClientCollection = {
|
type ClientCollection = {
|
||||||
@@ -32,7 +33,8 @@ type Actions = {
|
|||||||
export type Env = Environment & EnvState;
|
export type Env = Environment & EnvState;
|
||||||
export type EnvStore = Env & Actions;
|
export type EnvStore = Env & Actions;
|
||||||
|
|
||||||
export const STORAGE_KEY = 'vega_url';
|
const VERSION = 1;
|
||||||
|
export const STORAGE_KEY = `vega_url_${VERSION}`;
|
||||||
const SUBSCRIPTION_TIMEOUT = 3000;
|
const SUBSCRIPTION_TIMEOUT = 3000;
|
||||||
|
|
||||||
export const useEnvironment = create<EnvStore>()((set, get) => ({
|
export const useEnvironment = create<EnvStore>()((set, get) => ({
|
||||||
@@ -69,7 +71,10 @@ export const useEnvironment = create<EnvStore>()((set, get) => ({
|
|||||||
let nodes: string[] | undefined;
|
let nodes: string[] | undefined;
|
||||||
try {
|
try {
|
||||||
nodes = await fetchConfig(state.VEGA_CONFIG_URL);
|
nodes = await fetchConfig(state.VEGA_CONFIG_URL);
|
||||||
set({ nodes });
|
const enrichedNodes = uniq(
|
||||||
|
[...nodes, state.VEGA_URL, storedUrl].filter(Boolean) as string[]
|
||||||
|
);
|
||||||
|
set({ nodes: enrichedNodes });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(`Could not fetch node config from ${state.VEGA_CONFIG_URL}`);
|
console.warn(`Could not fetch node config from ${state.VEGA_CONFIG_URL}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,16 @@ export const useEtherscanLink = () => {
|
|||||||
return link;
|
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
|
// Vega blog
|
||||||
export const BLOG = 'https://blog.vega.xyz/';
|
export const BLOG = 'https://blog.vega.xyz/';
|
||||||
|
|
||||||
@@ -125,3 +135,9 @@ export const CONSOLE_MARKET = '/markets/:marketId';
|
|||||||
export const CONSOLE_MARKETS = '/markets/all';
|
export const CONSOLE_MARKETS = '/markets/all';
|
||||||
export const CONSOLE_PORTFOLIO = '/portfolio';
|
export const CONSOLE_PORTFOLIO = '/portfolio';
|
||||||
export const CONSOLE_LIQUIDITY = 'liquidity/:marketId';
|
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';
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
export const useNodeSwitcherStore = create<{
|
||||||
|
dialogOpen: boolean;
|
||||||
|
setDialogOpen: (isOpen: boolean) => void;
|
||||||
|
}>()((set) => ({
|
||||||
|
dialogOpen: false,
|
||||||
|
setDialogOpen: (isOpen) => {
|
||||||
|
set({ dialogOpen: isOpen });
|
||||||
|
},
|
||||||
|
}));
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import { Fragment, useState } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Link, Lozenge } from '@vegaprotocol/ui-toolkit';
|
import { Link, Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||||
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
|
import {
|
||||||
|
NodeSwitcherDialog,
|
||||||
|
useEnvironment,
|
||||||
|
useNodeSwitcherStore,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
|
|
||||||
const getFeedbackLinks = (gitOriginUrl?: string) =>
|
const getFeedbackLinks = (gitOriginUrl?: string) =>
|
||||||
[
|
[
|
||||||
@@ -19,64 +23,59 @@ export const NetworkInfo = () => {
|
|||||||
GITHUB_FEEDBACK_URL,
|
GITHUB_FEEDBACK_URL,
|
||||||
ETHEREUM_PROVIDER_URL,
|
ETHEREUM_PROVIDER_URL,
|
||||||
} = useEnvironment();
|
} = useEnvironment();
|
||||||
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
|
||||||
|
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||||
const feedbackLinks = getFeedbackLinks(GITHUB_FEEDBACK_URL);
|
const feedbackLinks = getFeedbackLinks(GITHUB_FEEDBACK_URL);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div data-testid="git-info">
|
||||||
<div data-testid="git-info">
|
<p data-testid="git-network-data" className="mb-2">
|
||||||
<p data-testid="git-network-data" className="mb-2">
|
{t('Reading network data from')}{' '}
|
||||||
{t('Reading network data from')}{' '}
|
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
||||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
{VEGA_URL}
|
||||||
{VEGA_URL}
|
</Lozenge>
|
||||||
</Lozenge>
|
. <Link onClick={() => setNodeSwitcher(true)}>{t('Edit')}</Link>
|
||||||
. <Link onClick={() => setNodeSwitcherOpen(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>
|
||||||
</p>
|
</p>
|
||||||
<p data-testid="git-eth-data" className="mb-2 break-all">
|
)}
|
||||||
{t('Reading Ethereum data from')}{' '}
|
{feedbackLinks.length > 0 && (
|
||||||
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
|
<p>
|
||||||
{ETHEREUM_PROVIDER_URL}
|
{t('Known issues and feedback on')}{' '}
|
||||||
</Lozenge>
|
{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>
|
</p>
|
||||||
{GIT_COMMIT_HASH && (
|
)}
|
||||||
<p data-testid="git-commit-hash" className="mb-2">
|
</div>
|
||||||
{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}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ inquirer
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
for (const env of answers.envs) {
|
for (const env of answers.envs) {
|
||||||
const branch = env === 'mainnet' ? 'master' : `release/${env}`;
|
const branch = env === 'mainnet' ? 'main' : `release/${env}`;
|
||||||
release(answers.tag, branch);
|
release(answers.tag, branch);
|
||||||
}
|
}
|
||||||
execSync('git checkout develop');
|
execSync('git checkout develop');
|
||||||
|
|||||||
Reference in New Issue
Block a user