Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba45e090f3 |
@@ -1,74 +0,0 @@
|
|||||||
name: After Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
after-release:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log in to the Container registry (ghcr)
|
|
||||||
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
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: resolve ipfs hashes for release
|
|
||||||
run: |
|
|
||||||
echo "Tag name: ${{ github.event.release.tag_name }}"
|
|
||||||
echo "Name: ${{ github.event.release.name }}"
|
|
||||||
echo "Description: ${{ github.event.release.body }}"
|
|
||||||
until docker pull vegaprotocol/trading:${{ github.event.release.tag_name }}; do
|
|
||||||
echo "Image not pushed yet, waiting 60 seconds"
|
|
||||||
sleep 60
|
|
||||||
done
|
|
||||||
docker run --rm vegaprotocol/trading:${{ github.event.release.tag_name }} cat /ipfs-hash > ipfs-hash
|
|
||||||
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
|
|
||||||
tar -xzf kubo.tgz
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
which ipfs
|
|
||||||
echo IPFS_V0=$(cat ipfs-hash) >> $GITHUB_ENV
|
|
||||||
echo IPFS_V1=$(ipfs cid format -v 1 -b base32 $(cat ipfs-hash)) >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Edit Release
|
|
||||||
uses: irongut/EditRelease@v1.2.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
id: ${{ github.event.release.id }}
|
|
||||||
body: |
|
|
||||||
---
|
|
||||||
|
|
||||||
# Deployments
|
|
||||||
* https://explorer.vega.xyz
|
|
||||||
* https://governance.vega.xyz
|
|
||||||
|
|
||||||
# IPFS releases
|
|
||||||
Tye IPFS hash of this release of the Trading app is:
|
|
||||||
|
|
||||||
CIDv0: ${{ env.IPFS_V0 }}
|
|
||||||
CIDv1: ${{ env.IPFS_V1 }}
|
|
||||||
|
|
||||||
You can always access the latest IPFS release by visiting [vega.trading](https://vega.trading).
|
|
||||||
|
|
||||||
You can also access Trading directly from an IPFS gateway.
|
|
||||||
BEWARE: The Trading interface uses [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported. You should always use an IPFS gateway that enforces [origin separation](https://ipfs.github.io/public-gateway-checker/).
|
|
||||||
|
|
||||||
Your settings are not remembered across different URLs.
|
|
||||||
|
|
||||||
IPFS gateways:
|
|
||||||
|
|
||||||
https://${{ env.IPFS_V1 }}.ipfs.dweb.link/
|
|
||||||
https://${{ env.IPFS_V1 }}.ipfs.cf-ipfs.com/
|
|
||||||
ipfs://${{ env.IPFS_V0 }}/
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: 'Check if branch is shorter than 52 chars'
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
branch-naming-rules:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# echo "branches that are longer than 51 chars can't be parsed by kubernetes to create previews. Each app has prefix of it's name like: 'governance-' (12 chars), what leaves 51 max branch length"
|
|
||||||
# current parsable length: $( git rev-parse --abbrev-ref HEAD | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | wc -c)
|
|
||||||
- uses: deepakputhraya/action-branch-name@master
|
|
||||||
with:
|
|
||||||
# regex: '([a-z])+\/([a-z])+' # Regex the branch should match. This example enforces grouping
|
|
||||||
# allowed_prefixes: 'feature,stable,fix' # All branches should start with the given prefix
|
|
||||||
# ignore: master,develop # Ignore exactly matching branch names from convention
|
|
||||||
min_length: 1 # Min length of the branch name
|
|
||||||
max_length: 51 # Max length of the branch name
|
|
||||||
@@ -5,8 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- release/*
|
- release/*
|
||||||
- develop
|
- develop
|
||||||
tags:
|
|
||||||
- v*
|
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
@@ -28,7 +26,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: node_modules
|
path: node_modules
|
||||||
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||||
# comment out "restore-keys" if you need to rebuild yarn from 0
|
# comment out "resotre-keys" if you need to rebuild yarn from 0
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-cache-node-modules-
|
${{ runner.os }}-cache-node-modules-
|
||||||
|
|
||||||
@@ -52,7 +50,7 @@ jobs:
|
|||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
lint-test-build:
|
lint-test-build:
|
||||||
timeout-minutes: 60
|
timeout-minutes: 20
|
||||||
needs: node-modules
|
needs: node-modules
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
name: '(CI) lint + unit test + build'
|
name: '(CI) lint + unit test + build'
|
||||||
@@ -99,50 +97,27 @@ 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 )"
|
|
||||||
projects_e2e=""
|
projects_e2e=""
|
||||||
preview_governance="not deployed"
|
if [[ $affected == *"governance"* ]]; then projects_e2e+='"governance-e2e" '; fi
|
||||||
preview_trading="not deployed"
|
if [[ $affected == *"trading"* ]]; then projects_e2e+='"trading-e2e" '; fi
|
||||||
preview_explorer="not deployed"
|
if [[ $affected == *"explorer"* ]]; then projects_e2e+='"explorer-e2e" '; fi
|
||||||
if [[ -z "$projects_e2e" ]]; then
|
if [[ -z "$projects_e2e" ]]; then projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '; fi
|
||||||
projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '
|
|
||||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
|
||||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
|
||||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
|
||||||
else
|
|
||||||
if [[ $affected == *"governance"* ]]; then
|
|
||||||
projects_e2e+='"governance-e2e" '
|
|
||||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
|
||||||
fi
|
|
||||||
if [[ $affected == *"trading"* ]]; then
|
|
||||||
projects_e2e+='"trading-e2e" '
|
|
||||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
|
||||||
fi
|
|
||||||
if [[ $affected == *"explorer"* ]]; then
|
|
||||||
projects_e2e+='"explorer-e2e" '
|
|
||||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
projects_e2e=${projects_e2e%?}
|
projects_e2e=${projects_e2e%?}
|
||||||
projects_e2e=[${projects_e2e// /,}]
|
projects_e2e=[${projects_e2e// /,}]
|
||||||
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
|
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
|
||||||
echo PROJECTS=$(echo $projects_e2e | sed 's|-e2e||g') >> $GITHUB_ENV
|
echo PROJECTS=$(echo $projects_e2e | sed 's|-e2e||g') >> $GITHUB_ENV
|
||||||
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
|
|
||||||
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
|
|
||||||
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
|
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
projects: ${{ env.PROJECTS }}
|
projects: ${{ env.PROJECTS }}
|
||||||
projects-e2e: ${{ env.PROJECTS_E2E }}
|
projects-e2e: ${{ env.PROJECTS_E2E }}
|
||||||
preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
|
|
||||||
preview_trading: ${{ env.PREVIEW_TRADING }}
|
|
||||||
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
|
||||||
|
|
||||||
cypress:
|
cypress:
|
||||||
needs: lint-test-build
|
needs: lint-test-build
|
||||||
@@ -165,9 +140,7 @@ jobs:
|
|||||||
|
|
||||||
dist-check:
|
dist-check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs: publish-dist
|
||||||
- publish-dist
|
|
||||||
- lint-test-build
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
name: '(CD) comment preview links'
|
name: '(CD) comment preview links'
|
||||||
steps:
|
steps:
|
||||||
@@ -178,16 +151,22 @@ jobs:
|
|||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
body-includes: Previews
|
body-includes: Previews
|
||||||
|
|
||||||
- name: Create comment
|
- name: Inject slug/short variables
|
||||||
uses: peter-evans/create-or-update-comment@v3
|
|
||||||
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
||||||
|
uses: rlespinasse/github-slug-action@v4
|
||||||
|
with:
|
||||||
|
prefix: CI_
|
||||||
|
|
||||||
|
- name: Create comment
|
||||||
|
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
||||||
|
uses: peter-evans/create-or-update-comment@v3
|
||||||
with:
|
with:
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
body: |
|
body: |
|
||||||
Previews:
|
Previews
|
||||||
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
|
- explorer https://explorer.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
|
||||||
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
- trading https://trading.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
|
||||||
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
- governance https://governance.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
|
||||||
|
|
||||||
cypress-check:
|
cypress-check:
|
||||||
name: '(CI) cypress - check'
|
name: '(CI) cypress - check'
|
||||||
|
|||||||
@@ -33,4 +33,5 @@ jobs:
|
|||||||
config: baseUrl=${{ github.event.inputs.url }}
|
config: baseUrl=${{ github.event.inputs.url }}
|
||||||
env: grepTags=@live
|
env: grepTags=@live
|
||||||
env:
|
env:
|
||||||
|
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
project: ${{ fromJSON(inputs.projects) }}
|
project: ${{ fromJSON(inputs.projects) }}
|
||||||
name: ${{ matrix.project }}
|
name: ${{ matrix.project }}
|
||||||
runs-on: self-hosted-runner
|
runs-on: self-hosted-runner
|
||||||
timeout-minutes: 60
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
# Checks if skip cache was requested
|
# Checks if skip cache was requested
|
||||||
- name: Set skip-nx-cache flag
|
- name: Set skip-nx-cache flag
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
######
|
######
|
||||||
|
|
||||||
- name: Run Cypress tests
|
- name: Run Cypress tests
|
||||||
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --browser chrome --env.grepTags="${{ inputs.tags }}"
|
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome --env.grepTags="${{ inputs.tags }}"
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
@@ -93,9 +93,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: logs-${{ matrix.project }}
|
name: logs-${{ matrix.project }}
|
||||||
path: /home/runner/.vegacapsule/testnet/logs
|
path: /home/runner/.vegacapsule/testnet/logs
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ failure() }}
|
|
||||||
with:
|
|
||||||
name: test-report-${{ matrix.project }}
|
|
||||||
path: frontend-monorepo/apps/${{ matrix.project }}/cypress/reports
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
app: ${{ fromJSON(inputs.projects) }}
|
app: ${{ fromJSON(inputs.projects) }}
|
||||||
name: ${{ matrix.app }}
|
name: ${{ matrix.app }}
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
timeout-minutes: 25
|
timeout-minutes: 20
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -30,21 +30,13 @@ 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 (ghcr)
|
- name: Log in to the Container registry
|
||||||
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:
|
||||||
@@ -62,26 +54,30 @@ jobs:
|
|||||||
- name: Define variables
|
- name: Define variables
|
||||||
run: |
|
run: |
|
||||||
envName=''
|
envName=''
|
||||||
domain="vega.rocks"
|
dockerfile="dist.Dockerfile"
|
||||||
if [[ "${{ github.event_name }}" = "push" ]]; then
|
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||||
|
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
|
||||||
|
domain="vega.community"
|
||||||
|
if [[ "${{ matrix.app }}" = "trading" ]]; then
|
||||||
|
dockerfile="ipfs.Dockerfile"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||||
envName="stagnet1"
|
envName="stagnet3"
|
||||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
|
||||||
envName="mainnet"
|
|
||||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
|
||||||
envName="mainnet"
|
|
||||||
fi
|
|
||||||
if [[ "${envName}" = "mainnet" ]]; then
|
|
||||||
domain="vega.xyz"
|
|
||||||
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
|
||||||
@@ -102,60 +98,62 @@ 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: docker/node-outside-docker.Dockerfile
|
file: ${{ env.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' }}
|
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
|
||||||
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"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
if [[ "${{ env.DOCKERFILE }}" = "docker/ipfs.Dockerfile" ]]; then
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matrix.app }}-ipfs-hash
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
||||||
echo "List html directory"
|
fi
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
|
||||||
|
|
||||||
- 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
|
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:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/node-outside-docker.Dockerfile
|
file: ${{ env.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 }}
|
|
||||||
vegaprotocol/${{ matrix.app }}:mainnet
|
|
||||||
|
|
||||||
# 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' && !startsWith(github.ref, 'refs/tags/v') }}
|
if: ${{ github.event_name == 'push' }}
|
||||||
with:
|
with:
|
||||||
args: --acl private --follow-symlinks --delete
|
args: --acl private --follow-symlinks --delete
|
||||||
env:
|
env:
|
||||||
@@ -171,52 +169,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
labels: ${{ matrix.app }}-preview
|
labels: ${{ matrix.app }}-preview
|
||||||
number: ${{ github.event.number }}
|
number: ${{ github.event.number }}
|
||||||
|
|
||||||
- name: Trigger fleek deployment
|
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
|
||||||
run: |
|
|
||||||
# display info about app
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "query{getSiteById(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id latestDeploy{id status}}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
# trigger new deployment as base image is always set to vegaprotocol/trading:mainnet
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
- name: Update vega.trading DNS to redirect to the new console
|
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
|
||||||
run: |
|
|
||||||
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
|
|
||||||
tar -xzf kubo.tgz
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
which ipfs
|
|
||||||
new_hash=$(cat ${{ matrix.app }}-ipfs-hash)
|
|
||||||
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
|
|
||||||
|
|
||||||
# Generate console URL
|
|
||||||
new_console_url_type=ipfs
|
|
||||||
# new_console_url_type=ipns
|
|
||||||
new_console_url_domain=cf-ipfs.com
|
|
||||||
# new_console_url_domain=dweb.link
|
|
||||||
new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
|
|
||||||
echo "new_console_url=${new_console_url}"
|
|
||||||
|
|
||||||
# Update record in DNSimple
|
|
||||||
# docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
|
|
||||||
dnsimple_account_id=84895
|
|
||||||
dnsimple_zone_name=vega.trading
|
|
||||||
dnsimple_record_id=44409591
|
|
||||||
# see: https://dnsimple.com/a/84895/domains/vega.trading/records/44409591/edit
|
|
||||||
|
|
||||||
curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
|
|
||||||
-H 'Accept: application/json' \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-X PATCH \
|
|
||||||
-d "{
|
|
||||||
\"content\": \"${new_console_url}\"
|
|
||||||
}" \
|
|
||||||
https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
|
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
name: 'Rollback console'
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: 'Version that should be set on rollback'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
rollback:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log in to the Container registry (docker hub)
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Retag mainnet
|
|
||||||
run: |
|
|
||||||
docker pull vegaprotocol/trading:${{ inputs.version }}
|
|
||||||
docker tag vegaprotocol/trading:${{ inputs.version }} vegaprotocol/trading:mainnet
|
|
||||||
docker push vegaprotocol/trading:mainnet
|
|
||||||
docker run --rm vegaprotocol/trading:mainnet cat /ipfs-hash > ipfs-hash
|
|
||||||
|
|
||||||
- name: Trigger fleek deployment
|
|
||||||
run: |
|
|
||||||
# display info about app
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "query{getSiteById(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id latestDeploy{id status}}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
# trigger new deployment as base image is always set to vegaprotocol/trading:mainnet
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
- name: Update vega.trading DNS to redirect to the new console
|
|
||||||
run: |
|
|
||||||
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
|
|
||||||
tar -xzf kubo.tgz
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
which ipfs
|
|
||||||
new_hash=$(cat ipfs-hash)
|
|
||||||
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
|
|
||||||
|
|
||||||
# Generate console URL
|
|
||||||
new_console_url_type=ipfs
|
|
||||||
# new_console_url_type=ipns
|
|
||||||
new_console_url_domain=cf-ipfs.com
|
|
||||||
# new_console_url_domain=dweb.link
|
|
||||||
new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
|
|
||||||
echo "new_console_url=${new_console_url}"
|
|
||||||
|
|
||||||
# Update record in DNSimple
|
|
||||||
# docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
|
|
||||||
dnsimple_account_id=84895
|
|
||||||
dnsimple_zone_name=vega.trading
|
|
||||||
dnsimple_record_id=44409591
|
|
||||||
# see: https://dnsimple.com/a/84895/domains/vega.trading/records/44409591/edit
|
|
||||||
|
|
||||||
curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
|
|
||||||
-H 'Accept: application/json' \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-X PATCH \
|
|
||||||
-d "{
|
|
||||||
\"content\": \"${new_console_url}\"
|
|
||||||
}" \
|
|
||||||
https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
/dist-result
|
|
||||||
/tmp
|
/tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
/tools/executors/**/*.js
|
/tools/executors/**/*.js
|
||||||
@@ -47,6 +46,3 @@ cypress.env.json
|
|||||||
|
|
||||||
# Next.js
|
# Next.js
|
||||||
.next
|
.next
|
||||||
|
|
||||||
#cypress
|
|
||||||
/apps/**/cypress/reports/
|
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ __generated___
|
|||||||
|
|
||||||
apps/static/src/assets/devnet-tranches.json
|
apps/static/src/assets/devnet-tranches.json
|
||||||
apps/static/src/assets/mainnet-tranches.json
|
apps/static/src/assets/mainnet-tranches.json
|
||||||
|
apps/static/src/assets/stagnet3-tranches.json
|
||||||
apps/static/src/assets/testnet-tranches.json
|
apps/static/src/assets/testnet-tranches.json
|
||||||
|
|||||||
Vendored
+19
-1
@@ -1,2 +1,20 @@
|
|||||||
@Library('vega-shared-library') _
|
@Library('vega-shared-library') _
|
||||||
runApprobation ignoreFailure: false, frontendBranch: env.BRANCH_NAME, type: 'frontend'
|
|
||||||
|
def commitHash = 'UNKNOWN'
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
options {
|
||||||
|
skipDefaultCheckout true
|
||||||
|
parallelsAlwaysFailFast()
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('approbation') {
|
||||||
|
steps {
|
||||||
|
sh 'printenv'
|
||||||
|
checkout scm
|
||||||
|
runApprobation ignoreFailure: false, frontendBranch: env.BRANCH_NAME, type: 'frontend'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 -r /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
|
|
||||||
@@ -72,7 +72,7 @@ Run `nx serve my-app` for a dev server. Navigate to the port specified in `app/<
|
|||||||
In order to generate the schemas for your GraphQL queries, you can run `GRAPHQL_SCHEMA_PATH=[YOUR SCHEMA FILE / API URL HERE] nx run types:generate`.
|
In order to generate the schemas for your GraphQL queries, you can run `GRAPHQL_SCHEMA_PATH=[YOUR SCHEMA FILE / API URL HERE] nx run types:generate`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export GRAPHQL_SCHEMA_PATH=https://api.n07.testnet.vega.xyz/graphql
|
export GRAPHQL_SCHEMA_PATH=https://api.n11.testnet.vega.xyz/graphql
|
||||||
yarn nx run types:generate
|
yarn nx run types:generate
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -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.
|
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
|
```bash
|
||||||
docker run -p 3000:80 [TAG]
|
docker run -p 3000:80 [TAG]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build instructions
|
Images ending with `.dist` are to pack locally created transpiled HTML files into nginx container for non-compatible with yarn architectures like M1 Mac
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=http://localhost:26617
|
NX_TENDERMINT_URL=http://localhost:26617
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||||
NX_VEGA_URL=http://localhost:3008/graphql
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_ENV=CUSTOM
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_CONFIG_URL=
|
NX_VEGA_CONFIG_URL=
|
||||||
|
|
||||||
@@ -18,4 +18,4 @@ NX_EXPLORER_PARTIES=1
|
|||||||
NX_EXPLORER_VALIDATORS=1
|
NX_EXPLORER_VALIDATORS=1
|
||||||
|
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
CYPRESS_VEGA_URL=http://localhost:3008/graphql
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
NX_VEGA_URL=https://api.vega.xyz/query
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest
|
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# App configuration variables
|
||||||
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
|
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||||
|
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
|
||||||
|
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
NX_VEGA_ENV=STAGNET3
|
||||||
|
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||||
|
|
||||||
|
# App flags
|
||||||
|
NX_EXPLORER_ASSETS=1
|
||||||
|
NX_EXPLORER_GENESIS=1
|
||||||
|
NX_EXPLORER_GOVERNANCE=1
|
||||||
|
NX_EXPLORER_MARKETS=1
|
||||||
|
NX_EXPLORER_ORACLES=1
|
||||||
|
NX_EXPLORER_TXS_LIST=0
|
||||||
|
NX_EXPLORER_NETWORK_PARAMETERS=1
|
||||||
|
NX_EXPLORER_PARTIES=1
|
||||||
|
NX_EXPLORER_VALIDATORS=1
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://tm.n07.testnet.vega.xyz/tm
|
NX_TENDERMINT_URL=https://tm.n07.testnet.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
||||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
|
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
reporter: '../../node_modules/cypress-mochawesome-reporter',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
require('cypress-mochawesome-reporter/plugin')(on);
|
|
||||||
require('@cypress/grep/src/plugin')(config);
|
require('@cypress/grep/src/plugin')(config);
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
@@ -22,11 +21,10 @@ module.exports = defineConfig({
|
|||||||
chromeWebSecurity: false,
|
chromeWebSecurity: false,
|
||||||
viewportWidth: 1440,
|
viewportWidth: 1440,
|
||||||
viewportHeight: 900,
|
viewportHeight: 900,
|
||||||
testIsolation: false,
|
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
environment: 'CUSTOM',
|
environment: 'CUSTOM',
|
||||||
networkQueryUrl: 'http://localhost:3008/graphql',
|
networkQueryUrl: 'http://localhost:3028/query',
|
||||||
ethUrl: 'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
ethUrl: 'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
||||||
commitHash: 'dev',
|
commitHash: 'dev',
|
||||||
tsConfig: 'tsconfig.json',
|
tsConfig: 'tsconfig.json',
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
"governance.proposal.updateMarket.minVoterBalance",
|
"governance.proposal.updateMarket.minVoterBalance",
|
||||||
"governance.proposal.updateNetParam.minProposerBalance",
|
"governance.proposal.updateNetParam.minProposerBalance",
|
||||||
"governance.proposal.updateNetParam.minVoterBalance",
|
"governance.proposal.updateNetParam.minVoterBalance",
|
||||||
"governance.proposal.updateAsset.minProposerBalance",
|
|
||||||
"governance.proposal.updateAsset.minVoterBalance",
|
|
||||||
"reward.staking.delegation.maxPayoutPerEpoch",
|
"reward.staking.delegation.maxPayoutPerEpoch",
|
||||||
"reward.staking.delegation.maxPayoutPerParticipant",
|
"reward.staking.delegation.maxPayoutPerParticipant",
|
||||||
"reward.staking.delegation.minimumValidatorStake",
|
"reward.staking.delegation.minimumValidatorStake",
|
||||||
@@ -21,6 +19,9 @@
|
|||||||
"validators.delegation.minAmount"
|
"validators.delegation.minAmount"
|
||||||
],
|
],
|
||||||
"fiveDecimal": [
|
"fiveDecimal": [
|
||||||
|
"governance.proposal.updateAsset.minProposerBalance",
|
||||||
|
"governance.proposal.updateAsset.minVoterBalance",
|
||||||
|
"governance.proposal.updateAsset.requiredParticipation",
|
||||||
"market.fee.factors.infrastructureFee",
|
"market.fee.factors.infrastructureFee",
|
||||||
"market.fee.factors.makerFee",
|
"market.fee.factors.makerFee",
|
||||||
"market.liquidity.bondPenaltyParameter",
|
"market.liquidity.bondPenaltyParameter",
|
||||||
@@ -76,7 +77,6 @@
|
|||||||
"governance.proposal.updateNetParam.requiredMajority",
|
"governance.proposal.updateNetParam.requiredMajority",
|
||||||
"governance.proposal.updateNetParam.requiredParticipation",
|
"governance.proposal.updateNetParam.requiredParticipation",
|
||||||
"governance.proposal.updateMarket.minProposerEquityLikeShare",
|
"governance.proposal.updateMarket.minProposerEquityLikeShare",
|
||||||
"governance.proposal.updateAsset.requiredParticipation",
|
|
||||||
"validators.vote.required"
|
"validators.vote.required"
|
||||||
],
|
],
|
||||||
"duration": [
|
"duration": [
|
||||||
|
|||||||
@@ -9,22 +9,21 @@ context('Home Page', function () {
|
|||||||
it('should show connected environment stats', function () {
|
it('should show connected environment stats', function () {
|
||||||
const statTitles = {
|
const statTitles = {
|
||||||
0: 'Status',
|
0: 'Status',
|
||||||
1: 'Epoch',
|
1: 'Block height',
|
||||||
2: 'Block height',
|
2: 'Uptime',
|
||||||
3: 'Uptime',
|
3: 'Total nodes',
|
||||||
4: 'Total nodes',
|
4: 'Total staked',
|
||||||
5: 'Total staked',
|
5: 'Backlog',
|
||||||
6: 'Backlog',
|
6: 'Trades / second',
|
||||||
7: 'Trades / second',
|
7: 'Orders / block',
|
||||||
8: 'Orders / block',
|
8: 'Orders / second',
|
||||||
9: 'Orders / second',
|
9: 'Transactions / block',
|
||||||
10: 'Transactions / block',
|
10: 'Block time',
|
||||||
11: 'Block time',
|
11: 'Time',
|
||||||
12: 'Time',
|
12: 'App',
|
||||||
13: 'App',
|
13: 'Tendermint',
|
||||||
14: 'Tendermint',
|
14: 'Up since',
|
||||||
15: 'Up since',
|
15: 'Chain ID',
|
||||||
16: 'Chain ID',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cy.get('[data-testid="stats-title"]')
|
cy.get('[data-testid="stats-title"]')
|
||||||
@@ -32,13 +31,42 @@ context('Home Page', function () {
|
|||||||
cy.wrap($list).should('contain.text', statTitles[index]);
|
cy.wrap($list).should('contain.text', statTitles[index]);
|
||||||
})
|
})
|
||||||
.then(($list) => {
|
.then(($list) => {
|
||||||
cy.wrap($list).should('have.length', 17);
|
cy.wrap($list).should('have.length', 16);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cy.get(statsValue).eq(0).should('contain.text', 'CONNECTED');
|
||||||
|
cy.get(statsValue).eq(1).should('not.be.empty');
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(2)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d+d \d+h \d+m \d+s/i);
|
||||||
|
cy.get(statsValue).eq(3).should('contain.text', '2');
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(4)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d+\.\d\d(?!\d)/i);
|
||||||
|
cy.get(statsValue).eq(5).should('contain.text', '0');
|
||||||
|
cy.get(statsValue).eq(6).should('contain.text', '0');
|
||||||
|
cy.get(statsValue).eq(7).should('contain.text', '0');
|
||||||
|
cy.get(statsValue).eq(8).should('contain.text', '0');
|
||||||
|
cy.get(statsValue).eq(9).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(10).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(11).should('not.be.empty');
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(12)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /v\d+\.\d+\.\d+/i);
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(13)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d+\.\d+\.\d+/i);
|
||||||
|
cy.get(statsValue).eq(14).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(15).should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Block height should be updating', function () {
|
it('Block height should be updating', function () {
|
||||||
cy.get(statsValue)
|
cy.get(statsValue)
|
||||||
.eq(2)
|
.eq(1)
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((blockHeightTxt) => {
|
.then((blockHeightTxt) => {
|
||||||
cy.get(statsValue)
|
cy.get(statsValue)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('should list each network parameter displayed as a currency value with four decimals - in the correct format', function () {
|
it('should list each network parameter displayed as a currency value with four decimals - in the correct format', function () {
|
||||||
cy.get_network_parameters().then((network_parameters) => {
|
cy.get_network_parameters().then((network_parameters) => {
|
||||||
network_parameters = Object.entries(network_parameters);
|
network_parameters = Object.entries(network_parameters);
|
||||||
network_parameters.forEach((network_parameter) => {
|
network_parameters.forEach((network_parameter) => {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const customNodeBtn = 'custom-node';
|
|||||||
context.skip('Node switcher', { tags: '@regression' }, function () {
|
context.skip('Node switcher', { tags: '@regression' }, function () {
|
||||||
beforeEach('visit home page', function () {
|
beforeEach('visit home page', function () {
|
||||||
cy.intercept('GET', 'https://static.vega.xyz/assets/capsule-network.json', {
|
cy.intercept('GET', 'https://static.vega.xyz/assets/capsule-network.json', {
|
||||||
hosts: ['http://localhost:3008/graphql'],
|
hosts: ['http://localhost:3028/query'],
|
||||||
}).as('nodeData');
|
}).as('nodeData');
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@nodeData');
|
cy.wait('@nodeData');
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ context.skip('Parties page', { tags: '@regression' }, function () {
|
|||||||
balance type asset {id symbol decimals}}}}}}}}';
|
balance type asset {id symbol decimals}}}}}}}}';
|
||||||
cy.request({
|
cy.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `http://localhost:3008/graphql`,
|
url: `http://localhost:3028/query`,
|
||||||
body: {
|
body: {
|
||||||
query: mutation,
|
query: mutation,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,6 +15,5 @@
|
|||||||
|
|
||||||
import '@vegaprotocol/cypress';
|
import '@vegaprotocol/cypress';
|
||||||
import './common.functions.js';
|
import './common.functions.js';
|
||||||
import 'cypress-mochawesome-reporter/register';
|
|
||||||
import registerCypressGrep from '@cypress/grep';
|
import registerCypressGrep from '@cypress/grep';
|
||||||
registerCypressGrep();
|
registerCypressGrep();
|
||||||
|
|||||||
+9
-16
@@ -1,20 +1,13 @@
|
|||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
|
||||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml
|
||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
NX_VEGA_NETWORKS='{"STAGNET1":"https://stagnet1.token.vega.xyz", "STAGNET3":"https://stagnet3.explorer.vega.xyz","VALIDATOR_TESTNET":"https://validator-testnet.fairground.wtf","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||||
NX_VEGA_ENV=STAGNET1
|
NX_VEGA_ENV=STAGNET3
|
||||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
|
||||||
NX_VEGA_TOKEN_URL=https://stagnet1.governance.vega.xyz
|
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
|
||||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
|
||||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
|
||||||
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"}'
|
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
|||||||
NX_VEGA_ENV=CUSTOM
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=/
|
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
|
NX_EXPLORER_ASSETS=1
|
||||||
|
NX_EXPLORER_GENESIS=1
|
||||||
|
NX_EXPLORER_GOVERNANCE=1
|
||||||
|
NX_EXPLORER_MARKETS=1
|
||||||
|
NX_EXPLORER_ORACLES=1
|
||||||
NX_EXPLORER_TXS_LIST=0
|
NX_EXPLORER_TXS_LIST=0
|
||||||
|
NX_EXPLORER_NETWORK_PARAMETERS=1
|
||||||
|
NX_EXPLORER_PARTIES=1
|
||||||
|
NX_EXPLORER_VALIDATORS=1
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-inter
|
|||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
|
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_VEGA_GOVERNANCE_URL=https://dev.governance.vega.xyz
|
NX_VEGA_GOVERNANCE_URL=https://dev.token.vega.xyz
|
||||||
NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql
|
NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql
|
||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=/
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_TENDERMINT_URL=https://be.vega.community
|
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz/websocket
|
||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
NX_BLOCK_EXPLORER=https://be.vega.community/rest/
|
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest/
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
|
NX_VEGA_GOVERNANCE_URL=https://token.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
|
|
||||||
@@ -1,2 +1,14 @@
|
|||||||
# .env is stagnet1, so there are no overrides required
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET3":"https://stagnet3.explorer.vega.xyz"}'
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||||
|
NX_VEGA_ENV=STAGNET1
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||||
|
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||||
|
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||||
|
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_VEGA_GOVERNANCE_URL=https://stagnet1.token.vega.xyz
|
||||||
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||||
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.stagnet3.vega.xyz/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml
|
||||||
|
NX_VEGA_ENV=STAGNET3
|
||||||
|
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||||
|
NX_VEGA_GOVERNANCE_URL=https://stagnet3.token.vega.xyz
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases/
|
||||||
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
@@ -7,6 +7,5 @@ NX_VEGA_ENV=TESTNET
|
|||||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
|
NX_VEGA_GOVERNANCE_URL=https://token.fairground.wtf
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
|
||||||
@@ -11,4 +11,3 @@ NX_VEGA_GOVERNANCE_URL=https://validator-testnet.governance.vega.xyz
|
|||||||
NX_TENDERMINT_URL=https://tm-be.validators-testnet.vega.rocks
|
NX_TENDERMINT_URL=https://tm-be.validators-testnet.vega.rocks
|
||||||
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
||||||
NX_VEGA_EXPLORER_URL=https://validator-testnet.explorer.vega.xyz/
|
|
||||||
@@ -5,4 +5,3 @@ NX_VEGA_ENV=CUSTOM
|
|||||||
NX_BLOCK_EXPLORER=
|
NX_BLOCK_EXPLORER=
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=/
|
|
||||||
@@ -35,11 +35,12 @@ Example configurations are provided here:
|
|||||||
- [Devnet](./.env.devnet)
|
- [Devnet](./.env.devnet)
|
||||||
- [Capsule](./.env.capsule)
|
- [Capsule](./.env.capsule)
|
||||||
- [Testnet](./.env.testnet)
|
- [Testnet](./.env.testnet)
|
||||||
|
- [Stagnet3](./.env.stagnet3)
|
||||||
|
|
||||||
For convenience, you can boot the app injecting one of the configurations above by running:
|
For convenience, you can boot the app injecting one of the configurations above by running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn nx run explorer:serve --env={env} # e.g. stagnet1
|
yarn nx run explorer:serve --env={env} # e.g. stagnet3
|
||||||
```
|
```
|
||||||
|
|
||||||
There are a few different configuration options offered for this app:
|
There are a few different configuration options offered for this app:
|
||||||
|
|||||||
@@ -1,18 +1,9 @@
|
|||||||
import {
|
import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment';
|
||||||
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>
|
||||||
@@ -21,23 +12,10 @@ 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}>
|
||||||
<NodeGuard
|
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||||
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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export type AssetBalanceProps = {
|
|||||||
assetId: string;
|
assetId: string;
|
||||||
price: string;
|
price: string;
|
||||||
showAssetLink?: boolean;
|
showAssetLink?: boolean;
|
||||||
showAssetSymbol?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,21 +16,18 @@ const AssetBalance = ({
|
|||||||
assetId,
|
assetId,
|
||||||
price,
|
price,
|
||||||
showAssetLink = true,
|
showAssetLink = true,
|
||||||
showAssetSymbol = false,
|
|
||||||
}: AssetBalanceProps) => {
|
}: AssetBalanceProps) => {
|
||||||
const { data: asset, loading } = useAssetDataProvider(assetId);
|
const { data: asset } = useAssetDataProvider(assetId);
|
||||||
|
|
||||||
const label =
|
const label =
|
||||||
!loading && asset && asset.decimals
|
asset && asset.decimals
|
||||||
? addDecimalsFormatNumber(price, asset.decimals)
|
? addDecimalsFormatNumber(price, asset.decimals)
|
||||||
: price;
|
: price;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="inline-block">
|
<div className="inline-block">
|
||||||
<span>{label}</span>{' '}
|
<span>{label}</span>{' '}
|
||||||
{showAssetLink && asset?.id ? (
|
{showAssetLink && asset?.id ? <AssetLink assetId={assetId} /> : null}
|
||||||
<AssetLink showAssetSymbol={showAssetSymbol} assetId={assetId} />
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,17 +13,11 @@ const DEFAULT_DECIMALS = 18;
|
|||||||
* the governance asset first, which is set by a network parameter
|
* the governance asset first, which is set by a network parameter
|
||||||
*/
|
*/
|
||||||
const GovernanceAssetBalance = ({ price }: GovernanceAssetBalanceProps) => {
|
const GovernanceAssetBalance = ({ price }: GovernanceAssetBalanceProps) => {
|
||||||
const { data, loading } = useExplorerGovernanceAssetQuery();
|
const { data } = useExplorerGovernanceAssetQuery();
|
||||||
|
|
||||||
if (!loading && data && data.networkParameter?.value) {
|
if (data && data.networkParameter?.value) {
|
||||||
const governanceAssetId = data.networkParameter.value;
|
const governanceAssetId = data.networkParameter.value;
|
||||||
return (
|
return <AssetBalance price={price} assetId={governanceAssetId} />;
|
||||||
<AssetBalance
|
|
||||||
price={price}
|
|
||||||
showAssetSymbol={true}
|
|
||||||
assetId={governanceAssetId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className="inline-block">
|
<div className="inline-block">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { t } from '@vegaprotocol/i18n';
|
|||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
|
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
|
||||||
import { useRef, useLayoutEffect } from 'react';
|
import { useRef, useLayoutEffect } from 'react';
|
||||||
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import {
|
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
|
||||||
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 } from 'react';
|
import { useMemo, useState } 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 setNodeSwitcherOpen = useNodeSwitcherStore(
|
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
||||||
(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),
|
||||||
@@ -21,42 +15,46 @@ 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">
|
<>
|
||||||
<div className="flex justify-between gap-2 align-middle">
|
<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">
|
||||||
{GIT_COMMIT_HASH && (
|
<div className="flex justify-between gap-2 align-middle">
|
||||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
{GIT_COMMIT_HASH && (
|
||||||
<p data-testid="git-commit-hash">
|
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||||
{t('Version')}:{' '}
|
<p data-testid="git-commit-hash">
|
||||||
<Link
|
{t('Version')}:{' '}
|
||||||
href={
|
<Link
|
||||||
GIT_ORIGIN_URL
|
href={
|
||||||
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
GIT_ORIGIN_URL
|
||||||
: undefined
|
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
|
||||||
}
|
: undefined
|
||||||
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
}
|
||||||
>
|
target={GIT_ORIGIN_URL ? '_blank' : undefined}
|
||||||
{GIT_COMMIT_HASH}
|
>
|
||||||
</Link>
|
{GIT_COMMIT_HASH}
|
||||||
</p>
|
</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>
|
||||||
)}
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
{ENV.addresses.feedback ? (
|
|
||||||
<div className="flex pl-2 content-center">
|
<div className="flex pl-2 content-center">
|
||||||
<ExternalLink href={ENV.addresses.feedback}>
|
<ExternalLink href={ENV.addresses.feedback}>
|
||||||
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
</div>
|
||||||
</div>
|
</footer>
|
||||||
</footer>
|
<NodeSwitcherDialog
|
||||||
|
open={nodeSwitcherOpen}
|
||||||
|
setOpen={setNodeSwitcherOpen}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,5 +62,9 @@ const NodeUrl = ({ url }: { url: string }) => {
|
|||||||
// get base url from api url, api sub domain
|
// get base url from api url, api sub domain
|
||||||
const urlObj = new URL(url);
|
const urlObj = new URL(url);
|
||||||
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
||||||
return <span className="cursor-default">{nodeUrl}</span>;
|
return (
|
||||||
|
<Link href={'https://' + nodeUrl} target="_blank">
|
||||||
|
{nodeUrl}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Header } from './header';
|
|||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/environment', () => ({
|
jest.mock('@vegaprotocol/environment', () => ({
|
||||||
...jest.requireActual('@vegaprotocol/environment'),
|
|
||||||
NetworkSwitcher: () => (
|
NetworkSwitcher: () => (
|
||||||
<div data-testid="network-switcher">NetworkSwitcher</div>
|
<div data-testid="network-switcher">NetworkSwitcher</div>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export const AssetLink = ({
|
|||||||
if (asDialog) {
|
if (asDialog) {
|
||||||
open(assetId, e.target as HTMLElement);
|
open(assetId, e.target as HTMLElement);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/${Routes.ASSETS}/${asset?.id}`);
|
navigate(`${Routes.ASSETS}/${asset?.id}`);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
import type { MarketInfoWithData } from '@vegaprotocol/market-info';
|
||||||
|
import { LiquidityInfoPanel } from '@vegaprotocol/market-info';
|
||||||
|
import { LiquidityMonitoringParametersInfoPanel } from '@vegaprotocol/market-info';
|
||||||
import {
|
import {
|
||||||
LiquidityInfoPanel,
|
|
||||||
LiquidityMonitoringParametersInfoPanel,
|
|
||||||
InstrumentInfoPanel,
|
InstrumentInfoPanel,
|
||||||
KeyDetailsInfoPanel,
|
KeyDetailsInfoPanel,
|
||||||
LiquidityPriceRangeInfoPanel,
|
LiquidityPriceRangeInfoPanel,
|
||||||
@@ -12,72 +12,13 @@ import {
|
|||||||
RiskModelInfoPanel,
|
RiskModelInfoPanel,
|
||||||
RiskParametersInfoPanel,
|
RiskParametersInfoPanel,
|
||||||
SettlementAssetInfoPanel,
|
SettlementAssetInfoPanel,
|
||||||
} from '@vegaprotocol/markets';
|
} from '@vegaprotocol/market-info';
|
||||||
import { MarketInfoTable } from '@vegaprotocol/markets';
|
import { MarketInfoTable } from '@vegaprotocol/market-info';
|
||||||
import type { DataSourceDefinition } from '@vegaprotocol/types';
|
import { Link } from 'react-router-dom';
|
||||||
import isEqual from 'lodash/isEqual';
|
|
||||||
|
|
||||||
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||||
if (!market) return null;
|
if (!market) return null;
|
||||||
|
|
||||||
const settlementData = market.tradableInstrument.instrument.product
|
|
||||||
.dataSourceSpecForSettlementData.data as DataSourceDefinition;
|
|
||||||
const terminationData = market.tradableInstrument.instrument.product
|
|
||||||
.dataSourceSpecForTradingTermination.data as DataSourceDefinition;
|
|
||||||
|
|
||||||
const getSigners = (data: DataSourceDefinition) => {
|
|
||||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
|
||||||
const signers = data.sourceType.sourceType.signers || [];
|
|
||||||
|
|
||||||
return signers.map(({ signer }, i) => {
|
|
||||||
return (
|
|
||||||
(signer.__typename === 'ETHAddress' && signer.address) ||
|
|
||||||
(signer.__typename === 'PubKey' && signer.key)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
const oraclePanels = isEqual(
|
|
||||||
getSigners(settlementData),
|
|
||||||
getSigners(terminationData)
|
|
||||||
)
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
title: t('Settlement Oracle'),
|
|
||||||
content: (
|
|
||||||
<OracleInfoPanel
|
|
||||||
noBorder={false}
|
|
||||||
market={market}
|
|
||||||
type="settlementData"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('Termination Oracle'),
|
|
||||||
content: (
|
|
||||||
<OracleInfoPanel
|
|
||||||
noBorder={false}
|
|
||||||
market={market}
|
|
||||||
type="termination"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
title: t('Oracle'),
|
|
||||||
content: (
|
|
||||||
<OracleInfoPanel
|
|
||||||
noBorder={false}
|
|
||||||
market={market}
|
|
||||||
type="settlementData"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const panels = [
|
const panels = [
|
||||||
{
|
{
|
||||||
title: t('Key details'),
|
title: t('Key details'),
|
||||||
@@ -119,11 +60,9 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
|||||||
<>
|
<>
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
noBorder={false}
|
noBorder={false}
|
||||||
data={{
|
data={trigger}
|
||||||
maxValidPrice: trigger.maxValidPrice,
|
|
||||||
minValidPrice: trigger.minValidPrice,
|
|
||||||
}}
|
|
||||||
decimalPlaces={market.decimalPlaces}
|
decimalPlaces={market.decimalPlaces}
|
||||||
|
omits={['referencePrice', '__typename']}
|
||||||
/>
|
/>
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
noBorder={false}
|
noBorder={false}
|
||||||
@@ -155,7 +94,25 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
|||||||
<LiquidityPriceRangeInfoPanel market={market} noBorder={false} />
|
<LiquidityPriceRangeInfoPanel market={market} noBorder={false} />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
...oraclePanels,
|
{
|
||||||
|
title: t('Oracle'),
|
||||||
|
content: (
|
||||||
|
<OracleInfoPanel noBorder={false} market={market}>
|
||||||
|
<Link
|
||||||
|
className="text-xs hover:underline"
|
||||||
|
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForSettlementData.id}`}
|
||||||
|
>
|
||||||
|
{t('View settlement data oracle specification')}
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
className="text-xs hover:underline"
|
||||||
|
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForTradingTermination.id}`}
|
||||||
|
>
|
||||||
|
{t('View termination oracle specification')}
|
||||||
|
</Link>
|
||||||
|
</OracleInfoPanel>
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { MarketFieldsFragment } from '@vegaprotocol/markets';
|
import type { MarketFieldsFragment } from '@vegaprotocol/market-list';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueGetterParams,
|
VegaValueGetterParams,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import SizeInMarket from '../size-in-market/size-in-market';
|
|||||||
export interface DeterministicOrderDetailsProps {
|
export interface DeterministicOrderDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
// Version to fetch, with 0 being 'latest' and 1 being 'first'. Defaults to 0
|
// Version to fetch, with 0 being 'latest' and 1 being 'first'. Defaults to 0
|
||||||
version?: number | null;
|
version?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const wrapperClasses =
|
export const wrapperClasses =
|
||||||
@@ -28,7 +28,7 @@ export const wrapperClasses =
|
|||||||
*/
|
*/
|
||||||
const DeterministicOrderDetails = ({
|
const DeterministicOrderDetails = ({
|
||||||
id,
|
id,
|
||||||
version = null,
|
version = 0,
|
||||||
}: DeterministicOrderDetailsProps) => {
|
}: DeterministicOrderDetailsProps) => {
|
||||||
const { data, error } = useExplorerDeterministicOrderQuery({
|
const { data, error } = useExplorerDeterministicOrderQuery({
|
||||||
variables: { orderId: id, version },
|
variables: { orderId: id, version },
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const PageHeader = ({
|
|||||||
copy = false,
|
copy = false,
|
||||||
className,
|
className,
|
||||||
}: PageHeaderProps) => {
|
}: PageHeaderProps) => {
|
||||||
const titleClasses = 'text-xl uppercase font-alpha calt';
|
const titleClasses = 'text-4xl xl:text-5xl uppercase font-alpha calt';
|
||||||
return (
|
return (
|
||||||
<header className={className}>
|
<header className={className}>
|
||||||
<span className={`${titleClasses} block`}>{prefix}</span>
|
<span className={`${titleClasses} block`}>{prefix}</span>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { VoteProgress } from '@vegaprotocol/proposals';
|
|||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
@@ -12,10 +12,7 @@ import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import type { RowClickedEvent } from 'ag-grid-community';
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import {
|
import { NetworkParams, useNetworkParams } from '@vegaprotocol/react-helpers';
|
||||||
NetworkParams,
|
|
||||||
useNetworkParams,
|
|
||||||
} from '@vegaprotocol/network-parameters';
|
|
||||||
import { ProposalStateMapping } from '@vegaprotocol/types';
|
import { ProposalStateMapping } from '@vegaprotocol/types';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||||
|
|||||||
+2
-8
@@ -1,5 +1,3 @@
|
|||||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
// https://github.com/vegaprotocol/vega/blob/develop/core/blockchain/response.go
|
// https://github.com/vegaprotocol/vega/blob/develop/core/blockchain/response.go
|
||||||
export const ErrorCodes = new Map([
|
export const ErrorCodes = new Map([
|
||||||
[51, 'Transaction failed validation'],
|
[51, 'Transaction failed validation'],
|
||||||
@@ -30,11 +28,7 @@ export const ChainResponseCode = ({
|
|||||||
}: ChainResponseCodeProps) => {
|
}: ChainResponseCodeProps) => {
|
||||||
const isSuccess = successCodes.has(code);
|
const isSuccess = successCodes.has(code);
|
||||||
|
|
||||||
const icon = isSuccess ? (
|
const icon = isSuccess ? '✅' : '❌';
|
||||||
<Icon name="tick-circle" className="fill-vega-green-550" />
|
|
||||||
) : (
|
|
||||||
<Icon name="cross" className="fill-vega-pink-550" />
|
|
||||||
);
|
|
||||||
const label = ErrorCodes.get(code) || 'Unknown response code';
|
const label = ErrorCodes.get(code) || 'Unknown response code';
|
||||||
|
|
||||||
// Hack for batches with many errors - see https://github.com/vegaprotocol/vega/issues/7245
|
// Hack for batches with many errors - see https://github.com/vegaprotocol/vega/issues/7245
|
||||||
@@ -42,7 +36,7 @@ export const ChainResponseCode = ({
|
|||||||
error && error.length > 100 ? error.replace(/,/g, ',\r\n') : error;
|
error && error.length > 100 ? error.replace(/,/g, ',\r\n') : error;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div title={`Response code: ${code} - ${label}`} className=" inline-block">
|
<div title={`Response code: ${code} - ${label}`} className="inline-block">
|
||||||
<span
|
<span
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
aria-label={isSuccess ? 'Success' : 'Warning'}
|
aria-label={isSuccess ? 'Success' : 'Warning'}
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ export const BundleExists = ({
|
|||||||
// Note if this is wrong, the wrong decoder will be used which will give incorrect data
|
// Note if this is wrong, the wrong decoder will be used which will give incorrect data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-auto h-10 max-w-lg border-2 border-solid border-vega-light-100 dark:border-vega-dark-200 p-5 mt-5">
|
<div className="w-auto max-w-lg border-2 border-solid border-vega-light-100 dark:border-vega-dark-200 p-5 mt-5">
|
||||||
<IconForBundleStatus status={status} />
|
<IconForBundleStatus status={status} />
|
||||||
<h1 className="text-xl pb-1">
|
<h1 className="text-xl pb-1">
|
||||||
{status === 'STATUS_ENABLED'
|
{status === 'STATUS_ENABLED'
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint
|
|||||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
import ProposalLink from '../../links/proposal-link/proposal-link';
|
import ProposalLink from '../../links/proposal-link/proposal-link';
|
||||||
import { VoteIcon } from '../../vote-icon/vote-icon';
|
|
||||||
|
|
||||||
interface TxProposalVoteProps {
|
interface TxProposalVoteProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -31,22 +30,27 @@ export const TxProposalVote = ({
|
|||||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vote = txData.command.voteSubmission.value === 'VALUE_YES';
|
const vote = txData.command.voteSubmission.value ? '👍' : '👎';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableWithTbody className="mb-8" allowWrap={true}>
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Proposal ID')}</TableCell>
|
||||||
|
<TableCell>{txData.command.voteSubmission.proposalId}</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell>{t('Proposal details')}</TableCell>
|
<TableCell>{t('Proposal details')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<ProposalLink id={txData.command.voteSubmission.proposalId} />
|
<ProposalLink id={txData.command.voteSubmission.proposalId} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Proposal')}</TableCell>
|
||||||
|
<TableCell>{txData.command.voteSubmission.proposalId}</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell>{t('Vote')}</TableCell>
|
<TableCell>{t('Vote')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>{vote}</TableCell>
|
||||||
<VoteIcon vote={vote} />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableWithTbody>
|
</TableWithTbody>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import type { Proposal } from './tx-proposal';
|
|
||||||
import { proposalRequiresSignatureBundle } from './tx-proposal';
|
|
||||||
|
|
||||||
describe('proposalRequiresSignatureBundle', () => {
|
|
||||||
it('should return false for freeform proposals, which do not require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newFreeform: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for newMarket proposals, which do not require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newMarket: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for newAsset proposals, which do require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newAsset: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for updateAsset proposals, which do require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
updateAsset: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when bad data is supplied', () => {
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle(false as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle(undefined as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle({ test: false } as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -28,16 +28,11 @@ interface TxProposalProps {
|
|||||||
* @returns boolean True if a signature bundle is required. Used to fetch a signature bundle
|
* @returns boolean True if a signature bundle is required. Used to fetch a signature bundle
|
||||||
*/
|
*/
|
||||||
export function proposalRequiresSignatureBundle(proposal?: Proposal): boolean {
|
export function proposalRequiresSignatureBundle(proposal?: Proposal): boolean {
|
||||||
const proposalsThatRequireBundles = ['newAsset', 'updateAsset'];
|
|
||||||
|
|
||||||
if (!proposal?.terms) {
|
if (!proposal?.terms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return !!['newAsset', 'updateAsset'].filter((requiredIfExists) =>
|
||||||
return (
|
has(proposal.terms, requiredIfExists)
|
||||||
proposalsThatRequireBundles.filter((requiredIfExists) =>
|
|
||||||
has(proposal.terms, requiredIfExists)
|
|
||||||
).length > 0
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +81,6 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
|
|||||||
|
|
||||||
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
|
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
|
||||||
|
|
||||||
// This component is not rendered if no bundle is required
|
|
||||||
const SignatureBundleComponent = proposal.terms?.newAsset
|
const SignatureBundleComponent = proposal.terms?.newAsset
|
||||||
? ProposalSignatureBundleNewAsset
|
? ProposalSignatureBundleNewAsset
|
||||||
: ProposalSignatureBundleUpdateAsset;
|
: ProposalSignatureBundleUpdateAsset;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export { TxList } from './tx-list';
|
||||||
export { TxOrderType } from './tx-order-type';
|
export { TxOrderType } from './tx-order-type';
|
||||||
export { TxsInfiniteList } from './txs-infinite-list';
|
export { TxsInfiniteList } from './txs-infinite-list';
|
||||||
export { TxsInfiniteListItem } from './txs-infinite-list-item';
|
export { TxsInfiniteListItem } from './txs-infinite-list-item';
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { TendermintUnconfirmedTransactionsResponse } from '../../routes/txs/tendermint-unconfirmed-transactions-response.d';
|
||||||
|
|
||||||
|
interface TxsProps {
|
||||||
|
data: TendermintUnconfirmedTransactionsResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TxList = ({ data }: TxsProps) => {
|
||||||
|
if (!data) {
|
||||||
|
return <div>{t('Awaiting transactions')}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div>{JSON.stringify(data, null, ' ')}</div>;
|
||||||
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { components } from '../../../types/explorer';
|
import type { components } from '../../../types/explorer';
|
||||||
import { VoteIcon } from '../vote-icon/vote-icon';
|
|
||||||
|
|
||||||
interface TxOrderTypeProps {
|
interface TxOrderTypeProps {
|
||||||
orderType: string;
|
orderType: string;
|
||||||
@@ -138,15 +137,12 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
|||||||
let type = displayString[orderType] || orderType;
|
let type = displayString[orderType] || orderType;
|
||||||
|
|
||||||
let colours =
|
let colours =
|
||||||
'text-white dark:text-white bg-vega-dark-150 dark:bg-vega-dark-250';
|
'text-white dark:text-white bg-vega-dark-150 dark:bg-vega-dark-150';
|
||||||
|
|
||||||
// This will get unwieldy and should probably produce a different colour of tag
|
// This will get unwieldy and should probably produce a different colour of tag
|
||||||
if (type === 'Chain Event' && !!command?.chainEvent) {
|
if (type === 'Chain Event' && !!command?.chainEvent) {
|
||||||
type = getLabelForChainEvent(command.chainEvent);
|
type = getLabelForChainEvent(command.chainEvent);
|
||||||
colours = 'text-white dark-text-white bg-vega-pink dark:bg-vega-pink';
|
colours = 'text-white dark-text-white bg-vega-pink dark:bg-vega-pink';
|
||||||
} else if (type === 'Validator Heartbeat') {
|
|
||||||
colours =
|
|
||||||
'text-white dark-text-white bg-vega-light-200 dark:bg-vega-dark-100';
|
|
||||||
} else if (type === 'Proposal' || type === 'Governance Proposal') {
|
} else if (type === 'Proposal' || type === 'Governance Proposal') {
|
||||||
if (command && !!command.proposalSubmission) {
|
if (command && !!command.proposalSubmission) {
|
||||||
type = getLabelForProposal(command.proposalSubmission);
|
type = getLabelForProposal(command.proposalSubmission);
|
||||||
@@ -154,16 +150,6 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
|||||||
colours = 'text-black bg-vega-yellow';
|
colours = 'text-black bg-vega-yellow';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Vote on Proposal') {
|
|
||||||
return (
|
|
||||||
<VoteIcon
|
|
||||||
vote={command?.voteSubmission?.value === 'VALUE_YES'}
|
|
||||||
yesText="Proposal vote"
|
|
||||||
noText="Proposal vote"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Vote on Proposal' || type === 'Vote Submission') {
|
if (type === 'Vote on Proposal' || type === 'Vote Submission') {
|
||||||
colours = 'text-black bg-vega-yellow';
|
colours = 'text-black bg-vega-yellow';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,6 @@ describe('Txs infinite list item', () => {
|
|||||||
expect(screen.getByTestId('pub-key')).toHaveTextContent('testPubKey');
|
expect(screen.getByTestId('pub-key')).toHaveTextContent('testPubKey');
|
||||||
expect(screen.getByTestId('tx-type')).toHaveTextContent('testType');
|
expect(screen.getByTestId('tx-type')).toHaveTextContent('testType');
|
||||||
expect(screen.getByTestId('tx-block')).toHaveTextContent('1');
|
expect(screen.getByTestId('tx-block')).toHaveTextContent('1');
|
||||||
expect(screen.getByTestId('tx-success')).toHaveTextContent('Success');
|
expect(screen.getByTestId('tx-success')).toHaveTextContent('Success: ✅');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { toHex } from '../search/detect-search';
|
|||||||
import { ChainResponseCode } from './details/chain-response-code/chain-reponse.code';
|
import { ChainResponseCode } from './details/chain-response-code/chain-reponse.code';
|
||||||
import isNumber from 'lodash/isNumber';
|
import isNumber from 'lodash/isNumber';
|
||||||
|
|
||||||
const TRUNCATE_LENGTH = 10;
|
const TRUNCATE_LENGTH = 5;
|
||||||
|
|
||||||
export const TxsInfiniteListItem = ({
|
export const TxsInfiniteListItem = ({
|
||||||
hash,
|
hash,
|
||||||
@@ -31,13 +31,13 @@ export const TxsInfiniteListItem = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-testid="transaction-row"
|
data-testid="transaction-row"
|
||||||
className="flex items-center h-full border-t border-neutral-600 dark:border-neutral-800 txs-infinite-list-item grid grid-cols-10"
|
className="flex items-center h-full border-t border-neutral-600 dark:border-neutral-800 txs-infinite-list-item grid grid-cols-10 py-2"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="text-sm col-span-10 md:col-span-3 leading-none"
|
className="text-sm col-span-10 xl:col-span-3 leading-none"
|
||||||
data-testid="tx-hash"
|
data-testid="tx-hash"
|
||||||
>
|
>
|
||||||
<span className="md:hidden uppercase text-vega-dark-300">
|
<span className="xl:hidden uppercase text-vega-dark-300">
|
||||||
ID:
|
ID:
|
||||||
</span>
|
</span>
|
||||||
<TruncatedLink
|
<TruncatedLink
|
||||||
@@ -48,10 +48,10 @@ export const TxsInfiniteListItem = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="text-sm col-span-10 md:col-span-3 leading-none"
|
className="text-sm col-span-10 xl:col-span-3 leading-none"
|
||||||
data-testid="pub-key"
|
data-testid="pub-key"
|
||||||
>
|
>
|
||||||
<span className="md:hidden uppercase text-vega-dark-300">
|
<span className="xl:hidden uppercase text-vega-dark-300">
|
||||||
By:
|
By:
|
||||||
</span>
|
</span>
|
||||||
<TruncatedLink
|
<TruncatedLink
|
||||||
@@ -61,14 +61,14 @@ export const TxsInfiniteListItem = ({
|
|||||||
endChars={TRUNCATE_LENGTH}
|
endChars={TRUNCATE_LENGTH}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm col-span-5 md:col-span-2 leading-none flex items-center">
|
<div className="text-sm col-span-5 xl:col-span-2 leading-none flex items-center">
|
||||||
<TxOrderType orderType={type} command={command} />
|
<TxOrderType orderType={type} command={command} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="text-sm col-span-3 md:col-span-1 leading-none flex items-center"
|
className="text-sm col-span-3 xl:col-span-1 leading-none flex items-center"
|
||||||
data-testid="tx-block"
|
data-testid="tx-block"
|
||||||
>
|
>
|
||||||
<span className="md:hidden uppercase text-vega-dark-300">
|
<span className="xl:hidden uppercase text-vega-dark-300">
|
||||||
Block:
|
Block:
|
||||||
</span>
|
</span>
|
||||||
<TruncatedLink
|
<TruncatedLink
|
||||||
@@ -79,11 +79,11 @@ export const TxsInfiniteListItem = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="text-sm col-span-2 md:col-span-1 leading-none flex items-center"
|
className="text-sm col-span-2 xl:col-span-1 leading-none flex items-center"
|
||||||
data-testid="tx-success"
|
data-testid="tx-success"
|
||||||
>
|
>
|
||||||
<span className="md:hidden uppercase text-vega-dark-300">
|
<span className="xl:hidden uppercase text-vega-dark-300">
|
||||||
Success
|
Success:
|
||||||
</span>
|
</span>
|
||||||
{isNumber(code) ? (
|
{isNumber(code) ? (
|
||||||
<ChainResponseCode code={code} hideLabel={true} />
|
<ChainResponseCode code={code} hideLabel={true} />
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ describe('Txs infinite list', () => {
|
|||||||
error={Error('test error!')}
|
error={Error('test error!')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('Cannot fetch transaction')).toBeInTheDocument();
|
expect(
|
||||||
|
screen.getByText('Cannot fetch transaction: Error: test error!')
|
||||||
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('item renders data of n length into list of n length', () => {
|
it('item renders data of n length into list of n length', () => {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const NOOP = () => {};
|
|||||||
const Item = ({ index, style, isLoading, error }: ItemProps) => {
|
const Item = ({ index, style, isLoading, error }: ItemProps) => {
|
||||||
let content;
|
let content;
|
||||||
if (error) {
|
if (error) {
|
||||||
content = t(`Cannot fetch transaction`);
|
content = t(`Cannot fetch transaction: ${error}`);
|
||||||
} else if (isLoading) {
|
} else if (isLoading) {
|
||||||
content = <Loader />;
|
content = <Loader />;
|
||||||
} else {
|
} else {
|
||||||
@@ -68,7 +68,7 @@ export const TxsInfiniteList = ({
|
|||||||
className,
|
className,
|
||||||
}: TxsInfiniteListProps) => {
|
}: TxsInfiniteListProps) => {
|
||||||
const { screenSize } = useScreenDimensions();
|
const { screenSize } = useScreenDimensions();
|
||||||
const isStacked = ['xs', 'sm'].includes(screenSize);
|
const isStacked = ['xs', 'sm', 'md', 'lg'].includes(screenSize);
|
||||||
|
|
||||||
if (!txs) {
|
if (!txs) {
|
||||||
if (!areTxsLoading) {
|
if (!areTxsLoading) {
|
||||||
@@ -95,15 +95,15 @@ export const TxsInfiniteList = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className} data-testid="transactions-list">
|
<div className={className} data-testid="transactions-list">
|
||||||
<div className="lg:grid grid-cols-10 w-full mb-3 hidden text-vega-dark-300 uppercase">
|
<div className="xl:grid grid-cols-10 w-full mb-3 hidden text-vega-dark-300 uppercase">
|
||||||
<div className="col-span-3">
|
<div className="col-span-3">
|
||||||
<span className="hidden xl:inline">{t('Transaction')} </span>
|
<span className="hidden xl:inline">Transaction </span>
|
||||||
<span>ID</span>
|
<span>ID</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-3">{t('Submitted By')}</div>
|
<div className="col-span-3">Submitted By</div>
|
||||||
<div className="col-span-2">{t('Type')}</div>
|
<div className="col-span-2">Type</div>
|
||||||
<div className="col-span-1">{t('Block')}</div>
|
<div className="col-span-1">Block</div>
|
||||||
<div className="col-span-1">{t('Success')}</div>
|
<div className="col-span-1">Success</div>
|
||||||
</div>
|
</div>
|
||||||
<div data-testid="infinite-scroll-wrapper">
|
<div data-testid="infinite-scroll-wrapper">
|
||||||
<InfiniteLoader
|
<InfiniteLoader
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Routes } from '../../routes/route-names';
|
import { Routes } from '../../routes/route-names';
|
||||||
|
import { RenderFetched } from '../render-fetched';
|
||||||
import { TruncatedLink } from '../truncate/truncated-link';
|
import { TruncatedLink } from '../truncate/truncated-link';
|
||||||
import { TxOrderType } from './tx-order-type';
|
import { TxOrderType } from './tx-order-type';
|
||||||
import { Table, TableRow, TableCell } from '../table';
|
import { Table, TableRow, TableCell } from '../table';
|
||||||
@@ -8,7 +9,7 @@ import type { BlockExplorerTransactions } from '../../routes/types/block-explore
|
|||||||
import isNumber from 'lodash/isNumber';
|
import isNumber from 'lodash/isNumber';
|
||||||
import { ChainResponseCode } from './details/chain-response-code/chain-reponse.code';
|
import { ChainResponseCode } from './details/chain-response-code/chain-reponse.code';
|
||||||
import { getTxsDataUrl } from '../../hooks/use-txs-data';
|
import { getTxsDataUrl } from '../../hooks/use-txs-data';
|
||||||
import { AsyncRenderer, Loader } from '@vegaprotocol/ui-toolkit';
|
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import EmptyList from '../empty-list/empty-list';
|
import EmptyList from '../empty-list/empty-list';
|
||||||
|
|
||||||
interface TxsPerBlockProps {
|
interface TxsPerBlockProps {
|
||||||
@@ -26,7 +27,7 @@ export const TxsPerBlock = ({ blockHeight, txCount }: TxsPerBlockProps) => {
|
|||||||
} = useFetch<BlockExplorerTransactions>(url);
|
} = useFetch<BlockExplorerTransactions>(url);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer data={data} error={error} loading={!!loading}>
|
<RenderFetched error={error} loading={loading} className="text-body-large">
|
||||||
{data && data.transactions.length > 0 ? (
|
{data && data.transactions.length > 0 ? (
|
||||||
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
||||||
<Table>
|
<Table>
|
||||||
@@ -94,6 +95,6 @@ export const TxsPerBlock = ({ blockHeight, txCount }: TxsPerBlockProps) => {
|
|||||||
label={t('0 transactions')}
|
label={t('0 transactions')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</AsyncRenderer>
|
</RenderFetched>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
import { VoteIcon } from './vote-icon';
|
|
||||||
|
|
||||||
describe('Vote TX icon', () => {
|
|
||||||
it('should use the text For by default for yes votes', () => {
|
|
||||||
const yes = render(<VoteIcon vote={true} />);
|
|
||||||
expect(yes.getByTestId('label')).toHaveTextContent('For');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the yesText for yes votes if specified', () => {
|
|
||||||
const yes = render(<VoteIcon vote={true} yesText="Test" />);
|
|
||||||
expect(yes.getByTestId('label')).toHaveTextContent('Test');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the tick icon for yes votes', () => {
|
|
||||||
const no = render(<VoteIcon vote={true} />);
|
|
||||||
expect(no.getByRole('img')).toHaveAttribute(
|
|
||||||
'aria-label',
|
|
||||||
'tick-circle icon'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the text Against by default for no votes', () => {
|
|
||||||
const no = render(<VoteIcon vote={false} />);
|
|
||||||
expect(no.getByTestId('label')).toHaveTextContent('Against');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the noText for no votes if specified', () => {
|
|
||||||
const no = render(<VoteIcon vote={false} noText="Test" />);
|
|
||||||
expect(no.getByTestId('label')).toHaveTextContent('Test');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the delete icon for no votes', () => {
|
|
||||||
const no = render(<VoteIcon vote={false} />);
|
|
||||||
expect(no.getByRole('img')).toHaveAttribute('aria-label', 'delete icon');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import type { IconName } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
export interface VoteIconProps {
|
|
||||||
// True is a yes vote, false is undefined or no vorte
|
|
||||||
vote: boolean;
|
|
||||||
// Defaults to 'For', but can be any text
|
|
||||||
yesText?: string;
|
|
||||||
// Defaults to 'Against', but can be any text
|
|
||||||
noText?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a lozenge with an icon representing the way a user voted for a proposal.
|
|
||||||
* The yes and no text can be overridden
|
|
||||||
*
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function VoteIcon({
|
|
||||||
vote,
|
|
||||||
yesText = 'For',
|
|
||||||
noText = 'Against',
|
|
||||||
}: VoteIconProps) {
|
|
||||||
const label = vote ? yesText : noText;
|
|
||||||
const bg = vote ? 'bg-vega-green-550' : 'bg-vega-pink-550';
|
|
||||||
const icon: IconName = vote ? 'tick-circle' : 'delete';
|
|
||||||
const fill = vote ? 'vega-green-300' : 'vega-pink-300';
|
|
||||||
const text = vote ? 'vega-green-200' : 'vega-pink-200';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`voteicon inline-block my-1 py-1 px-2 py rounded-md text-white leading-one sm align-top ${bg}`}
|
|
||||||
>
|
|
||||||
<Icon name={icon} size={3} className={`mr-2 p-0 fill-${fill}`} />
|
|
||||||
<span className={`text-base text-${text}`} data-testid="label">
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -144,12 +144,12 @@ afterEach(() => {
|
|||||||
describe('Block', () => {
|
describe('Block', () => {
|
||||||
it('renders error state if error is present', async () => {
|
it('renders error state if error is present', async () => {
|
||||||
(useFetch as jest.Mock).mockReturnValue({
|
(useFetch as jest.Mock).mockReturnValue({
|
||||||
state: { data: null, loading: false, error: new Error('asd') },
|
state: { data: null, loading: false, error: 'asd' },
|
||||||
});
|
});
|
||||||
render(renderComponent());
|
render(renderComponent());
|
||||||
|
|
||||||
expect(screen.getByText(`BLOCK ${blockId}`)).toBeInTheDocument();
|
expect(screen.getByText(`BLOCK ${blockId}`)).toBeInTheDocument();
|
||||||
expect(screen.getByText('Something went wrong: asd')).toBeInTheDocument();
|
expect(screen.getByText('Error retrieving data')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders loading state if present', async () => {
|
it('renders loading state if present', async () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
import { Link, useParams } from 'react-router-dom';
|
import { Link, useParams } from 'react-router-dom';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||||
@@ -11,8 +12,9 @@ import {
|
|||||||
TableCell,
|
TableCell,
|
||||||
} from '../../../components/table';
|
} from '../../../components/table';
|
||||||
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
|
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
|
||||||
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
|
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Routes } from '../../route-names';
|
import { Routes } from '../../route-names';
|
||||||
|
import { RenderFetched } from '../../../components/render-fetched';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import { NodeLink } from '../../../components/links';
|
import { NodeLink } from '../../../components/links';
|
||||||
@@ -32,7 +34,7 @@ const Block = () => {
|
|||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
|
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
|
||||||
<AsyncRenderer data={blockData} error={error} loading={!!loading}>
|
<RenderFetched error={error} loading={loading}>
|
||||||
<>
|
<>
|
||||||
<div className="grid grid-cols-2 gap-2 mb-8">
|
<div className="grid grid-cols-2 gap-2 mb-8">
|
||||||
<Link
|
<Link
|
||||||
@@ -121,7 +123,7 @@ const Block = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
</AsyncRenderer>
|
</RenderFetched>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||||
import { DATA_SOURCES } from '../../config';
|
import { DATA_SOURCES } from '../../config';
|
||||||
import type { TendermintGenesisResponse } from './tendermint-genesis-response';
|
import type { TendermintGenesisResponse } from './tendermint-genesis-response';
|
||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
@@ -10,26 +10,21 @@ const Genesis = () => {
|
|||||||
useDocumentTitle(['Genesis']);
|
useDocumentTitle(['Genesis']);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
state: { data, loading, error },
|
state: { data: genesis, loading },
|
||||||
} = useFetch<TendermintGenesisResponse>(
|
} = useFetch<TendermintGenesisResponse>(
|
||||||
`${DATA_SOURCES.tendermintUrl}/genesis`
|
`${DATA_SOURCES.tendermintUrl}/genesis`
|
||||||
);
|
);
|
||||||
|
if (!genesis?.result.genesis) {
|
||||||
|
if (loading) {
|
||||||
|
return <Loader />;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<section>
|
||||||
<RouteTitle data-testid="genesis-header">{t('Genesis')}</RouteTitle>
|
<RouteTitle data-testid="genesis-header">{t('Genesis')}</RouteTitle>
|
||||||
<AsyncRenderer
|
<SyntaxHighlighter data={genesis?.result.genesis} />
|
||||||
data={data}
|
</section>
|
||||||
error={error}
|
|
||||||
loading={!!loading}
|
|
||||||
loadingMessage={t('Loading genesis information...')}
|
|
||||||
errorMessage={t('Could not fetch genesis data')}
|
|
||||||
>
|
|
||||||
<section>
|
|
||||||
<SyntaxHighlighter data={data?.result.genesis} />
|
|
||||||
</section>
|
|
||||||
</AsyncRenderer>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { proposalsDataProvider } from '@vegaprotocol/proposals';
|
import { proposalsDataProvider } from '@vegaprotocol/proposals';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { ProposalsTable } from '../../components/proposals/proposals-table';
|
import { ProposalsTable } from '../../components/proposals/proposals-table';
|
||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
@@ -8,7 +8,7 @@ import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
|||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
import compact from 'lodash/compact';
|
import compact from 'lodash/compact';
|
||||||
import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
||||||
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
|
import { marketInfoWithDataProvider } from '@vegaprotocol/market-info';
|
||||||
import { PageTitle } from '../../components/page-helpers/page-title';
|
import { PageTitle } from '../../components/page-helpers/page-title';
|
||||||
|
|
||||||
export const MarketPage = () => {
|
export const MarketPage = () => {
|
||||||
@@ -49,7 +49,6 @@ export const MarketPage = () => {
|
|||||||
/>
|
/>
|
||||||
<AsyncRenderer
|
<AsyncRenderer
|
||||||
noDataMessage={t('This chain has no markets')}
|
noDataMessage={t('This chain has no markets')}
|
||||||
errorMessage={t('Could not fetch market') + ' ' + marketId}
|
|
||||||
data={data}
|
data={data}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
import { marketsProvider } from '@vegaprotocol/markets';
|
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import { MarketsTable } from '../../components/markets/markets-table';
|
import { MarketsTable } from '../../components/markets/markets-table';
|
||||||
|
|
||||||
export const MarketsPage = () => {
|
export const MarketsPage = () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
|
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
|
||||||
import { NetworkParametersTable } from './network-parameters';
|
import { NetworkParametersTable } from './network-parameters';
|
||||||
|
|
||||||
describe('NetworkParametersTable', () => {
|
describe('NetworkParametersTable', () => {
|
||||||
|
|||||||
@@ -13,15 +13,14 @@ import {
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
import { useNetworkParamsQuery } from '@vegaprotocol/network-parameters';
|
import { useNetworkParamsQuery } from '@vegaprotocol/react-helpers';
|
||||||
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
|
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
|
||||||
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
|
|
||||||
const PERCENTAGE_PARAMS = [
|
const PERCENTAGE_PARAMS = [
|
||||||
'governance.proposal.asset.requiredMajority',
|
'governance.proposal.asset.requiredMajority',
|
||||||
'governance.proposal.asset.requiredParticipation',
|
'governance.proposal.asset.requiredParticipation',
|
||||||
'governance.proposal.updateAsset.requiredParticipation',
|
|
||||||
'governance.proposal.freeform.requiredMajority',
|
'governance.proposal.freeform.requiredMajority',
|
||||||
'governance.proposal.freeform.requiredParticipation',
|
'governance.proposal.freeform.requiredParticipation',
|
||||||
'governance.proposal.market.requiredMajority',
|
'governance.proposal.market.requiredMajority',
|
||||||
@@ -54,8 +53,6 @@ const BIG_NUMBER_PARAMS = [
|
|||||||
'governance.proposal.asset.minProposerBalance',
|
'governance.proposal.asset.minProposerBalance',
|
||||||
'governance.proposal.market.minProposerBalance',
|
'governance.proposal.market.minProposerBalance',
|
||||||
'governance.proposal.market.minVoterBalance',
|
'governance.proposal.market.minVoterBalance',
|
||||||
'governance.proposal.updateAsset.minProposerBalance',
|
|
||||||
'governance.proposal.updateAsset.minVoterBalance',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const NetworkParameterRow = ({
|
export const NetworkParameterRow = ({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useExplorerOracleSpecsQuery } from '../__generated__/Oracles';
|
import { useExplorerOracleSpecsQuery } from '../__generated__/Oracles';
|
||||||
@@ -8,7 +8,7 @@ import { useScrollToLocation } from '../../../hooks/scroll-to-location';
|
|||||||
import filter from 'recursive-key-filter';
|
import filter from 'recursive-key-filter';
|
||||||
|
|
||||||
const Oracles = () => {
|
const Oracles = () => {
|
||||||
const { data, loading, error } = useExplorerOracleSpecsQuery();
|
const { data, loading } = useExplorerOracleSpecsQuery();
|
||||||
|
|
||||||
useDocumentTitle(['Oracles']);
|
useDocumentTitle(['Oracles']);
|
||||||
useScrollToLocation();
|
useScrollToLocation();
|
||||||
@@ -16,40 +16,28 @@ const Oracles = () => {
|
|||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<RouteTitle data-testid="oracle-specs-heading">{t('Oracles')}</RouteTitle>
|
<RouteTitle data-testid="oracle-specs-heading">{t('Oracles')}</RouteTitle>
|
||||||
<AsyncRenderer
|
{loading ? <Loader /> : null}
|
||||||
data={data}
|
{data?.oracleSpecsConnection?.edges
|
||||||
loading={loading}
|
? data.oracleSpecsConnection.edges.map((o) => {
|
||||||
error={error}
|
const id = o?.node.dataSourceSpec.spec.id;
|
||||||
loadingMessage={t('Loading oracle data...')}
|
if (!id) {
|
||||||
errorMessage={t('Oracle data could not be loaded')}
|
return null;
|
||||||
noDataMessage={t('No oracles found')}
|
}
|
||||||
noDataCondition={(data) =>
|
return (
|
||||||
!data?.oracleSpecsConnection?.edges ||
|
<div id={id} key={id} className="mb-10">
|
||||||
data.oracleSpecsConnection.edges?.length === 0
|
<OracleDetails
|
||||||
}
|
id={id}
|
||||||
>
|
dataSource={o?.node}
|
||||||
{data?.oracleSpecsConnection?.edges
|
showBroadcasts={false}
|
||||||
? data.oracleSpecsConnection.edges.map((o) => {
|
/>
|
||||||
const id = o?.node.dataSourceSpec.spec.id;
|
<details>
|
||||||
if (!id) {
|
<summary className="pointer">JSON</summary>
|
||||||
return null;
|
<SyntaxHighlighter data={filter(o, ['__typename'])} />
|
||||||
}
|
</details>
|
||||||
return (
|
</div>
|
||||||
<div id={id} key={id} className="mb-10">
|
);
|
||||||
<OracleDetails
|
})
|
||||||
id={id}
|
: null}
|
||||||
dataSource={o?.node}
|
|
||||||
showBroadcasts={false}
|
|
||||||
/>
|
|
||||||
<details>
|
|
||||||
<summary className="pointer">JSON</summary>
|
|
||||||
<SyntaxHighlighter data={filter(o, ['__typename'])} />
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
: null}
|
|
||||||
</AsyncRenderer>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
|
import { RenderFetched } from '../../../components/render-fetched';
|
||||||
import { truncateByChars } from '@vegaprotocol/utils';
|
import { truncateByChars } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useExplorerOracleSpecByIdQuery } from '../__generated__/Oracles';
|
import { useExplorerOracleSpecByIdQuery } from '../__generated__/Oracles';
|
||||||
import { OracleDetails } from '../components/oracle';
|
import { OracleDetails } from '../components/oracle';
|
||||||
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||||
import filter from 'recursive-key-filter';
|
import filter from 'recursive-key-filter';
|
||||||
import { TruncateInline } from '../../../components/truncate/truncate';
|
import { TruncateInline } from '../../../components/truncate/truncate';
|
||||||
|
|
||||||
@@ -26,14 +27,7 @@ export const Oracle = () => {
|
|||||||
{t(`Oracle `)}
|
{t(`Oracle `)}
|
||||||
<TruncateInline startChars={5} endChars={5} text={id || '1'} />
|
<TruncateInline startChars={5} endChars={5} text={id || '1'} />
|
||||||
</RouteTitle>
|
</RouteTitle>
|
||||||
<AsyncRenderer
|
<RenderFetched error={error} loading={loading}>
|
||||||
data={data}
|
|
||||||
error={error}
|
|
||||||
loading={loading}
|
|
||||||
noDataCondition={(data) => !data?.oracleSpec}
|
|
||||||
errorMessage={t('Could not load oracle data')}
|
|
||||||
loadingMessage={t('Loading oracle data...')}
|
|
||||||
>
|
|
||||||
{data?.oracleSpec ? (
|
{data?.oracleSpec ? (
|
||||||
<div id={id} key={id} className="mb-10">
|
<div id={id} key={id} className="mb-10">
|
||||||
<OracleDetails
|
<OracleDetails
|
||||||
@@ -50,7 +44,7 @@ export const Oracle = () => {
|
|||||||
) : (
|
) : (
|
||||||
<span></span>
|
<span></span>
|
||||||
)}
|
)}
|
||||||
</AsyncRenderer>
|
</RenderFetched>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,13 +48,6 @@ query ExplorerPartyAssets($partyId: ID!) {
|
|||||||
}
|
}
|
||||||
stakingSummary {
|
stakingSummary {
|
||||||
currentStakeAvailable
|
currentStakeAvailable
|
||||||
linkings(pagination: { first: 100 }) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
amount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
accountsConnection {
|
accountsConnection {
|
||||||
edges {
|
edges {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export type ExplorerPartyAssetsQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type ExplorerPartyAssetsQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string, linkings: { __typename?: 'StakesConnection', edges?: Array<{ __typename?: 'StakeLinkingEdge', node: { __typename?: 'StakeLinking', amount: string } } | null> | null } }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null } } | null> | null } | null } }> } | null };
|
export type ExplorerPartyAssetsQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null } } | null> | null } | null } }> } | null };
|
||||||
|
|
||||||
export const ExplorerPartyAssetsAccountsFragmentDoc = gql`
|
export const ExplorerPartyAssetsAccountsFragmentDoc = gql`
|
||||||
fragment ExplorerPartyAssetsAccounts on AccountBalance {
|
fragment ExplorerPartyAssetsAccounts on AccountBalance {
|
||||||
@@ -64,13 +64,6 @@ export const ExplorerPartyAssetsDocument = gql`
|
|||||||
}
|
}
|
||||||
stakingSummary {
|
stakingSummary {
|
||||||
currentStakeAvailable
|
currentStakeAvailable
|
||||||
linkings(pagination: {first: 100}) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
amount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
accountsConnection {
|
accountsConnection {
|
||||||
edges {
|
edges {
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import { useParams } from 'react-router-dom';
|
|
||||||
import { toNonHex } from '../../../../components/search/detect-search';
|
|
||||||
import { PageHeader } from '../../../../components/page-header';
|
|
||||||
import { useDocumentTitle } from '../../../../hooks/use-document-title';
|
|
||||||
|
|
||||||
import { PartyAccounts } from '../components/party-accounts';
|
|
||||||
|
|
||||||
const PartyAccountsByAsset = () => {
|
|
||||||
const { party } = useParams<{ party: string }>();
|
|
||||||
|
|
||||||
useDocumentTitle(['Public keys', party || '-']);
|
|
||||||
const partyId = toNonHex(party ? party : '');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<PageHeader title={t('Balances by asset')} />
|
|
||||||
|
|
||||||
<PartyAccounts partyId={partyId} />
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { PartyAccountsByAsset };
|
|
||||||
@@ -1,9 +1,32 @@
|
|||||||
import { AccountManager } from '@vegaprotocol/accounts';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useCallback } from 'react';
|
import get from 'lodash/get';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import AssetBalance from '../../../../components/asset-balance/asset-balance';
|
||||||
|
import { AssetLink, MarketLink } from '../../../../components/links';
|
||||||
|
import { Table, TableRow } from '../../../../components/table';
|
||||||
|
import type * as Schema from '@vegaprotocol/types';
|
||||||
|
import type { ExplorerPartyAssetsAccountsFragment } from '../__generated__/Party-assets';
|
||||||
|
|
||||||
|
const accountTypeString: Record<Schema.AccountType, string> = {
|
||||||
|
ACCOUNT_TYPE_BOND: t('Bond'),
|
||||||
|
ACCOUNT_TYPE_EXTERNAL: t('External'),
|
||||||
|
ACCOUNT_TYPE_FEES_INFRASTRUCTURE: t('Fees (Infrastructure)'),
|
||||||
|
ACCOUNT_TYPE_FEES_LIQUIDITY: t('Fees (Liquidity)'),
|
||||||
|
ACCOUNT_TYPE_FEES_MAKER: t('Fees (Maker)'),
|
||||||
|
ACCOUNT_TYPE_GENERAL: t('General'),
|
||||||
|
ACCOUNT_TYPE_GLOBAL_INSURANCE: t('Global Insurance Pool'),
|
||||||
|
ACCOUNT_TYPE_GLOBAL_REWARD: t('Global Reward Pool'),
|
||||||
|
ACCOUNT_TYPE_INSURANCE: t('Insurance'),
|
||||||
|
ACCOUNT_TYPE_MARGIN: t('Margin'),
|
||||||
|
ACCOUNT_TYPE_PENDING_TRANSFERS: t('Pending Transfers'),
|
||||||
|
ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: t('Reward - LP Fees received'),
|
||||||
|
ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES: t('Reward - Maker fees paid'),
|
||||||
|
ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES: t('Reward - Maker fees received'),
|
||||||
|
ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS: t('Reward - Market proposers'),
|
||||||
|
ACCOUNT_TYPE_SETTLEMENT: t('Settlement'),
|
||||||
|
};
|
||||||
|
|
||||||
interface PartyAccountsProps {
|
interface PartyAccountsProps {
|
||||||
partyId: string;
|
accounts: ExplorerPartyAssetsAccountsFragment[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,22 +34,49 @@ interface PartyAccountsProps {
|
|||||||
* probably do with sorting by asset, and then within asset, by type with general
|
* probably do with sorting by asset, and then within asset, by type with general
|
||||||
* appearing first and... tbd
|
* appearing first and... tbd
|
||||||
*/
|
*/
|
||||||
export const PartyAccounts = ({ partyId }: PartyAccountsProps) => {
|
export const PartyAccounts = ({ accounts }: PartyAccountsProps) => {
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
|
||||||
const onClickAsset = useCallback(
|
|
||||||
(assetId?: string) => {
|
|
||||||
assetId && openAssetDetailsDialog(assetId);
|
|
||||||
},
|
|
||||||
[openAssetDetailsDialog]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="block min-h-44 h-60 4 w-full border-red-800 relative">
|
<Table className="max-w-5xl min-w-fit">
|
||||||
<AccountManager
|
<thead>
|
||||||
partyId={partyId}
|
<TableRow modifier="bordered" className="font-mono">
|
||||||
onClickAsset={onClickAsset}
|
<td>{t('Type')}</td>
|
||||||
isReadOnly={true}
|
<td>{t('Market')}</td>
|
||||||
/>
|
<td className="text-right pr-2">{t('Balance')}</td>
|
||||||
</div>
|
<td>{t('Asset')}</td>
|
||||||
|
</TableRow>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{accounts.map((account) => {
|
||||||
|
const m = get(account, 'market.tradableInstrument.instrument.name');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow
|
||||||
|
key={`pa-${account.asset.id}-${account.type}`}
|
||||||
|
title={account.asset.name}
|
||||||
|
id={`${accountTypeString[account.type]} ${m ? ` - ${m}` : ''}`}
|
||||||
|
>
|
||||||
|
<td className="text-md">{accountTypeString[account.type]}</td>
|
||||||
|
<td className="text-md">
|
||||||
|
{account.market?.id ? (
|
||||||
|
<MarketLink id={account.market?.id} />
|
||||||
|
) : (
|
||||||
|
<p>-</p>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-md text-right pr-2">
|
||||||
|
<AssetBalance
|
||||||
|
assetId={account.asset.id}
|
||||||
|
price={account.balance}
|
||||||
|
showAssetLink={false}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td className="text-md">
|
||||||
|
<AssetLink assetId={account.asset.id} />
|
||||||
|
</td>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { Routes } from '../../../../routes/route-names';
|
|
||||||
import { Button, Icon, Loader } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { PartyBlock } from './party-block';
|
|
||||||
import type { AccountFields } from '@vegaprotocol/accounts';
|
|
||||||
|
|
||||||
export interface PartyBlockAccountProps {
|
|
||||||
partyId: string;
|
|
||||||
accountData: AccountFields[] | null;
|
|
||||||
accountLoading: boolean;
|
|
||||||
accountError?: Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays an overview of a party's assets. This uses existing data
|
|
||||||
* providers to structure the details by asset, rather than looking at
|
|
||||||
* it by account. The assumption is that this is a more natural way to
|
|
||||||
* get an idea of the assets and activity of a party.
|
|
||||||
*/
|
|
||||||
export const PartyBlockAccounts = ({
|
|
||||||
partyId,
|
|
||||||
accountData,
|
|
||||||
accountLoading,
|
|
||||||
accountError,
|
|
||||||
}: PartyBlockAccountProps) => {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const shouldShowActionButton =
|
|
||||||
accountData && accountData.length > 0 && !accountLoading && !accountError;
|
|
||||||
|
|
||||||
const action = shouldShowActionButton ? (
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
onClick={() => navigate(`/${Routes.PARTIES}/${partyId}/assets`)}
|
|
||||||
>
|
|
||||||
{t('Show all')}
|
|
||||||
</Button>
|
|
||||||
) : null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PartyBlock title={t('Assets')} action={action}>
|
|
||||||
{accountData && accountData.length > 0 ? (
|
|
||||||
<p>
|
|
||||||
{accountData.length} {t('assets, including')}{' '}
|
|
||||||
{accountData
|
|
||||||
.map((a) => a.asset.symbol)
|
|
||||||
.slice(0, 3)
|
|
||||||
.join(', ')}
|
|
||||||
</p>
|
|
||||||
) : accountLoading && !accountError ? (
|
|
||||||
<Loader size="small" />
|
|
||||||
) : accountData && accountData.length === 0 ? (
|
|
||||||
<p>{t('No accounts found')}</p>
|
|
||||||
) : (
|
|
||||||
<p>
|
|
||||||
<Icon className="mr-1" name="error" />
|
|
||||||
<span className="text-sm">{t('Could not load assets')}</span>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</PartyBlock>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import { useExplorerPartyAssetsQuery } from '../__generated__/Party-assets';
|
|
||||||
import GovernanceAssetBalance from '../../../../components/asset-balance/governance-asset-balance';
|
|
||||||
import {
|
|
||||||
Icon,
|
|
||||||
KeyValueTable,
|
|
||||||
KeyValueTableRow,
|
|
||||||
Loader,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { PartyBlock } from './party-block';
|
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
|
|
||||||
export interface PartyBlockStakeProps {
|
|
||||||
partyId: string;
|
|
||||||
accountLoading: boolean;
|
|
||||||
accountError?: Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays an overview of a single party's staking balance, importantly maintaining'
|
|
||||||
* the same height before and after the details are loaded in.
|
|
||||||
*
|
|
||||||
* Unlike PartyBlockAccounts there is not action button in the title of this block as
|
|
||||||
* there is no page for it to link to currently. That's a future task.
|
|
||||||
*/
|
|
||||||
export const PartyBlockStake = ({
|
|
||||||
partyId,
|
|
||||||
accountLoading,
|
|
||||||
accountError,
|
|
||||||
}: PartyBlockStakeProps) => {
|
|
||||||
const partyRes = useExplorerPartyAssetsQuery({
|
|
||||||
// Don't cache data for this query, party information can move quite quickly
|
|
||||||
fetchPolicy: 'network-only',
|
|
||||||
variables: { partyId: partyId },
|
|
||||||
skip: !partyId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const p = partyRes.data?.partiesConnection?.edges[0].node;
|
|
||||||
|
|
||||||
const linkedLength = p?.stakingSummary?.linkings?.edges?.length;
|
|
||||||
const linkedStake =
|
|
||||||
linkedLength && linkedLength > 0
|
|
||||||
? p?.stakingSummary?.linkings?.edges
|
|
||||||
?.reduce((total, e) => {
|
|
||||||
return new BigNumber(total).plus(
|
|
||||||
new BigNumber(e?.node.amount || 0)
|
|
||||||
);
|
|
||||||
}, new BigNumber(0))
|
|
||||||
.toString()
|
|
||||||
: '0';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PartyBlock title={t('Staking')}>
|
|
||||||
{p?.stakingSummary.currentStakeAvailable ? (
|
|
||||||
<KeyValueTable>
|
|
||||||
<KeyValueTableRow noBorder={true}>
|
|
||||||
<div>{t('Available stake')}</div>
|
|
||||||
<div>
|
|
||||||
<GovernanceAssetBalance
|
|
||||||
price={p.stakingSummary.currentStakeAvailable}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
<KeyValueTableRow noBorder={true}>
|
|
||||||
<div>{t('Active stake')}</div>
|
|
||||||
<div>
|
|
||||||
<GovernanceAssetBalance price={linkedStake || '0'} />
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
</KeyValueTable>
|
|
||||||
) : accountLoading && !accountError ? (
|
|
||||||
<Loader size="small" />
|
|
||||||
) : !accountError ? (
|
|
||||||
<p>{t('No staking balance')}</p>
|
|
||||||
) : (
|
|
||||||
<p>
|
|
||||||
<Icon className="mr-1" name="error" />
|
|
||||||
<span className="text-sm">{t('Could not load stake details')}</span>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</PartyBlock>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import type { ReactNode } from 'react';
|
|
||||||
|
|
||||||
export interface PartyBlockProps {
|
|
||||||
children: ReactNode;
|
|
||||||
title: string;
|
|
||||||
action?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PartyBlock({ children, title, action }: PartyBlockProps) {
|
|
||||||
return (
|
|
||||||
<div className="border-2 min-h-[138px] border-solid border-vega-light-100 dark:border-vega-dark-200 p-5 mt-5">
|
|
||||||
<div
|
|
||||||
className="flex flex-col md:flex-row gap-1 justify-between content-start mb-2"
|
|
||||||
data-testid="page-title"
|
|
||||||
>
|
|
||||||
<h3 className="font-semibold text-lg">{title}</h3>
|
|
||||||
|
|
||||||
{action ? action : null}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,26 +1,24 @@
|
|||||||
|
import { getNodes } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { SubHeading } from '../../../components/sub-heading';
|
import { SubHeading } from '../../../components/sub-heading';
|
||||||
|
import { Panel } from '../../../components/panel';
|
||||||
import { toNonHex } from '../../../components/search/detect-search';
|
import { toNonHex } from '../../../components/search/detect-search';
|
||||||
import { useTxsData } from '../../../hooks/use-txs-data';
|
import { useTxsData } from '../../../hooks/use-txs-data';
|
||||||
import { TxsInfiniteList } from '../../../components/txs';
|
import { TxsInfiniteList } from '../../../components/txs';
|
||||||
import { PageHeader } from '../../../components/page-header';
|
import { PageHeader } from '../../../components/page-header';
|
||||||
|
import { useExplorerPartyAssetsQuery } from './__generated__/Party-assets';
|
||||||
|
import type { ExplorerPartyAssetsAccountsFragment } from './__generated__/Party-assets';
|
||||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||||
import { Icon, Intent, Notification, Splash } from '@vegaprotocol/ui-toolkit';
|
import GovernanceAssetBalance from '../../../components/asset-balance/governance-asset-balance';
|
||||||
import { aggregatedAccountsDataProvider } from '@vegaprotocol/accounts';
|
import { PartyAccounts } from './components/party-accounts';
|
||||||
import { PartyBlockStake } from './components/party-block-stake';
|
|
||||||
import { PartyBlockAccounts } from './components/party-block-accounts';
|
|
||||||
import { isValidPartyId } from './components/party-id-error';
|
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
|
||||||
|
|
||||||
const Party = () => {
|
const Party = () => {
|
||||||
const { party } = useParams<{ party: string }>();
|
const { party } = useParams<{ party: string }>();
|
||||||
|
|
||||||
useDocumentTitle(['Public keys', party || '-']);
|
useDocumentTitle(['Public keys', party || '-']);
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const partyId = toNonHex(party ? party : '');
|
const partyId = toNonHex(party ? party : '');
|
||||||
const { isMobile } = useScreenDimensions();
|
const { isMobile } = useScreenDimensions();
|
||||||
const visibleChars = useMemo(() => (isMobile ? 10 : 14), [isMobile]);
|
const visibleChars = useMemo(() => (isMobile ? 10 : 14), [isMobile]);
|
||||||
@@ -30,72 +28,71 @@ const Party = () => {
|
|||||||
filters,
|
filters,
|
||||||
});
|
});
|
||||||
|
|
||||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
const partyRes = useExplorerPartyAssetsQuery({
|
||||||
const {
|
// Don't cache data for this query, party information can move quite quickly
|
||||||
data: AccountData,
|
fetchPolicy: 'network-only',
|
||||||
loading: AccountLoading,
|
variables: { partyId: partyId },
|
||||||
error: AccountError,
|
skip: !party,
|
||||||
} = useDataProvider({
|
|
||||||
dataProvider: aggregatedAccountsDataProvider,
|
|
||||||
variables,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isValidPartyId(partyId)) {
|
const p = partyRes.data?.partiesConnection?.edges[0].node;
|
||||||
return (
|
|
||||||
<div className="max-w-sm mx-auto">
|
const header = p?.id ? (
|
||||||
<Notification
|
<PageHeader
|
||||||
message={t('Invalid party ID')}
|
title={p.id}
|
||||||
intent={Intent.Danger}
|
copy
|
||||||
buttonProps={{
|
truncateStart={visibleChars}
|
||||||
text: t('Go back'),
|
truncateEnd={visibleChars}
|
||||||
action: () => navigate(-1),
|
/>
|
||||||
className: 'py-1',
|
) : (
|
||||||
size: 'sm',
|
<Panel>
|
||||||
}}
|
<p>No data found for public key {party}</p>
|
||||||
/>
|
</Panel>
|
||||||
</div>
|
);
|
||||||
);
|
|
||||||
}
|
const staking = (
|
||||||
|
<section>
|
||||||
|
{p?.stakingSummary?.currentStakeAvailable ? (
|
||||||
|
<div className="mt-4 leading-3">
|
||||||
|
<strong className="font-semibold">{t('Staking Balance: ')}</strong>
|
||||||
|
<GovernanceAssetBalance
|
||||||
|
price={p.stakingSummary.currentStakeAvailable}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
const accounts = getNodes<ExplorerPartyAssetsAccountsFragment>(
|
||||||
|
p?.accountsConnection
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<PageHeader
|
<h1
|
||||||
title={partyId}
|
className="font-alpha calt uppercase font-xl mb-4 text-vega-dark-100 dark:text-vega-light-100"
|
||||||
copy
|
data-testid="parties-header"
|
||||||
truncateStart={visibleChars}
|
>
|
||||||
truncateEnd={visibleChars}
|
{t('Public key')}
|
||||||
/>
|
</h1>
|
||||||
|
{partyRes.data ? (
|
||||||
|
<>
|
||||||
|
{header}
|
||||||
|
<SubHeading>{t('Asset data')}</SubHeading>
|
||||||
|
{accounts ? <PartyAccounts accounts={accounts} /> : null}
|
||||||
|
{staking}
|
||||||
|
|
||||||
<div className="grid md:grid-flow-col grid-flow-row md:space-x-4 grid-cols-1 md:grid-cols-2 w-full">
|
<SubHeading>{t('Transactions')}</SubHeading>
|
||||||
<PartyBlockAccounts
|
<TxsInfiniteList
|
||||||
accountError={AccountError}
|
hasMoreTxs={hasMoreTxs}
|
||||||
accountLoading={AccountLoading}
|
areTxsLoading={loading}
|
||||||
accountData={AccountData}
|
txs={txsData}
|
||||||
partyId={partyId}
|
loadMoreTxs={loadTxs}
|
||||||
/>
|
error={error}
|
||||||
<PartyBlockStake
|
className="mb-28"
|
||||||
accountError={AccountError}
|
/>
|
||||||
accountLoading={AccountLoading}
|
</>
|
||||||
partyId={partyId}
|
) : null}
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<SubHeading>{t('Transactions')}</SubHeading>
|
|
||||||
{!error && txsData ? (
|
|
||||||
<TxsInfiniteList
|
|
||||||
hasMoreTxs={hasMoreTxs}
|
|
||||||
areTxsLoading={loading}
|
|
||||||
txs={txsData}
|
|
||||||
loadMoreTxs={loadTxs}
|
|
||||||
error={error}
|
|
||||||
className="mb-28"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Splash>
|
|
||||||
<Icon name="error" className="mr-1" />
|
|
||||||
{t('Could not load transaction list for party')}
|
|
||||||
</Splash>
|
|
||||||
)}
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import { Outlet } from 'react-router-dom';
|
|
||||||
|
|
||||||
const PartiesSubPage = () => {
|
|
||||||
return <Outlet />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PartiesSubPage;
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DATA_SOURCES } from '../../config';
|
||||||
|
import type { TendermintUnconfirmedTransactionsResponse } from '../txs/tendermint-unconfirmed-transactions-response.d';
|
||||||
|
import { TxList } from '../../components/txs';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
|
|
||||||
|
const PendingTxs = () => {
|
||||||
|
const {
|
||||||
|
state: { data: unconfirmedTransactions },
|
||||||
|
} = useFetch<TendermintUnconfirmedTransactionsResponse>(
|
||||||
|
`${DATA_SOURCES.tendermintUrl}/unconfirmed_txs`
|
||||||
|
);
|
||||||
|
|
||||||
|
useDocumentTitle(['Pending transactions']);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<RouteTitle data-testid="unconfirmed-transactions-header">
|
||||||
|
{t('Unconfirmed transactions')}
|
||||||
|
</RouteTitle>
|
||||||
|
<br />
|
||||||
|
<div>{t(`Number: ${unconfirmedTransactions?.result?.n_txs || 0}`)}</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
<TxList data={unconfirmedTransactions} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { PendingTxs };
|
||||||
@@ -14,6 +14,7 @@ import { Block } from './blocks/id';
|
|||||||
import { Blocks } from './blocks/home';
|
import { Blocks } from './blocks/home';
|
||||||
import { Tx } from './txs/id';
|
import { Tx } from './txs/id';
|
||||||
import { TxsList } from './txs/home';
|
import { TxsList } from './txs/home';
|
||||||
|
import { PendingTxs } from './pending';
|
||||||
import flags from '../config/flags';
|
import flags from '../config/flags';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Routes } from './route-names';
|
import { Routes } from './route-names';
|
||||||
@@ -28,7 +29,6 @@ import compact from 'lodash/compact';
|
|||||||
import { AssetLink, MarketLink } from '../components/links';
|
import { AssetLink, MarketLink } from '../components/links';
|
||||||
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||||
import { remove0x } from '@vegaprotocol/utils';
|
import { remove0x } from '@vegaprotocol/utils';
|
||||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
|
||||||
|
|
||||||
export type Navigable = {
|
export type Navigable = {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -75,43 +75,14 @@ const partiesRoutes: Route[] = flags.parties
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':party',
|
path: ':party',
|
||||||
element: <Party />,
|
element: <PartySingle />,
|
||||||
|
handle: {
|
||||||
children: [
|
breadcrumb: (params: Params<string>) => (
|
||||||
{
|
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
||||||
index: true,
|
{truncateMiddle(params.party as string)}
|
||||||
element: <PartySingle />,
|
</Link>
|
||||||
handle: {
|
),
|
||||||
breadcrumb: (params: Params<string>) => (
|
},
|
||||||
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
|
||||||
{truncateMiddle(params.party as string)}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'assets',
|
|
||||||
element: <Party />,
|
|
||||||
handle: {
|
|
||||||
breadcrumb: (params: Params<string>) => (
|
|
||||||
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
|
||||||
{truncateMiddle(params.party as string)}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <PartyAccountsByAsset />,
|
|
||||||
handle: {
|
|
||||||
breadcrumb: () => {
|
|
||||||
return t('Assets');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -266,6 +237,17 @@ export const routerConfig: Route[] = [
|
|||||||
breadcrumb: () => <Link to={Routes.TX}>{t('Transactions')}</Link>,
|
breadcrumb: () => <Link to={Routes.TX}>{t('Transactions')}</Link>,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: 'pending',
|
||||||
|
element: <PendingTxs />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: () => (
|
||||||
|
<Link to={linkTo(Routes.TX, 'pending')}>
|
||||||
|
{t('Pending transactions')}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: ':txHash',
|
path: ':txHash',
|
||||||
element: <Tx />,
|
element: <Tx />,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface TxDetailsProps {
|
|||||||
|
|
||||||
export const txDetailsTruncateLength = 30;
|
export const txDetailsTruncateLength = 30;
|
||||||
|
|
||||||
export const TxDetails = ({ txData, pubKey }: TxDetailsProps) => {
|
export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
|
||||||
if (!txData) {
|
if (!txData) {
|
||||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { NodeStatus, NodeStatusMapping } from '@vegaprotocol/types';
|
import { NodeStatus, NodeStatusMapping } from '@vegaprotocol/types';
|
||||||
import { PartyLink } from '../../components/links';
|
|
||||||
|
|
||||||
type RateProps = {
|
type RateProps = {
|
||||||
value: BigNumber | number | undefined;
|
value: BigNumber | number | undefined;
|
||||||
@@ -192,9 +191,7 @@ export const ValidatorsPage = () => {
|
|||||||
<KeyValueTable>
|
<KeyValueTable>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<div>{t('ID')}</div>
|
<div>{t('ID')}</div>
|
||||||
<div className="break-all text-xs font-mono">
|
<div className="break-all text-xs">{v.id}</div>
|
||||||
{v.id}
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<div>{t('Status')}</div>
|
<div>{t('Status')}</div>
|
||||||
@@ -221,14 +218,12 @@ export const ValidatorsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<div>{t('Key')}</div>
|
<div>{t('Public key')}</div>
|
||||||
<div className="break-all text-xs">
|
<div className="break-all text-xs">{v.pubkey}</div>
|
||||||
<PartyLink id={v.pubkey} />
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<div>{t('Ethereum address')}</div>
|
<div>{t('Ethereum address')}</div>
|
||||||
<div className="break-all text-xs font-mono">
|
<div className="break-all text-xs">
|
||||||
<EtherscanLink address={v.ethereumAddress} />{' '}
|
<EtherscanLink address={v.ethereumAddress} />{' '}
|
||||||
<CopyWithTooltip text={v.ethereumAddress}>
|
<CopyWithTooltip text={v.ethereumAddress}>
|
||||||
<button title={t('Copy address to clipboard')}>
|
<button title={t('Copy address to clipboard')}>
|
||||||
@@ -239,9 +234,7 @@ export const ValidatorsPage = () => {
|
|||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<div>{t('Tendermint public key')}</div>
|
<div>{t('Tendermint public key')}</div>
|
||||||
<div className="break-all text-xs font-mono">
|
<div className="break-all text-xs">{v.tmPubkey}</div>
|
||||||
{v.tmPubkey}
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
|
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
@import 'ag-grid-community/dist/styles/ag-grid.css';
|
|
||||||
@import 'ag-grid-community/dist/styles/ag-theme-balham.css';
|
|
||||||
@import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
|
|
||||||
|
|
||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@@ -15,50 +11,3 @@
|
|||||||
.react-markdown-container a:before {
|
.react-markdown-container a:before {
|
||||||
content: '🔗 ';
|
content: '🔗 ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AG GRID - Do not edit without updating other global stylesheets for each app */
|
|
||||||
|
|
||||||
.vega-ag-grid .ag-root-wrapper {
|
|
||||||
border: solid 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vega-ag-grid .ag-react-container {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vega-ag-grid .ag-cell,
|
|
||||||
.vega-ag-grid .ag-full-width-row .ag-cell-wrapper.ag-row-group {
|
|
||||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vega-ag-grid .ag-row,
|
|
||||||
.vega-ag-grid .ag-cell {
|
|
||||||
border-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Light variables */
|
|
||||||
.ag-theme-balham {
|
|
||||||
--ag-background-color: theme(colors.white);
|
|
||||||
--ag-border-color: theme(colors.neutral[300]);
|
|
||||||
--ag-header-background-color: theme(colors.white);
|
|
||||||
--ag-odd-row-background-color: theme(colors.white);
|
|
||||||
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
|
||||||
--ag-row-border-color: theme(colors.white);
|
|
||||||
--ag-row-hover-color: theme(colors.neutral[100]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark variables */
|
|
||||||
.ag-theme-balham-dark {
|
|
||||||
--ag-background-color: theme(colors.black);
|
|
||||||
--ag-border-color: theme(colors.neutral[700]);
|
|
||||||
--ag-header-background-color: theme(colors.black);
|
|
||||||
--ag-odd-row-background-color: theme(colors.black);
|
|
||||||
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
|
||||||
--ag-row-border-color: theme(colors.black);
|
|
||||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
|
||||||
}
|
|
||||||
|
|
||||||
.voteicon svg {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,23 +5,20 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|||||||
NX_FAIRGROUND=false
|
NX_FAIRGROUND=false
|
||||||
NX_VEGA_NETWORKS={}
|
NX_VEGA_NETWORKS={}
|
||||||
|
|
||||||
NX_VEGA_URL=http://localhost:3008/graphql
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_ETHEREUM_CHAIN_ID=1440
|
NX_ETHEREUM_CHAIN_ID=1440
|
||||||
NX_ETH_URL_CONNECT=1
|
NX_ETH_URL_CONNECT=1
|
||||||
NX_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
NX_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||||
NX_LOCAL_PROVIDER_URL=http://localhost:8545/
|
NX_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet3-k8s.ops.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
|
||||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
|
||||||
|
|
||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
CYPRESS_VEGA_URL=http://localhost:3008/graphql
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||||
@@ -31,6 +28,7 @@ CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
|||||||
CYPRESS_VEGA_ENV=CUSTOM
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
||||||
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
|
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
|
||||||
CYPRESS_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
NX_VEGA_URL=https://api.vega.xyz/query
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# App configuration variables
|
||||||
|
NX_VEGA_ENV=STAGNET3
|
||||||
|
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
reporter: '../../node_modules/cypress-mochawesome-reporter',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
require('cypress-mochawesome-reporter/plugin')(on);
|
|
||||||
require('@cypress/grep/src/plugin')(config);
|
require('@cypress/grep/src/plugin')(config);
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
@@ -26,7 +25,6 @@ module.exports = defineConfig({
|
|||||||
viewportWidth: 1440,
|
viewportWidth: 1440,
|
||||||
viewportHeight: 900,
|
viewportHeight: 900,
|
||||||
numTestsKeptInMemory: 5,
|
numTestsKeptInMemory: 5,
|
||||||
testIsolation: false,
|
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
ethProviderUrl: 'http://localhost:8545/',
|
ethProviderUrl: 'http://localhost:8545/',
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
export const upgradeProposalsData = {
|
|
||||||
lastBlockHeight: '2014133',
|
|
||||||
protocolUpgradeProposals: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
upgradeBlockHeight: '2015942',
|
|
||||||
vegaReleaseTag: 'v1',
|
|
||||||
approvers: [
|
|
||||||
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
|
||||||
'121934387281812a2d5e6913e5d57c0f85a8f169e2752347ee2e23b52d46623c',
|
|
||||||
'65c80e2f5f84e2109eec30810f137ba04cbbecaba8f27706c146cc6c6f90db29',
|
|
||||||
'bd6339d2428c79ac3bc9011771236d17bac92bcb1806423388d52fb440043aef',
|
|
||||||
],
|
|
||||||
status: 'PROTOCOL_UPGRADE_PROPOSAL_STATUS_APPROVED',
|
|
||||||
__typename: 'ProtocolUpgradeProposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProtocolUpgradeProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
upgradeBlockHeight: '1955065',
|
|
||||||
vegaReleaseTag: 'v0.71.0+dev-12156-bca1d57e',
|
|
||||||
approvers: [
|
|
||||||
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
|
||||||
'121934387281812a2d5e6913e5d57c0f85a8f169e2752347ee2e23b52d46623c',
|
|
||||||
'65c80e2f5f84e2109eec30810f137ba04cbbecaba8f27706c146cc6c6f90db29',
|
|
||||||
'bd6339d2428c79ac3bc9011771236d17bac92bcb1806423388d52fb440043aef',
|
|
||||||
],
|
|
||||||
status: 'PROTOCOL_UPGRADE_PROPOSAL_STATUS_APPROVED',
|
|
||||||
__typename: 'ProtocolUpgradeProposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProtocolUpgradeProposalEdge',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'ProtocolUpgradeProposalConnection',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
export const nodeData = {
|
|
||||||
epoch: {
|
|
||||||
id: '204731',
|
|
||||||
timestamps: {
|
|
||||||
start: '2023-04-14T09:30:09.452005Z',
|
|
||||||
end: null,
|
|
||||||
expiry: '2023-04-14T09:31:09.452005Z',
|
|
||||||
__typename: 'EpochTimestamps',
|
|
||||||
},
|
|
||||||
__typename: 'Epoch',
|
|
||||||
},
|
|
||||||
nodesConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
avatarUrl:
|
|
||||||
'https://www.gravatar.com/avatar/y2hwc4xjds7zvlam3y4in94q2rcdimsn?d=identicon',
|
|
||||||
id: 'f337b5cc50c49a928e49129a2eca62277a81b4b7336b6e4131f8f0431e8db029',
|
|
||||||
name: 'lovely-fisherman',
|
|
||||||
pubkey:
|
|
||||||
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
|
||||||
stakedByOperator: '3000000000000000000000',
|
|
||||||
stakedByDelegates: '0',
|
|
||||||
stakedTotal: '3000000000000000000000',
|
|
||||||
pendingStake: '0',
|
|
||||||
rankingScore: {
|
|
||||||
rankingScore: '0.4999166805532412',
|
|
||||||
stakeScore: '0.2499583402766206',
|
|
||||||
performanceScore: '1',
|
|
||||||
votingPower: '2499',
|
|
||||||
status: 'VALIDATOR_NODE_STATUS_TENDERMINT',
|
|
||||||
__typename: 'RankingScore',
|
|
||||||
},
|
|
||||||
__typename: 'Node',
|
|
||||||
},
|
|
||||||
__typename: 'NodeEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
avatarUrl:
|
|
||||||
'https://www.gravatar.com/avatar/g1tw70qnoo0tf8ror30jefwhae92zy16?d=identicon',
|
|
||||||
id: 'cdadcf885556e372b6b39679d6ad46854d1d9c1e982da7ff2929544df01f9088',
|
|
||||||
name: 'magnificent-door',
|
|
||||||
pubkey:
|
|
||||||
'121934387281812a2d5e6913e5d57c0f85a8f169e2752347ee2e23b52d46623c',
|
|
||||||
stakedByOperator: '3000000000000000000000',
|
|
||||||
stakedByDelegates: '0',
|
|
||||||
stakedTotal: '3000000000000000000000',
|
|
||||||
pendingStake: '0',
|
|
||||||
rankingScore: {
|
|
||||||
rankingScore: '0.4999166805532412',
|
|
||||||
stakeScore: '0.2499583402766206',
|
|
||||||
performanceScore: '1',
|
|
||||||
votingPower: '2499',
|
|
||||||
status: 'VALIDATOR_NODE_STATUS_TENDERMINT',
|
|
||||||
__typename: 'RankingScore',
|
|
||||||
},
|
|
||||||
__typename: 'Node',
|
|
||||||
},
|
|
||||||
__typename: 'NodeEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
avatarUrl:
|
|
||||||
'https://www.gravatar.com/avatar/s2e7hp7soq5zdhxeap7p21onetsjiy6w?d=identicon',
|
|
||||||
id: '9a13de2548fef30d928e71e76004c98ec7ad9d8fc3ddcd16ddee210b28ea4cfc',
|
|
||||||
name: 'helpful-tree',
|
|
||||||
pubkey:
|
|
||||||
'bd6339d2428c79ac3bc9011771236d17bac92bcb1806423388d52fb440043aef',
|
|
||||||
stakedByOperator: '3000000000000000000000',
|
|
||||||
stakedByDelegates: '2000000000000000000',
|
|
||||||
stakedTotal: '3002000000000000000000',
|
|
||||||
pendingStake: '0',
|
|
||||||
rankingScore: {
|
|
||||||
rankingScore: '0.5002499583402766',
|
|
||||||
stakeScore: '0.2501249791701383',
|
|
||||||
performanceScore: '1',
|
|
||||||
votingPower: '2501',
|
|
||||||
status: 'VALIDATOR_NODE_STATUS_TENDERMINT',
|
|
||||||
__typename: 'RankingScore',
|
|
||||||
},
|
|
||||||
__typename: 'Node',
|
|
||||||
},
|
|
||||||
__typename: 'NodeEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
avatarUrl:
|
|
||||||
'https://www.gravatar.com/avatar/3gop683kg2cvd8rpv286hzagqt3yjsdq?d=identicon',
|
|
||||||
id: '93ac271ab95038333587e47d11461e6edc0126e6e77156281c545f4c5650a6d0',
|
|
||||||
name: 'easy-cookie',
|
|
||||||
pubkey:
|
|
||||||
'65c80e2f5f84e2109eec30810f137ba04cbbecaba8f27706c146cc6c6f90db29',
|
|
||||||
stakedByOperator: '3000000000000000000000',
|
|
||||||
stakedByDelegates: '0',
|
|
||||||
stakedTotal: '3000000000000000000000',
|
|
||||||
pendingStake: '0',
|
|
||||||
rankingScore: {
|
|
||||||
rankingScore: '0.4999166805532412',
|
|
||||||
stakeScore: '0.2499583402766206',
|
|
||||||
performanceScore: '1',
|
|
||||||
votingPower: '2499',
|
|
||||||
status: 'VALIDATOR_NODE_STATUS_TENDERMINT',
|
|
||||||
__typename: 'RankingScore',
|
|
||||||
},
|
|
||||||
__typename: 'Node',
|
|
||||||
},
|
|
||||||
__typename: 'NodeEdge',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'NodesConnection',
|
|
||||||
},
|
|
||||||
nodeData: {
|
|
||||||
stakedTotal: '12002000000000000000000',
|
|
||||||
__typename: 'NodeData',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,325 +0,0 @@
|
|||||||
export const proposalsData = {
|
|
||||||
proposalsConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'e8ba9d268e12514644fd1fc7ff289292f4ce6489cc32cc73133aea52c04aef89',
|
|
||||||
rationale: {
|
|
||||||
title: 'Add asset Wrapped Ether',
|
|
||||||
description: 'Proposal to add asset WETH to Vega network',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: '',
|
|
||||||
state: 'STATE_OPEN',
|
|
||||||
datetime: '2026-12-01T11:41:28.654288Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2026-12-01T11:45:33Z',
|
|
||||||
enactmentDatetime: '2026-12-01T11:45:43Z',
|
|
||||||
change: {
|
|
||||||
name: 'Wrapped Ether',
|
|
||||||
symbol: 'WETH',
|
|
||||||
decimals: 18,
|
|
||||||
quantum: '0.0008',
|
|
||||||
source: {
|
|
||||||
contractAddress: '0x9B18C6CaD886D5653783E2B25759124760F4407F',
|
|
||||||
withdrawThreshold: '1',
|
|
||||||
lifetimeLimit: '400000000000000000',
|
|
||||||
__typename: 'ERC20',
|
|
||||||
},
|
|
||||||
__typename: 'NewAsset',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'd848fc7881f13d366df5f61ab139d5fcfa72bf838151bb51b54381870e357931',
|
|
||||||
rationale: {
|
|
||||||
title: 'Add asset Dai Stablecoin',
|
|
||||||
description: 'Proposal to add asset DAI to Vega network',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: '',
|
|
||||||
state: 'STATE_ENACTED',
|
|
||||||
datetime: '2022-11-29T15:49:57.80978Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2023-04-13T15:52:58Z',
|
|
||||||
enactmentDatetime: '2023-04-13T15:53:08Z',
|
|
||||||
change: {
|
|
||||||
name: 'Dai Stablecoin',
|
|
||||||
symbol: 'DAI',
|
|
||||||
decimals: 18,
|
|
||||||
quantum: '1',
|
|
||||||
source: {
|
|
||||||
contractAddress: '0xad018fB8ec00bfd622B91C83E684a6AC7bB8fbA4',
|
|
||||||
withdrawThreshold: '1',
|
|
||||||
lifetimeLimit: '500000000000000000000',
|
|
||||||
__typename: 'ERC20',
|
|
||||||
},
|
|
||||||
__typename: 'NewAsset',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'ccbd651b4a1167fd73c4a0340ac759fa0a31ca487ad46a13254b741ad71947ed',
|
|
||||||
rationale: {
|
|
||||||
title: 'New DAI market',
|
|
||||||
description: 'New DAI market',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: '0VFQusmmESdrP5GuL8naB6lxfoE3RPGaEeo7abdN',
|
|
||||||
state: 'STATE_ENACTED',
|
|
||||||
datetime: '2022-11-26T19:36:19.26034Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2022-11-26T19:36:42Z',
|
|
||||||
enactmentDatetime: '2023-03-22T13:57:37Z',
|
|
||||||
change: {
|
|
||||||
instrument: {
|
|
||||||
name: 'UNIDAI Monthly (Dec 2022)',
|
|
||||||
code: 'UNIDAI.MF21',
|
|
||||||
futureProduct: {
|
|
||||||
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
|
|
||||||
__typename: 'FutureProduct',
|
|
||||||
},
|
|
||||||
__typename: 'InstrumentConfiguration',
|
|
||||||
},
|
|
||||||
__typename: 'NewMarket',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'bc70383f0e9515b15542cf4c63590cd2ca46b3363ba7c4a72af0e62112b3951b',
|
|
||||||
rationale: {
|
|
||||||
title: 'USDC-III',
|
|
||||||
description: 'USDC-III D List test',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: '',
|
|
||||||
state: 'STATE_ENACTED',
|
|
||||||
datetime: '2022-11-22T15:17:28.829605Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2022-11-22T15:18:56Z',
|
|
||||||
enactmentDatetime: '2022-11-22T15:19:06Z',
|
|
||||||
change: {
|
|
||||||
name: 'USDC-III',
|
|
||||||
symbol: 'USDC-III',
|
|
||||||
decimals: 18,
|
|
||||||
quantum: '1',
|
|
||||||
source: {
|
|
||||||
contractAddress: '0x1F1A067aEC530b66BA5128C9Db76825eC22c3C6b',
|
|
||||||
withdrawThreshold: '100000000000000000000000000',
|
|
||||||
lifetimeLimit: '1000000000000000000000000000',
|
|
||||||
__typename: 'ERC20',
|
|
||||||
},
|
|
||||||
__typename: 'NewAsset',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: '9d9b2a9d0179d0e4ccb317f6c4a5db0b905d893190bfb5e5499985ef313281c8',
|
|
||||||
rationale: {
|
|
||||||
title: 'New BTC market',
|
|
||||||
description: 'New BTC market',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: 'AXeRWS3TvLBFDgWOSHQpKFJf3NTbnWK6310q02fZ',
|
|
||||||
state: 'STATE_ENACTED',
|
|
||||||
datetime: '2022-11-26T19:36:19.26034Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2022-11-26T19:36:42Z',
|
|
||||||
enactmentDatetime: '2023-03-22T13:57:37Z',
|
|
||||||
change: {
|
|
||||||
instrument: {
|
|
||||||
name: 'ETHBTC Quarterly (Feb 2023)',
|
|
||||||
code: 'ETHBTC.QM21',
|
|
||||||
futureProduct: {
|
|
||||||
settlementAsset: { symbol: 'tBTC', __typename: 'Asset' },
|
|
||||||
__typename: 'FutureProduct',
|
|
||||||
},
|
|
||||||
__typename: 'InstrumentConfiguration',
|
|
||||||
},
|
|
||||||
__typename: 'NewMarket',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: '9c48796e7988769ededc2b2b02220b00e93f65f23e8141bf1fd23a6983d95943',
|
|
||||||
rationale: {
|
|
||||||
title: 'Update governance.proposal.asset.requiredMajority',
|
|
||||||
description:
|
|
||||||
'Proposal to update governance.proposal.asset.requiredMajority to 300}',
|
|
||||||
__typename: 'ProposalRationale',
|
|
||||||
},
|
|
||||||
reference: '',
|
|
||||||
state: 'STATE_ENACTED',
|
|
||||||
datetime: '2022-11-22T13:22:52.370655Z',
|
|
||||||
rejectionReason: null,
|
|
||||||
party: {
|
|
||||||
id: '69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f',
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
errorDetails: null,
|
|
||||||
terms: {
|
|
||||||
closingDatetime: '2022-11-22T13:27:13Z',
|
|
||||||
enactmentDatetime: '2022-11-22T13:27:33Z',
|
|
||||||
change: {
|
|
||||||
networkParameter: {
|
|
||||||
key: 'governance.proposal.asset.requiredParticipation',
|
|
||||||
value: '0.000001',
|
|
||||||
__typename: 'NetworkParameter',
|
|
||||||
},
|
|
||||||
__typename: 'UpdateNetworkParameter',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalTerms',
|
|
||||||
},
|
|
||||||
votes: {
|
|
||||||
yes: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
no: {
|
|
||||||
totalTokens: '0',
|
|
||||||
totalNumber: '0',
|
|
||||||
totalEquityLikeShareWeight: '0',
|
|
||||||
__typename: 'ProposalVoteSide',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalVotes',
|
|
||||||
},
|
|
||||||
__typename: 'Proposal',
|
|
||||||
},
|
|
||||||
__typename: 'ProposalEdge',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'ProposalsConnection',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
{
|
|
||||||
"rationale": {
|
|
||||||
"title": "New Market Proposal E2E submission",
|
|
||||||
"description": "E2E new market proposal"
|
|
||||||
},
|
|
||||||
"terms": {
|
|
||||||
"newMarket": {
|
|
||||||
"changes": {
|
|
||||||
"decimalPlaces": "5",
|
|
||||||
"positionDecimalPlaces": "5",
|
|
||||||
"linearSlippageFactor": "0.001",
|
|
||||||
"quadraticSlippageFactor": "0",
|
|
||||||
"lpPriceRange": "10",
|
|
||||||
"instrument": {
|
|
||||||
"name": "Token test market",
|
|
||||||
"code": "TEST.24h",
|
|
||||||
"future": {
|
|
||||||
"settlementAsset": "73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0",
|
|
||||||
"quoteName": "fBTC",
|
|
||||||
"dataSourceSpecForSettlementData": {
|
|
||||||
"external": {
|
|
||||||
"oracle": {
|
|
||||||
"signers": [
|
|
||||||
{
|
|
||||||
"pubKey": {
|
|
||||||
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"name": "prices.ETH.value",
|
|
||||||
"type": "TYPE_INTEGER",
|
|
||||||
"numberDecimalPlaces": "0"
|
|
||||||
},
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"operator": "OPERATOR_GREATER_THAN",
|
|
||||||
"value": "0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dataSourceSpecForTradingTermination": {
|
|
||||||
"external": {
|
|
||||||
"oracle": {
|
|
||||||
"signers": [
|
|
||||||
{
|
|
||||||
"pubKey": {
|
|
||||||
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"name": "trading.terminated.ETH5",
|
|
||||||
"type": "TYPE_BOOLEAN"
|
|
||||||
},
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"operator": "OPERATOR_EQUALS",
|
|
||||||
"value": "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dataSourceSpecBinding": {
|
|
||||||
"settlementDataProperty": "prices.ETH.value",
|
|
||||||
"tradingTerminationProperty": "trading.terminated.ETH5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": ["sector:energy", "sector:tech", "source:docs.vega.xyz"],
|
|
||||||
"priceMonitoringParameters": {
|
|
||||||
"triggers": [
|
|
||||||
{
|
|
||||||
"horizon": "43200",
|
|
||||||
"probability": "0.9999999",
|
|
||||||
"auctionExtension": "600"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"liquidityMonitoringParameters": {
|
|
||||||
"targetStakeParameters": {
|
|
||||||
"timeWindow": "3600",
|
|
||||||
"scalingFactor": 10
|
|
||||||
},
|
|
||||||
"triggeringRatio": "0.7",
|
|
||||||
"auctionExtension": "1"
|
|
||||||
},
|
|
||||||
"logNormal": {
|
|
||||||
"tau": 0.0001140771161,
|
|
||||||
"riskAversionParameter": 0.01,
|
|
||||||
"params": {
|
|
||||||
"mu": 0,
|
|
||||||
"r": 0.016,
|
|
||||||
"sigma": 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"closingTimestamp": 0,
|
|
||||||
"enactmentTimestamp": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"name": "Token test market",
|
"name": "Token test market",
|
||||||
"code": "Token.24h",
|
"code": "Token.24h",
|
||||||
"future": {
|
"future": {
|
||||||
"settlementAsset": "73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0",
|
"settlementAsset": "fBTC",
|
||||||
"quoteName": "fBTC",
|
"quoteName": "fBTC",
|
||||||
"dataSourceSpecForSettlementData": {
|
"dataSourceSpecForSettlementData": {
|
||||||
"external": {
|
"external": {
|
||||||
|
|||||||
@@ -2,23 +2,27 @@ import {
|
|||||||
navigateTo,
|
navigateTo,
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
|
convertUnixTimestampToDateformat,
|
||||||
createRawProposal,
|
createRawProposal,
|
||||||
createTenDigitUnixTimeStampForSpecifiedDays,
|
createTenDigitUnixTimeStampForSpecifiedDays,
|
||||||
|
enterUniqueFreeFormProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getDateFormatForSpecifiedDays,
|
getGovernanceProposalDateFormatForSpecifiedDays,
|
||||||
getProposalFromTitle,
|
getProposalIdFromList,
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
submitUniqueRawProposal,
|
getSubmittedProposalFromProposalList,
|
||||||
|
goToMakeNewProposal,
|
||||||
|
governanceProposalType,
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
|
waitForProposalSubmitted,
|
||||||
|
waitForProposalSync,
|
||||||
} from '../../../../governance-e2e/src/support/governance.functions';
|
} from '../../../../governance-e2e/src/support/governance.functions';
|
||||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../../../governance-e2e/src/support/staking.functions';
|
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../../../governance-e2e/src/support/staking.functions';
|
||||||
import { ethereumWalletConnect } from '../../../../governance-e2e/src/support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../../../governance-e2e/src/support/wallet-eth.functions';
|
||||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../../../governance-e2e/src/support/wallet-teardown.functions';
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../../../governance-e2e/src/support/wallet-teardown.functions';
|
||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import type { testFreeformProposal } from '../../support/common-interfaces';
|
||||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
|
||||||
|
|
||||||
const proposalVoteProgressForPercentage =
|
const proposalVoteProgressForPercentage =
|
||||||
'[data-testid="vote-progress-indicator-percentage-for"]';
|
'[data-testid="vote-progress-indicator-percentage-for"]';
|
||||||
@@ -33,8 +37,6 @@ const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
|||||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const voteBreakdownToggle = 'vote-breakdown-toggle';
|
|
||||||
const proposalTermsToggle = 'proposal-terms-toggle';
|
|
||||||
|
|
||||||
describe(
|
describe(
|
||||||
'Governance flow for proposal details',
|
'Governance flow for proposal details',
|
||||||
@@ -47,8 +49,6 @@ describe(
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit proposals tab', function () {
|
beforeEach('visit proposals tab', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -59,25 +59,23 @@ describe(
|
|||||||
|
|
||||||
// 3001-VOTE-050 3001-VOTE-054 3001-VOTE-055 3002-PROP-019
|
// 3001-VOTE-050 3001-VOTE-054 3001-VOTE-055 3002-PROP-019
|
||||||
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
||||||
const proposalDescription =
|
|
||||||
'I propose that everyone evaluate the following IPFS document and vote Yes if they agree. bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si';
|
|
||||||
|
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
cy.get(openProposals).within(() => {
|
getProposalIdFromList(rawProposal.rationale.title);
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
cy.get(viewProposalButton).should('be.visible').click();
|
cy.get(openProposals).within(() => {
|
||||||
|
cy.get(`#${proposalId}`).within(() => {
|
||||||
|
cy.get(viewProposalButton).should('be.visible').click();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.get(proposalDetailsTitle).should(
|
cy.get(proposalDetailsTitle)
|
||||||
'contain.text',
|
.should('contain', rawProposal.rationale.title)
|
||||||
rawProposal.rationale.title
|
.and('be.visible');
|
||||||
);
|
|
||||||
cy.get(proposalDetailsDescription)
|
cy.get(proposalDetailsDescription)
|
||||||
.find('p')
|
.should('contain', rawProposal.rationale.description)
|
||||||
.should('have.text', proposalDescription);
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
cy.getByTestId(proposalTermsToggle).click();
|
|
||||||
// 3001-VOTE-052
|
// 3001-VOTE-052
|
||||||
cy.get('code.language-json')
|
cy.get('code.language-json')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
@@ -88,37 +86,32 @@ describe(
|
|||||||
|
|
||||||
// 3001-VOTE-043
|
// 3001-VOTE-043
|
||||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||||
|
const closingVoteHrs = '72';
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
const proposalTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
const proposalTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
||||||
// const currentDate = new Date(createTenDigitUnixTimeStampForSpecifiedDays(0) * 1000)
|
|
||||||
// const proposedDate = new Date(currentDate.getTime() + 60000)
|
|
||||||
|
|
||||||
submitUniqueRawProposal({
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
proposalTitle: proposalTitle,
|
enterUniqueFreeFormProposalBody(closingVoteHrs, proposalTitle);
|
||||||
closingTimestamp: proposalTimeStamp,
|
waitForProposalSubmitted();
|
||||||
});
|
waitForProposalSync();
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() =>
|
getSubmittedProposalFromProposalList(proposalTitle).within(() =>
|
||||||
cy.get(viewProposalButton).click()
|
cy.get(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.wrap(
|
convertUnixTimestampToDateformat(proposalTimeStamp).then(
|
||||||
formatDateWithLocalTimezone(new Date(proposalTimeStamp * 1000))
|
(closingDate) => {
|
||||||
).then((closingDate) => {
|
getProposalInformationFromTable('Closes on')
|
||||||
getProposalInformationFromTable('Closes on').should(
|
.contains(closingDate)
|
||||||
'have.text',
|
.should('be.visible');
|
||||||
closingDate
|
}
|
||||||
);
|
);
|
||||||
});
|
getGovernanceProposalDateFormatForSpecifiedDays(0).then(
|
||||||
cy.wrap(
|
(proposalDate) => {
|
||||||
formatDateWithLocalTimezone(
|
getProposalInformationFromTable('Proposed on')
|
||||||
new Date(createTenDigitUnixTimeStampForSpecifiedDays(0) * 1000)
|
.contains(proposalDate)
|
||||||
)
|
.should('be.visible');
|
||||||
).then((proposalDate) => {
|
}
|
||||||
getProposalInformationFromTable('Proposed on').should(
|
);
|
||||||
'have.text',
|
|
||||||
proposalDate
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposal details - shows default status set to fail', function () {
|
it('Newly created proposal details - shows default status set to fail', function () {
|
||||||
@@ -127,14 +120,13 @@ describe(
|
|||||||
// 3001-VOTE-067
|
// 3001-VOTE-067
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
||||||
'be.visible'
|
'be.visible'
|
||||||
);
|
);
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
getProposalInformationFromTable('Expected to pass')
|
||||||
.contains('👎')
|
.contains('👎')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
@@ -154,24 +146,26 @@ describe(
|
|||||||
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
// 3001-VOTE-080
|
// 3001-VOTE-080
|
||||||
cy.getByTestId('vote-buttons').contains('against').should('be.visible');
|
cy.getByTestId('vote-buttons').contains('against').should('be.visible');
|
||||||
cy.getByTestId('vote-buttons').contains('for').should('be.visible');
|
cy.getByTestId('vote-buttons').contains('for').should('be.visible');
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
getDateFormatForSpecifiedDays(0).then((votedDate) => {
|
getGovernanceProposalDateFormatForSpecifiedDays(0, 'shortMonth').then(
|
||||||
// 3001-VOTE-051
|
(votedDate) => {
|
||||||
// 3001-VOTE-093
|
// 3001-VOTE-051
|
||||||
cy.contains('You voted:')
|
// 3001-VOTE-093
|
||||||
.siblings()
|
cy.contains('You voted:')
|
||||||
.contains('For')
|
.siblings()
|
||||||
.siblings()
|
.contains('For')
|
||||||
.contains(votedDate)
|
.siblings()
|
||||||
.should('be.visible');
|
.contains(votedDate)
|
||||||
});
|
.should('be.visible');
|
||||||
|
}
|
||||||
|
);
|
||||||
cy.get(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
cy.get(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
||||||
.contains('100.00%')
|
.contains('100.00%')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -182,7 +176,6 @@ describe(
|
|||||||
cy.get(proposalVoteProgressAgainstTokens)
|
cy.get(proposalVoteProgressAgainstTokens)
|
||||||
.contains('0.00')
|
.contains('0.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
getProposalInformationFromTable('Tokens for proposal')
|
||||||
.should('have.text', (1).toFixed(2))
|
.should('have.text', (1).toFixed(2))
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -224,15 +217,14 @@ describe(
|
|||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(rawProposal.rationale.title)
|
||||||
cy.get(viewProposalButton).click()
|
.as('submittedProposal')
|
||||||
);
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
// 3001-VOTE-079
|
// 3001-VOTE-079
|
||||||
cy.contains('You voted: For').should('be.visible');
|
cy.contains('You voted: For').should('be.visible');
|
||||||
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Total Supply')
|
getProposalInformationFromTable('Total Supply')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((totalSupply) => {
|
.then((totalSupply) => {
|
||||||
@@ -240,15 +232,14 @@ describe(
|
|||||||
(Number(totalSupply.replace(/,/g, '')) * 0.001) /
|
(Number(totalSupply.replace(/,/g, '')) * 0.001) /
|
||||||
100
|
100
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
ethereumWalletConnect();
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated(
|
ensureSpecifiedUnstakedTokensAreAssociated(
|
||||||
tokensRequiredToAchieveResult
|
tokensRequiredToAchieveResult
|
||||||
);
|
);
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(rawProposal.rationale.title)
|
||||||
cy.get(viewProposalButton).click()
|
.as('submittedProposal')
|
||||||
);
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalVoteProgressForPercentage)
|
cy.get(proposalVoteProgressForPercentage)
|
||||||
.contains('100.00%')
|
.contains('100.00%')
|
||||||
@@ -265,7 +256,6 @@ describe(
|
|||||||
cy.get(proposalVoteProgressAgainstTokens)
|
cy.get(proposalVoteProgressAgainstTokens)
|
||||||
.contains('0.00')
|
.contains('0.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Total tokens voted percentage')
|
getProposalInformationFromTable('Total tokens voted percentage')
|
||||||
.should('have.text', '0.00%')
|
.should('have.text', '0.00%')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import {
|
import {
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
@@ -17,7 +16,6 @@ import {
|
|||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
|
||||||
const closedProposals = '[data-testid="closed-proposals"]';
|
const closedProposals = '[data-testid="closed-proposals"]';
|
||||||
const proposalStatus = '[data-testid="proposal-status"]';
|
const proposalStatus = '[data-testid="proposal-status"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
@@ -37,8 +35,6 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit proposals', function () {
|
beforeEach('visit proposals', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -55,15 +51,16 @@ context(
|
|||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.get(closedProposals).within(() => {
|
cy.get(closedProposals).within(() => {
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
.last()
|
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(proposalStatus).should('have.text', 'Enacted');
|
cy.get(proposalStatus).should('have.text', 'Enacted ');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
||||||
cy.get(proposalStatus).should('have.text', 'Enacted');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted')
|
||||||
|
.and('be.visible');
|
||||||
cy.get(votesTable).within(() => {
|
cy.get(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
@@ -81,14 +78,19 @@ context(
|
|||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.get(openProposals).within(() => {
|
cy.get(openProposals).within(() => {
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
.last()
|
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Passed');
|
getProposalInformationFromTable('State') // 3001-VOTE-047
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Enacted');
|
.contains('Passed', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
cy.get(votesTable).within(() => {
|
cy.get(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
@@ -109,13 +111,16 @@ context(
|
|||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.get(openProposals, { timeout: 6000 }).within(() => {
|
cy.get(openProposals, { timeout: 6000 }).within(() => {
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
.last()
|
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Enacted');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-048 3001-VOTE-049 3001-VOTE-050
|
// 3001-VOTE-048 3001-VOTE-049 3001-VOTE-050
|
||||||
@@ -128,12 +133,15 @@ context(
|
|||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.get(openProposals).within(() => {
|
cy.get(openProposals).within(() => {
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
.last()
|
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Declined');
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('State') // 3001-VOTE-047
|
||||||
|
.contains('Declined', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
getProposalInformationFromTable('Rejection reason')
|
getProposalInformationFromTable('Rejection reason')
|
||||||
.contains('PROPOSAL_ERROR_PARTICIPATION_THRESHOLD_NOT_REACHED')
|
.contains('PROPOSAL_ERROR_PARTICIPATION_THRESHOLD_NOT_REACHED')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import {
|
|||||||
enterRawProposalBody,
|
enterRawProposalBody,
|
||||||
enterUniqueFreeFormProposalBody,
|
enterUniqueFreeFormProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getProposalFromTitle,
|
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
|
getSubmittedProposalFromProposalList,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
governanceProposalType,
|
||||||
submitUniqueRawProposal,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
waitForProposalSubmitted,
|
waitForProposalSubmitted,
|
||||||
waitForProposalSync,
|
waitForProposalSync,
|
||||||
@@ -21,7 +20,6 @@ import {
|
|||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
closeDialog,
|
closeDialog,
|
||||||
turnTelemetryOff,
|
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
clickOnValidatorFromList,
|
clickOnValidatorFromList,
|
||||||
@@ -82,11 +80,10 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
|
cy.associateTokensToVegaWallet('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit governance tab', function () {
|
beforeEach('visit governance tab', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -95,8 +92,7 @@ context(
|
|||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test can only pass if run before other proposal tests.
|
it('Should be able to see that no proposals exist', function () {
|
||||||
it.skip('Should be able to see that no proposals exist', function () {
|
|
||||||
// 3001-VOTE-003
|
// 3001-VOTE-003
|
||||||
cy.get(noOpenProposals)
|
cy.get(noOpenProposals)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
@@ -108,7 +104,7 @@ context(
|
|||||||
|
|
||||||
// 3002-PROP-002
|
// 3002-PROP-002
|
||||||
// 3002-PROP-003
|
// 3002-PROP-003
|
||||||
it('Proposal form - shows how many vega tokens are required to make a proposal', function () {
|
it('Submit a proposal form - shows how many vega tokens are required to make a proposal', function () {
|
||||||
// 3002-PROP-005
|
// 3002-PROP-005
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||||
cy.contains(
|
cy.contains(
|
||||||
@@ -116,9 +112,8 @@ context(
|
|||||||
).should('be.visible');
|
).should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Skipping as currently unable to propose using forms other than raw
|
|
||||||
// 3002-PROP-011
|
// 3002-PROP-011
|
||||||
it.skip('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
||||||
cy.get(maxVoteButton).should('be.visible');
|
cy.get(maxVoteButton).should('be.visible');
|
||||||
@@ -142,13 +137,16 @@ context(
|
|||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
|
|
||||||
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
||||||
createRawProposal();
|
|
||||||
|
navigateTo(navigation.proposals);
|
||||||
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
|
enterUniqueFreeFormProposalBody('50', generateFreeFormProposalTitle());
|
||||||
|
waitForProposalSubmitted();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
it('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
enterUniqueFreeFormProposalBody('0.1', generateFreeFormProposalTitle());
|
enterUniqueFreeFormProposalBody('0.1', generateFreeFormProposalTitle());
|
||||||
|
|
||||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||||
'not.exist'
|
'not.exist'
|
||||||
);
|
);
|
||||||
@@ -157,7 +155,7 @@ context(
|
|||||||
.should('equal', 'Value must be greater than or equal to 1.');
|
.should('equal', 'Value must be greater than or equal to 1.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
it('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
enterUniqueFreeFormProposalBody(
|
enterUniqueFreeFormProposalBody(
|
||||||
'100000',
|
'100000',
|
||||||
@@ -184,13 +182,17 @@ context(
|
|||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get(rejectProposalsLink).click();
|
cy.get(rejectProposalsLink).click();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getSubmittedProposalFromProposalList(
|
||||||
|
rawProposal.rationale.title
|
||||||
|
).within(() => {
|
||||||
cy.contains('Rejected').should('be.visible');
|
cy.contains('Rejected').should('be.visible');
|
||||||
cy.contains('Close time too late').should('be.visible');
|
cy.contains('Close time too late').should('be.visible');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.getByTestId('proposal-status').should('have.text', 'Rejected');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Rejected')
|
||||||
|
.and('be.visible');
|
||||||
getProposalInformationFromTable('Rejection reason')
|
getProposalInformationFromTable('Rejection reason')
|
||||||
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -285,19 +287,18 @@ context(
|
|||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
ethereumWalletConnect();
|
enterUniqueFreeFormProposalBody('50', proposalTitle);
|
||||||
|
waitForProposalSubmitted();
|
||||||
stakingPageDisassociateTokens('0.0001');
|
stakingPageDisassociateTokens('0.0001');
|
||||||
cy.get(vegaWallet)
|
cy.get(vegaWallet).within(() => {
|
||||||
.first()
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
.within(() => {
|
'contain',
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
'0.9999'
|
||||||
'contain',
|
);
|
||||||
'0.9999'
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() =>
|
getSubmittedProposalFromProposalList(proposalTitle).within(() =>
|
||||||
cy.get(viewProposalButton).click()
|
cy.get(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.contains('Vote breakdown').should('be.visible', {
|
cy.contains('Vote breakdown').should('be.visible', {
|
||||||
@@ -315,9 +316,9 @@ context(
|
|||||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||||
cy.get('[data-testid="disconnect"]').click();
|
cy.get('[data-testid="disconnect"]').click();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
// 3001-VOTE-075
|
// 3001-VOTE-075
|
||||||
// 3001-VOTE-076
|
// 3001-VOTE-076
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ import {
|
|||||||
closeDialog,
|
closeDialog,
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
waitForProposalSubmitted,
|
waitForProposalSubmitted,
|
||||||
} from '../../support/governance.functions';
|
} from '../../support/governance.functions';
|
||||||
@@ -52,13 +50,21 @@ const liquidityVoteStatus = 'liquidity-votes-status';
|
|||||||
const tokenVoteStatus = 'token-votes-status';
|
const tokenVoteStatus = 'token-votes-status';
|
||||||
const proposalTermsSection = 'proposal';
|
const proposalTermsSection = 'proposal';
|
||||||
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
||||||
const fUSDCId =
|
|
||||||
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
|
|
||||||
const epochTimeout = Cypress.env('epochTimeout');
|
const epochTimeout = Cypress.env('epochTimeout');
|
||||||
const proposalTimeout = { timeout: 14000 };
|
const proposalTimeout = { timeout: 14000 };
|
||||||
|
|
||||||
|
const governanceProposalType = {
|
||||||
|
NETWORK_PARAMETER: 'Network parameter',
|
||||||
|
NEW_MARKET: 'New market',
|
||||||
|
UPDATE_MARKET: 'Update market',
|
||||||
|
NEW_ASSET: 'New asset',
|
||||||
|
UPDATE_ASSET: 'Update asset',
|
||||||
|
FREEFORM: 'Freeform',
|
||||||
|
RAW: 'raw proposal',
|
||||||
|
};
|
||||||
|
|
||||||
// 3001-VOTE-007
|
// 3001-VOTE-007
|
||||||
context.skip(
|
context(
|
||||||
'Governance flow - form validations for different governance proposals',
|
'Governance flow - form validations for different governance proposals',
|
||||||
{ tags: '@slow' },
|
{ tags: '@slow' },
|
||||||
function () {
|
function () {
|
||||||
@@ -68,8 +74,6 @@ context.skip(
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit governance tab', function () {
|
beforeEach('visit governance tab', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -260,7 +264,7 @@ context.skip(
|
|||||||
it('Unable to submit update market proposal without minimum amount of tokens', function () {
|
it('Unable to submit update market proposal without minimum amount of tokens', function () {
|
||||||
vegaWalletTeardown();
|
vegaWalletTeardown();
|
||||||
vegaWalletFaucetAssetsWithoutCheck(
|
vegaWalletFaucetAssetsWithoutCheck(
|
||||||
fUSDCId,
|
'fUSDC',
|
||||||
'1000000',
|
'1000000',
|
||||||
vegaWalletPublicKey
|
vegaWalletPublicKey
|
||||||
);
|
);
|
||||||
@@ -286,7 +290,7 @@ context.skip(
|
|||||||
// 3001-VOTE-092 3004-PMAC-001
|
// 3001-VOTE-092 3004-PMAC-001
|
||||||
it('Able to submit update market proposal and vote for proposal', function () {
|
it('Able to submit update market proposal and vote for proposal', function () {
|
||||||
vegaWalletFaucetAssetsWithoutCheck(
|
vegaWalletFaucetAssetsWithoutCheck(
|
||||||
fUSDCId,
|
'fUSDC',
|
||||||
'1000000',
|
'1000000',
|
||||||
vegaWalletPublicKey
|
vegaWalletPublicKey
|
||||||
);
|
);
|
||||||
@@ -298,10 +302,7 @@ context.skip(
|
|||||||
cy.get('dd').eq(0).should('have.text', 'Test market 1');
|
cy.get('dd').eq(0).should('have.text', 'Test market 1');
|
||||||
cy.get('dd').eq(1).should('have.text', 'TEST.24h');
|
cy.get('dd').eq(1).should('have.text', 'TEST.24h');
|
||||||
cy.get('dd').eq(2).should('not.be.empty');
|
cy.get('dd').eq(2).should('not.be.empty');
|
||||||
cy.get('dd')
|
cy.get('dd').eq(2).invoke('text').as('EnactedMarketId');
|
||||||
.eq(2)
|
|
||||||
.invoke('text')
|
|
||||||
.as('EnactedMarketId', { type: 'static' });
|
|
||||||
});
|
});
|
||||||
cy.get('@EnactedMarketId').then((marketId) => {
|
cy.get('@EnactedMarketId').then((marketId) => {
|
||||||
cy.VegaWalletSubmitLiquidityProvision(String(marketId), '1');
|
cy.VegaWalletSubmitLiquidityProvision(String(marketId), '1');
|
||||||
@@ -319,7 +320,6 @@ context.skip(
|
|||||||
cy.get('@EnactedMarketId').then((marketId) => {
|
cy.get('@EnactedMarketId').then((marketId) => {
|
||||||
cy.contains(String(marketId))
|
cy.contains(String(marketId))
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
});
|
});
|
||||||
@@ -373,19 +373,16 @@ context.skip(
|
|||||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
// cannot submit a proposal with ERC20 address already in use
|
// cannot submit a proposal with ERC20 address already in use
|
||||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||||
cy.getByTestId('dialog-content')
|
cy.getByTestId('dialog-content').within(() => {
|
||||||
.last()
|
cy.get('p').should(
|
||||||
.within(() => {
|
'have.text',
|
||||||
cy.get('p').should(
|
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
||||||
'have.text',
|
);
|
||||||
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
closeDialog();
|
closeDialog();
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
});
|
});
|
||||||
@@ -423,7 +420,6 @@ context.skip(
|
|||||||
cy.get(proposalType)
|
cy.get(proposalType)
|
||||||
.contains('Update asset')
|
.contains('Update asset')
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import type { testFreeformProposal } from '../../support/common-interfaces';
|
|||||||
import {
|
import {
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
|
createFreeformProposal,
|
||||||
createRawProposal,
|
createRawProposal,
|
||||||
createTenDigitUnixTimeStampForSpecifiedDays,
|
createTenDigitUnixTimeStampForSpecifiedDays,
|
||||||
enterRawProposalBody,
|
enterRawProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getProposalFromTitle,
|
getProposalIdFromList,
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
|
getSubmittedProposalFromProposalList,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
governanceProposalType,
|
||||||
submitUniqueRawProposal,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
waitForProposalSubmitted,
|
waitForProposalSubmitted,
|
||||||
waitForProposalSync,
|
waitForProposalSync,
|
||||||
@@ -23,14 +23,10 @@ import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/stakin
|
|||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const proposalListItem = 'proposals-list-item';
|
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
const voteStatus = 'vote-status';
|
const voteStatus = '[data-testid="vote-status"]';
|
||||||
const proposalType = 'proposal-type';
|
|
||||||
const proposalStatus = 'proposal-status';
|
|
||||||
const proposalClosingDate = '[data-testid="vote-details"]';
|
const proposalClosingDate = '[data-testid="vote-details"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const voteBreakDownToggle = 'vote-breakdown-toggle';
|
|
||||||
|
|
||||||
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||||
before('connect wallets and set approval limit', function () {
|
before('connect wallets and set approval limit', function () {
|
||||||
@@ -39,8 +35,6 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit proposals tab', function () {
|
beforeEach('visit proposals tab', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -63,12 +57,9 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get(openProposals).within(() => {
|
cy.get(openProposals).within(() => {
|
||||||
cy.get(proposalClosingDate)
|
cy.get(proposalClosingDate).first().should('contain.text', 'year');
|
||||||
.first()
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', /days|minutes/);
|
|
||||||
cy.get(proposalClosingDate).should('contain.text', 'months');
|
cy.get(proposalClosingDate).should('contain.text', 'months');
|
||||||
cy.get(proposalClosingDate).last().should('contain.text', 'year');
|
cy.get(proposalClosingDate).last().should('contain.text', 'days');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,27 +67,36 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
const proposerId = Cypress.env('vegaWalletPublicKey');
|
const proposerId = Cypress.env('vegaWalletPublicKey');
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
createFreeformProposal(proposalTitle);
|
||||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
getProposalIdFromList(proposalTitle);
|
||||||
cy.get('[data-testid="filter-input"]').type(proposerId);
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
// cy.get(`#${proposalId}`).should('contain', proposalId);
|
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||||
cy.contains(proposalTitle).should('be.visible');
|
cy.get('[data-testid="filter-input"]').type(proposerId);
|
||||||
cy.get('[data-testid="filter-input"]').type('123');
|
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||||
cy.getByTestId(proposalListItem).should('not.exist');
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposals list - shows title and portion of summary', function () {
|
it('Newly created proposals list - shows title and portion of summary', function () {
|
||||||
const proposalPath = '/proposals/new-market-raw.json';
|
createRawProposal(this.minProposerBalance); // 3001-VOTE-052
|
||||||
const enactmentTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
submitUniqueRawProposal({
|
getProposalIdFromList(rawProposal.rationale.title);
|
||||||
proposalBody: proposalPath,
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
enactmentTimestamp: enactmentTimestamp,
|
cy.get(openProposals).within(() => {
|
||||||
}); // 3001-VOTE-052
|
// 3001-VOTE-008
|
||||||
// 3001-VOTE-008
|
// 3001-VOTE-034
|
||||||
// 3001-VOTE-034
|
cy.get(`#${proposalId}`)
|
||||||
// 3001-VOTE-097
|
// 3001-VOTE-097
|
||||||
cy.contains('New Market Proposal E2E submission');
|
.should('contain', rawProposal.rationale.title)
|
||||||
cy.contains('Code: TEST.24h. fBTC settled future.').should('be.visible');
|
.and('be.visible');
|
||||||
|
cy.get(`#${proposalId}`)
|
||||||
|
.should(
|
||||||
|
'contain',
|
||||||
|
rawProposal.rationale.description.substring(0, 59)
|
||||||
|
)
|
||||||
|
.and('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposals list - shows open proposals in an open state', function () {
|
it('Newly created proposals list - shows open proposals in an open state', function () {
|
||||||
@@ -104,11 +104,23 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
// 3001-VOTE-035
|
// 3001-VOTE-035
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getSubmittedProposalFromProposalList(rawProposal.rationale.title).within(
|
||||||
cy.get(viewProposalButton).should('be.visible');
|
() => {
|
||||||
cy.getByTestId(proposalType).should('have.text', 'Freeform');
|
cy.get(viewProposalButton).should('be.visible').click();
|
||||||
cy.getByTestId(proposalStatus).should('have.text', 'Open');
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
|
getProposalInformationFromTable('ID')
|
||||||
|
.contains(String(proposalId))
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('Type')
|
||||||
|
.contains('Freeform')
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -116,22 +128,18 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
createFreeformProposal(proposalTitle);
|
||||||
getProposalFromTitle(proposalTitle).within(() => {
|
getSubmittedProposalFromProposalList(proposalTitle).within(() => {
|
||||||
// 3001-VOTE-039
|
// 3001-VOTE-039
|
||||||
cy.getByTestId(voteStatus).should(
|
cy.get(voteStatus).should('have.text', 'Participation not reached');
|
||||||
'have.text',
|
|
||||||
'Participation not reached'
|
|
||||||
);
|
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() => {
|
getSubmittedProposalFromProposalList(proposalTitle).within(() => {
|
||||||
cy.getByTestId(voteStatus).should('have.text', 'Set to pass');
|
cy.get(voteStatus).should('have.text', 'Set to pass');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
cy.getByTestId(voteBreakDownToggle).click();
|
|
||||||
getProposalInformationFromTable('Token participation met')
|
getProposalInformationFromTable('Token participation met')
|
||||||
.contains('👍')
|
.contains('👍')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
@@ -26,11 +25,9 @@ const rewardsTimeOut = { timeout: 60000 };
|
|||||||
|
|
||||||
context('rewards - flow', { tags: '@slow' }, function () {
|
context('rewards - flow', { tags: '@slow' }, function () {
|
||||||
before('set up environment to allow rewards', function () {
|
before('set up environment to allow rewards', function () {
|
||||||
cy.clearLocalStorage();
|
|
||||||
turnTelemetryOff();
|
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
depositAsset(vegaAssetAddress, '1000', 18);
|
depositAsset(vegaAssetAddress, '1000');
|
||||||
cy.validatorsSelfDelegate();
|
cy.validatorsSelfDelegate();
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -59,7 +56,7 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
|||||||
cy.getByTestId(rewardsTable)
|
cy.getByTestId(rewardsTable)
|
||||||
.first()
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId('asset', rewardsTimeOut).should('have.text', 'Vega');
|
cy.getByTestId('asset').should('have.text', 'Vega');
|
||||||
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD').should('have.text', '1');
|
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD').should('have.text', '1');
|
||||||
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE').should(
|
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
@@ -96,13 +93,13 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
|||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get('h2').first().should('contain.text', 'EPOCH');
|
cy.get('h2').first().should('contain.text', 'EPOCH');
|
||||||
cy.getByTestId('individual-rewards-asset').should('have.text', 'Vega');
|
cy.getByTestId('individual-rewards-asset').should('have.text', 'Vega');
|
||||||
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD', rewardsTimeOut)
|
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD')
|
||||||
.should('contain.text', '0.4415')
|
.should('contain.text', '0.1177')
|
||||||
.and('contain.text', '(44.15%)');
|
.and('contain.text', '(11.7733%)');
|
||||||
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE')
|
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE')
|
||||||
.should('contain.text', '0.0004')
|
.should('contain.text', '0.0001')
|
||||||
.and('contain.text', '(44.15%)');
|
.and('contain.text', '(11.7733%)');
|
||||||
cy.getByTestId('total').should('have.text', '0.4419');
|
cy.getByTestId('total').should('have.text', '0.1179');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user