Compare commits
96
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc622012e1 | ||
|
|
283f654a4c | ||
|
|
6945514b49 | ||
|
|
f74687d30c | ||
|
|
2a7574bd8e | ||
|
|
872f1d300f | ||
|
|
60ca6c2eb6 | ||
|
|
eeff4ffcd4 | ||
|
|
73ae00f12c | ||
|
|
8b249e1917 | ||
|
|
abb771e2f9 | ||
|
|
acf1d50d0f | ||
|
|
30da1663eb | ||
|
|
79cbe62774 | ||
|
|
2f0be0bf34 | ||
|
|
5b5802104e | ||
|
|
ff2e2574f6 | ||
|
|
478cc9e753 | ||
|
|
e2a72cb395 | ||
|
|
7fe269fad6 | ||
|
|
b761023069 | ||
|
|
7ac3a68ac9 | ||
|
|
2640ccb20a | ||
|
|
d78de10855 | ||
|
|
bb402c02f6 | ||
|
|
8a9b1c7874 | ||
|
|
a7e8b0eb01 | ||
|
|
89b3c06107 | ||
|
|
cd5c73d3fd | ||
|
|
b3a5ab022d | ||
|
|
496d1f5c68 | ||
|
|
e914e7bb70 | ||
|
|
71a36c2382 | ||
|
|
1c6a307bcd | ||
|
|
ef4a740b91 | ||
|
|
2d4be5fcb3 | ||
|
|
835f2b793f | ||
|
|
d50b988b4a | ||
|
|
a6aec899c8 | ||
|
|
8b19572dc9 | ||
|
|
80399d04f7 | ||
|
|
8322fc7edd | ||
|
|
46752816ec | ||
|
|
f99f78780c | ||
|
|
f7037bca80 | ||
|
|
ba39720f05 | ||
|
|
6d35f2b39d | ||
|
|
78afecc2e5 | ||
|
|
3de5b07495 | ||
|
|
e944d3e37c | ||
|
|
5596392835 | ||
|
|
5c57106c04 | ||
|
|
2fc688f477 | ||
|
|
9ea8c839db | ||
|
|
d7e2da7a54 | ||
|
|
b29c268257 | ||
|
|
01ca05a313 | ||
|
|
e3c6dd41c9 | ||
|
|
fbd01dc1bd | ||
|
|
af6719cc9d | ||
|
|
c433a4ee06 | ||
|
|
e3a00ada05 | ||
|
|
aa38e0c001 | ||
|
|
86da521da5 | ||
|
|
c6df34fe95 | ||
|
|
c7d0803164 | ||
|
|
250a654544 | ||
|
|
7f5e8ebb15 | ||
|
|
ccbe34e172 | ||
|
|
27e8ce88bf | ||
|
|
41804d9869 | ||
|
|
293288286b | ||
|
|
a77765b1e9 | ||
|
|
2453d7841a | ||
|
|
a0945be721 | ||
|
|
84e40ccb2b | ||
|
|
a868f6d2f5 | ||
|
|
8b83c51014 | ||
|
|
bf7aacf984 | ||
|
|
5183f2591b | ||
|
|
b3308439bd | ||
|
|
719d210219 | ||
|
|
f810a3a0b1 | ||
|
|
db19ee80ac | ||
|
|
45623f33c5 | ||
|
|
08e204fe31 | ||
|
|
81f7b0595e | ||
|
|
4ed0e3a056 | ||
|
|
47a84b4dac | ||
|
|
c540d4b17f | ||
|
|
f1fa3250a4 | ||
|
|
707c00def2 | ||
|
|
78aff54360 | ||
|
|
6160fd7638 | ||
|
|
c345623a06 | ||
|
|
e9173796f5 |
@@ -1,6 +1,6 @@
|
|||||||
# Related issues 🔗
|
# Related issues 🔗
|
||||||
|
|
||||||
Issue: #[Issue number here]
|
Closes #[Issue number here]
|
||||||
|
|
||||||
# Description ℹ️
|
# Description ℹ️
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- release/*
|
- release/*
|
||||||
- develop
|
- develop
|
||||||
|
- main
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
- ready_for_review
|
- ready_for_review
|
||||||
- reopened
|
- reopened
|
||||||
- edited
|
|
||||||
- synchronize
|
- synchronize
|
||||||
jobs:
|
jobs:
|
||||||
node-modules:
|
node-modules:
|
||||||
@@ -21,7 +21,6 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Cache node modules
|
||||||
id: cache
|
id: cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
@@ -39,23 +38,15 @@ jobs:
|
|||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
||||||
- name: yarn install
|
- name: yarn install
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
run: yarn install --pure-lockfile
|
run: yarn install --pure-lockfile
|
||||||
|
|
||||||
lint-pr-title:
|
lint-format:
|
||||||
needs: node-modules
|
timeout-minutes: 20
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
name: Verify PR title
|
|
||||||
uses: ./.github/workflows/lint-pr.yml
|
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
lint-test-build:
|
|
||||||
timeout-minutes: 60
|
|
||||||
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 + format check'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -81,6 +72,76 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
main-branch-name: develop
|
main-branch-name: develop
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: yarn nx format:check
|
||||||
|
|
||||||
|
- name: Lint affected
|
||||||
|
run: yarn nx affected:lint --max-warnings=0
|
||||||
|
|
||||||
|
- name: Build affected spec
|
||||||
|
run: yarn nx affected --target=build-spec
|
||||||
|
|
||||||
|
test-affected:
|
||||||
|
timeout-minutes: 30
|
||||||
|
needs: build-sources
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
name: 'run unit test of affected apps'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||||
|
|
||||||
|
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||||
|
uses: nrwl/nx-set-shas@v3
|
||||||
|
with:
|
||||||
|
main-branch-name: develop
|
||||||
|
|
||||||
|
- name: Test affected
|
||||||
|
run: yarn nx affected:test
|
||||||
|
|
||||||
|
build-sources:
|
||||||
|
timeout-minutes: 30
|
||||||
|
needs: lint-format
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
name: 'Build sources of affected apps'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||||
|
|
||||||
|
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||||
|
uses: nrwl/nx-set-shas@v3
|
||||||
|
with:
|
||||||
|
main-branch-name: develop
|
||||||
|
|
||||||
# See affected apps
|
# See affected apps
|
||||||
- name: See affected apps
|
- name: See affected apps
|
||||||
run: |
|
run: |
|
||||||
@@ -97,21 +158,8 @@ jobs:
|
|||||||
echo "preview_explorer: ${{ env.PREVIEW_EXPLORER }}"
|
echo "preview_explorer: ${{ env.PREVIEW_EXPLORER }}"
|
||||||
echo "preview_tools: ${{ env.PREVIEW_TOOLS }}"
|
echo "preview_tools: ${{ env.PREVIEW_TOOLS }}"
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
run: yarn nx format:check
|
|
||||||
|
|
||||||
- name: Lint affected
|
|
||||||
run: yarn nx affected:lint --max-warnings=0
|
|
||||||
|
|
||||||
- name: Build affected spec
|
|
||||||
run: yarn nx affected --target=build-spec
|
|
||||||
|
|
||||||
- name: Test affected
|
|
||||||
run: yarn nx affected:test
|
|
||||||
|
|
||||||
- name: Build affected
|
- name: Build affected
|
||||||
run: yarn nx affected:build || (yarn install && yarn nx affected:build)
|
run: yarn nx affected:build || (yarn install && yarn nx affected:build)
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
projects: ${{ env.PROJECTS }}
|
projects: ${{ env.PROJECTS }}
|
||||||
projects-e2e: ${{ env.PROJECTS_E2E }}
|
projects-e2e: ${{ env.PROJECTS_E2E }}
|
||||||
@@ -120,39 +168,62 @@ jobs:
|
|||||||
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
||||||
preview_tools: ${{ env.PREVIEW_TOOLS }}
|
preview_tools: ${{ env.PREVIEW_TOOLS }}
|
||||||
|
|
||||||
console-e2e:
|
# console-e2e:
|
||||||
needs: lint-test-build
|
# needs: build-sources
|
||||||
name: '(CI) console python'
|
# name: '(CI) console python'
|
||||||
uses: ./.github/workflows/console-test-run.yml
|
# uses: ./.github/workflows/console-test-run.yml
|
||||||
secrets: inherit
|
# secrets: inherit
|
||||||
if: ${{ contains(fromJSON(needs.lint-test-build.outputs.projects), 'trading') && github.event_name == 'pull_request' }}
|
# if: ${{ contains(fromJSON(needs.build-sources.outputs.projects), 'trading') && github.event_name == 'pull_request' }}
|
||||||
with:
|
# with:
|
||||||
github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
|
# github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
|
check-e2e-needed:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-sources
|
||||||
|
name: '(CI) check if e2e needed'
|
||||||
|
outputs:
|
||||||
|
run-tests: ${{ steps.check-test.outputs.e2e-needed }}
|
||||||
|
steps:
|
||||||
|
- name: Check branch
|
||||||
|
id: check-test
|
||||||
|
run: |
|
||||||
|
if [[ "${{ github.base_ref }}" == "develop" ]]; then
|
||||||
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "${{ github.base_ref }}" == "main" ]]; then
|
||||||
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
|
||||||
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "e2e-needed=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: Print result
|
||||||
|
run: |
|
||||||
|
echo "e2e-needed: ${{ steps.check-test.outputs.e2e-needed }}"
|
||||||
|
|
||||||
cypress:
|
cypress:
|
||||||
needs: lint-test-build
|
needs: [build-sources, check-e2e-needed]
|
||||||
name: '(CI) cypress'
|
name: '(CI) cypress'
|
||||||
# if: ${{ needs.lint-test-build.outputs.projects-e2e != '[]' }}
|
if: ${{ needs.check-e2e-needed.outputs.run-tests == 'true' }}
|
||||||
uses: ./.github/workflows/cypress-run.yml
|
uses: ./.github/workflows/cypress-run.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
projects: ${{ needs.lint-test-build.outputs.projects-e2e }}
|
projects: ${{ needs.build-sources.outputs.projects-e2e }}
|
||||||
tags: '@smoke'
|
tags: '@smoke'
|
||||||
|
|
||||||
publish-dist:
|
publish-dist:
|
||||||
needs: lint-test-build
|
needs: build-sources
|
||||||
name: '(CD) publish dist'
|
name: '(CD) publish dist'
|
||||||
if: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo') || github.event_name == 'push' }}
|
if: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo') || github.event_name == 'push' }}
|
||||||
uses: ./.github/workflows/publish-dist.yml
|
uses: ./.github/workflows/publish-dist.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
projects: ${{ needs.lint-test-build.outputs.projects }}
|
projects: ${{ needs.build-sources.outputs.projects }}
|
||||||
|
|
||||||
dist-check:
|
dist-check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
- publish-dist
|
- publish-dist
|
||||||
- lint-test-build
|
- build-sources
|
||||||
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo' }}
|
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo' }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
name: '(CD) comment preview links'
|
name: '(CD) comment preview links'
|
||||||
@@ -168,27 +239,27 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# https://stackoverflow.com/questions/3183444/check-for-valid-link-url
|
# https://stackoverflow.com/questions/3183444/check-for-valid-link-url
|
||||||
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
|
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
|
||||||
if [[ "${{ needs.lint-test-build.outputs.preview_governance }}" =~ $regex ]]; then
|
if [[ "${{ needs.build-sources.outputs.preview_governance }}" =~ $regex ]]; then
|
||||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_governance }}"; do
|
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_governance }}"; do
|
||||||
echo "waiting for governance preview: ${{ needs.lint-test-build.outputs.preview_governance }}"
|
echo "waiting for governance preview: ${{ needs.build-sources.outputs.preview_governance }}"
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if [[ "${{ needs.lint-test-build.outputs.preview_explorer }}" =~ $regex ]]; then
|
if [[ "${{ needs.build-sources.outputs.preview_explorer }}" =~ $regex ]]; then
|
||||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_explorer }}"; do
|
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_explorer }}"; do
|
||||||
echo "waiting for explorer preview: ${{ needs.lint-test-build.outputs.preview_explorer }}"
|
echo "waiting for explorer preview: ${{ needs.build-sources.outputs.preview_explorer }}"
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if [[ "${{ needs.lint-test-build.outputs.preview_trading }}" =~ $regex ]]; then
|
if [[ "${{ needs.build-sources.outputs.preview_trading }}" =~ $regex ]]; then
|
||||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_trading }}"; do
|
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_trading }}"; do
|
||||||
echo "waiting for trading preview: ${{ needs.lint-test-build.outputs.preview_trading }}"
|
echo "waiting for trading preview: ${{ needs.build-sources.outputs.preview_trading }}"
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if [[ "${{ needs.lint-test-build.outputs.preview_tools }}" =~ $regex ]]; then
|
if [[ "${{ needs.build-sources.outputs.preview_tools }}" =~ $regex ]]; then
|
||||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_tools }}"; do
|
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_tools }}"; do
|
||||||
echo "waiting for tools preview: ${{ needs.lint-test-build.outputs.preview_tools }}"
|
echo "waiting for tools preview: ${{ needs.build-sources.outputs.preview_tools }}"
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
@@ -200,10 +271,10 @@ jobs:
|
|||||||
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 }}
|
* governance: ${{ needs.build-sources.outputs.preview_governance }}
|
||||||
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
* explorer: ${{ needs.build-sources.outputs.preview_explorer }}
|
||||||
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
* trading: ${{ needs.build-sources.outputs.preview_trading }}
|
||||||
* tools: ${{ needs.lint-test-build.outputs.preview_tools }}
|
* tools: ${{ needs.build-sources.outputs.preview_tools }}
|
||||||
|
|
||||||
# Report single result at the end, to avoid mess with required checks in PR
|
# Report single result at the end, to avoid mess with required checks in PR
|
||||||
cypress-check:
|
cypress-check:
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ on:
|
|||||||
github-sha:
|
github-sha:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
console-test-branch:
|
||||||
|
type: choice
|
||||||
|
description: 'main: v0.72.14, develop: v0.73.0-preview7'
|
||||||
|
options:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-tests:
|
run-tests:
|
||||||
@@ -16,13 +24,19 @@ jobs:
|
|||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# check-out frontend-monorepo
|
# check-out frontend-monorepo
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Checkout console test repo
|
- name: Checkout frontend-monorepo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.github-sha }}
|
ref: ${{ inputs.github-sha || github.sha }}
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# cache node modules
|
# cache node modules
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
|
- name: setup node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Cache node modules
|
||||||
id: cache
|
id: cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
@@ -33,15 +47,6 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-cache-node-modules-
|
${{ runner.os }}-cache-node-modules-
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# setup node
|
|
||||||
#----------------------------------------------
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
|
||||||
cache: yarn
|
|
||||||
#----------------------------------------------
|
|
||||||
# install deps if cache missing
|
# install deps if cache missing
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: yarn install
|
- name: yarn install
|
||||||
@@ -74,58 +79,42 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: vegaprotocol/console-test
|
repository: vegaprotocol/console-test
|
||||||
|
ref: ${{ inputs.console-test-branch }}
|
||||||
path: './console-test'
|
path: './console-test'
|
||||||
#----------------------------------------------
|
|
||||||
# set-up python
|
- name: Load console test envs
|
||||||
#----------------------------------------------
|
id: console-test-env
|
||||||
- name: Set up python
|
uses: falti/dotenv-action@v1.0.4
|
||||||
id: setup-python
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
with:
|
||||||
python-version: '3.10.11'
|
path: './console-test/.env.${{ inputs.console-test-branch }}'
|
||||||
#----------------------------------------------
|
export-variables: true
|
||||||
# ----- install & configure poetry -----
|
keys-case: upper
|
||||||
#----------------------------------------------
|
log-variables: true
|
||||||
- name: Install Poetry
|
|
||||||
uses: snok/install-poetry@v1
|
|
||||||
with:
|
|
||||||
virtualenvs-create: true
|
|
||||||
virtualenvs-in-project: true
|
|
||||||
virtualenvs-path: console-test/.venv
|
|
||||||
#----------------------------------------------
|
|
||||||
# load cached venv if cache exists
|
|
||||||
#----------------------------------------------
|
|
||||||
- name: Load cached venv
|
|
||||||
id: cached-poetry-dependencies
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: console-test/.venv
|
|
||||||
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
|
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# install dependencies if cache does not exist
|
# install dependencies if cache does not exist
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
working-directory: ./console-test
|
working-directory: ./console-test
|
||||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
|
||||||
run: poetry install --no-interaction --no-root
|
run: poetry install --no-interaction --no-root
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# install vega binaries
|
# install vega binaries
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Install vega binaries
|
- name: Install vega binaries
|
||||||
working-directory: ./console-test
|
working-directory: ./console-test
|
||||||
run: poetry run python -m vega_sim.tools.load_binaries --force
|
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# install playwright
|
# install playwright
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: install playwright
|
- name: install playwright
|
||||||
run: poetry run playwright install
|
run: poetry run playwright install --with-deps chromium
|
||||||
working-directory: ./console-test
|
working-directory: ./console-test
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# run tests
|
# run tests
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: ./console-test
|
working-directory: ./console-test
|
||||||
run: poetry run pytest -v -s --numprocesses auto --dist loadfile --durations=20
|
run: poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
|
||||||
- name: Check files
|
- name: Check files
|
||||||
run: |
|
run: |
|
||||||
ls -al .
|
ls -al .
|
||||||
@@ -140,3 +129,13 @@ jobs:
|
|||||||
name: playwright-trace
|
name: playwright-trace
|
||||||
path: ./traces/
|
path: ./traces/
|
||||||
retention-days: 15
|
retention-days: 15
|
||||||
|
#----------------------------------------------
|
||||||
|
# ----- upload logs -----
|
||||||
|
#----------------------------------------------
|
||||||
|
- name: Upload worker logs
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: worker-logs
|
||||||
|
path: ./logs/
|
||||||
|
retention-days: 15
|
||||||
|
|||||||
@@ -13,13 +13,35 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
runner-choice:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
runner: ${{ steps.step.outputs.runner }}
|
||||||
|
steps:
|
||||||
|
- name: Check branch
|
||||||
|
id: step
|
||||||
|
run: |
|
||||||
|
if [[ "${{ github.base_ref }}" == "main" ]]; then
|
||||||
|
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "${{ github.base_ref }}" == "develop" && "${{ github.ref_name }}" == "main" ]]; then
|
||||||
|
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
|
||||||
|
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "runner=self-hosted-runner" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Print runner
|
||||||
|
run: echo ${{ steps.step.outputs.runner }}
|
||||||
|
|
||||||
e2e:
|
e2e:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
project: ${{ fromJSON(inputs.projects) }}
|
project: ${{ fromJSON(inputs.projects) }}
|
||||||
name: ${{ matrix.project }}
|
name: ${{ matrix.project }}
|
||||||
runs-on: self-hosted-runner
|
needs: runner-choice
|
||||||
|
runs-on: ${{ needs.runner-choice.outputs.runner }}
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
steps:
|
steps:
|
||||||
# Checks if skip cache was requested
|
# Checks if skip cache was requested
|
||||||
@@ -37,6 +59,7 @@ jobs:
|
|||||||
|
|
||||||
# Restore node_modules from cache if possible
|
# Restore node_modules from cache if possible
|
||||||
- name: Restore node_modules from cache
|
- name: Restore node_modules from cache
|
||||||
|
id: cache-node-modules
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -46,6 +69,7 @@ jobs:
|
|||||||
|
|
||||||
# Install frontend dependencies
|
# Install frontend dependencies
|
||||||
- name: Install root dependencies
|
- name: Install root dependencies
|
||||||
|
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
@@ -61,13 +85,14 @@ jobs:
|
|||||||
- name: Run Vegacapsule network and Vega wallet
|
- name: Run Vegacapsule network and Vega wallet
|
||||||
id: setup-vega
|
id: setup-vega
|
||||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
timeout-minutes: 10
|
||||||
|
|
||||||
######
|
######
|
||||||
## Run some tests
|
## Run some tests
|
||||||
######
|
######
|
||||||
|
|
||||||
- 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 }} --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 }}
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
name: Verify PR title
|
name: Verify PR title
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- edited
|
||||||
|
- reopened
|
||||||
|
- synchronize
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint_pr:
|
lint_pr:
|
||||||
@@ -11,21 +16,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version: 16
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
|
||||||
cache: yarn
|
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Install dependencies
|
||||||
uses: actions/cache@v3
|
run: |
|
||||||
with:
|
rm package.json
|
||||||
path: node_modules
|
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
|
||||||
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Check PR title
|
- name: Check PR title
|
||||||
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
|
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
|
||||||
|
|||||||
@@ -30,12 +30,18 @@ jobs:
|
|||||||
echo IS_IPFS_RELEASE=false >> $GITHUB_ENV
|
echo IS_IPFS_RELEASE=false >> $GITHUB_ENV
|
||||||
echo IS_S3_RELEASE=false >> $GITHUB_ENV
|
echo IS_S3_RELEASE=false >> $GITHUB_ENV
|
||||||
echo IS_DEV_IMAGE=false >> $GITHUB_ENV
|
echo IS_DEV_IMAGE=false >> $GITHUB_ENV
|
||||||
|
echo IS_MAIN_IMAGE=false >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Is dev image
|
- name: Is dev image
|
||||||
if: ${{ contains(github.ref, 'develop') && github.event_name == 'push' && matrix.app == 'trading' }}
|
if: ${{ github.ref_name == 'develop' && github.event_name == 'push' && matrix.app == 'trading' }}
|
||||||
run: |
|
run: |
|
||||||
echo IS_DEV_IMAGE=true >> $GITHUB_ENV
|
echo IS_DEV_IMAGE=true >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Is main image
|
||||||
|
if: ${{ github.ref_name == 'main' && github.event_name == 'push' && matrix.app == 'trading' }}
|
||||||
|
run: |
|
||||||
|
echo IS_MAIN_IMAGE=true >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Is PR
|
- name: Is PR
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
run: |
|
run: |
|
||||||
@@ -57,7 +63,7 @@ jobs:
|
|||||||
echo IS_IPFS_RELEASE=true >> $GITHUB_ENV
|
echo IS_IPFS_RELEASE=true >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Is S3 Release
|
- name: Is S3 Release
|
||||||
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' }}
|
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' && github.ref_name != 'main'}}
|
||||||
run: |
|
run: |
|
||||||
echo IS_S3_RELEASE=true >> $GITHUB_ENV
|
echo IS_S3_RELEASE=true >> $GITHUB_ENV
|
||||||
|
|
||||||
@@ -81,7 +87,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Log in to the Container registry (docker hub)
|
- name: Log in to the Container registry (docker hub)
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
|
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -155,10 +161,10 @@ jobs:
|
|||||||
- name: Sanity check docker image
|
- name: Sanity check docker image
|
||||||
run: |
|
run: |
|
||||||
echo "Check ipfs-hash"
|
echo "Check ipfs-hash"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local /bin/sh -c 'cat /ipfs-hash'
|
||||||
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 /bin/sh -c 'cat /ipfs-hash' > ${{ matrix.app }}-ipfs-hash
|
||||||
echo "List html directory"
|
echo "List html directory"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local /bin/sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
||||||
|
|
||||||
- name: Publish dist as docker image (ghcr)
|
- name: Publish dist as docker image (ghcr)
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
@@ -179,7 +185,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
id: dockerhub-push
|
id: dockerhub-push
|
||||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
|
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/node-outside-docker.Dockerfile
|
file: docker/node-outside-docker.Dockerfile
|
||||||
@@ -189,7 +195,7 @@ jobs:
|
|||||||
ENV_NAME=${{ env.ENV_NAME }}
|
ENV_NAME=${{ env.ENV_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
||||||
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || '' }}
|
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
|
||||||
|
|
||||||
- name: Publish dist as docker image (ghcr - retry)
|
- name: Publish dist as docker image (ghcr - retry)
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
@@ -216,7 +222,7 @@ jobs:
|
|||||||
ENV_NAME=${{ env.ENV_NAME }}
|
ENV_NAME=${{ env.ENV_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
||||||
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || '' }}
|
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
|
||||||
|
|
||||||
# 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
|
||||||
@@ -329,7 +335,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# create commit
|
# create commit
|
||||||
commit_msg="Automated hash update from ${{ github.ref }}"
|
if ! git diff --cached --exit-code; then
|
||||||
git commit -m "$commit_msg"
|
commit_msg="Automated hash update from ${{ github.ref }}"
|
||||||
git push -u origin "main"
|
git commit -m "$commit_msg"
|
||||||
|
git push -u origin "main"
|
||||||
|
fi
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
* @vegaprotocol/frontend
|
* @vegaprotocol/frontend
|
||||||
|
* @vegaprotocol/frontend-qa
|
||||||
*.graphql @vegaprotocol/core
|
*.graphql @vegaprotocol/core
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ recalculate-ipfs:
|
|||||||
echo "ipfs hash inside the image"
|
echo "ipfs hash inside the image"
|
||||||
docker run --rm ${TAG} cat /ipfs-hash
|
docker run --rm ${TAG} cat /ipfs-hash
|
||||||
echo "recalculating ipfs hash"
|
echo "recalculating ipfs hash"
|
||||||
docker run --rm ${TAG} ipfs add -r /usr/share/nginx/html
|
docker run --rm ${TAG} ipfs add -rQ /usr/share/nginx/html
|
||||||
|
|
||||||
.PHONY: eject-ipfs-hash
|
.PHONY: eject-ipfs-hash
|
||||||
unpack:
|
unpack:
|
||||||
|
|||||||
@@ -113,13 +113,47 @@ In order to run a container on port 3000:
|
|||||||
docker run -p 3000:80 [TAG]
|
docker run -p 3000:80 [TAG]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On top of that there are two possible scenarios for running docker image - using nginx server (default) of ipfs daemon.
|
||||||
|
|
||||||
|
to run ipfs on port 3000:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 3000:80 [TAG] /run-ipfs.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
to run nginx on port 3000:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 3000:80 [TAG]
|
||||||
|
```
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
|
||||||
The [`docker`](./docker) subfolder has some docker configurations for easily setting up your own hosted version of console either for the web, or ready for pinning on IPFS
|
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 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). The multistage builds ensures consistent CPU architecture and build toolchains are used so that the result will be identical.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=16.5.1 --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 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.
|
||||||
|
|
||||||
### nx build outside the docker
|
### 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.
|
This Docker image packages a pre-built `dist` folder into an [`nginx`](https://hub.docker.com/_/nginx)([server configuration](./nginx/nginx.conf)) docker image. In this case, 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:
|
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:
|
||||||
|
|
||||||
@@ -130,41 +164,21 @@ As a prerequisite you need to perform build of `dist` directory and move its con
|
|||||||
You can build any of the containers locally with the following command:
|
You can build any of the containers locally with the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build --dockerfile docker/node-outside-docker.Dockerfile . --tag=[TAG]
|
docker build -f 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
|
### 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:
|
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)
|
1. Show latest release by running: `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`
|
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`
|
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`.
|
4. Download docker image with the desired release `docker pull $TAG`.
|
||||||
5. Recalculate hash: `make recalculate-ipfs`
|
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`
|
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`
|
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**
|
8. Now `dist` directory contains valid application build
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
|||||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||||
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_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocke
|
|||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
NX_VEGA_URL=https://api.vega.community/graphql
|
||||||
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
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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.n07.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
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
context('Network parameters page', { tags: '@smoke' }, function () {
|
context('Network parameters page', { tags: '@smoke' }, function () {
|
||||||
before('navigate to network parameter page', function () {
|
before('navigate to network parameter page', function () {
|
||||||
cy.fixture('net_parameter_format_lookup').as('networkParameterFormat');
|
cy.fixture('net_parameter_format_lookup').as('networkParameterFormat');
|
||||||
|
cy.visit('/network-parameters');
|
||||||
});
|
});
|
||||||
describe('Verify elements on page', function () {
|
describe('Verify elements on page', function () {
|
||||||
beforeEach(() => {
|
|
||||||
cy.visit('/network-parameters');
|
|
||||||
});
|
|
||||||
|
|
||||||
const networkParametersHeader = '[data-testid="network-param-header"]';
|
const networkParametersHeader = '[data-testid="network-param-header"]';
|
||||||
const tableRows = '[data-testid="key-value-table-row"]';
|
const tableRows = '[data-testid="key-value-table-row"]';
|
||||||
|
|
||||||
@@ -16,6 +13,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
|||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 0006-NETW-021
|
||||||
it('should list each of the network parameters available', function () {
|
it('should list each of the network parameters available', function () {
|
||||||
cy.get_network_parameters().then((network_parameters) => {
|
cy.get_network_parameters().then((network_parameters) => {
|
||||||
const numberOfNetworkParametersInSystem =
|
const numberOfNetworkParametersInSystem =
|
||||||
@@ -198,6 +196,19 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 0006-NETW-022 0006-NETW-023
|
||||||
|
it('governance assets should be correctly grouped', function () {
|
||||||
|
cy.getByTestId('governance')
|
||||||
|
.should('exist')
|
||||||
|
.parent()
|
||||||
|
.should('have.attr', 'href', '/network-parameters#governance');
|
||||||
|
cy.get('[id="governance-proposal-asset"]')
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.getByTestId('key-value-table-row').should('have.length', 8);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should be able to see network parameters - on mobile', function () {
|
it('should be able to see network parameters - on mobile', function () {
|
||||||
cy.switchToMobile();
|
cy.switchToMobile();
|
||||||
cy.get_network_parameters().then((network_parameters) => {
|
cy.get_network_parameters().then((network_parameters) => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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=/
|
NX_VEGA_EXPLORER_URL=/
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_TXS_LIST=0
|
NX_EXPLORER_TXS_LIST=0
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ 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=/
|
NX_VEGA_EXPLORER_URL=/
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ NX_VEGA_GOVERNANCE_URL=https://governance.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/
|
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
|
||||||
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://be.vega.community
|
NX_TENDERMINT_URL=https://be.vega.community
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks
|
|||||||
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.mainnet-mirror.vega.rocks/
|
NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/
|
||||||
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
|
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
|
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
# .env is stagnet1, so there are no overrides required
|
# .env is stagnet1, so there are no overrides required
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET1":"https://stagnet1.explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET1":"https://stagnet1.explorer.vega.xyz"}'
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ NX_VEGA_GOVERNANCE_URL=https://governance.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
|
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
|||||||
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
|
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
||||||
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
|
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ 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=/
|
NX_VEGA_EXPLORER_URL=/
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { AssetTypeMapping, AssetStatusMapping } from '@vegaprotocol/assets';
|
|||||||
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 { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { 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';
|
||||||
|
|||||||
@@ -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 type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueGetterParams,
|
VegaValueGetterParams,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
|||||||
import { VoteProgress } from '@vegaprotocol/proposals';
|
import { VoteProgress } from '@vegaprotocol/proposals';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
@@ -33,7 +33,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
|
|||||||
const { params } = useNetworkParams([
|
const { params } = useNetworkParams([
|
||||||
NetworkParams.governance_proposal_market_requiredMajority,
|
NetworkParams.governance_proposal_market_requiredMajority,
|
||||||
]);
|
]);
|
||||||
const tokenLink = useLinks(DApp.Token);
|
const tokenLink = useLinks(DApp.Governance);
|
||||||
const requiredMajorityPercentage = useMemo(() => {
|
const requiredMajorityPercentage = useMemo(() => {
|
||||||
const requiredMajority =
|
const requiredMajority =
|
||||||
params?.governance_proposal_market_requiredMajority ?? 1;
|
params?.governance_proposal_market_requiredMajority ?? 1;
|
||||||
@@ -105,7 +105,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
|
|||||||
? new BigNumber(0)
|
? new BigNumber(0)
|
||||||
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
||||||
return (
|
return (
|
||||||
<div className="uppercase flex h-full items-center justify-center pt-2">
|
<div className="flex items-center justify-center h-full pt-2 uppercase">
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
threshold={requiredMajorityPercentage}
|
threshold={requiredMajorityPercentage}
|
||||||
progress={yesPercentage}
|
progress={yesPercentage}
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ export const BundleSigners = ({
|
|||||||
tx,
|
tx,
|
||||||
id,
|
id,
|
||||||
}: BundleSignersProps) => {
|
}: BundleSignersProps) => {
|
||||||
const tokenLink = useLinks(DApp.Token);
|
const tokenLink = useLinks(DApp.Governance);
|
||||||
|
|
||||||
const bridgeFunction: BridgeFunction =
|
const bridgeFunction: BridgeFunction =
|
||||||
tx?.changes?.erc20 && 'contractAddress' in tx.changes.erc20
|
tx?.changes?.erc20 && 'contractAddress' in tx.changes.erc20
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ 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, error } = useExplorerOracleSpecsQuery({
|
||||||
|
errorPolicy: 'ignore',
|
||||||
|
});
|
||||||
|
|
||||||
useDocumentTitle(['Oracles']);
|
useDocumentTitle(['Oracles']);
|
||||||
useScrollToLocation();
|
useScrollToLocation();
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export const ValidatorsPage = () => {
|
|||||||
const [vegaDialog, setVegaDialog] = useState<boolean>(false);
|
const [vegaDialog, setVegaDialog] = useState<boolean>(false);
|
||||||
const [tmDialog, setTmDialog] = useState<boolean>(false);
|
const [tmDialog, setTmDialog] = useState<boolean>(false);
|
||||||
|
|
||||||
const tokenLink = useLinks(DApp.Token);
|
const tokenLink = useLinks(DApp.Governance);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ 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-stagnet1-k8s.ops.vega.xyz
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
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_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ NX_VEGA_ENV=DEVNET
|
|||||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n04.d.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
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ NX_VEGA_ENV=MAINNET
|
|||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
NX_VEGA_URL=https://api.vega.community/graphql
|
||||||
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
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ 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_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
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|||||||
@@ -19,7 +19,22 @@ export const upgradeProposalsData = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
node: {
|
node: {
|
||||||
upgradeBlockHeight: '1955065',
|
upgradeBlockHeight: '10001',
|
||||||
|
vegaReleaseTag: 'v0.71.0+dev-12156-bca1d57e',
|
||||||
|
approvers: [
|
||||||
|
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
||||||
|
'121934387281812a2d5e6913e5d57c0f85a8f169e2752347ee2e23b52d46623c',
|
||||||
|
'65c80e2f5f84e2109eec30810f137ba04cbbecaba8f27706c146cc6c6f90db29',
|
||||||
|
'bd6339d2428c79ac3bc9011771236d17bac92bcb1806423388d52fb440043aef',
|
||||||
|
],
|
||||||
|
status: 'PROTOCOL_UPGRADE_PROPOSAL_STATUS_APPROVED',
|
||||||
|
__typename: 'ProtocolUpgradeProposal',
|
||||||
|
},
|
||||||
|
__typename: 'ProtocolUpgradeProposalEdge',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
upgradeBlockHeight: '20',
|
||||||
vegaReleaseTag: 'v0.71.0+dev-12156-bca1d57e',
|
vegaReleaseTag: 'v0.71.0+dev-12156-bca1d57e',
|
||||||
approvers: [
|
approvers: [
|
||||||
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
'02a6531716b7a6d82779b7793c3ad2fcb47290ea2ff0912c56f61219bd9675ff',
|
||||||
|
|||||||
@@ -34,19 +34,20 @@ import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
|||||||
import { createSuccessorMarketProposalTxBody } from '../../support/proposal.functions';
|
import { createSuccessorMarketProposalTxBody } from '../../support/proposal.functions';
|
||||||
|
|
||||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||||
const proposalVoteProgressForPercentage =
|
const participationNotMet = 'token-participation-not-met';
|
||||||
'vote-progress-indicator-percentage-for';
|
const voteStatus = 'vote-status';
|
||||||
const proposalVoteProgressAgainstPercentage =
|
const voteMajorityNotMet = 'token-majority-not-met';
|
||||||
'vote-progress-indicator-percentage-against';
|
const numberOfVotesFor = 'num-votes-for';
|
||||||
const proposalVoteProgressForTokens = 'vote-progress-indicator-tokens-for';
|
const votesForPercentage = 'votes-for-percentage';
|
||||||
const proposalVoteProgressAgainstTokens =
|
const numberOfVotesAgainst = 'num-votes-against';
|
||||||
'vote-progress-indicator-tokens-against';
|
const votesAgainstPercentage = 'votes-against-percentage';
|
||||||
|
const totalVotedNumber = 'total-voted';
|
||||||
|
const totalVotedPercentage = 'total-voted-percentage';
|
||||||
const changeVoteButton = 'change-vote-button';
|
const changeVoteButton = 'change-vote-button';
|
||||||
const proposalDetailsTitle = 'proposal-title';
|
const proposalDetailsTitle = 'proposal-title';
|
||||||
const proposalDetailsDescription = 'proposal-description';
|
const proposalDetailsDescription = 'proposal-description';
|
||||||
const openProposals = 'open-proposals';
|
const openProposals = 'open-proposals';
|
||||||
const viewProposalButton = 'view-proposal-btn';
|
const viewProposalButton = 'view-proposal-btn';
|
||||||
const voteBreakdownToggle = 'vote-breakdown-toggle';
|
|
||||||
const proposalTermsToggle = 'proposal-json-toggle';
|
const proposalTermsToggle = 'proposal-json-toggle';
|
||||||
const marketDataToggle = 'proposal-market-data-toggle';
|
const marketDataToggle = 'proposal-market-data-toggle';
|
||||||
|
|
||||||
@@ -150,29 +151,32 @@ describe(
|
|||||||
// 3001-VOTE-037
|
// 3001-VOTE-037
|
||||||
// 3001-VOTE-040
|
// 3001-VOTE-040
|
||||||
// 3001-VOTE-067
|
// 3001-VOTE-067
|
||||||
|
// 3001-VOTE-023
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
||||||
cy.getByTestId(viewProposalButton).click()
|
cy.getByTestId(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
cy.getByTestId(participationNotMet).should(
|
||||||
'be.visible'
|
'have.text',
|
||||||
|
'0.000000000000000000000015% participation threshold not met'
|
||||||
|
);
|
||||||
|
cy.getByTestId(voteMajorityNotMet).should(
|
||||||
|
'have.text',
|
||||||
|
'66% majority threshold not met'
|
||||||
|
);
|
||||||
|
cy.getByTestId(voteStatus).should(
|
||||||
|
'have.text',
|
||||||
|
'Currently expected to fail'
|
||||||
);
|
);
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
|
||||||
.contains('👎')
|
|
||||||
.should('be.visible');
|
|
||||||
// 3001-VOTE-062
|
// 3001-VOTE-062
|
||||||
// 3001-VOTE-040
|
// 3001-VOTE-040
|
||||||
// 3001-VOTE-070
|
// 3001-VOTE-070
|
||||||
getProposalInformationFromTable('Token majority met')
|
|
||||||
.contains('👎')
|
|
||||||
.should('be.visible');
|
|
||||||
// 3001-VOTE-068
|
// 3001-VOTE-068
|
||||||
getProposalInformationFromTable('Token participation met')
|
cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M');
|
||||||
.contains('👎')
|
cy.getByTestId(numberOfVotesAgainst).should('have.text', '0.0M');
|
||||||
.should('be.visible');
|
cy.getByTestId(totalVotedNumber).should('have.text', '0.0M');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073
|
// 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073
|
||||||
@@ -197,43 +201,16 @@ describe(
|
|||||||
.contains(votedDate)
|
.contains(votedDate)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
cy.getByTestId(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
cy.getByTestId(votesForPercentage) // 3001-VOTE-072
|
||||||
.contains('100.00%')
|
.should('have.text', '100%');
|
||||||
.and('be.visible');
|
cy.getByTestId(votesAgainstPercentage).should('have.text', '0%');
|
||||||
cy.getByTestId(proposalVoteProgressAgainstPercentage)
|
cy.getByTestId('token-majority-progress')
|
||||||
.contains('0.00%')
|
.should('have.attr', 'style')
|
||||||
.and('be.visible');
|
.and('eq', 'width: 100%;'); // 3001-VOTE-024
|
||||||
cy.getByTestId(proposalVoteProgressForTokens)
|
|
||||||
.contains('1.00')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(proposalVoteProgressAgainstTokens)
|
|
||||||
.contains('0.00')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
|
||||||
.should('have.text', (1).toFixed(2))
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Tokens against proposal')
|
|
||||||
.should('have.text', '0.00')
|
|
||||||
.and('be.visible');
|
|
||||||
// 3001-VOTE-061
|
|
||||||
getProposalInformationFromTable('Participation required')
|
|
||||||
.contains('0.00%')
|
|
||||||
.should('be.visible');
|
|
||||||
// 3001-VOTE-066
|
|
||||||
getProposalInformationFromTable('Majority Required') // 3001-VOTE-073
|
|
||||||
.contains(`${(66).toFixed(2)}%`)
|
|
||||||
.should('be.visible');
|
|
||||||
getProposalInformationFromTable('Number of voting parties')
|
|
||||||
.should('have.text', '1')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
// 3001-VOTE-064
|
// 3001-VOTE-064
|
||||||
cy.getByTestId('user-voted-yes').should('exist');
|
cy.getByTestId('user-voted-yes').should('exist');
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
|
||||||
.should('have.text', (1).toFixed(2))
|
|
||||||
.and('be.visible');
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
||||||
@@ -244,16 +221,7 @@ describe(
|
|||||||
});
|
});
|
||||||
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
||||||
voteForProposal('against');
|
voteForProposal('against');
|
||||||
cy.getByTestId(proposalVoteProgressAgainstPercentage)
|
cy.getByTestId(votesAgainstPercentage).should('have.text', '100%');
|
||||||
.contains('100.00%')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Tokens against proposal')
|
|
||||||
.should('have.text', (1).toFixed(2))
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Number of voting parties')
|
|
||||||
.should('have.text', '1')
|
|
||||||
.and('be.visible');
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
||||||
@@ -265,6 +233,7 @@ describe(
|
|||||||
|
|
||||||
// 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060
|
// 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060
|
||||||
it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () {
|
it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () {
|
||||||
|
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
@@ -275,69 +244,28 @@ describe(
|
|||||||
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.getByTestId(proposalVoteProgressForTokens)
|
cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M');
|
||||||
.contains('1')
|
cy.getByTestId(votesForPercentage).should('have.text', '100%');
|
||||||
.and('be.visible');
|
cy.getByTestId(totalVotedNumber).should('have.text', '0.0M');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
cy.getByTestId(totalVotedPercentage).should('have.text', '(0.00%)');
|
||||||
getProposalInformationFromTable('Total Supply')
|
ethereumWalletConnect();
|
||||||
.invoke('text')
|
stakingPageAssociateTokens('1000000', { approve: true });
|
||||||
.then((totalSupply) => {
|
navigateTo(navigation.proposals);
|
||||||
const tokensRequiredToAchieveResult = (
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
(Number(totalSupply.replace(/,/g, '')) * 0.001) /
|
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
||||||
100
|
cy.getByTestId(viewProposalButton).click()
|
||||||
).toFixed(2);
|
);
|
||||||
ethereumWalletConnect();
|
});
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated(
|
cy.getByTestId(votesForPercentage).should('have.text', '100%');
|
||||||
tokensRequiredToAchieveResult
|
cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M');
|
||||||
);
|
cy.getByTestId(totalVotedNumber).should('have.text', '0.0M');
|
||||||
navigateTo(navigation.proposals);
|
cy.getByTestId(totalVotedPercentage).should('have.text', '(0.00%)');
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
// 3001-VOTE-065
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
||||||
cy.getByTestId(viewProposalButton).click()
|
voteForProposal('for');
|
||||||
);
|
cy.getByTestId(numberOfVotesFor).should('have.text', '1.0M');
|
||||||
});
|
cy.getByTestId(totalVotedNumber).should('have.text', '1.0M');
|
||||||
cy.getByTestId(proposalVoteProgressForPercentage)
|
cy.getByTestId(totalVotedPercentage).should('have.text', '(1.54%)');
|
||||||
.contains('100.00%')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(proposalVoteProgressAgainstPercentage)
|
|
||||||
.contains('0.00%')
|
|
||||||
.and('be.visible');
|
|
||||||
// 3001-VOTE-065
|
|
||||||
cy.getByTestId(changeVoteButton).should('be.visible').click();
|
|
||||||
voteForProposal('for');
|
|
||||||
cy.getByTestId(proposalVoteProgressForTokens)
|
|
||||||
.contains(tokensRequiredToAchieveResult)
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(proposalVoteProgressAgainstTokens)
|
|
||||||
.contains('0.00')
|
|
||||||
.and('be.visible');
|
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Total tokens voted percentage')
|
|
||||||
.should('have.text', '0.00%')
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
|
||||||
.should('have.text', tokensRequiredToAchieveResult)
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Tokens against proposal')
|
|
||||||
.should('have.text', '0.00')
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Number of voting parties')
|
|
||||||
.should('have.text', '1')
|
|
||||||
.and('be.visible');
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
|
||||||
.contains('👍')
|
|
||||||
.should('be.visible');
|
|
||||||
// 3001-VOTE-062
|
|
||||||
getProposalInformationFromTable('Token majority met')
|
|
||||||
.contains('👍')
|
|
||||||
.should('be.visible');
|
|
||||||
getProposalInformationFromTable('Token participation met')
|
|
||||||
.contains('👍')
|
|
||||||
.should('be.visible');
|
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
|
||||||
.contains(tokensRequiredToAchieveResult)
|
|
||||||
.and('be.visible');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to vote for proposal twice by switching public key', function () {
|
it('Able to vote for proposal twice by switching public key', function () {
|
||||||
@@ -360,10 +288,6 @@ describe(
|
|||||||
voteForProposal('against');
|
voteForProposal('against');
|
||||||
cy.contains('You voted: Against').should('be.visible');
|
cy.contains('You voted: Against').should('be.visible');
|
||||||
switchVegaWalletPubKey();
|
switchVegaWalletPubKey();
|
||||||
cy.getByTestId(proposalVoteProgressForTokens).should(
|
|
||||||
'contain.text',
|
|
||||||
'1.00'
|
|
||||||
);
|
|
||||||
// Checking vote status for different public keys is displayed correctly
|
// Checking vote status for different public keys is displayed correctly
|
||||||
cy.contains('You voted: For').should('be.visible');
|
cy.contains('You voted: For').should('be.visible');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,12 +22,10 @@ const proposalListItem = '[data-testid="proposals-list-item"]';
|
|||||||
const closedProposals = 'closed-proposals';
|
const closedProposals = 'closed-proposals';
|
||||||
const proposalStatus = 'proposal-status';
|
const proposalStatus = 'proposal-status';
|
||||||
const viewProposalButton = 'view-proposal-btn';
|
const viewProposalButton = 'view-proposal-btn';
|
||||||
const votesTable = 'votes-table';
|
const votesTable = 'user-vote';
|
||||||
const openProposals = 'open-proposals';
|
const openProposals = 'open-proposals';
|
||||||
const proposalVoteProgressForPercentage =
|
const majorityVoteReached = 'token-majority-met';
|
||||||
'vote-progress-indicator-percentage-for';
|
const minParticipationReached = 'token-participation-met';
|
||||||
const majorityVoteReached = 'majority-reached';
|
|
||||||
const minParticipationReached = 'participation-reached';
|
|
||||||
const proposalTimeout = { timeout: 8000 };
|
const proposalTimeout = { timeout: 8000 };
|
||||||
|
|
||||||
context(
|
context(
|
||||||
@@ -70,7 +68,6 @@ context(
|
|||||||
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
||||||
cy.getByTestId(proposalStatus).should('have.text', 'Enacted');
|
cy.getByTestId(proposalStatus).should('have.text', 'Enacted');
|
||||||
cy.getByTestId(votesTable).within(() => {
|
cy.getByTestId(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -92,7 +89,7 @@ context(
|
|||||||
// 3001-VOTE-019 time to vote is highlighted red
|
// 3001-VOTE-019 time to vote is highlighted red
|
||||||
cy.getByTestId('vote-details')
|
cy.getByTestId('vote-details')
|
||||||
.find('span')
|
.find('span')
|
||||||
.should('have.class', 'text-vega-pink');
|
.should('have.class', 'text-vega-orange');
|
||||||
cy.getByTestId(viewProposalButton).click();
|
cy.getByTestId(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -109,12 +106,9 @@ context(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
cy.getByTestId(votesTable).within(() => {
|
cy.getByTestId(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
});
|
});
|
||||||
cy.getByTestId(proposalVoteProgressForPercentage)
|
cy.getByTestId('votes-for-percentage').should('have.text', '100%');
|
||||||
.contains('100.00%')
|
|
||||||
.and('be.visible');
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
|
|||||||
@@ -298,9 +298,6 @@ context(
|
|||||||
getProposalFromTitle(proposalTitle).within(() =>
|
getProposalFromTitle(proposalTitle).within(() =>
|
||||||
cy.getByTestId(viewProposalButton).click()
|
cy.getByTestId(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.contains('Vote breakdown').should('be.visible', {
|
|
||||||
timeout: 10000,
|
|
||||||
});
|
|
||||||
cy.getByTestId(voteButtons).should('not.exist');
|
cy.getByTestId(voteButtons).should('not.exist');
|
||||||
cy.getByTestId('min-proposal-requirements').should(
|
cy.getByTestId('min-proposal-requirements').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ const enactmentDeadlineError = 'enactment-before-voting-deadline';
|
|||||||
const proposalDownloadBtn = 'proposal-download-json';
|
const proposalDownloadBtn = 'proposal-download-json';
|
||||||
const feedbackError = '[data-testid="Error"]';
|
const feedbackError = '[data-testid="Error"]';
|
||||||
const viewProposalBtn = 'view-proposal-btn';
|
const viewProposalBtn = 'view-proposal-btn';
|
||||||
const liquidityVoteStatus = 'liquidity-votes-status';
|
|
||||||
const tokenVoteStatus = 'token-votes-status';
|
|
||||||
const proposalJsonToggle = 'proposal-json-toggle';
|
const proposalJsonToggle = 'proposal-json-toggle';
|
||||||
const proposalJsonSection = 'proposal-json';
|
const proposalJsonSection = 'proposal-json';
|
||||||
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
||||||
@@ -421,27 +419,28 @@ context(
|
|||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.getByTestId(liquidityVoteStatus).should(
|
cy.getByTestId('lp-majority-not-met').should(
|
||||||
'contain.text',
|
'have.text',
|
||||||
'Currently expected to fail'
|
'66% majority threshold not met'
|
||||||
);
|
);
|
||||||
cy.getByTestId(tokenVoteStatus).should(
|
|
||||||
'contain.text',
|
cy.getByTestId('token-majority-not-met').should(
|
||||||
'Currently expected to fail'
|
'have.text',
|
||||||
|
'66% majority threshold not met'
|
||||||
);
|
);
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
cy.getByTestId(liquidityVoteStatus).should(
|
cy.getByTestId('lp-majority-met').should(
|
||||||
'contain.text',
|
'have.text',
|
||||||
'Currently expected to pass'
|
'66% majority threshold met'
|
||||||
);
|
);
|
||||||
cy.getByTestId(tokenVoteStatus).should(
|
cy.getByTestId('token-majority-met').should(
|
||||||
'contain.text',
|
'have.text',
|
||||||
'Currently expected to pass'
|
'66% majority threshold met'
|
||||||
|
);
|
||||||
|
cy.getByTestId('vote-status').should(
|
||||||
|
'have.text',
|
||||||
|
'Currently expected to pass by token vote'
|
||||||
);
|
);
|
||||||
cy.getByTestId('vote-breakdown-toggle').click();
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
|
||||||
.contains('👍 by token vote')
|
|
||||||
.should('be.visible');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001
|
// 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
enterRawProposalBody,
|
enterRawProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getProposalFromTitle,
|
getProposalFromTitle,
|
||||||
getProposalInformationFromTable,
|
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
governanceProposalType,
|
||||||
submitUniqueRawProposal,
|
submitUniqueRawProposal,
|
||||||
@@ -30,7 +29,9 @@ const proposalType = 'proposal-type';
|
|||||||
const proposalStatus = 'proposal-status';
|
const proposalStatus = 'proposal-status';
|
||||||
const proposalClosingDate = 'vote-details';
|
const proposalClosingDate = 'vote-details';
|
||||||
const viewProposalButton = 'view-proposal-btn';
|
const viewProposalButton = 'view-proposal-btn';
|
||||||
const voteBreakDownToggle = 'vote-breakdown-toggle';
|
const voteMajorityNotMet = 'token-majority-not-met';
|
||||||
|
const voteMajorityMet = 'token-majority-met';
|
||||||
|
const votesForPercentage = 'votes-for-percentage';
|
||||||
|
|
||||||
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 () {
|
||||||
@@ -121,10 +122,15 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
||||||
getProposalFromTitle(proposalTitle).within(() => {
|
getProposalFromTitle(proposalTitle).within(() => {
|
||||||
// 3001-VOTE-039
|
// 3001-VOTE-039
|
||||||
cy.getByTestId('participation-not-reached').should(
|
cy.getByTestId(voteMajorityNotMet).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Min. participation not reached'
|
'66% majority threshold not met'
|
||||||
);
|
);
|
||||||
|
cy.getByTestId('token-participation-not-met').should(
|
||||||
|
'have.text',
|
||||||
|
'0.000000000000000000000015% participation threshold not met'
|
||||||
|
);
|
||||||
|
cy.getByTestId(votesForPercentage).should('have.text', '0%');
|
||||||
cy.getByTestId(viewProposalButton).click();
|
cy.getByTestId(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
@@ -134,16 +140,15 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
'have.text',
|
'have.text',
|
||||||
'Currently expected to pass'
|
'Currently expected to pass'
|
||||||
);
|
);
|
||||||
cy.getByTestId('user-voted-yes').should('exist');
|
cy.getByTestId(voteMajorityMet).should(
|
||||||
cy.getByTestId('participation-reached').should(
|
|
||||||
'have.text',
|
'have.text',
|
||||||
'Min. participation reached'
|
'66% majority threshold met'
|
||||||
|
);
|
||||||
|
cy.getByTestId(votesForPercentage).should('have.text', '100%');
|
||||||
|
cy.getByTestId('token-participation-met').should(
|
||||||
|
'have.text',
|
||||||
|
'0.000000000000000000000015% participation threshold met'
|
||||||
);
|
);
|
||||||
cy.getByTestId(viewProposalButton).click();
|
|
||||||
});
|
});
|
||||||
cy.getByTestId(voteBreakDownToggle).click();
|
|
||||||
getProposalInformationFromTable('Token participation met')
|
|
||||||
.contains('👍')
|
|
||||||
.should('be.visible');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ context(
|
|||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
cy.get(`[row-id="${0}"]`)
|
cy.get(`[row-id="${0}"]`)
|
||||||
.eq(1)
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(stakeValidatorListTotalStake)
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
.should('have.text', '3,002.00')
|
.should('have.text', '3,002.00')
|
||||||
@@ -222,7 +222,7 @@ context(
|
|||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
cy.get(`[row-id="${1}"]`)
|
cy.get(`[row-id="${1}"]`)
|
||||||
.eq(1)
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(stakeValidatorListTotalStake)
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
@@ -262,10 +262,10 @@ context(
|
|||||||
'2'
|
'2'
|
||||||
);
|
);
|
||||||
waitForBeginningOfEpoch();
|
waitForBeginningOfEpoch();
|
||||||
cy.getByTestId(stakeValidatorListStakePercentage).should(
|
cy.getByTestId(
|
||||||
'have.text',
|
stakeValidatorListStakePercentage,
|
||||||
'50.02%'
|
epochTimeout
|
||||||
);
|
).should('have.text', '50.02%');
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const proposalDocumentationLink = 'proposal-documentation-link';
|
|||||||
const connectToVegaWalletButton = 'connect-to-vega-wallet-btn';
|
const connectToVegaWalletButton = 'connect-to-vega-wallet-btn';
|
||||||
const governanceDocsUrl = 'https://vega.xyz/governance';
|
const governanceDocsUrl = 'https://vega.xyz/governance';
|
||||||
const networkUpgradeProposalListItem = 'protocol-upgrade-proposals-list-item';
|
const networkUpgradeProposalListItem = 'protocol-upgrade-proposals-list-item';
|
||||||
|
const proposalUpgradeBlockHeight = 'protocol-upgrade-proposal-block-height';
|
||||||
const closedProposals = 'closed-proposals';
|
const closedProposals = 'closed-proposals';
|
||||||
const closedProposalToggle = 'closed-proposals-toggle-networkUpgrades';
|
const closedProposalToggle = 'closed-proposals-toggle-networkUpgrades';
|
||||||
const protocolUpgradeTime = 'protocol-upgrade-time';
|
const protocolUpgradeTime = 'protocol-upgrade-time';
|
||||||
@@ -37,11 +38,39 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 3002-PROP-023 3004-PMAC-002 3005-PASN-002 3006-PASC-002 3007-PNEC-002 3008-PFRO-003
|
// 3002-PROP-023 3004-PMAC-002 3005-PASN-002 3006-PASC-002 3007-PNEC-002 3008-PFRO-003
|
||||||
it('should have button for link to more information on proposals', function () {
|
it('new proposal page should have button for link to more information on proposals', function () {
|
||||||
const proposalsUrl = 'https://docs.vega.xyz/mainnet/tutorials/proposals';
|
cy.getByTestId('new-proposal-link').click();
|
||||||
cy.getByTestId('new-proposal-link')
|
cy.url().should('include', '/proposals/propose/raw');
|
||||||
.find('a')
|
cy.contains('To see Explorer data on proposals visit').within(() => {
|
||||||
.should('have.attr', 'href', proposalsUrl);
|
cy.getByTestId('external-link').should(
|
||||||
|
'have.attr',
|
||||||
|
'href',
|
||||||
|
'https://explorer.fairground.wtf/governance'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
cy.contains(
|
||||||
|
'1. Sense check your proposal with the community on the forum:'
|
||||||
|
).within(() => {
|
||||||
|
cy.getByTestId('external-link').should(
|
||||||
|
'have.attr',
|
||||||
|
'href',
|
||||||
|
'https://community.vega.xyz/c/governance/25'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
cy.contains(
|
||||||
|
'2. Use the appropriate proposal template in the docs:'
|
||||||
|
).within(() => {
|
||||||
|
cy.getByTestId('external-link').should(
|
||||||
|
'have.attr',
|
||||||
|
'href',
|
||||||
|
'https://docs.vega.xyz/mainnet/tutorials/proposals'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
cy.contains('Connect your wallet to submit a proposal').should(
|
||||||
|
'be.visible'
|
||||||
|
);
|
||||||
|
cy.getByTestId('connect-to-vega-wallet-btn').should('exist');
|
||||||
|
navigateTo(navigation.proposals);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to see a working link for - find out more about Vega governance', function () {
|
it('should be able to see a working link for - find out more about Vega governance', function () {
|
||||||
@@ -156,7 +185,7 @@ context(
|
|||||||
'have.text',
|
'have.text',
|
||||||
'Vega release tag: v1'
|
'Vega release tag: v1'
|
||||||
);
|
);
|
||||||
cy.getByTestId('protocol-upgrade-proposal-block-height').should(
|
cy.getByTestId(proposalUpgradeBlockHeight).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Upgrade block height: 2015942'
|
'Upgrade block height: 2015942'
|
||||||
);
|
);
|
||||||
@@ -171,7 +200,15 @@ context(
|
|||||||
});
|
});
|
||||||
cy.getByTestId(closedProposalToggle).click();
|
cy.getByTestId(closedProposalToggle).click();
|
||||||
cy.getByTestId(closedProposals).within(() => {
|
cy.getByTestId(closedProposals).within(() => {
|
||||||
cy.getByTestId(networkUpgradeProposalListItem).should('have.length', 1);
|
cy.getByTestId(networkUpgradeProposalListItem).should('have.length', 2);
|
||||||
|
cy.getByTestId(networkUpgradeProposalListItem)
|
||||||
|
.first()
|
||||||
|
.within(() => {
|
||||||
|
cy.getByTestId(proposalUpgradeBlockHeight).should(
|
||||||
|
'contain.text',
|
||||||
|
'10001'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -183,7 +220,7 @@ context(
|
|||||||
.first()
|
.first()
|
||||||
.find('[data-testid="view-proposal-btn"]')
|
.find('[data-testid="view-proposal-btn"]')
|
||||||
.click();
|
.click();
|
||||||
cy.url().should('contain', '/protocol-upgrades/v1');
|
cy.url().should('contain', '/protocol-upgrades/v1/2015942');
|
||||||
cy.getByTestId('protocol-upgrade-proposal').within(() => {
|
cy.getByTestId('protocol-upgrade-proposal').within(() => {
|
||||||
cy.get('h1').should('have.text', 'Vega Release v1');
|
cy.get('h1').should('have.text', 'Vega Release v1');
|
||||||
cy.getByTestId('protocol-upgrade-block-height').should(
|
cy.getByTestId('protocol-upgrade-block-height').should(
|
||||||
@@ -243,7 +280,7 @@ context(
|
|||||||
);
|
);
|
||||||
cy.getByTestId('external-link')
|
cy.getByTestId('external-link')
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('contain', '/proposals/protocol-upgrade/v1');
|
.and('contain', '/proposals/protocol-upgrade/v1/2015942');
|
||||||
});
|
});
|
||||||
|
|
||||||
// estimate does not display possibly due to mocks or Cypress unless the proposal is clicked on several times
|
// estimate does not display possibly due to mocks or Cypress unless the proposal is clicked on several times
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ export function getProposalInformationFromTable(heading: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function voteForProposal(vote: string) {
|
export function voteForProposal(vote: string) {
|
||||||
cy.contains('Vote breakdown').should('be.visible', { timeout: 10000 });
|
cy.get(voteButtons).should('be.visible', { timeout: 10000 });
|
||||||
cy.get(voteButtons).contains(vote).click();
|
cy.get(voteButtons).contains(vote).click();
|
||||||
cy.get(dialogTitle, proposalTimeout).should(
|
cy.get(dialogTitle, proposalTimeout).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
|
|||||||
@@ -170,21 +170,20 @@ export function clickOnValidatorFromList(
|
|||||||
validatorName = null
|
validatorName = null
|
||||||
) {
|
) {
|
||||||
cy.contains('Loading...', epochTimeout).should('not.exist');
|
cy.contains('Loading...', epochTimeout).should('not.exist');
|
||||||
waitForBeginningOfEpoch();
|
|
||||||
// below is to ensure validator list is shown
|
// below is to ensure validator list is shown
|
||||||
cy.get(stakeValidatorListName, { timeout: 10000 }).should('exist');
|
cy.get(stakeValidatorListName, { timeout: 10000 }).should('exist');
|
||||||
cy.get(stakeValidatorListPendingStake, txTimeout).should(
|
cy.get(stakeValidatorListPendingStake, txTimeout).should(
|
||||||
'not.contain',
|
'not.contain',
|
||||||
'2,000,000,000,000,000,000.00' // number due to bug #936
|
'2,000,000,000,000,000,000.00' // number due to bug #936
|
||||||
);
|
);
|
||||||
|
waitForBeginningOfEpoch();
|
||||||
if (validatorName) {
|
if (validatorName) {
|
||||||
cy.contains(validatorName).click();
|
cy.contains(validatorName).click();
|
||||||
} else {
|
} else {
|
||||||
cy.get(`[row-id="${validatorNumber}"]`)
|
cy.get(`[row-id="${validatorNumber}"]`)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.first()
|
.first()
|
||||||
.as('validatorOnList');
|
.click();
|
||||||
cy.get('@validatorOnList').click();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +195,7 @@ export function validateValidatorListTotalStakeAndShare(
|
|||||||
cy.contains('Loading...', epochTimeout).should('not.exist');
|
cy.contains('Loading...', epochTimeout).should('not.exist');
|
||||||
waitForBeginningOfEpoch();
|
waitForBeginningOfEpoch();
|
||||||
cy.get(`[row-id="${positionOnList}"]`)
|
cy.get(`[row-id="${positionOnList}"]`)
|
||||||
.eq(1)
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(stakeValidatorListTotalStake, epochTimeout).should(
|
cy.getByTestId(stakeValidatorListTotalStake, epochTimeout).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
@@ -219,7 +218,9 @@ export function ensureSpecifiedUnstakedTokensAreAssociated(
|
|||||||
.eq(1)
|
.eq(1)
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((unstakedBalance) => {
|
.then((unstakedBalance) => {
|
||||||
if (parseFloat(unstakedBalance) != parseFloat(tokenAmount)) {
|
const tokenFloat = parseFloat(tokenAmount);
|
||||||
|
const unstakedFloat = parseFloat(unstakedBalance.replace(/,/g, ''));
|
||||||
|
if (tokenFloat != unstakedFloat) {
|
||||||
vegaWalletTeardown();
|
vegaWalletTeardown();
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||||
'0.00',
|
'0.00',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ NX_FAIRGROUND=false
|
|||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
|||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fa
|
|||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
|
|||||||
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
|
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
NX_TENDERMINT_URL=https://be.vega.community
|
NX_TENDERMINT_URL=https://be.vega.community
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
|
|||||||
NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
|
NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
|
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ NX_DELEGATIONS_PAGINATION=50
|
|||||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||||
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_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ NX_TRANCHES_SERVICE_URL=https://tranches-testnet-k8s.ops.vega.xyz
|
|||||||
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_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
||||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
|||||||
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_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
|
NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
|
||||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ const Web3Container = ({
|
|||||||
<TemplateSidebar sidebar={sideBar}>
|
<TemplateSidebar sidebar={sideBar}>
|
||||||
<AppRouter />
|
<AppRouter />
|
||||||
</TemplateSidebar>
|
</TemplateSidebar>
|
||||||
<footer className="p-4 border-t border-neutral-700">
|
<footer className="p-4 border-t border-neutral-700 break-all">
|
||||||
<NetworkInfo />
|
<NetworkInfo />
|
||||||
</footer>
|
</footer>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
@@ -308,7 +308,7 @@ const AppContainer = () => {
|
|||||||
<Router>
|
<Router>
|
||||||
<ScrollToTop />
|
<ScrollToTop />
|
||||||
<AppStateProvider>
|
<AppStateProvider>
|
||||||
<div className="min-h-full text-white grid">
|
<div className="min-h-full text-white">
|
||||||
<NodeGuard
|
<NodeGuard
|
||||||
skeleton={<div>{t('Loading')}</div>}
|
skeleton={<div>{t('Loading')}</div>}
|
||||||
failure={
|
failure={
|
||||||
|
|||||||
@@ -474,7 +474,7 @@
|
|||||||
"rewardsColLiquidityProvisionHeader": "LIQUIDITY PROVISION",
|
"rewardsColLiquidityProvisionHeader": "LIQUIDITY PROVISION",
|
||||||
"rewardsColLiquidityProvisionTooltip": "Liquidity provision rewards are distributed based on how much you have earned in liquidity fees, funded by a liquidity reward pool for that market",
|
"rewardsColLiquidityProvisionTooltip": "Liquidity provision rewards are distributed based on how much you have earned in liquidity fees, funded by a liquidity reward pool for that market",
|
||||||
"rewardsColMarketCreationHeader": "MARKET CREATION",
|
"rewardsColMarketCreationHeader": "MARKET CREATION",
|
||||||
"rewardsColMarketCreationTooltip": "Market creation rewards are paid out to the creator of any market that exceeds a set threshold of cumulative volume in a given epoch, currently [rewards.marketCreationQuantumMultiple]",
|
"rewardsColMarketCreationTooltip": "Market creation rewards are paid out to the creator of any market that exceeds a set threshold of cumulative volume in a given epoch, currently {{marketCreationQuantumMultiple}}",
|
||||||
"rewardsColTotalHeader": "TOTAL",
|
"rewardsColTotalHeader": "TOTAL",
|
||||||
"ofTotalDistributed": "of total distributed",
|
"ofTotalDistributed": "of total distributed",
|
||||||
"checkBackSoon": "Check back soon",
|
"checkBackSoon": "Check back soon",
|
||||||
@@ -708,7 +708,7 @@
|
|||||||
"NewAssetProposal": "New asset proposal",
|
"NewAssetProposal": "New asset proposal",
|
||||||
"UpdateAssetProposal": "Update asset proposal",
|
"UpdateAssetProposal": "Update asset proposal",
|
||||||
"NewFreeformProposal": "New freeform proposal",
|
"NewFreeformProposal": "New freeform proposal",
|
||||||
"NewRawProposal": "New raw proposal",
|
"NewRawProposal": "New proposal",
|
||||||
"MinProposalRequirements": "You must have at least {{value}} VEGA associated to make a proposal",
|
"MinProposalRequirements": "You must have at least {{value}} VEGA associated to make a proposal",
|
||||||
"MinProposalVoteRequirements": "You must have at least {{value}} VEGA associated to vote on this proposal",
|
"MinProposalVoteRequirements": "You must have at least {{value}} VEGA associated to vote on this proposal",
|
||||||
"totalSupply": "Total Supply",
|
"totalSupply": "Total Supply",
|
||||||
@@ -870,5 +870,9 @@
|
|||||||
"Upgraded at": "Upgraded at",
|
"Upgraded at": "Upgraded at",
|
||||||
"dataIsIdentical": "Data is identical",
|
"dataIsIdentical": "Data is identical",
|
||||||
"updatesToMarket": "Updates to market",
|
"updatesToMarket": "Updates to market",
|
||||||
"viewAsParty": "View as party"
|
"viewAsParty": "View as party",
|
||||||
|
"HowToPropose": "How to make a proposal",
|
||||||
|
"HowToProposeRawStep1": "1. Sense check your proposal with the community on the forum:",
|
||||||
|
"HowToProposeRawStep2": "2. Use the appropriate proposal template in the docs:",
|
||||||
|
"HowToProposeRawStep3": "3. Submit on-chain below"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const HomeProposals = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="mb-16" data-testid="home-proposals">
|
<section className="mb-16 break-all" data-testid="home-proposals">
|
||||||
<Heading title={t('vegaGovernance')} />
|
<Heading title={t('vegaGovernance')} />
|
||||||
<h3 className="mb-6">{t('homeProposalsIntro')}</h3>
|
<h3 className="mb-6">{t('homeProposalsIntro')}</h3>
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
@@ -279,8 +279,8 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
|||||||
trimmedActiveNodes={trimmedActiveNodes}
|
trimmedActiveNodes={trimmedActiveNodes}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section className="grid grid-cols-2 gap-12 mb-16">
|
<section className="flex justify-between flex-wrap gap-12 mb-16">
|
||||||
<div data-testid="home-rewards">
|
<div className="min-w-[360px] flex-1" data-testid="home-rewards">
|
||||||
<Heading title={t('Rewards')} marginTop={false} />
|
<Heading title={t('Rewards')} marginTop={false} />
|
||||||
<h3 className="mb-6">{t('homeRewardsIntro')}</h3>
|
<h3 className="mb-6">{t('homeRewardsIntro')}</h3>
|
||||||
<div className="flex items-center mb-8 gap-4">
|
<div className="flex items-center mb-8 gap-4">
|
||||||
@@ -290,7 +290,7 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-testid="home-vega-token">
|
<div className="min-w-[360px] flex-1" data-testid="home-vega-token">
|
||||||
<Heading title={t('vegaToken')} marginTop={false} />
|
<Heading title={t('vegaToken')} marginTop={false} />
|
||||||
<h3 className="mb-6">{t('homeVegaTokenIntro')}</h3>
|
<h3 className="mb-6">{t('homeVegaTokenIntro')}</h3>
|
||||||
<div className="flex items-center mb-8 gap-4">
|
<div className="flex items-center mb-8 gap-4">
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ export const ProposalHeader = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-testid="proposal-title">
|
<div data-testid="proposal-title" className="break-all">
|
||||||
{isListItem ? (
|
{isListItem ? (
|
||||||
<header>
|
<header>
|
||||||
<SubHeading
|
<SubHeading
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export const Proposal = ({
|
|||||||
voteState={voteState}
|
voteState={voteState}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="my-10">
|
<div className="my-10 break-all">
|
||||||
<ProposalChangeTable proposal={proposal} />
|
<ProposalChangeTable proposal={proposal} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,13 @@ import { ProposalsListItem } from '../proposals-list-item';
|
|||||||
import { ProtocolUpgradeProposalsListItem } from '../protocol-upgrade-proposals-list-item/protocol-upgrade-proposals-list-item';
|
import { ProtocolUpgradeProposalsListItem } from '../protocol-upgrade-proposals-list-item/protocol-upgrade-proposals-list-item';
|
||||||
import { ProposalsListFilter } from '../proposals-list-filter';
|
import { ProposalsListFilter } from '../proposals-list-filter';
|
||||||
import Routes from '../../../routes';
|
import Routes from '../../../routes';
|
||||||
import {
|
import { Button, Toggle } from '@vegaprotocol/ui-toolkit';
|
||||||
Button,
|
|
||||||
Toggle,
|
|
||||||
VegaIcon,
|
|
||||||
VegaIconNames,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||||
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
|
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||||
import { DocsLinks, ExternalLinks } from '@vegaprotocol/environment';
|
import { ExternalLinks } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
interface ProposalsListProps {
|
interface ProposalsListProps {
|
||||||
proposals: Array<ProposalFieldsFragment | ProposalQuery['proposal']>;
|
proposals: Array<ProposalFieldsFragment | ProposalQuery['proposal']>;
|
||||||
@@ -55,7 +50,10 @@ export const orderByUpgradeBlockHeight = (
|
|||||||
) =>
|
) =>
|
||||||
orderBy(
|
orderBy(
|
||||||
arr,
|
arr,
|
||||||
[(p) => p?.upgradeBlockHeight, (p) => p.vegaReleaseTag],
|
[
|
||||||
|
(p) => (p?.upgradeBlockHeight ? parseInt(p.upgradeBlockHeight, 10) : 0),
|
||||||
|
(p) => p.vegaReleaseTag,
|
||||||
|
],
|
||||||
['desc', 'desc']
|
['desc', 'desc']
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -142,18 +140,13 @@ export const ProposalsList = ({
|
|||||||
title={t('pageTitleProposals')}
|
title={t('pageTitleProposals')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{DocsLinks && (
|
<div className="xs:justify-self-end" data-testid="new-proposal-link">
|
||||||
<div className="xs:justify-self-end" data-testid="new-proposal-link">
|
<Link to={`${Routes.PROPOSALS}/propose/raw`}>
|
||||||
<ExternalLink href={DocsLinks.PROPOSALS_GUIDE}>
|
<Button variant="primary" size="sm">
|
||||||
<Button variant="primary" size="sm">
|
<div className="flex items-center gap-1">{t('NewProposal')}</div>
|
||||||
<div className="flex items-center gap-1">
|
</Button>
|
||||||
{t('NewProposal')}
|
</Link>
|
||||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={13} />
|
</div>
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</ExternalLink>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="mb-8">
|
<p className="mb-8">
|
||||||
@@ -224,10 +217,10 @@ export const ProposalsList = ({
|
|||||||
sortedProtocolUpgradeProposals.closed.length > 0 &&
|
sortedProtocolUpgradeProposals.closed.length > 0 &&
|
||||||
filterString.length < 1 && (
|
filterString.length < 1 && (
|
||||||
<div
|
<div
|
||||||
className="grid w-full justify-end xl:-mt-12 pb-6"
|
className="flex justify-end xl:-mt-12 pb-6"
|
||||||
data-testid="toggle-closed-proposals"
|
data-testid="toggle-closed-proposals"
|
||||||
>
|
>
|
||||||
<div className="w-[440px]">
|
<div className="w-full max-w-[420px]">
|
||||||
<Toggle
|
<Toggle
|
||||||
name="closed-proposals-toggle"
|
name="closed-proposals-toggle"
|
||||||
toggles={[
|
toggles={[
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ export const ProtocolUpgradeProposalsListItem = ({
|
|||||||
<Link
|
<Link
|
||||||
to={`${Routes.PROTOCOL_UPGRADES}/${stripFullStops(
|
to={`${Routes.PROTOCOL_UPGRADES}/${stripFullStops(
|
||||||
proposal.vegaReleaseTag
|
proposal.vegaReleaseTag
|
||||||
)}`}
|
)}/${proposal.upgradeBlockHeight}`}
|
||||||
>
|
>
|
||||||
<Button data-testid="view-proposal-btn">{t('viewDetails')}</Button>
|
<Button data-testid="view-proposal-btn">{t('viewDetails')}</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -130,7 +130,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
? t('byTokenVote')
|
? t('byTokenVote')
|
||||||
: t('byLiquidityVote');
|
: t('byLiquidityVote');
|
||||||
|
|
||||||
const sectionWrapperClasses = classNames('grid sm:grid-cols-2 gap-6');
|
const sectionWrapperClasses = classNames(
|
||||||
|
'flex justify-between flex-wrap gap-6'
|
||||||
|
);
|
||||||
|
const sectionClasses = classNames('min-w-[300px] flex-1 flex-grow');
|
||||||
const headingClasses = classNames('mb-2 text-vega-dark-400');
|
const headingClasses = classNames('mb-2 text-vega-dark-400');
|
||||||
const progressDetailsClasses = classNames(
|
const progressDetailsClasses = classNames(
|
||||||
'flex justify-between flex-wrap mt-2 text-sm'
|
'flex justify-between flex-wrap mt-2 text-sm'
|
||||||
@@ -166,7 +169,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
||||||
<div className={sectionWrapperClasses}>
|
<div className={sectionWrapperClasses}>
|
||||||
<section data-testid="lp-majority-breakdown">
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="lp-majority-breakdown"
|
||||||
|
>
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
percentageFor={yesLPPercentage}
|
percentageFor={yesLPPercentage}
|
||||||
colourfulBg={true}
|
colourfulBg={true}
|
||||||
@@ -241,7 +247,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-testid="lp-participation-breakdown">
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="lp-participation-breakdown"
|
||||||
|
>
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
percentageFor={
|
percentageFor={
|
||||||
lpParticipationThresholdProgress || new BigNumber(0)
|
lpParticipationThresholdProgress || new BigNumber(0)
|
||||||
@@ -288,7 +297,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
|
|
||||||
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
|
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
|
||||||
<div className={sectionWrapperClasses}>
|
<div className={sectionWrapperClasses}>
|
||||||
<section data-testid="token-majority-breakdown">
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="token-majority-breakdown"
|
||||||
|
>
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
percentageFor={yesPercentage}
|
percentageFor={yesPercentage}
|
||||||
colourfulBg={true}
|
colourfulBg={true}
|
||||||
@@ -308,7 +320,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<span>{t('tokenVotesFor')}:</span>
|
<span>{t('tokenVotesFor')}:</span>
|
||||||
<Tooltip description={formatNumber(yesTokens, defaultDP)}>
|
<Tooltip description={formatNumber(yesTokens, defaultDP)}>
|
||||||
<button>
|
<button data-testid="num-votes-for">
|
||||||
{yesTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
{yesTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -317,7 +329,9 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
description={<span>{yesPercentage.toFixed(defaultDP)}%</span>}
|
description={<span>{yesPercentage.toFixed(defaultDP)}%</span>}
|
||||||
>
|
>
|
||||||
<button>{yesPercentage.toFixed(0)}%</button>
|
<button data-testid="votes-for-percentage">
|
||||||
|
{yesPercentage.toFixed(0)}%
|
||||||
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
</span>
|
</span>
|
||||||
@@ -326,7 +340,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<span>{t('tokenVotesAgainst')}:</span>
|
<span>{t('tokenVotesAgainst')}:</span>
|
||||||
<Tooltip description={formatNumber(noTokens, defaultDP)}>
|
<Tooltip description={formatNumber(noTokens, defaultDP)}>
|
||||||
<button>
|
<button data-testid="num-votes-against">
|
||||||
{noTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
{noTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -335,7 +349,9 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
description={<span>{noPercentage.toFixed(defaultDP)}%</span>}
|
description={<span>{noPercentage.toFixed(defaultDP)}%</span>}
|
||||||
>
|
>
|
||||||
<button>{noPercentage.toFixed(0)}%</button>
|
<button data-testid="votes-against-percentage">
|
||||||
|
{noPercentage.toFixed(0)}%
|
||||||
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
</span>
|
</span>
|
||||||
@@ -343,7 +359,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-testid="token-participation-breakdown">
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="token-participation-breakdown"
|
||||||
|
>
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
percentageFor={participationThresholdProgress}
|
percentageFor={participationThresholdProgress}
|
||||||
testId="token-participation-progress"
|
testId="token-participation-progress"
|
||||||
@@ -364,11 +383,13 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
|||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<span>{t('totalTokensVoted')}:</span>
|
<span>{t('totalTokensVoted')}:</span>
|
||||||
<Tooltip description={formatNumber(totalTokensVoted, defaultDP)}>
|
<Tooltip description={formatNumber(totalTokensVoted, defaultDP)}>
|
||||||
<button>
|
<button data-testid="total-voted">
|
||||||
{totalTokensVoted.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
{totalTokensVoted.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<span>({totalTokensPercentage.toFixed(defaultDP)}%)</span>
|
<span data-testid="total-voted-percentage">
|
||||||
|
({totalTokensPercentage.toFixed(defaultDP)}%)
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ import { MockedProvider } from '@apollo/client/testing';
|
|||||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||||
import { ProposalDocument } from './__generated__/Proposal';
|
import { ProposalDocument } from './__generated__/Proposal';
|
||||||
|
|
||||||
|
jest.mock('@vegaprotocol/data-provider', () => ({
|
||||||
|
...jest.requireActual('@vegaprotocol/data-provider'),
|
||||||
|
useDataProvider: jest.fn(() => ({ data: [], loading: false })),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('../components/proposal', () => ({
|
jest.mock('../components/proposal', () => ({
|
||||||
Proposal: () => <div data-testid="proposal" />,
|
Proposal: () => <div data-testid="proposal" />,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
import {
|
||||||
import { Heading } from '../../../../components/heading';
|
useEnvironment,
|
||||||
|
DocsLinks,
|
||||||
|
ExternalLinks,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
|
import { Heading, SubHeading } from '../../../../components/heading';
|
||||||
import {
|
import {
|
||||||
AsyncRenderer,
|
AsyncRenderer,
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
InputError,
|
InputError,
|
||||||
|
RoundedWrapper,
|
||||||
TextArea,
|
TextArea,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { validateJson } from '@vegaprotocol/utils';
|
import { validateJson } from '@vegaprotocol/utils';
|
||||||
@@ -79,15 +84,6 @@ export const ProposeRaw = () => {
|
|||||||
spamProtectionMin={params.spam_protection_proposal_min_tokens}
|
spamProtectionMin={params.spam_protection_proposal_min_tokens}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{DocsLinks && (
|
|
||||||
<p className="text-sm" data-testid="proposal-docs-link">
|
|
||||||
<span className="mr-1">{t('ProposalTermsText')}</span>
|
|
||||||
<ExternalLink href={DocsLinks.PROPOSALS_GUIDE} target="_blank">
|
|
||||||
{DocsLinks.PROPOSALS_GUIDE}
|
|
||||||
</ExternalLink>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{VEGA_EXPLORER_URL && (
|
{VEGA_EXPLORER_URL && (
|
||||||
<p className="text-sm">
|
<p className="text-sm">
|
||||||
{t('MoreProposalsInfo')}{' '}
|
{t('MoreProposalsInfo')}{' '}
|
||||||
@@ -98,12 +94,44 @@ export const ProposeRaw = () => {
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<section data-testid="how-to" className="my-10">
|
||||||
|
<RoundedWrapper paddingBottom={true}>
|
||||||
|
<SubHeading title={t('HowToPropose')} />
|
||||||
|
<ul>
|
||||||
|
<li className="p-1">
|
||||||
|
{t('HowToProposeRawStep1')}{' '}
|
||||||
|
{ExternalLinks && (
|
||||||
|
<span data-testid="proposal-docs-link">
|
||||||
|
<ExternalLink
|
||||||
|
href={ExternalLinks.PROPOSALS_FORUM}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{ExternalLinks.PROPOSALS_FORUM}
|
||||||
|
</ExternalLink>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
<li className="p-1">
|
||||||
|
{t('HowToProposeRawStep2')}{' '}
|
||||||
|
{DocsLinks && (
|
||||||
|
<span data-testid="proposal-docs-link">
|
||||||
|
<ExternalLink
|
||||||
|
href={DocsLinks.PROPOSALS_GUIDE}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{DocsLinks.PROPOSALS_GUIDE}
|
||||||
|
</ExternalLink>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
<li className="p-1">{t('HowToProposeRawStep3')}</li>
|
||||||
|
</ul>
|
||||||
|
</RoundedWrapper>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div data-testid="raw-proposal-form">
|
<div data-testid="raw-proposal-form">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<FormGroup
|
<FormGroup label="Valid JSON required" labelFor="proposal-data">
|
||||||
label="Make a proposal by submitting JSON"
|
|
||||||
labelFor="proposal-data"
|
|
||||||
>
|
|
||||||
<TextArea
|
<TextArea
|
||||||
id="proposal-data"
|
id="proposal-data"
|
||||||
className="min-h-[200px]"
|
className="min-h-[200px]"
|
||||||
|
|||||||
+4
-1
@@ -43,7 +43,10 @@ describe('EpochIndividualRewardsTable', () => {
|
|||||||
it('should render correctly', () => {
|
it('should render correctly', () => {
|
||||||
const { getByTestId } = render(
|
const { getByTestId } = render(
|
||||||
<AppStateProvider>
|
<AppStateProvider>
|
||||||
<EpochIndividualRewardsTable data={mockData} />
|
<EpochIndividualRewardsTable
|
||||||
|
data={mockData}
|
||||||
|
marketCreationQuantumMultiple={'1000'}
|
||||||
|
/>
|
||||||
</AppStateProvider>
|
</AppStateProvider>
|
||||||
);
|
);
|
||||||
expect(getByTestId('epoch-individual-rewards-table')).toBeInTheDocument();
|
expect(getByTestId('epoch-individual-rewards-table')).toBeInTheDocument();
|
||||||
|
|||||||
+3
@@ -8,6 +8,7 @@ import type { EpochIndividualReward } from './generate-epoch-individual-rewards-
|
|||||||
|
|
||||||
interface EpochIndividualRewardsGridProps {
|
interface EpochIndividualRewardsGridProps {
|
||||||
data: EpochIndividualReward;
|
data: EpochIndividualReward;
|
||||||
|
marketCreationQuantumMultiple: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RewardItemProps {
|
interface RewardItemProps {
|
||||||
@@ -69,9 +70,11 @@ const RewardItem = ({
|
|||||||
|
|
||||||
export const EpochIndividualRewardsTable = ({
|
export const EpochIndividualRewardsTable = ({
|
||||||
data,
|
data,
|
||||||
|
marketCreationQuantumMultiple,
|
||||||
}: EpochIndividualRewardsGridProps) => {
|
}: EpochIndividualRewardsGridProps) => {
|
||||||
return (
|
return (
|
||||||
<RewardsTable
|
<RewardsTable
|
||||||
|
marketCreationQuantumMultiple={marketCreationQuantumMultiple}
|
||||||
dataTestId="epoch-individual-rewards-table"
|
dataTestId="epoch-individual-rewards-table"
|
||||||
epoch={Number(data.epoch)}
|
epoch={Number(data.epoch)}
|
||||||
>
|
>
|
||||||
|
|||||||
+15
-4
@@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useEffect, useState, useCallback } from 'react';
|
import { useMemo, useEffect, useState, useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { AsyncRenderer, Pagination } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Pagination } from '@vegaprotocol/ui-toolkit';
|
||||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||||
@@ -9,6 +9,7 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
|||||||
import { EpochIndividualRewardsTable } from './epoch-individual-rewards-table';
|
import { EpochIndividualRewardsTable } from './epoch-individual-rewards-table';
|
||||||
import { generateEpochIndividualRewardsList } from './generate-epoch-individual-rewards-list';
|
import { generateEpochIndividualRewardsList } from './generate-epoch-individual-rewards-list';
|
||||||
import { calculateEpochOffset } from '../../../lib/epoch-pagination';
|
import { calculateEpochOffset } from '../../../lib/epoch-pagination';
|
||||||
|
import { useNetworkParam } from '@vegaprotocol/network-parameters';
|
||||||
|
|
||||||
const EPOCHS_PAGE_SIZE = 10;
|
const EPOCHS_PAGE_SIZE = 10;
|
||||||
|
|
||||||
@@ -26,6 +27,9 @@ export const EpochIndividualRewards = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const { delegationsPagination } = ENV;
|
const { delegationsPagination } = ENV;
|
||||||
|
const { param: marketCreationQuantumMultiple } = useNetworkParam(
|
||||||
|
'rewards_marketCreationQuantumMultiple'
|
||||||
|
);
|
||||||
|
|
||||||
const { data, loading, error, refetch } = useRewardsQuery({
|
const { data, loading, error, refetch } = useRewardsQuery({
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
@@ -82,12 +86,18 @@ export const EpochIndividualRewards = ({
|
|||||||
[epochId, page, refetch, delegationsPagination, pubKey]
|
[epochId, page, refetch, delegationsPagination, pubKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const prevEpochIdRef = useRef<number | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// when the epoch changes, we want to refetch the data to update the current page
|
if (prevEpochIdRef.current === null) {
|
||||||
if (data) {
|
prevEpochIdRef.current = epochId;
|
||||||
|
} else if (epochId !== prevEpochIdRef.current) {
|
||||||
|
// When the epoch changes, we want to refetch the data to update the current page
|
||||||
refetchData();
|
refetchData();
|
||||||
}
|
}
|
||||||
}, [epochId, data, refetchData]);
|
|
||||||
|
prevEpochIdRef.current = epochId;
|
||||||
|
}, [epochId, refetchData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer
|
<AsyncRenderer
|
||||||
@@ -103,6 +113,7 @@ export const EpochIndividualRewards = ({
|
|||||||
{epochIndividualRewardSummaries.map(
|
{epochIndividualRewardSummaries.map(
|
||||||
(epochIndividualRewardSummary) => (
|
(epochIndividualRewardSummary) => (
|
||||||
<EpochIndividualRewardsTable
|
<EpochIndividualRewardsTable
|
||||||
|
marketCreationQuantumMultiple={marketCreationQuantumMultiple}
|
||||||
data={epochIndividualRewardSummary}
|
data={epochIndividualRewardSummary}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-1
@@ -66,7 +66,10 @@ describe('EpochTotalRewardsTable', () => {
|
|||||||
it('should render correctly', () => {
|
it('should render correctly', () => {
|
||||||
const { getByTestId } = render(
|
const { getByTestId } = render(
|
||||||
<AppStateProvider>
|
<AppStateProvider>
|
||||||
<EpochTotalRewardsTable data={mockData} />
|
<EpochTotalRewardsTable
|
||||||
|
data={mockData}
|
||||||
|
marketCreationQuantumMultiple={'1000'}
|
||||||
|
/>
|
||||||
</AppStateProvider>
|
</AppStateProvider>
|
||||||
);
|
);
|
||||||
expect(getByTestId('epoch-total-rewards-table')).toBeInTheDocument();
|
expect(getByTestId('epoch-total-rewards-table')).toBeInTheDocument();
|
||||||
|
|||||||
+7
-1
@@ -8,6 +8,7 @@ import type { EpochTotalSummary } from './generate-epoch-total-rewards-list';
|
|||||||
|
|
||||||
interface EpochTotalRewardsGridProps {
|
interface EpochTotalRewardsGridProps {
|
||||||
data: EpochTotalSummary;
|
data: EpochTotalSummary;
|
||||||
|
marketCreationQuantumMultiple: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RewardItemProps {
|
interface RewardItemProps {
|
||||||
@@ -52,9 +53,14 @@ const RewardItem = ({
|
|||||||
|
|
||||||
export const EpochTotalRewardsTable = ({
|
export const EpochTotalRewardsTable = ({
|
||||||
data,
|
data,
|
||||||
|
marketCreationQuantumMultiple,
|
||||||
}: EpochTotalRewardsGridProps) => {
|
}: EpochTotalRewardsGridProps) => {
|
||||||
return (
|
return (
|
||||||
<RewardsTable dataTestId="epoch-total-rewards-table" epoch={data.epoch}>
|
<RewardsTable
|
||||||
|
marketCreationQuantumMultiple={marketCreationQuantumMultiple}
|
||||||
|
dataTestId="epoch-total-rewards-table"
|
||||||
|
epoch={data.epoch}
|
||||||
|
>
|
||||||
{Array.from(data.assetRewards.values()).map(
|
{Array.from(data.assetRewards.values()).map(
|
||||||
({ name, rewards, totalAmount, decimals }, i) => (
|
({ name, rewards, totalAmount, decimals }, i) => (
|
||||||
<div className="contents" key={i}>
|
<div className="contents" key={i}>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useEpochAssetsRewardsQuery } from '../home/__generated__/Rewards';
|
|||||||
import { generateEpochTotalRewardsList } from './generate-epoch-total-rewards-list';
|
import { generateEpochTotalRewardsList } from './generate-epoch-total-rewards-list';
|
||||||
import { EpochTotalRewardsTable } from './epoch-total-rewards-table';
|
import { EpochTotalRewardsTable } from './epoch-total-rewards-table';
|
||||||
import { calculateEpochOffset } from '../../../lib/epoch-pagination';
|
import { calculateEpochOffset } from '../../../lib/epoch-pagination';
|
||||||
|
import { useNetworkParam } from '@vegaprotocol/network-parameters';
|
||||||
|
|
||||||
const EPOCHS_PAGE_SIZE = 10;
|
const EPOCHS_PAGE_SIZE = 10;
|
||||||
|
|
||||||
@@ -18,6 +19,9 @@ export const EpochTotalRewards = ({ currentEpoch }: EpochTotalRewardsProps) => {
|
|||||||
const epochId = Number(currentEpoch.id) - 1;
|
const epochId = Number(currentEpoch.id) - 1;
|
||||||
const totalPages = Math.ceil(epochId / EPOCHS_PAGE_SIZE);
|
const totalPages = Math.ceil(epochId / EPOCHS_PAGE_SIZE);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { param: marketCreationQuantumMultiple } = useNetworkParam(
|
||||||
|
'rewards_marketCreationQuantumMultiple'
|
||||||
|
);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const { data, loading, error, refetch } = useEpochAssetsRewardsQuery({
|
const { data, loading, error, refetch } = useEpochAssetsRewardsQuery({
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
@@ -70,7 +74,11 @@ export const EpochTotalRewards = ({ currentEpoch }: EpochTotalRewardsProps) => {
|
|||||||
>
|
>
|
||||||
{Array.from(epochTotalRewardSummaries.values()).map(
|
{Array.from(epochTotalRewardSummaries.values()).map(
|
||||||
(epochTotalSummary, index) => (
|
(epochTotalSummary, index) => (
|
||||||
<EpochTotalRewardsTable data={epochTotalSummary} key={index} />
|
<EpochTotalRewardsTable
|
||||||
|
marketCreationQuantumMultiple={marketCreationQuantumMultiple}
|
||||||
|
data={epochTotalSummary}
|
||||||
|
key={index}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
<Pagination
|
<Pagination
|
||||||
|
|||||||
@@ -133,24 +133,26 @@ export const RewardsPage = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-[360px]">
|
<div className="flex justify-end">
|
||||||
<Toggle
|
<div className="w-full max-w-[360px]">
|
||||||
name="epoch-reward-view-toggle"
|
<Toggle
|
||||||
toggles={[
|
name="epoch-reward-view-toggle"
|
||||||
{
|
toggles={[
|
||||||
label: t('totalDistributed'),
|
{
|
||||||
value: 'total',
|
label: t('totalDistributed'),
|
||||||
},
|
value: 'total',
|
||||||
{
|
},
|
||||||
label: t('earnedByMe'),
|
{
|
||||||
value: 'individual',
|
label: t('earnedByMe'),
|
||||||
},
|
value: 'individual',
|
||||||
]}
|
},
|
||||||
checkedValue={toggleRewardsView}
|
]}
|
||||||
onChange={(e) =>
|
checkedValue={toggleRewardsView}
|
||||||
setToggleRewardsView(e.target.value as RewardsView)
|
onChange={(e) =>
|
||||||
}
|
setToggleRewardsView(e.target.value as RewardsView)
|
||||||
/>
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -77,7 +77,11 @@ const ColumnHeader = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const ColumnHeaders = () => {
|
const ColumnHeaders = ({
|
||||||
|
marketCreationQuantumMultiple,
|
||||||
|
}: {
|
||||||
|
marketCreationQuantumMultiple: string | null;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className="contents">
|
<div className="contents">
|
||||||
@@ -89,7 +93,9 @@ const ColumnHeaders = () => {
|
|||||||
<ColumnHeader
|
<ColumnHeader
|
||||||
key={columnTitle}
|
key={columnTitle}
|
||||||
title={t(columnTitle)}
|
title={t(columnTitle)}
|
||||||
tooltipContent={t(description)}
|
tooltipContent={t(description, {
|
||||||
|
marketCreationQuantumMultiple,
|
||||||
|
})}
|
||||||
className={headerGridItemStyles()}
|
className={headerGridItemStyles()}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -105,6 +111,7 @@ export interface RewardTableProps {
|
|||||||
dataTestId: string;
|
dataTestId: string;
|
||||||
epoch: number;
|
epoch: number;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
marketCreationQuantumMultiple: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewards table children will be the row items. Make sure they contain
|
// Rewards table children will be the row items. Make sure they contain
|
||||||
@@ -113,12 +120,15 @@ export const RewardsTable = ({
|
|||||||
dataTestId,
|
dataTestId,
|
||||||
epoch,
|
epoch,
|
||||||
children,
|
children,
|
||||||
|
marketCreationQuantumMultiple,
|
||||||
}: RewardTableProps) => (
|
}: RewardTableProps) => (
|
||||||
<div data-testid={dataTestId} className="mb-12">
|
<div data-testid={dataTestId} className="mb-12">
|
||||||
<SubHeading title={`EPOCH ${epoch}`} />
|
<SubHeading title={`EPOCH ${epoch}`} />
|
||||||
|
|
||||||
<div className={gridStyles}>
|
<div className={gridStyles}>
|
||||||
<ColumnHeaders />
|
<ColumnHeaders
|
||||||
|
marketCreationQuantumMultiple={marketCreationQuantumMultiple}
|
||||||
|
/>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ const routerConfig = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${Routes.PROTOCOL_UPGRADES}/:proposalReleaseTag`,
|
path: `${Routes.PROTOCOL_UPGRADES}/:proposalReleaseTag/:proposalBlockHeight`,
|
||||||
element: <LazyProtocolUpgradeProposal />,
|
element: <LazyProtocolUpgradeProposal />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+5
-7
@@ -3,7 +3,7 @@ import { forwardRef, useMemo, useRef, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
|
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
||||||
import { BigNumber } from '../../../../lib/bignumber';
|
import { BigNumber } from '../../../../lib/bignumber';
|
||||||
import {
|
import {
|
||||||
@@ -85,17 +85,17 @@ const TopThirdCellRenderer = (
|
|||||||
}}
|
}}
|
||||||
className="grid grid-cols-[60px_1fr] w-full h-full py-4 px-0 text-sm text-white text-center overflow-scroll"
|
className="grid grid-cols-[60px_1fr] w-full h-full py-4 px-0 text-sm text-white text-center overflow-scroll"
|
||||||
>
|
>
|
||||||
<div className="text-xs text-left px-3">
|
<div className="px-3 text-xs text-left">
|
||||||
{params?.data?.rankingDisplay}
|
{params?.data?.rankingDisplay}
|
||||||
</div>
|
</div>
|
||||||
<div className="whitespace-normal px-3">
|
<div className="px-3 whitespace-normal">
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<Button
|
<Button
|
||||||
data-testid="show-all-validators"
|
data-testid="show-all-validators"
|
||||||
rightIcon={
|
rightIcon={
|
||||||
<Icon
|
<Icon
|
||||||
name="arrow-right"
|
name="arrow-right"
|
||||||
className="fill-current mr-2 align-text-top"
|
className="mr-2 align-text-top fill-current"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
className="inline-flex items-center"
|
className="inline-flex items-center"
|
||||||
@@ -103,7 +103,7 @@ const TopThirdCellRenderer = (
|
|||||||
{t('Reveal top validators')}
|
{t('Reveal top validators')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<p className="font-semibold text-white mb-0">
|
<p className="mb-0 font-semibold text-white">
|
||||||
{t(
|
{t(
|
||||||
'Validators with too great a stake share will have the staking rewards for their delegators penalised.'
|
'Validators with too great a stake share will have the staking rewards for their delegators penalised.'
|
||||||
)}
|
)}
|
||||||
@@ -352,7 +352,6 @@ export const ConsensusValidatorsTable = ({
|
|||||||
field: ValidatorFields.RANKING_INDEX,
|
field: ValidatorFields.RANKING_INDEX,
|
||||||
headerName: '#',
|
headerName: '#',
|
||||||
width: 60,
|
width: 60,
|
||||||
pinned: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.VALIDATOR,
|
field: ValidatorFields.VALIDATOR,
|
||||||
@@ -362,7 +361,6 @@ export const ConsensusValidatorsTable = ({
|
|||||||
if (a === b) return 0;
|
if (a === b) return 0;
|
||||||
return a > b ? 1 : -1;
|
return a > b ? 1 : -1;
|
||||||
},
|
},
|
||||||
pinned: 'left',
|
|
||||||
width: 260,
|
width: 260,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-3
@@ -1,7 +1,7 @@
|
|||||||
import { forwardRef, useMemo, useRef } from 'react';
|
import { forwardRef, useMemo, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
||||||
import { BigNumber } from '../../../../lib/bignumber';
|
import { BigNumber } from '../../../../lib/bignumber';
|
||||||
import {
|
import {
|
||||||
@@ -195,14 +195,12 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
field: ValidatorFields.RANKING_INDEX,
|
field: ValidatorFields.RANKING_INDEX,
|
||||||
headerName: '#',
|
headerName: '#',
|
||||||
width: 60,
|
width: 60,
|
||||||
pinned: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.VALIDATOR,
|
field: ValidatorFields.VALIDATOR,
|
||||||
headerName: t(ValidatorFields.VALIDATOR).toString(),
|
headerName: t(ValidatorFields.VALIDATOR).toString(),
|
||||||
cellRenderer: ValidatorRenderer,
|
cellRenderer: ValidatorRenderer,
|
||||||
comparator: ({ name: a }, { name: b }) => Math.sign(a - b),
|
comparator: ({ name: a }, { name: b }) => Math.sign(a - b),
|
||||||
pinned: 'left',
|
|
||||||
width: 260,
|
width: 260,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,38 +122,43 @@ export const ValidatorTable = ({
|
|||||||
|
|
||||||
<div className="my-12" data-testid="validator-table">
|
<div className="my-12" data-testid="validator-table">
|
||||||
<SubHeading title={t('profile')} />
|
<SubHeading title={t('profile')} />
|
||||||
<RoundedWrapper paddingBottom={true}>
|
<div className="break-all">
|
||||||
<KeyValueTable data-testid="validator-table-profile">
|
<RoundedWrapper paddingBottom={true}>
|
||||||
<KeyValueTableRow>
|
<KeyValueTable data-testid="validator-table-profile">
|
||||||
<span>{t('id')}</span>
|
<KeyValueTableRow>
|
||||||
<ValidatorTableCell dataTestId="validator-id">
|
<span>{t('id')}</span>
|
||||||
{node.id}
|
<ValidatorTableCell dataTestId="validator-id">
|
||||||
</ValidatorTableCell>
|
{node.id}
|
||||||
</KeyValueTableRow>
|
</ValidatorTableCell>
|
||||||
<KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<span>{t('ABOUT THIS VALIDATOR')}</span>
|
<KeyValueTableRow>
|
||||||
|
<span>{t('ABOUT THIS VALIDATOR')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('AboutThisValidatorDescription')}>
|
<Tooltip description={t('AboutThisValidatorDescription')}>
|
||||||
<a data-testid="validator-description-url" href={node.infoUrl}>
|
<a
|
||||||
{node.infoUrl}
|
data-testid="validator-description-url"
|
||||||
</a>
|
href={node.infoUrl}
|
||||||
</Tooltip>
|
>
|
||||||
</KeyValueTableRow>
|
{node.infoUrl}
|
||||||
<KeyValueTableRow noBorder={true}>
|
</a>
|
||||||
<span>
|
</Tooltip>
|
||||||
<strong>{t('STATUS')}</strong>
|
</KeyValueTableRow>
|
||||||
</span>
|
<KeyValueTableRow noBorder={true}>
|
||||||
|
<span>
|
||||||
<Tooltip description={t('ValidatorStatusDescription')}>
|
<strong>{t('STATUS')}</strong>
|
||||||
<span data-testid="validator-status">
|
|
||||||
<strong>
|
|
||||||
{t(statusTranslationKey(node.rankingScore.status))}
|
|
||||||
</strong>
|
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
|
||||||
</KeyValueTableRow>
|
<Tooltip description={t('ValidatorStatusDescription')}>
|
||||||
</KeyValueTable>
|
<span data-testid="validator-status">
|
||||||
</RoundedWrapper>
|
<strong>
|
||||||
|
{t(statusTranslationKey(node.rankingScore.status))}
|
||||||
|
</strong>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
</KeyValueTable>
|
||||||
|
</RoundedWrapper>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mb-10">
|
<div className="mb-10">
|
||||||
{t('validatorTableIntro')}{' '}
|
{t('validatorTableIntro')}{' '}
|
||||||
@@ -167,144 +172,154 @@ export const ValidatorTable = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SubHeading title={t('ADDRESS')} />
|
<SubHeading title={t('ADDRESS')} />
|
||||||
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
<div className="break-all">
|
||||||
<KeyValueTable data-testid="validator-table-address">
|
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
||||||
<KeyValueTableRow>
|
<KeyValueTable data-testid="validator-table-address">
|
||||||
<span>{t('VEGA ADDRESS / PUBLIC KEY')}</span>
|
<KeyValueTableRow>
|
||||||
<ValidatorTableCell dataTestId="validator-public-key">
|
<span>{t('VEGA ADDRESS / PUBLIC KEY')}</span>
|
||||||
{node.pubkey}
|
<ValidatorTableCell dataTestId="validator-public-key">
|
||||||
</ValidatorTableCell>
|
{node.pubkey}
|
||||||
</KeyValueTableRow>
|
</ValidatorTableCell>
|
||||||
<KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<span>{t('SERVER LOCATION')}</span>
|
<KeyValueTableRow>
|
||||||
<ValidatorTableCell dataTestId="validator-server-location">
|
<span>{t('SERVER LOCATION')}</span>
|
||||||
{countryData.find((c) => c.code === node.location)?.name ||
|
<ValidatorTableCell dataTestId="validator-server-location">
|
||||||
t('not available')}
|
{countryData.find((c) => c.code === node.location)?.name ||
|
||||||
</ValidatorTableCell>
|
t('not available')}
|
||||||
</KeyValueTableRow>
|
</ValidatorTableCell>
|
||||||
<KeyValueTableRow noBorder={true}>
|
</KeyValueTableRow>
|
||||||
<span>{t('ETHEREUM ADDRESS')}</span>
|
<KeyValueTableRow noBorder={true}>
|
||||||
<span data-testid="validator-eth-address">
|
<span>{t('ETHEREUM ADDRESS')}</span>
|
||||||
<Link
|
<span data-testid="validator-eth-address">
|
||||||
title={t('View on Etherscan (opens in a new tab)')}
|
<Link
|
||||||
href={`${ETHERSCAN_URL}/address/${node.ethereumAddress}`}
|
title={t('View on Etherscan (opens in a new tab)')}
|
||||||
target="_blank"
|
href={`${ETHERSCAN_URL}/address/${node.ethereumAddress}`}
|
||||||
>
|
target="_blank"
|
||||||
{node.ethereumAddress}
|
>
|
||||||
</Link>
|
{node.ethereumAddress}
|
||||||
</span>
|
</Link>
|
||||||
</KeyValueTableRow>
|
</span>
|
||||||
</KeyValueTable>
|
</KeyValueTableRow>
|
||||||
</RoundedWrapper>
|
</KeyValueTable>
|
||||||
|
</RoundedWrapper>
|
||||||
|
</div>
|
||||||
|
|
||||||
<SubHeading title={t('STAKE')} />
|
<SubHeading title={t('STAKE')} />
|
||||||
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
<div className="break-all">
|
||||||
<KeyValueTable data-testid="validator-table-stake">
|
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
||||||
<KeyValueTableRow>
|
<KeyValueTable data-testid="validator-table-stake">
|
||||||
<span>{t('STAKED BY OPERATOR')}</span>
|
<KeyValueTableRow>
|
||||||
|
<span>{t('STAKED BY OPERATOR')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('StakedByOperatorDescription')}>
|
<Tooltip description={t('StakedByOperatorDescription')}>
|
||||||
<span data-testid="staked-by-operator">
|
<span data-testid="staked-by-operator">
|
||||||
{formatNumber(toBigNum(node.stakedByOperator, decimals))}
|
{formatNumber(toBigNum(node.stakedByOperator, decimals))}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
<KeyValueTableRow>
|
||||||
|
<span>{t('STAKED BY DELEGATES')}</span>
|
||||||
|
|
||||||
|
<Tooltip description={t('StakedByDelegatesDescription')}>
|
||||||
|
<span data-testid="staked-by-delegates">
|
||||||
|
{formatNumber(toBigNum(node.stakedByDelegates, decimals))}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
<KeyValueTableRow>
|
||||||
|
<span>
|
||||||
|
<strong>{t('TOTAL STAKE')}</strong>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
<KeyValueTableRow>
|
|
||||||
<span>{t('STAKED BY DELEGATES')}</span>
|
|
||||||
|
|
||||||
<Tooltip description={t('StakedByDelegatesDescription')}>
|
<span data-testid="total-stake">
|
||||||
<span data-testid="staked-by-delegates">
|
<strong>
|
||||||
{formatNumber(toBigNum(node.stakedByDelegates, decimals))}
|
{formatNumber(toBigNum(node.stakedTotal, decimals))}
|
||||||
|
</strong>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</KeyValueTableRow>
|
||||||
</KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<span>{t('PENDING STAKE')}</span>
|
||||||
<span>
|
|
||||||
<strong>{t('TOTAL STAKE')}</strong>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span data-testid="total-stake">
|
<Tooltip description={t('PendingStakeDescription')}>
|
||||||
<strong>
|
<span data-testid="pending-stake">
|
||||||
{formatNumber(toBigNum(node.stakedTotal, decimals))}
|
{formatNumber(toBigNum(node.pendingStake, decimals))}
|
||||||
</strong>
|
</span>
|
||||||
</span>
|
</Tooltip>
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow noBorder={true}>
|
||||||
<span>{t('PENDING STAKE')}</span>
|
<span>{t('STAKE SHARE')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('PendingStakeDescription')}>
|
<Tooltip description={t('StakeShareDescription')}>
|
||||||
<span data-testid="pending-stake">
|
<span data-testid="stake-percentage">{stakePercentage}</span>
|
||||||
{formatNumber(toBigNum(node.pendingStake, decimals))}
|
</Tooltip>
|
||||||
</span>
|
</KeyValueTableRow>
|
||||||
</Tooltip>
|
</KeyValueTable>
|
||||||
</KeyValueTableRow>
|
</RoundedWrapper>
|
||||||
<KeyValueTableRow noBorder={true}>
|
</div>
|
||||||
<span>{t('STAKE SHARE')}</span>
|
|
||||||
|
|
||||||
<Tooltip description={t('StakeShareDescription')}>
|
|
||||||
<span data-testid="stake-percentage">{stakePercentage}</span>
|
|
||||||
</Tooltip>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
</KeyValueTable>
|
|
||||||
</RoundedWrapper>
|
|
||||||
|
|
||||||
<SubHeading title={t('PENALTIES')} />
|
<SubHeading title={t('PENALTIES')} />
|
||||||
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
<div className="break-all">
|
||||||
<KeyValueTable data-testid="validator-table-penalties">
|
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
||||||
<KeyValueTableRow>
|
<KeyValueTable data-testid="validator-table-penalties">
|
||||||
<span>{t('OVERSTAKED PENALTY')}</span>
|
<KeyValueTableRow>
|
||||||
|
<span>{t('OVERSTAKED PENALTY')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('OverstakedPenaltyDescription')}>
|
<Tooltip description={t('OverstakedPenaltyDescription')}>
|
||||||
<span data-testid="overstaking-penalty">
|
<span data-testid="overstaking-penalty">
|
||||||
{formatNumberPercentage(penalties.overstaked, 2)}
|
{formatNumberPercentage(penalties.overstaked, 2)}
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
<span>{t('PERFORMANCE PENALTY')}</span>
|
<span>{t('PERFORMANCE PENALTY')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('PerformancePenaltyDescription')}>
|
<Tooltip description={t('PerformancePenaltyDescription')}>
|
||||||
<span data-testid="performance-penalty">
|
<span data-testid="performance-penalty">
|
||||||
{formatNumberPercentage(penalties.performance, 2)}
|
{formatNumberPercentage(penalties.performance, 2)}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
<KeyValueTableRow noBorder={true}>
|
||||||
|
<span>
|
||||||
|
<strong>{t('TOTAL PENALTIES')}</strong>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
<span data-testid="total-penalties">
|
||||||
</KeyValueTableRow>
|
<strong>
|
||||||
<KeyValueTableRow noBorder={true}>
|
{formatNumberPercentage(penalties.overall, 2)}
|
||||||
<span>
|
</strong>
|
||||||
<strong>{t('TOTAL PENALTIES')}</strong>
|
</span>
|
||||||
</span>
|
</KeyValueTableRow>
|
||||||
<span data-testid="total-penalties">
|
</KeyValueTable>
|
||||||
<strong>{formatNumberPercentage(penalties.overall, 2)}</strong>
|
</RoundedWrapper>
|
||||||
</span>
|
</div>
|
||||||
</KeyValueTableRow>
|
|
||||||
</KeyValueTable>
|
|
||||||
</RoundedWrapper>
|
|
||||||
|
|
||||||
<SubHeading title={t('VOTING POWER')} />
|
<SubHeading title={t('VOTING POWER')} />
|
||||||
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
<div className="break-all">
|
||||||
<KeyValueTable data-testid="validator-table-voting-power">
|
<RoundedWrapper marginBottomLarge={true} paddingBottom={true}>
|
||||||
<KeyValueTableRow>
|
<KeyValueTable data-testid="validator-table-voting-power">
|
||||||
<span>{t('UNNORMALISED VOTING POWER')}</span>
|
<KeyValueTableRow>
|
||||||
|
<span>{t('UNNORMALISED VOTING POWER')}</span>
|
||||||
|
|
||||||
<Tooltip description={t('UnnormalisedVotingPowerDescription')}>
|
<Tooltip description={t('UnnormalisedVotingPowerDescription')}>
|
||||||
<span data-testid="unnormalised-voting-power">
|
<span data-testid="unnormalised-voting-power">
|
||||||
{getUnnormalisedVotingPower(rawValidatorScore)}
|
{getUnnormalisedVotingPower(rawValidatorScore)}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
<KeyValueTableRow noBorder={true}>
|
||||||
|
<span>
|
||||||
|
<strong>{t('NORMALISED VOTING POWER')}</strong>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
<KeyValueTableRow noBorder={true}>
|
|
||||||
<span>
|
|
||||||
<strong>{t('NORMALISED VOTING POWER')}</strong>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<Tooltip description={t('NormalisedVotingPowerDescription')}>
|
<Tooltip description={t('NormalisedVotingPowerDescription')}>
|
||||||
<strong data-testid="normalised-voting-power">
|
<strong data-testid="normalised-voting-power">
|
||||||
{getNormalisedVotingPower(node.rankingScore.votingPower)}
|
{getNormalisedVotingPower(node.rankingScore.votingPower)}
|
||||||
</strong>
|
</strong>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
</KeyValueTable>
|
</KeyValueTable>
|
||||||
</RoundedWrapper>
|
</RoundedWrapper>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ const Home = ({ name }: RouteChildProps) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
</HomeSection>
|
</HomeSection>
|
||||||
<div className="flex gap-12">
|
<div className="flex justify-between flex-wrap gap-x-12 gap-y-4">
|
||||||
<div className="flex-1">
|
<div className="flex-1 min-w-[360px]">
|
||||||
<HomeSection>
|
<HomeSection>
|
||||||
<SubHeading title={t('Staking')} />
|
<SubHeading title={t('Staking')} />
|
||||||
<p>
|
<p>
|
||||||
@@ -118,7 +118,7 @@ const Home = ({ name }: RouteChildProps) => {
|
|||||||
</p>
|
</p>
|
||||||
</HomeSection>
|
</HomeSection>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1 min-w-[360px]">
|
||||||
<HomeSection>
|
<HomeSection>
|
||||||
<SubHeading title={t('Governance')} />
|
<SubHeading title={t('Governance')} />
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const TokenDetails = ({
|
|||||||
config.token_vesting_contract?.address || ENV.addresses.tokenVestingAddress;
|
config.token_vesting_contract?.address || ENV.addresses.tokenVestingAddress;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="token-details">
|
<div className="token-details break-all">
|
||||||
<RoundedWrapper>
|
<RoundedWrapper>
|
||||||
<KeyValueTable>
|
<KeyValueTable>
|
||||||
<KeyValueTableRow>
|
<KeyValueTableRow>
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@apply text-2xl text-white uppercase mb-4;
|
@apply text-2xl text-white uppercase mb-4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
|||||||
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_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
NX_SENTRY_DSN=https://dummy@o999999.ingest.sentry.io/9999999
|
NX_SENTRY_DSN=https://dummy@o999999.ingest.sentry.io/9999999
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
|
|
||||||
# Expose some env vars to cypress environment for market setup
|
# Expose some env vars to cypress environment for market setup
|
||||||
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
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ NX_VEGA_URL=http://localhost:3008/graphql
|
|||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||||
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_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
|
|
||||||
# Expose some env vars to cypress environment for market setup
|
# Expose some env vars to cypress environment for market setup
|
||||||
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
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ describe('deposit actions', { tags: '@smoke' }, () => {
|
|||||||
cy.visit('/#/markets/market-1');
|
cy.visit('/#/markets/market-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Deposit to trade is visible', () => {
|
it.skip('Deposit to trade is visible', () => {
|
||||||
cy.getByTestId('Collateral').click();
|
cy.getByTestId('Collateral').click();
|
||||||
cy.get('[row-id="asset-id"]').contains('tEURO').should('be.visible');
|
cy.get('[row-id="asset-id"]').contains('tEURO').should('be.visible');
|
||||||
cy.contains('[data-testid="deposit"]', 'Deposit').should('be.visible');
|
cy.contains('[data-testid="deposit"]', 'Deposit').should('be.visible');
|
||||||
|
|||||||
@@ -1,256 +0,0 @@
|
|||||||
import { MarketTradingModeMapping } from '@vegaprotocol/types';
|
|
||||||
import { MarketState } from '@vegaprotocol/types';
|
|
||||||
import compact from 'lodash/compact';
|
|
||||||
|
|
||||||
const accordionContent = 'accordion-content';
|
|
||||||
const blockExplorerLink = 'block-explorer-link';
|
|
||||||
const dialogClose = 'dialog-close';
|
|
||||||
const dialogContent = 'dialog-content';
|
|
||||||
const externalLink = 'external-link';
|
|
||||||
const githubLink = 'github-link';
|
|
||||||
const liquidityLink = 'view-liquidity-link';
|
|
||||||
const marketInfoBtn = 'Info';
|
|
||||||
const marketTitle = 'accordion-title';
|
|
||||||
const providerName = 'provider-name';
|
|
||||||
const row = 'key-value-table-row';
|
|
||||||
const verifiedProofs = 'verified-proofs';
|
|
||||||
|
|
||||||
describe('market info is displayed', { tags: '@smoke' }, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockTradingPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
cy.setOnBoardingViewed();
|
|
||||||
cy.mockTradingPage(MarketState.STATE_ACTIVE);
|
|
||||||
cy.mockSubscription();
|
|
||||||
cy.visit('/#/markets/market-0');
|
|
||||||
cy.wait('@Markets');
|
|
||||||
cy.getByTestId(marketInfoBtn).click();
|
|
||||||
cy.wait('@MarketInfo');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('current fees displayed', () => {
|
|
||||||
// 6002-MDET-101
|
|
||||||
cy.getByTestId(marketTitle).contains('Current fees').click();
|
|
||||||
validateMarketDataRow(0, 'Maker Fee', '0.02%');
|
|
||||||
validateMarketDataRow(1, 'Infrastructure Fee', '0.05%');
|
|
||||||
validateMarketDataRow(2, 'Liquidity Fee', '1.00%');
|
|
||||||
validateMarketDataRow(3, 'Total Fees', '1.07%');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('market price', () => {
|
|
||||||
// 6002-MDET-102
|
|
||||||
cy.getByTestId(marketTitle).contains('Market price').click();
|
|
||||||
validateMarketDataRow(0, 'Mark Price', '46,126.90058');
|
|
||||||
validateMarketDataRow(1, 'Best Bid Price', '44,126.90058 ');
|
|
||||||
validateMarketDataRow(2, 'Best Offer Price', '48,126.90058 ');
|
|
||||||
validateMarketDataRow(3, 'Quote Unit', 'BTC');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('market volume displayed', () => {
|
|
||||||
// 6002-MDET-103
|
|
||||||
cy.getByTestId(marketTitle).contains('Market volume').click();
|
|
||||||
validateMarketDataRow(1, 'Open Interest', '-');
|
|
||||||
validateMarketDataRow(2, 'Best Bid Volume', '1');
|
|
||||||
validateMarketDataRow(3, 'Best Offer Volume', '3');
|
|
||||||
validateMarketDataRow(4, 'Best Static Bid Volume', '2');
|
|
||||||
validateMarketDataRow(5, 'Best Static Offer Volume', '4');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('insurance pool displayed', () => {
|
|
||||||
// 6002-MDET-104
|
|
||||||
cy.getByTestId(marketTitle).contains('Insurance pool').click();
|
|
||||||
validateMarketDataRow(0, 'Balance', '0');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('key details displayed', () => {
|
|
||||||
// 6002-MDET-201
|
|
||||||
cy.getByTestId(marketTitle).contains('Key details').click();
|
|
||||||
|
|
||||||
const rows: [string, string][] = compact([
|
|
||||||
['Name', 'BTCUSD Monthly (30 Jun 2022)'],
|
|
||||||
['Market ID', 'market-0'],
|
|
||||||
Cypress.env('NX_SUCCESSOR_MARKETS') && ['Parent Market ID', 'PARENT-A'],
|
|
||||||
Cypress.env('NX_SUCCESSOR_MARKETS') && [
|
|
||||||
'Insurance Pool Fraction',
|
|
||||||
'0.75',
|
|
||||||
],
|
|
||||||
['Trading Mode', MarketTradingModeMapping.TRADING_MODE_CONTINUOUS],
|
|
||||||
['Market Decimal Places', '5'],
|
|
||||||
['Position Decimal Places', '0'],
|
|
||||||
['Settlement Asset Decimal Places', '5'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
for (const rowNumber in rows) {
|
|
||||||
const [name, value] = rows[rowNumber];
|
|
||||||
validateMarketDataRow(Number(rowNumber), name, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('instrument displayed', () => {
|
|
||||||
// 6002-MDET-202
|
|
||||||
cy.getByTestId(marketTitle).contains('Instrument').click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Market Name', 'BTCUSD Monthly (30 Jun 2022)');
|
|
||||||
validateMarketDataRow(1, 'Code', 'BTCUSD.MF21');
|
|
||||||
validateMarketDataRow(2, 'Product Type', 'Future');
|
|
||||||
validateMarketDataRow(3, 'Quote Name', 'BTC');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('oracle displayed', () => {
|
|
||||||
// 6002-MDET-203
|
|
||||||
cy.getByTestId(marketTitle).contains('Oracle').click();
|
|
||||||
|
|
||||||
cy.getByTestId(accordionContent)
|
|
||||||
.getByTestId(providerName)
|
|
||||||
.and('contain', 'Another oracle');
|
|
||||||
|
|
||||||
cy.getByTestId(providerName).should('be.visible').click();
|
|
||||||
cy.getByTestId(dialogContent)
|
|
||||||
.eq(1)
|
|
||||||
.within(() => {
|
|
||||||
cy.getByTestId(blockExplorerLink).contains('Block explorer');
|
|
||||||
cy.getByTestId(githubLink).contains('Oracle repository');
|
|
||||||
});
|
|
||||||
cy.getByTestId(dialogClose).click();
|
|
||||||
|
|
||||||
cy.getByTestId(accordionContent)
|
|
||||||
.getByTestId(verifiedProofs)
|
|
||||||
.and('contain', '1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('settlement asset displayed', () => {
|
|
||||||
// 6002-MDET-206
|
|
||||||
cy.getByTestId(marketTitle).contains('Settlement asset').click();
|
|
||||||
cy.window().then((win) => {
|
|
||||||
cy.stub(win, 'prompt').returns('DISABLED WINDOW PROMPT');
|
|
||||||
});
|
|
||||||
validateMarketDataRow(0, 'ID', 'asset-id');
|
|
||||||
validateMarketDataRow(1, 'Type', 'ERC20');
|
|
||||||
validateMarketDataRow(2, 'Name', 'Euro');
|
|
||||||
validateMarketDataRow(3, 'Symbol', 'tEURO');
|
|
||||||
validateMarketDataRow(4, 'Decimals', '5');
|
|
||||||
validateMarketDataRow(5, 'Quantum', '1');
|
|
||||||
validateMarketDataRow(6, 'Status', 'Enabled');
|
|
||||||
validateMarketDataRow(7, 'Contract address', '0x0158…78a4');
|
|
||||||
validateMarketDataRow(8, 'Withdrawal threshold', '0.0005');
|
|
||||||
validateMarketDataRow(9, 'Lifetime limit', '1,230');
|
|
||||||
validateMarketDataRow(10, 'Infrastructure fee account balance', '0.00001');
|
|
||||||
validateMarketDataRow(11, 'Global reward pool account balance', '0.00002');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('metadata displayed', () => {
|
|
||||||
// 6002-MDET-207
|
|
||||||
cy.getByTestId(marketTitle).contains('Metadata').click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Formerly', '076BB86A5AA41E3E');
|
|
||||||
validateMarketDataRow(1, 'Base', 'BTC');
|
|
||||||
validateMarketDataRow(2, 'Quote', 'USD');
|
|
||||||
validateMarketDataRow(3, 'Class', 'fx/crypto');
|
|
||||||
validateMarketDataRow(4, 'Sector', 'crypto');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('risk model displayed', () => {
|
|
||||||
// 6002-MDET-208
|
|
||||||
cy.getByTestId(marketTitle).contains('Risk model').click();
|
|
||||||
validateMarketDataRow(0, 'Tau', '0.0001140771161');
|
|
||||||
validateMarketDataRow(1, 'Risk Aversion Parameter', '0.01');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('risk parameters displayed', () => {
|
|
||||||
// 6002-MDET-209
|
|
||||||
cy.getByTestId(marketTitle).contains('Risk parameters').click();
|
|
||||||
validateMarketDataRow(0, 'R', '0.016');
|
|
||||||
validateMarketDataRow(1, 'Sigma', '0.3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('risk factors displayed', () => {
|
|
||||||
// 6002-MDET-210
|
|
||||||
cy.getByTestId(marketTitle).contains('Risk factors').click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Short', '0.008571790367285281');
|
|
||||||
validateMarketDataRow(1, 'Long', '0.008508132993273576');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('price monitoring bounds displayed', () => {
|
|
||||||
// 6002-MDET-211
|
|
||||||
cy.getByTestId(marketTitle).contains('Price monitoring bounds 1').click();
|
|
||||||
cy.get('p.col-span-1').contains('99.99999% probability price bounds');
|
|
||||||
cy.get('p.col-span-1').contains('Within 43,200 seconds');
|
|
||||||
validateMarketDataRow(0, 'Highest Price', '7.97323 ');
|
|
||||||
validateMarketDataRow(1, 'Lowest Price', '6.54701 ');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('liquidity monitoring parameters displayed', () => {
|
|
||||||
// 6002-MDET-212
|
|
||||||
cy.getByTestId(marketTitle)
|
|
||||||
.contains('Liquidity monitoring parameters')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Triggering Ratio', '0.7');
|
|
||||||
validateMarketDataRow(1, 'Time Window', '3,600');
|
|
||||||
validateMarketDataRow(2, 'Scaling Factor', '10');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('liquidity displayed', () => {
|
|
||||||
// 6002-MDET-213
|
|
||||||
cy.getByTestId(marketTitle)
|
|
||||||
.contains(/Liquidity(?! m)/)
|
|
||||||
.click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Target Stake', '10.00 tBTC');
|
|
||||||
validateMarketDataRow(1, 'Supplied Stake', '0.01 tBTC');
|
|
||||||
validateMarketDataRow(2, 'Market Value Proxy', '20.00 tBTC');
|
|
||||||
cy.getByTestId(liquidityLink).should(
|
|
||||||
'have.text',
|
|
||||||
'View liquidity provision table'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('liquidity price range displayed', () => {
|
|
||||||
// 6002-MDET-214
|
|
||||||
cy.getByTestId(marketTitle).contains('Liquidity price range').click();
|
|
||||||
|
|
||||||
validateMarketDataRow(0, 'Liquidity Price Range', '2.00% of mid price');
|
|
||||||
validateMarketDataRow(1, 'Lowest Price', '45,204.362 BTC');
|
|
||||||
validateMarketDataRow(2, 'Highest Price', '47,049.438 BTC');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('proposal displayed', () => {
|
|
||||||
// 6002-MDET-301
|
|
||||||
cy.getByTestId(marketTitle).contains('Proposal').click();
|
|
||||||
|
|
||||||
cy.getByTestId(accordionContent)
|
|
||||||
.find(`[data-testid="${externalLink}"]`)
|
|
||||||
.first()
|
|
||||||
.should('have.text', 'View governance proposal')
|
|
||||||
.and('have.attr', 'href')
|
|
||||||
.and('contain', '/proposals/market-0');
|
|
||||||
cy.getByTestId(accordionContent)
|
|
||||||
.find(`[data-testid="${externalLink}"]`)
|
|
||||||
.eq(1)
|
|
||||||
.should('have.text', 'Propose a change to market')
|
|
||||||
.and('have.attr', 'href')
|
|
||||||
.and('contain', '/proposals/propose/update-market');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach('close toggle', () => {
|
|
||||||
cy.get('[data-state="open"]').then((tab) => {
|
|
||||||
if (tab) tab.find('button').trigger('click');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function validateMarketDataRow(
|
|
||||||
rowNumber: number,
|
|
||||||
name: string,
|
|
||||||
value: string
|
|
||||||
) {
|
|
||||||
cy.getByTestId(row)
|
|
||||||
.eq(rowNumber)
|
|
||||||
.within(() => {
|
|
||||||
cy.get('dt').should('contain.text', name);
|
|
||||||
cy.get('dd').should('contain.text', value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -24,9 +24,7 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.getByTestId('deal-ticket-fee-margin-required').within(() => {
|
cy.getByTestId('deal-ticket-fee-margin-required').click();
|
||||||
cy.get('button').click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('limit order', () => {
|
describe('limit order', () => {
|
||||||
@@ -111,6 +109,7 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
|||||||
'Total margin available100.01 tDAI'
|
'Total margin available100.01 tDAI'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
cy.getByTestId('deal-ticket-fee-margin-required').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must have current margin allocation', () => {
|
it('must have current margin allocation', () => {
|
||||||
@@ -120,6 +119,7 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
|||||||
'Current margin allocation'
|
'Current margin allocation'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
cy.getByTestId('deal-ticket-fee-margin-required').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open usage breakdown dialog when clicked on current margin allocation', () => {
|
it('should open usage breakdown dialog when clicked on current margin allocation', () => {
|
||||||
@@ -128,6 +128,7 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
cy.getByTestId('usage-breakdown').should('exist');
|
cy.getByTestId('usage-breakdown').should('exist');
|
||||||
cy.getByTestId('dialog-close').click();
|
cy.getByTestId('dialog-close').click();
|
||||||
|
cy.getByTestId('deal-ticket-fee-margin-required').click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
testOrderAmendment,
|
testOrderAmendment,
|
||||||
} from '../support/order-validation';
|
} from '../support/order-validation';
|
||||||
|
|
||||||
const orderSymbol = 'market.tradableInstrument.instrument.code';
|
const orderSymbol = 'instrument-code';
|
||||||
const orderSize = 'size';
|
const orderSize = 'size';
|
||||||
const orderType = 'type';
|
const orderType = 'type';
|
||||||
const orderStatus = 'status';
|
const orderStatus = 'status';
|
||||||
@@ -229,10 +229,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
|
|||||||
status: Schema.OrderStatus.STATUS_FILLED,
|
status: Schema.OrderStatus.STATUS_FILLED,
|
||||||
});
|
});
|
||||||
cy.getByTestId(`order-status-${orderId}`).should('have.text', 'Filled');
|
cy.getByTestId(`order-status-${orderId}`).should('have.text', 'Filled');
|
||||||
cy.get('[col-id="market.tradableInstrument.instrument.code"]').contains(
|
cy.get(`[col-id="${orderSymbol}"]`).contains('[title="Future"]', 'Futr');
|
||||||
'[title="Future"]',
|
|
||||||
'Futr'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must see a rejected order', () => {
|
it('must see a rejected order', () => {
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ describe('trades', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('copy price to deal ticket form', () => {
|
it('copy price to deal ticket form', () => {
|
||||||
cy.getByTestId('Order').click();
|
|
||||||
// 6005-THIS-007
|
// 6005-THIS-007
|
||||||
|
cy.getByTestId('order-type-Limit').click();
|
||||||
cy.get(colIdPrice).last().should('be.visible').click();
|
cy.get(colIdPrice).last().should('be.visible').click();
|
||||||
cy.getByTestId('order-price').should('have.value', '171.16898');
|
cy.getByTestId('order-price').should('have.value', '171.16898');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ const dialogContent = 'dialog-content';
|
|||||||
describe('connect vega wallet', { tags: '@smoke', testIsolation: true }, () => {
|
describe('connect vega wallet', { tags: '@smoke', testIsolation: true }, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Using portfolio page as it requires vega wallet connection
|
// Using portfolio page as it requires vega wallet connection
|
||||||
cy.visit('/#/portfolio');
|
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.setOnBoardingViewed();
|
cy.setOnBoardingViewed();
|
||||||
|
cy.visit('/#/portfolio');
|
||||||
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+12
-9
@@ -1,27 +1,30 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
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_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
NX_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
|
||||||
NX_VEGA_ENV=STAGNET1
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
NX_VEGA_NETWORKS={\"MAINNET\":\"https://console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||||
|
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_STOP_ORDERS=true
|
NX_STOP_ORDERS=true
|
||||||
# NX_ICEBERG_ORDERS
|
NX_ICEBERG_ORDERS=true
|
||||||
# NX_PRODUCT_PERPETUALS
|
# NX_PRODUCT_PERPETUALS
|
||||||
NX_METAMASK_SNAPS=true
|
NX_METAMASK_SNAPS=true
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
|
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
|||||||
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-mainnet/codfcglpplgmmlokgilfkpcjnmkbfiel
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-mainnet/codfcglpplgmmlokgilfkpcjnmkbfiel
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
|
||||||
# TAG name of the current app version - TODO: bump to the latest upon release
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
NX_APP_VERSION=v0.21.0-core-0.72.14
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_STOP_ORDERS=true
|
NX_STOP_ORDERS=true
|
||||||
NX_ICEBERG_ORDERS=true
|
NX_ICEBERG_ORDERS=true
|
||||||
# NX_PRODUCT_PERPETUALS
|
# NX_PRODUCT_PERPETUALS
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://be.vega.community
|
NX_TENDERMINT_URL=https://be.vega.community
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
|
|||||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
|
|||||||
@@ -16,13 +16,15 @@ NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
|||||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_STOP_ORDERS=true
|
NX_STOP_ORDERS=true
|
||||||
NX_ICEBERG_ORDERS=true
|
NX_ICEBERG_ORDERS=true
|
||||||
# NX_PRODUCT_PERPETUALS
|
# NX_PRODUCT_PERPETUALS
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks
|
|||||||
|
|
||||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||||
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import MarketPage from '../market';
|
||||||
|
|
||||||
|
export const ClosedMarketPage = () => {
|
||||||
|
return <MarketPage closed />;
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { ClosedMarketPage as default } from './closed-market';
|
||||||
@@ -1,18 +1,58 @@
|
|||||||
import { DepositContainer } from '@vegaprotocol/deposits';
|
import { DepositContainer } from '@vegaprotocol/deposits';
|
||||||
import { GetStarted } from '../../components/welcome-dialog';
|
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { GetStartedCheckList } from '../../components/welcome-dialog';
|
||||||
|
import {
|
||||||
|
useGetOnboardingStep,
|
||||||
|
useOnboardingStore,
|
||||||
|
OnboardingStep,
|
||||||
|
} from '../../components/welcome-dialog/use-get-onboarding-step';
|
||||||
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
export const Deposit = () => {
|
export const Deposit = () => {
|
||||||
return (
|
return (
|
||||||
<div className="py-16 px-8 flex w-full justify-center">
|
<div className="max-w-[600px] px-4 py-8 mx-auto lg:px-8">
|
||||||
<div className="lg:min-w-[700px] min-w-[300px] max-w-[700px]">
|
<h1 className="mb-6 text-4xl uppercase xl:text-5xl font-alpha calt">
|
||||||
<h1 className="text-4xl xl:text-5xl uppercase font-alpha calt">
|
{t('Deposit')}
|
||||||
{t('Deposit')}
|
</h1>
|
||||||
</h1>
|
<div className="flex flex-col gap-6">
|
||||||
<div className="mt-10">
|
<DepositContainer />
|
||||||
<DepositContainer />
|
<DepositGetStarted />
|
||||||
<GetStarted />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DepositGetStarted = () => {
|
||||||
|
const onboardingDismissed = useOnboardingStore((store) => store.dismissed);
|
||||||
|
const dismiss = useOnboardingStore((store) => store.dismiss);
|
||||||
|
const step = useGetOnboardingStep();
|
||||||
|
const wrapperClasses = classNames(
|
||||||
|
'flex flex-col py-4 px-6 gap-4 rounded',
|
||||||
|
'bg-vega-blue-300 dark:bg-vega-blue-700',
|
||||||
|
'border border-vega-blue-350 dark:border-vega-blue-650'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dont show unless still onboarding
|
||||||
|
if (onboardingDismissed) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="pt-6 border-t border-default">
|
||||||
|
<div className={wrapperClasses}>
|
||||||
|
<h3 className="text-lg">{t('Get started')}</h3>
|
||||||
|
<GetStartedCheckList />
|
||||||
|
{step > OnboardingStep.ONBOARDING_DEPOSIT_STEP && (
|
||||||
|
<TradingAnchorButton
|
||||||
|
href={Links[Routes.HOME]()}
|
||||||
|
onClick={() => dismiss()}
|
||||||
|
intent={Intent.Info}
|
||||||
|
>
|
||||||
|
{t('Start trading')}
|
||||||
|
</TradingAnchorButton>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { marketsWithDataProvider } from '@vegaprotocol/markets';
|
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { Links, Routes } from '../../pages/client-router';
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
import { useGlobalStore } from '../../stores';
|
import { useGlobalStore } from '../../stores';
|
||||||
|
import { useTopTradedMarkets } from '../../lib/hooks/use-top-traded-markets';
|
||||||
|
|
||||||
|
// The home pages only purpose is to redirect to the users last market,
|
||||||
|
// the top traded if they are new, or fall back to the list of markets.
|
||||||
|
// Thats why we just render a loader here
|
||||||
export const Home = () => {
|
export const Home = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// The default market selected in the platform behind the overlay
|
const { data } = useTopTradedMarkets();
|
||||||
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
|
|
||||||
const { data, error, loading } = useDataProvider({
|
|
||||||
dataProvider: marketsWithDataProvider,
|
|
||||||
variables: undefined,
|
|
||||||
});
|
|
||||||
const update = useGlobalStore((store) => store.update);
|
|
||||||
const marketId = useGlobalStore((store) => store.marketId);
|
const marketId = useGlobalStore((store) => store.marketId);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -32,12 +28,11 @@ export const Home = () => {
|
|||||||
navigate(Links[Routes.MARKETS]());
|
navigate(Links[Routes.MARKETS]());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [marketId, data, navigate, update]);
|
}, [marketId, data, navigate]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer data={data} loading={loading} error={error}>
|
<Splash>
|
||||||
{/* Render a loading and error state but we will redirect if markets are found */}
|
<Loader />
|
||||||
{null}
|
</Splash>
|
||||||
</AsyncRenderer>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { TradePanels } from './trade-panels';
|
|||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { Links, Routes } from '../../pages/client-router';
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||||
|
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||||
|
import { MarketState } from '@vegaprotocol/types';
|
||||||
|
|
||||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||||
return markPrice && decimalPlaces
|
return markPrice && decimalPlaces
|
||||||
@@ -55,10 +57,12 @@ const TitleUpdater = ({
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MarketPage = () => {
|
export const MarketPage = ({ closed }: { closed?: boolean }) => {
|
||||||
const { marketId } = useParams();
|
const { marketId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { init, view, setView } = useSidebar();
|
const currentRouteId = useGetCurrentRouteId();
|
||||||
|
const { setViews, getView } = useSidebar();
|
||||||
|
const view = getView(currentRouteId);
|
||||||
const { screenSize } = useScreenDimensions();
|
const { screenSize } = useScreenDimensions();
|
||||||
const largeScreen = ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize);
|
const largeScreen = ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize);
|
||||||
const update = useGlobalStore((store) => store.update);
|
const update = useGlobalStore((store) => store.update);
|
||||||
@@ -67,17 +71,33 @@ export const MarketPage = () => {
|
|||||||
const { data, error, loading } = useMarket(marketId);
|
const { data, error, loading } = useMarket(marketId);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.id && data.id !== lastMarketId) {
|
if (
|
||||||
|
data?.state &&
|
||||||
|
[
|
||||||
|
MarketState.STATE_SETTLED,
|
||||||
|
MarketState.STATE_TRADING_TERMINATED,
|
||||||
|
].includes(data.state) &&
|
||||||
|
currentRouteId !== Routes.CLOSED_MARKETS &&
|
||||||
|
marketId
|
||||||
|
) {
|
||||||
|
navigate(Links[Routes.CLOSED_MARKETS](marketId));
|
||||||
|
}
|
||||||
|
}, [data?.state, currentRouteId, navigate, marketId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.id && data.id !== lastMarketId && !closed) {
|
||||||
update({ marketId: data.id });
|
update({ marketId: data.id });
|
||||||
}
|
}
|
||||||
}, [update, lastMarketId, data?.id]);
|
}, [update, lastMarketId, data?.id, closed]);
|
||||||
|
|
||||||
// Make sidebar open on deal ticket by default
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (init && view === null) {
|
if (largeScreen && view === undefined) {
|
||||||
setView({ type: ViewType.Order });
|
setViews(
|
||||||
|
{ type: closed ? ViewType.Info : ViewType.Order },
|
||||||
|
currentRouteId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [init, view, setView]);
|
}, [setViews, view, currentRouteId, largeScreen, closed]);
|
||||||
|
|
||||||
const tradeView = useMemo(() => {
|
const tradeView = useMemo(() => {
|
||||||
if (largeScreen) {
|
if (largeScreen) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const MainGrid = memo(
|
|||||||
<Tabs storageKey="console-trade-grid-main-left">
|
<Tabs storageKey="console-trade-grid-main-left">
|
||||||
<Tab
|
<Tab
|
||||||
id="chart"
|
id="chart"
|
||||||
|
overflowHidden
|
||||||
name={t('Chart')}
|
name={t('Chart')}
|
||||||
menu={<TradingViews.candles.menu />}
|
menu={<TradingViews.candles.menu />}
|
||||||
>
|
>
|
||||||
@@ -72,7 +73,7 @@ const MainGrid = memo(
|
|||||||
</ResizableGridPanel>
|
</ResizableGridPanel>
|
||||||
<ResizableGridPanel
|
<ResizableGridPanel
|
||||||
minSize={200}
|
minSize={200}
|
||||||
preferredSize={sizesMiddle[1] || 300}
|
preferredSize={sizesMiddle[1] || 275}
|
||||||
>
|
>
|
||||||
<TradeGridChild>
|
<TradeGridChild>
|
||||||
<Tabs storageKey="console-trade-grid-main-right">
|
<Tabs storageKey="console-trade-grid-main-right">
|
||||||
@@ -127,7 +128,7 @@ const MainGrid = memo(
|
|||||||
</Tab>
|
</Tab>
|
||||||
) : null}
|
) : null}
|
||||||
<Tab id="fills" name={t('Fills')}>
|
<Tab id="fills" name={t('Fills')}>
|
||||||
<TradingViews.fills.component marketId={marketId} />
|
<TradingViews.fills.component />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
id="accounts"
|
id="accounts"
|
||||||
@@ -180,7 +181,7 @@ const TradeGridChild = ({ children }: TradeGridChildProps) => {
|
|||||||
{({ width, height }) => (
|
{({ width, height }) => (
|
||||||
<div
|
<div
|
||||||
style={{ width, height }}
|
style={{ width, height }}
|
||||||
className="border border-default rounded-sm"
|
className="border rounded-sm border-default"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { act, render, screen, within, waitFor } from '@testing-library/react';
|
import { act, render, screen, within } from '@testing-library/react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import { Closed } from './closed';
|
import { Closed } from './closed';
|
||||||
import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types';
|
import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types';
|
||||||
@@ -10,55 +10,21 @@ import type {
|
|||||||
OracleSpecDataConnectionQuery,
|
OracleSpecDataConnectionQuery,
|
||||||
MarketsDataQuery,
|
MarketsDataQuery,
|
||||||
MarketsQuery,
|
MarketsQuery,
|
||||||
SuccessorMarketIdsQuery,
|
|
||||||
} from '@vegaprotocol/markets';
|
} from '@vegaprotocol/markets';
|
||||||
import {
|
import {
|
||||||
OracleSpecDataConnectionDocument,
|
OracleSpecDataConnectionDocument,
|
||||||
MarketsDataDocument,
|
MarketsDataDocument,
|
||||||
MarketsDocument,
|
MarketsDocument,
|
||||||
SuccessorMarketIdsDocument,
|
|
||||||
} from '@vegaprotocol/markets';
|
} from '@vegaprotocol/markets';
|
||||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||||
import { FLAGS } from '@vegaprotocol/environment';
|
|
||||||
import {
|
import {
|
||||||
createMarketFragment,
|
createMarketFragment,
|
||||||
marketsQuery,
|
marketsQuery,
|
||||||
marketsDataQuery,
|
marketsDataQuery,
|
||||||
createMarketsDataFragment,
|
createMarketsDataFragment,
|
||||||
} from '@vegaprotocol/mock';
|
} from '@vegaprotocol/mock';
|
||||||
import type { FeatureFlags } from '@vegaprotocol/environment';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/markets', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/markets'),
|
|
||||||
useSuccessorMarket: (marketId: string) =>
|
|
||||||
marketId === 'include-0'
|
|
||||||
? {
|
|
||||||
data: {
|
|
||||||
id: 'successorMarketID',
|
|
||||||
state: 'STATE_ACTIVE',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
name: 'Successor Market Name',
|
|
||||||
code: 'SuccessorCode',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: { data: undefined },
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/environment', () => {
|
|
||||||
const actual = jest.requireActual('@vegaprotocol/environment');
|
|
||||||
return {
|
|
||||||
...actual,
|
|
||||||
FLAGS: {
|
|
||||||
...actual.FLAGS,
|
|
||||||
SUCCESSOR_MARKETS: true,
|
|
||||||
} as FeatureFlags,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Closed', () => {
|
describe('Closed', () => {
|
||||||
let originalNow: typeof Date.now;
|
let originalNow: typeof Date.now;
|
||||||
@@ -218,10 +184,8 @@ describe('Closed', () => {
|
|||||||
const headers = screen.getAllByRole('columnheader');
|
const headers = screen.getAllByRole('columnheader');
|
||||||
const expectedHeaders = [
|
const expectedHeaders = [
|
||||||
'Market',
|
'Market',
|
||||||
'Description',
|
|
||||||
'Status',
|
'Status',
|
||||||
'Settlement date',
|
'Settlement date',
|
||||||
'Successor market',
|
|
||||||
'Best bid',
|
'Best bid',
|
||||||
'Best offer',
|
'Best offer',
|
||||||
'Mark price',
|
'Mark price',
|
||||||
@@ -235,10 +199,8 @@ describe('Closed', () => {
|
|||||||
const cells = screen.getAllByRole('gridcell');
|
const cells = screen.getAllByRole('gridcell');
|
||||||
const expectedValues = [
|
const expectedValues = [
|
||||||
market.tradableInstrument.instrument.code,
|
market.tradableInstrument.instrument.code,
|
||||||
market.tradableInstrument.instrument.name,
|
|
||||||
MarketStateMapping[market.state],
|
MarketStateMapping[market.state],
|
||||||
'3 days ago',
|
'3 days ago',
|
||||||
'-',
|
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
addDecimalsFormatNumber(marketsData.bestBidPrice, market.decimalPlaces),
|
addDecimalsFormatNumber(marketsData.bestBidPrice, market.decimalPlaces),
|
||||||
addDecimalsFormatNumber(
|
addDecimalsFormatNumber(
|
||||||
@@ -340,43 +302,26 @@ describe('Closed', () => {
|
|||||||
.getAllByRole('gridcell')
|
.getAllByRole('gridcell')
|
||||||
.filter((cell) => cell.getAttribute('col-id') === 'code')
|
.filter((cell) => cell.getAttribute('col-id') === 'code')
|
||||||
.map((cell) => {
|
.map((cell) => {
|
||||||
const marketId = within(cell)
|
const marketCode = within(cell).getByTestId('stack-cell-primary');
|
||||||
.getByTestId('market-code')
|
return marketCode.textContent;
|
||||||
.getAttribute('data-market-id');
|
|
||||||
return marketId;
|
|
||||||
});
|
});
|
||||||
expect(cells).toEqual(expectedRows.map((m) => m.node.id));
|
expect(cells).toEqual(
|
||||||
|
expectedRows.map((m) => m.node.tradableInstrument.instrument.code)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('successor marked should be visible', async () => {
|
it('successor marked should be visible', async () => {
|
||||||
const mixedMarkets = [
|
const marketsWithSuccessorID = [
|
||||||
{
|
{
|
||||||
__typename: 'MarketEdge' as const,
|
__typename: 'MarketEdge' as const,
|
||||||
node: createMarketFragment({
|
node: createMarketFragment({
|
||||||
id: 'include-0',
|
id: 'include-0',
|
||||||
state: MarketState.STATE_SETTLED,
|
state: MarketState.STATE_SETTLED,
|
||||||
|
successorMarketID: 'successor',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
__typename: 'MarketEdge' as const,
|
|
||||||
node: {
|
|
||||||
...createMarketFragment({
|
|
||||||
id: 'successorMarketID',
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
}),
|
|
||||||
tradableInstrument: {
|
|
||||||
...createMarketFragment().tradableInstrument,
|
|
||||||
instrument: {
|
|
||||||
...createMarketFragment().tradableInstrument.instrument,
|
|
||||||
id: 'successorAssset',
|
|
||||||
name: 'Successor Market Name',
|
|
||||||
code: 'SuccessorCode',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
const mixedMarketsMock: MockedResponse<MarketsQuery> = {
|
const mockWithSuccessors: MockedResponse<MarketsQuery> = {
|
||||||
request: {
|
request: {
|
||||||
query: MarketsDocument,
|
query: MarketsDocument,
|
||||||
},
|
},
|
||||||
@@ -384,42 +329,17 @@ describe('Closed', () => {
|
|||||||
data: {
|
data: {
|
||||||
marketsConnection: {
|
marketsConnection: {
|
||||||
__typename: 'MarketConnection',
|
__typename: 'MarketConnection',
|
||||||
edges: mixedMarkets,
|
edges: marketsWithSuccessorID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const successorMarketsMock: MockedResponse<SuccessorMarketIdsQuery> = {
|
|
||||||
request: {
|
await act(async () => {
|
||||||
query: SuccessorMarketIdsDocument,
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
marketsConnection: {
|
|
||||||
__typename: 'MarketConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'include-0',
|
|
||||||
successorMarketID: 'successorMarketID',
|
|
||||||
parentMarketID: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
await act(() => {
|
|
||||||
render(
|
render(
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<MockedProvider
|
<MockedProvider
|
||||||
mocks={[
|
mocks={[mockWithSuccessors, marketsDataMock, oracleDataMock]}
|
||||||
mixedMarketsMock,
|
|
||||||
marketsDataMock,
|
|
||||||
oracleDataMock,
|
|
||||||
successorMarketsMock,
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<VegaWalletContext.Provider
|
<VegaWalletContext.Provider
|
||||||
value={{ pubKey } as VegaWalletContextShape}
|
value={{ pubKey } as VegaWalletContextShape}
|
||||||
@@ -431,122 +351,15 @@ describe('Closed', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
const container = within(
|
||||||
expect(
|
document.querySelector('.ag-center-cols-container') as HTMLElement
|
||||||
screen.getByRole('button', { name: /^SuccessorCode/ })
|
);
|
||||||
).toBeInTheDocument();
|
const cell = container.getAllByRole('gridcell', {
|
||||||
});
|
name: (_name, element) => element.getAttribute('col-id') === 'code',
|
||||||
expect(
|
})[0];
|
||||||
screen.getByRole('columnheader', {
|
|
||||||
name: (_name, element) =>
|
|
||||||
element.getAttribute('col-id') === 'successorMarket',
|
|
||||||
})
|
|
||||||
).toBeInTheDocument();
|
|
||||||
screen
|
|
||||||
.getAllByRole('gridcell', {
|
|
||||||
name: (_name, element) =>
|
|
||||||
element.getAttribute('col-id') === 'successorMarket',
|
|
||||||
})
|
|
||||||
.forEach((element) => {
|
|
||||||
expect(element.querySelector('[title="Future"]')?.textContent).toEqual(
|
|
||||||
'Futr'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('feature flag should hide successors', async () => {
|
expect(within(cell).getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
const mockedFlags = jest.mocked(FLAGS);
|
'PRNT'
|
||||||
mockedFlags.SUCCESSOR_MARKETS = false;
|
|
||||||
|
|
||||||
const mixedMarkets = [
|
|
||||||
{
|
|
||||||
__typename: 'MarketEdge' as const,
|
|
||||||
node: createMarketFragment({
|
|
||||||
id: 'include-0',
|
|
||||||
state: MarketState.STATE_SETTLED,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'MarketEdge' as const,
|
|
||||||
node: {
|
|
||||||
...createMarketFragment({
|
|
||||||
id: 'successorMarketID',
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
}),
|
|
||||||
tradableInstrument: {
|
|
||||||
...createMarketFragment().tradableInstrument,
|
|
||||||
instrument: {
|
|
||||||
...createMarketFragment().tradableInstrument.instrument,
|
|
||||||
id: 'successorAssset',
|
|
||||||
name: 'Successor Market Name',
|
|
||||||
code: 'SuccessorCode',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const mixedMarketsMock: MockedResponse<MarketsQuery> = {
|
|
||||||
request: {
|
|
||||||
query: MarketsDocument,
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
marketsConnection: {
|
|
||||||
__typename: 'MarketConnection',
|
|
||||||
edges: mixedMarkets,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const successorMarketsMock: MockedResponse<SuccessorMarketIdsQuery> = {
|
|
||||||
request: {
|
|
||||||
query: SuccessorMarketIdsDocument,
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
marketsConnection: {
|
|
||||||
__typename: 'MarketConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'include-0',
|
|
||||||
successorMarketID: 'successorMarketID',
|
|
||||||
parentMarketID: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MockedProvider
|
|
||||||
mocks={[
|
|
||||||
mixedMarketsMock,
|
|
||||||
marketsDataMock,
|
|
||||||
oracleDataMock,
|
|
||||||
successorMarketsMock,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<VegaWalletContext.Provider
|
|
||||||
value={{ pubKey } as VegaWalletContextShape}
|
|
||||||
>
|
|
||||||
<Closed />
|
|
||||||
</VegaWalletContext.Provider>
|
|
||||||
</MockedProvider>
|
|
||||||
</MemoryRouter>
|
|
||||||
);
|
);
|
||||||
await waitFor(() => {
|
|
||||||
expect(
|
|
||||||
screen.getByRole('columnheader', {
|
|
||||||
name: (_name, element) =>
|
|
||||||
element.getAttribute('col-id') === 'settlementDate',
|
|
||||||
})
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
screen.getAllByRole('columnheader').forEach((element) => {
|
|
||||||
expect(element.getAttribute('col-id')).not.toEqual('successorMarket');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,13 +4,10 @@ import type {
|
|||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import {
|
import { AgGrid, COL_DEFS } from '@vegaprotocol/datagrid';
|
||||||
AgGridLazy as AgGrid,
|
|
||||||
COL_DEFS,
|
|
||||||
MarketNameCell,
|
|
||||||
} from '@vegaprotocol/datagrid';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { ProductType } from '@vegaprotocol/types';
|
||||||
import { MarketState, MarketStateMapping } from '@vegaprotocol/types';
|
import { MarketState, MarketStateMapping } from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
@@ -20,17 +17,15 @@ import type {
|
|||||||
DataSourceFilterFragment,
|
DataSourceFilterFragment,
|
||||||
MarketMaybeWithData,
|
MarketMaybeWithData,
|
||||||
} from '@vegaprotocol/markets';
|
} from '@vegaprotocol/markets';
|
||||||
import {
|
import { closedMarketsWithDataProvider } from '@vegaprotocol/markets';
|
||||||
MarketActionsDropdown,
|
|
||||||
closedMarketsWithDataProvider,
|
|
||||||
} from '@vegaprotocol/markets';
|
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
|
||||||
import { FLAGS } from '@vegaprotocol/environment';
|
|
||||||
import { SettlementDateCell } from './settlement-date-cell';
|
import { SettlementDateCell } from './settlement-date-cell';
|
||||||
import { SettlementPriceCell } from './settlement-price-cell';
|
import { SettlementPriceCell } from './settlement-price-cell';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||||
import { SuccessorMarketRenderer } from './successor-market-cell';
|
import { MarketActionsDropdown } from './market-table-actions';
|
||||||
|
import { MarketCodeCell } from './market-code-cell';
|
||||||
|
import type { CellClickedEvent } from 'ag-grid-community';
|
||||||
|
import { useClosedMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||||
|
|
||||||
type SettlementAsset =
|
type SettlementAsset =
|
||||||
MarketMaybeWithData['tradableInstrument']['instrument']['product']['settlementAsset'];
|
MarketMaybeWithData['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||||
@@ -51,7 +46,9 @@ interface Row {
|
|||||||
setlementDataSourceFilter: DataSourceFilterFragment | undefined;
|
setlementDataSourceFilter: DataSourceFilterFragment | undefined;
|
||||||
tradingTerminationOracleId: string;
|
tradingTerminationOracleId: string;
|
||||||
settlementAsset: SettlementAsset;
|
settlementAsset: SettlementAsset;
|
||||||
productType: string;
|
productType: ProductType | undefined;
|
||||||
|
successorMarketID: string | null | undefined;
|
||||||
|
parentMarketID: string | null | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Closed = () => {
|
export const Closed = () => {
|
||||||
@@ -95,16 +92,19 @@ export const Closed = () => {
|
|||||||
tradingTerminationOracleId:
|
tradingTerminationOracleId:
|
||||||
instrument.product.dataSourceSpecForTradingTermination.id,
|
instrument.product.dataSourceSpecForTradingTermination.id,
|
||||||
settlementAsset: instrument.product.settlementAsset,
|
settlementAsset: instrument.product.settlementAsset,
|
||||||
productType: instrument.product.__typename || '',
|
productType: instrument.product.__typename,
|
||||||
|
successorMarketID: market.successorMarketID,
|
||||||
|
parentMarketID: market.parentMarketID,
|
||||||
};
|
};
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
});
|
});
|
||||||
return (
|
|
||||||
<div className="h-full relative">
|
return <ClosedMarketsDataGrid rowData={rowData} error={error} />;
|
||||||
<ClosedMarketsDataGrid rowData={rowData} error={error} />
|
};
|
||||||
</div>
|
|
||||||
);
|
const components = {
|
||||||
|
MarketCodeCell,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClosedMarketsDataGrid = ({
|
const ClosedMarketsDataGrid = ({
|
||||||
@@ -114,18 +114,15 @@ const ClosedMarketsDataGrid = ({
|
|||||||
rowData: Row[];
|
rowData: Row[];
|
||||||
error: Error | undefined;
|
error: Error | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
|
const handleOnSelect = useClosedMarketClickHandler();
|
||||||
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
|
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
|
||||||
|
|
||||||
const colDefs = useMemo(() => {
|
const colDefs = useMemo(() => {
|
||||||
const cols: ColDef[] = compact([
|
return [
|
||||||
{
|
{
|
||||||
headerName: t('Market'),
|
headerName: t('Market'),
|
||||||
field: 'code',
|
field: 'code',
|
||||||
cellRenderer: 'MarketNameCell',
|
cellRenderer: 'MarketCodeCell',
|
||||||
},
|
|
||||||
{
|
|
||||||
headerName: t('Description'),
|
|
||||||
field: 'name',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headerName: t('Status'),
|
headerName: t('Status'),
|
||||||
@@ -176,12 +173,6 @@ const ClosedMarketsDataGrid = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
FLAGS.SUCCESSOR_MARKETS && {
|
|
||||||
headerName: t('Successor market'),
|
|
||||||
field: 'id',
|
|
||||||
colId: 'successorMarket',
|
|
||||||
cellRenderer: 'SuccessorMarketRenderer',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
headerName: t('Best bid'),
|
headerName: t('Best bid'),
|
||||||
field: 'bestBidPrice',
|
field: 'bestBidPrice',
|
||||||
@@ -263,12 +254,13 @@ const ClosedMarketsDataGrid = ({
|
|||||||
<MarketActionsDropdown
|
<MarketActionsDropdown
|
||||||
marketId={data.id}
|
marketId={data.id}
|
||||||
assetId={data.settlementAsset.id}
|
assetId={data.settlementAsset.id}
|
||||||
|
successorMarketID={data.successorMarketID}
|
||||||
|
parentMarketID={data.parentMarketID}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
return cols;
|
|
||||||
}, [openAssetDialog]);
|
}, [openAssetDialog]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -276,8 +268,30 @@ const ClosedMarketsDataGrid = ({
|
|||||||
rowData={rowData}
|
rowData={rowData}
|
||||||
columnDefs={colDefs}
|
columnDefs={colDefs}
|
||||||
getRowId={({ data }) => data.id}
|
getRowId={({ data }) => data.id}
|
||||||
components={{ SuccessorMarketRenderer, MarketNameCell }}
|
|
||||||
overlayNoRowsTemplate={error ? error.message : t('No markets')}
|
overlayNoRowsTemplate={error ? error.message : t('No markets')}
|
||||||
|
components={components}
|
||||||
|
rowHeight={45}
|
||||||
|
onCellClicked={({ data, column, event }: CellClickedEvent<Row>) => {
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
// prevent navigating to the market page if any of the below cells are clicked
|
||||||
|
// event.preventDefault or event.stopPropagation dont seem to apply for aggird
|
||||||
|
const colId = column.getColId();
|
||||||
|
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'settlementDate',
|
||||||
|
'settlementDataOracleId',
|
||||||
|
'settlementAsset',
|
||||||
|
'market-actions',
|
||||||
|
].includes(colId)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore metaKey exists
|
||||||
|
handleOnSelect(data.id, event ? event.metaKey : false);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import { ProductTypeShortName } from '@vegaprotocol/types';
|
||||||
|
import type { MarketCodeCellProps } from './market-code-cell';
|
||||||
|
import { MarketCodeCell } from './market-code-cell';
|
||||||
|
|
||||||
|
describe('MarketCodeCell', () => {
|
||||||
|
const renderComponent = (props: MarketCodeCellProps) => {
|
||||||
|
return render(<MarketCodeCell {...props} />);
|
||||||
|
};
|
||||||
|
|
||||||
|
it('renders SCCR if the market is a successor', () => {
|
||||||
|
const productType = 'Future';
|
||||||
|
const code = 'code';
|
||||||
|
const props = {
|
||||||
|
value: 'code',
|
||||||
|
data: {
|
||||||
|
productType,
|
||||||
|
parentMarketID: 'foo',
|
||||||
|
successorMarketID: undefined,
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
renderComponent(props);
|
||||||
|
expect(screen.getByTestId('stack-cell-primary')).toHaveTextContent(code);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
ProductTypeShortName[productType]
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
'SCCR'
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).not.toHaveTextContent(
|
||||||
|
'PRNT'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders PRNT if the market is a parent', () => {
|
||||||
|
const productType = 'Future';
|
||||||
|
const code = 'code';
|
||||||
|
const props = {
|
||||||
|
value: 'code',
|
||||||
|
data: {
|
||||||
|
productType,
|
||||||
|
parentMarketID: undefined,
|
||||||
|
successorMarketID: 'foo',
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
renderComponent(props);
|
||||||
|
expect(screen.getByTestId('stack-cell-primary')).toHaveTextContent(code);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
ProductTypeShortName[productType]
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
'PRNT'
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).not.toHaveTextContent(
|
||||||
|
'SCCR'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders both SCCR and PRNT if the market is both a parent and a successor', () => {
|
||||||
|
const productType = 'Future';
|
||||||
|
const code = 'code';
|
||||||
|
const props = {
|
||||||
|
value: 'code',
|
||||||
|
data: {
|
||||||
|
productType,
|
||||||
|
parentMarketID: 'foo',
|
||||||
|
successorMarketID: 'bar',
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
renderComponent(props);
|
||||||
|
expect(screen.getByTestId('stack-cell-primary')).toHaveTextContent(code);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
ProductTypeShortName[productType]
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
'PRNT'
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||||
|
'SCCR'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import compact from 'lodash/compact';
|
||||||
|
import type { ProductType } from '@vegaprotocol/types';
|
||||||
|
import { ProductTypeMapping, ProductTypeShortName } from '@vegaprotocol/types';
|
||||||
|
import { StackedCell } from '@vegaprotocol/datagrid';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
|
||||||
|
export interface MarketCodeCellProps {
|
||||||
|
value: string | undefined; // market code
|
||||||
|
data: {
|
||||||
|
productType: ProductType | undefined;
|
||||||
|
parentMarketID: string | null | undefined;
|
||||||
|
successorMarketID: string | null | undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MarketCodeCell = ({ value, data }: MarketCodeCellProps) => {
|
||||||
|
if (!value || !data || !data.productType) return null;
|
||||||
|
|
||||||
|
const infoSpanClasses =
|
||||||
|
'mr-1 pr-1 uppercase border-r last:pr-0 last:mr-0 last:border-r-0 border-vega-clight-200 dark:border-vega-cdark-200';
|
||||||
|
|
||||||
|
const info = compact([
|
||||||
|
<span
|
||||||
|
className={infoSpanClasses}
|
||||||
|
key="productType"
|
||||||
|
title={ProductTypeMapping[data.productType]}
|
||||||
|
>
|
||||||
|
{ProductTypeShortName[data.productType]}
|
||||||
|
</span>,
|
||||||
|
data.parentMarketID && (
|
||||||
|
<span
|
||||||
|
className={infoSpanClasses}
|
||||||
|
key="successor"
|
||||||
|
title={t('Successor of a market')}
|
||||||
|
>
|
||||||
|
{t('SCCR')}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
data.successorMarketID && (
|
||||||
|
<span
|
||||||
|
className={infoSpanClasses}
|
||||||
|
key="parent"
|
||||||
|
title={t('Parent of a market')}
|
||||||
|
>
|
||||||
|
{t('PRNT')}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return <StackedCell primary={value} secondary={info} />;
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
||||||
|
import { AgGrid, PriceFlashCell } from '@vegaprotocol/datagrid';
|
||||||
|
import type { MarketMaybeWithData } from '@vegaprotocol/markets';
|
||||||
|
import { useColumnDefs } from './use-column-defs';
|
||||||
|
|
||||||
|
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
||||||
|
|
||||||
|
const defaultColDef = {
|
||||||
|
sortable: true,
|
||||||
|
filter: true,
|
||||||
|
filterParams: { buttons: ['reset'] },
|
||||||
|
};
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
PriceFlashCell,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = TypedDataAgGrid<MarketMaybeWithData>;
|
||||||
|
|
||||||
|
export const MarketListTable = (props: Props) => {
|
||||||
|
const columnDefs = useColumnDefs();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AgGrid
|
||||||
|
getRowId={getRowId}
|
||||||
|
defaultColDef={defaultColDef}
|
||||||
|
columnDefs={columnDefs}
|
||||||
|
components={components}
|
||||||
|
rowHeight={45}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MarketListTable;
|
||||||
+27
@@ -9,14 +9,21 @@ import {
|
|||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { DApp, EXPLORER_MARKET, useLinks } from '@vegaprotocol/environment';
|
import { DApp, EXPLORER_MARKET, useLinks } from '@vegaprotocol/environment';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
|
|
||||||
export const MarketActionsDropdown = ({
|
export const MarketActionsDropdown = ({
|
||||||
marketId,
|
marketId,
|
||||||
assetId,
|
assetId,
|
||||||
|
successorMarketID,
|
||||||
|
parentMarketID,
|
||||||
}: {
|
}: {
|
||||||
marketId: string;
|
marketId: string;
|
||||||
assetId: string;
|
assetId: string;
|
||||||
|
successorMarketID: string | null | undefined;
|
||||||
|
parentMarketID: string | null | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const open = useAssetDetailsDialogStore((store) => store.open);
|
const open = useAssetDetailsDialogStore((store) => store.open);
|
||||||
const linkCreator = useLinks(DApp.Explorer);
|
const linkCreator = useLinks(DApp.Explorer);
|
||||||
|
|
||||||
@@ -42,6 +49,26 @@ export const MarketActionsDropdown = ({
|
|||||||
<VegaIcon name={VegaIconNames.INFO} size={16} />
|
<VegaIcon name={VegaIconNames.INFO} size={16} />
|
||||||
{t('View settlement asset details')}
|
{t('View settlement asset details')}
|
||||||
</TradingDropdownItem>
|
</TradingDropdownItem>
|
||||||
|
{parentMarketID && (
|
||||||
|
<TradingDropdownItem
|
||||||
|
onClick={() => {
|
||||||
|
navigate(Links[Routes.MARKET](parentMarketID));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<VegaIcon name={VegaIconNames.EYE} size={16} />
|
||||||
|
{t('View parent market')}
|
||||||
|
</TradingDropdownItem>
|
||||||
|
)}
|
||||||
|
{successorMarketID && (
|
||||||
|
<TradingDropdownItem
|
||||||
|
onClick={() => {
|
||||||
|
navigate(Links[Routes.MARKET](successorMarketID));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<VegaIcon name={VegaIconNames.EYE} size={16} />
|
||||||
|
{t('View successor market')}
|
||||||
|
</TradingDropdownItem>
|
||||||
|
)}
|
||||||
</ActionsDropdown>
|
</ActionsDropdown>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user