Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a29a8c1d4e |
@@ -6,7 +6,7 @@ name: 'Add Issues To Project Board'
|
||||
types:
|
||||
- opened
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PROJECT_MANAGE_ACTION }}
|
||||
GH_TOKEN: ${{ secrets.GH_NEW_CARD_TO_PROJECT }}
|
||||
PROJECT_ID: ${{ secrets.FRONT_END_PROJECT_ID }}
|
||||
ISSUE_ID: ${{ github.event.issue.node_id }}
|
||||
USER: ${{ github.actor }}
|
||||
|
||||
@@ -5,7 +5,10 @@ on:
|
||||
branches:
|
||||
- release/*
|
||||
- develop
|
||||
pull_request:
|
||||
- main
|
||||
# uncomment pull_request and comment pull_request_target to test CI changes against feature branch not target branch (develop)
|
||||
# pull_request:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- ready_for_review
|
||||
@@ -46,7 +49,7 @@ jobs:
|
||||
|
||||
lint-pr-title:
|
||||
needs: node-modules
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
name: Verify PR title
|
||||
uses: ./.github/workflows/lint-pr.yml
|
||||
secrets: inherit
|
||||
@@ -81,22 +84,6 @@ jobs:
|
||||
with:
|
||||
main-branch-name: develop
|
||||
|
||||
# See affected apps
|
||||
- name: See affected apps
|
||||
run: |
|
||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
python3 tools/ci/check-affected.py --github-ref="${{ github.ref }}" --branch-slug="$branch_slug" --event-name="${{ github.event_name }}"
|
||||
|
||||
- name: Verify script result
|
||||
run: |
|
||||
echo "Check outputs from script"
|
||||
echo "projects: ${{ env.PROJECTS }}"
|
||||
echo "projects-e2e: ${{ env.PROJECTS_E2E }}"
|
||||
echo "preview_governance: ${{ env.PREVIEW_GOVERNANCE }}"
|
||||
echo "preview_trading: ${{ env.PREVIEW_TRADING }}"
|
||||
echo "preview_explorer: ${{ env.PREVIEW_EXPLORER }}"
|
||||
echo "preview_tools: ${{ env.PREVIEW_TOOLS }}"
|
||||
|
||||
- name: Check formatting
|
||||
run: yarn nx format:check
|
||||
|
||||
@@ -112,6 +99,100 @@ jobs:
|
||||
- name: Build affected
|
||||
run: yarn nx affected:build || (yarn install && yarn nx affected:build)
|
||||
|
||||
# See affected apps
|
||||
- name: See affected apps
|
||||
run: |
|
||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
|
||||
echo ">>>> debug"
|
||||
echo "NX_BASE: ${{ env.NX_BASE }}"
|
||||
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
||||
echo "Affected: ${affected}"
|
||||
echo "Branch slug: ${branch_slug}"
|
||||
echo ">>>> eof debug"
|
||||
|
||||
projects_array=()
|
||||
|
||||
preview_governance="not deployed"
|
||||
preview_trading="not deployed"
|
||||
preview_explorer="not deployed"
|
||||
preview_tools="not deployed"
|
||||
|
||||
# parse if affected is any of three main applications, if none - use all of them
|
||||
if echo "$affected" | grep -q governance; then
|
||||
echo "Governance is affected"
|
||||
projects_array+=("governance")
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
fi
|
||||
if echo "$affected" | grep -q trading; then
|
||||
echo "Trading is affected"
|
||||
projects_array+=("trading")
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
fi
|
||||
if echo "$affected" | grep -q explorer; then
|
||||
echo "Explorer is affected"
|
||||
projects_array+=("explorer")
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
if [[ ${#projects_array[@]} -eq 0 ]]; then
|
||||
projects_array=("governance" "trading" "explorer")
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
|
||||
# applications parsed before this loop are applicable for running e2e-tests
|
||||
projects_e2e_array=()
|
||||
for project in "${projects_array[@]}"; do
|
||||
projects_e2e_array+=("${project}-e2e")
|
||||
done
|
||||
# all applications below this loop are not applicable for running e2e-test
|
||||
|
||||
# check if pull request event to deploy tools
|
||||
if [[ "${{ github.event_name }}" = "pull_request" ]]; then
|
||||
if echo "$affected" | grep -q multisig-signer; then
|
||||
echo "Tools are affected"
|
||||
echo "Deploying tools on preview"
|
||||
preview_tools=$(printf "https://%s.%s.vega.rocks" "tools" "$branch_slug")
|
||||
|
||||
projects_array+=("multisig-signer")
|
||||
fi
|
||||
# those apps deploy only from develop to mainnet
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
if echo "$affected" | grep -q multisig-signer; then
|
||||
echo "Tools are affected"
|
||||
echo "Deploying tools on s3"
|
||||
|
||||
projects_array+=("multisig-signer")
|
||||
fi
|
||||
if echo "$affected" | grep -q static; then
|
||||
echo "static is affected"
|
||||
echo "Deploying static on s3"
|
||||
|
||||
projects_array+=("static")
|
||||
fi
|
||||
if echo "$affected" | grep -q ui-toolkit; then
|
||||
echo "ui-toolkit is affected"
|
||||
echo "Deploying ui-toolkit on s3"
|
||||
|
||||
projects_array+=("ui-toolkit")
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Projects: ${projects_array[@]}"
|
||||
echo "Projects E2E: ${projects_e2e_array[@]}"
|
||||
projects_json=$(jq -M --compact-output --null-input '$ARGS.positional' --args -- "${projects_array[@]}")
|
||||
projects_e2e_json=$(jq -M --compact-output --null-input '$ARGS.positional' --args -- "${projects_e2e_array[@]}")
|
||||
|
||||
echo PROJECTS_E2E=$projects_e2e_json >> $GITHUB_ENV
|
||||
echo PROJECTS=$projects_json >> $GITHUB_ENV
|
||||
|
||||
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
|
||||
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
|
||||
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
|
||||
echo PREVIEW_TOOLS=$preview_tools >> $GITHUB_ENV
|
||||
|
||||
outputs:
|
||||
projects: ${{ env.PROJECTS }}
|
||||
projects-e2e: ${{ env.PROJECTS_E2E }}
|
||||
@@ -133,7 +214,7 @@ jobs:
|
||||
publish-dist:
|
||||
needs: lint-test-build
|
||||
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: ${{ needs.lint-test-build.outputs.projects != '[]' }}
|
||||
uses: ./.github/workflows/publish-dist.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
@@ -144,7 +225,7 @@ jobs:
|
||||
needs:
|
||||
- publish-dist
|
||||
- lint-test-build
|
||||
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_name == 'pull_request_target' }}
|
||||
timeout-minutes: 60
|
||||
name: '(CD) comment preview links'
|
||||
steps:
|
||||
@@ -160,26 +241,26 @@ jobs:
|
||||
# https://stackoverflow.com/questions/3183444/check-for-valid-link-url
|
||||
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_governance }}" =~ $regex ]]; then
|
||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_governance }}"; do
|
||||
echo "waiting for governance preview: ${{ needs.lint-test-build.outputs.preview_governance }}"
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_governance }}"; do
|
||||
echo "waiting for governance preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_explorer }}" =~ $regex ]]; then
|
||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_explorer }}"; do
|
||||
echo "waiting for explorer preview: ${{ needs.lint-test-build.outputs.preview_explorer }}"
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_explorer }}"; do
|
||||
echo "waiting for explorer preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_trading }}" =~ $regex ]]; then
|
||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_trading }}"; do
|
||||
echo "waiting for trading preview: ${{ needs.lint-test-build.outputs.preview_trading }}"
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_trading }}"; do
|
||||
echo "waiting for trading preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_tools }}" =~ $regex ]]; then
|
||||
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_tools }}"; do
|
||||
echo "waiting for tools preview: ${{ needs.lint-test-build.outputs.preview_tools }}"
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_tools }}"; do
|
||||
echo "waiting for tools preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
@@ -190,7 +271,7 @@ jobs:
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
Previews
|
||||
Previews:
|
||||
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
|
||||
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
||||
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
name: console-test-run
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
github-sha:
|
||||
required: true
|
||||
type: string
|
||||
jobs:
|
||||
console-test:
|
||||
timeout-minutes: 5
|
||||
runs-on: self-hosted-runner
|
||||
steps:
|
||||
- name: Checkout console test repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: vegaprotocol/console-test
|
||||
path: './console-test'
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10.11'
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
poetry install --no-root
|
||||
working-directory: ./console-test
|
||||
|
||||
- name: load Binaries
|
||||
run: |
|
||||
poetry run python -m vega_sim.tools.load_binaries
|
||||
working-directory: ./console-test
|
||||
|
||||
- name: pull console
|
||||
run: |
|
||||
poetry run docker pull ghcr.io/vegaprotocol/frontend/trading:${{ inputs.github-sha }}
|
||||
|
||||
- name: Update container_name in config.py
|
||||
run: |
|
||||
sed -i "s/container_name = \".*\"/container_name = \"vegaprotocol\/frontend\/trading:${{ inputs.github-sha }}\"/g" config.py
|
||||
|
||||
- name: install playwright
|
||||
run: poetry run playwright install
|
||||
working-directory: ./console-test
|
||||
|
||||
- name: run tests
|
||||
run: poetry run pytest --numprocesses auto
|
||||
working-directory: ./console-test
|
||||
|
||||
- name: Upload Playwright Trace
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-trace
|
||||
path: ./traces/
|
||||
retention-days: 15
|
||||
@@ -22,39 +22,6 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Init variables
|
||||
run: |
|
||||
echo IS_PR=false >> $GITHUB_ENV
|
||||
echo IS_MAINNET_RELEASE=false >> $GITHUB_ENV
|
||||
echo IS_TESTNET_RELEASE=false >> $GITHUB_ENV
|
||||
echo IS_IPFS_RELEASE=false >> $GITHUB_ENV
|
||||
echo IS_S3_RELEASE=false >> $GITHUB_ENV
|
||||
|
||||
- name: Is PR
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
echo IS_PR=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is mainnet release
|
||||
if: ${{ contains(github.ref, 'release/mainnnet') && !contains(github.ref, 'mirror') }}
|
||||
run: |
|
||||
echo IS_MAINNET_RELEASE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is testnet release
|
||||
if: ${{ contains(github.ref, 'release/testnet') }}
|
||||
run: |
|
||||
echo IS_TESTNET_RELEASE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is IPFS Release
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( env.IS_MAINNET_RELEASE == 'true' || env.IS_TESTNET_RELEASE == 'true' ) }}
|
||||
run: |
|
||||
echo IS_IPFS_RELEASE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is S3 Release
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' }}
|
||||
run: |
|
||||
echo IS_S3_RELEASE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Set up QEMU
|
||||
id: quemu
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@@ -66,7 +33,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Log in to the Container registry (ghcr)
|
||||
if: ${{ env.IS_PR == 'true' }}
|
||||
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
@@ -75,8 +42,9 @@ jobs:
|
||||
|
||||
- name: Log in to the Container registry (docker hub)
|
||||
uses: docker/login-action@v2
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' }}
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
||||
with:
|
||||
# registry: registry.hub.docker.com
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
@@ -97,13 +65,51 @@ jobs:
|
||||
- name: Define dist variables
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: |
|
||||
python3 tools/ci/define-dist-variables.py --github-ref="${{ github.ref }}" --app="${{ matrix.app }}"
|
||||
envName=''
|
||||
domain="vega.rocks"
|
||||
bucketName=''
|
||||
|
||||
- name: Verify script result
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: |
|
||||
echo "BUCKET_NAME=${{ env.BUCKET_NAME }}"
|
||||
echo "ENV_NAME=${{ env.ENV_NAME }}"
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
if [[ "${{ matrix.app }}" = "multisig-signer" ]]; then
|
||||
envName="mainnet"
|
||||
bucketName="tools.vega.xyz"
|
||||
fi
|
||||
if [[ "${{ matrix.app }}" = "static" ]]; then
|
||||
envName="mainnet"
|
||||
bucketName="static.vega.xyz"
|
||||
fi
|
||||
if [[ "${{ matrix.app }}" = "ui-toolkit" ]]; then
|
||||
envName="mainnet"
|
||||
bucketName="ui.vega.rocks"
|
||||
fi
|
||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
||||
envName="mainnet"
|
||||
fi
|
||||
|
||||
if [[ "${envName}" = "mainnet" ]]; then
|
||||
domain="vega.xyz"
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
fi
|
||||
elif [[ "${envName}" = "testnet" ]]; then
|
||||
domain="fairground.wtf"
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||
fi
|
||||
|
||||
echo "bucket name: ${bucketName}"
|
||||
echo "env name: ${envName}"
|
||||
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||
|
||||
- name: Build local dist
|
||||
run: |
|
||||
@@ -118,12 +124,8 @@ jobs:
|
||||
elif [ "${{ matrix.app }}" = "ui-toolkit" ]; then
|
||||
NODE_ENV=production yarn nx run ui-toolkit:build-storybook
|
||||
DIST_LOCATION=dist/storybook/ui-toolkit
|
||||
elif [ "${{ matrix.app }}" = "static" ]; then
|
||||
yarn nx build static || (yarn install && yarn nx build static)
|
||||
else
|
||||
$envCmd yarn nx build ${{ matrix.app }} || (yarn install && $envCmd yarn nx build ${{ matrix.app }})
|
||||
fi
|
||||
if [[ -z "$DIST_LOCATION" ]]; then
|
||||
DIST_LOCATION=dist/apps/${{ matrix.app }}
|
||||
fi
|
||||
mv $DIST_LOCATION dist-result
|
||||
@@ -143,7 +145,7 @@ jobs:
|
||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
|
||||
|
||||
- name: Image digest
|
||||
if: ${{ env.IS_PR == 'true' }}
|
||||
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
- name: Sanity check docker image
|
||||
@@ -158,7 +160,7 @@ jobs:
|
||||
uses: docker/build-push-action@v3
|
||||
continue-on-error: true
|
||||
id: ghcr-push
|
||||
if: ${{ env.IS_PR == 'true' }}
|
||||
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
@@ -173,7 +175,7 @@ jobs:
|
||||
uses: docker/build-push-action@v3
|
||||
continue-on-error: true
|
||||
id: dockerhub-push
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' }}
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
@@ -183,7 +185,7 @@ jobs:
|
||||
ENV_NAME=${{ env.ENV_NAME }}
|
||||
tags: |
|
||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
||||
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || '' }}
|
||||
vegaprotocol/${{ matrix.app }}:${{ endsWith(github.ref, 'main') && 'mainnet' || endsWith(github.ref, 'release/testnet') && 'testnet' || '' }}
|
||||
|
||||
- name: Publish dist as docker image (ghcr - retry)
|
||||
uses: docker/build-push-action@v3
|
||||
@@ -210,13 +212,13 @@ jobs:
|
||||
ENV_NAME=${{ env.ENV_NAME }}
|
||||
tags: |
|
||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
||||
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || '' }}
|
||||
vegaprotocol/${{ matrix.app }}:${{ endsWith(github.ref, 'main') && 'mainnet' || endsWith(github.ref, 'release/testnet') && 'testnet' || '' }}
|
||||
|
||||
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||
- name: Publish dist to s3
|
||||
uses: jakejarvis/s3-sync-action@master
|
||||
# s3 releases are not happening for trading on mainnet - it's IPFS
|
||||
if: ${{ env.IS_S3_RELEASE == 'true' }}
|
||||
if: ${{ github.event_name == 'push' && ( matrix.app != 'trading' || (matrix.app == 'trading' && !( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) ) ) }}
|
||||
with:
|
||||
args: --acl private --follow-symlinks --delete
|
||||
env:
|
||||
@@ -227,11 +229,11 @@ jobs:
|
||||
SOURCE_DIR: 'dist-result'
|
||||
|
||||
- name: Install aws CLI
|
||||
if: ${{ env.IS_S3_RELEASE == 'true' }}
|
||||
if: ${{ github.event_name == 'push' && ( matrix.app != 'trading' || (matrix.app == 'trading' && !( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) ) ) }}
|
||||
uses: unfor19/install-aws-cli-action@master
|
||||
|
||||
- name: Perform cache invalidation
|
||||
if: ${{ env.IS_S3_RELEASE == 'true' }}
|
||||
if: ${{ github.event_name == 'push' && ( matrix.app != 'trading' || (matrix.app == 'trading' && !( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) ) ) }}
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -244,16 +246,16 @@ jobs:
|
||||
|
||||
- name: Add preview label
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
if: ${{ env.IS_PR == 'true' }}
|
||||
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
with:
|
||||
labels: ${{ matrix.app }}-preview
|
||||
number: ${{ github.event.number }}
|
||||
|
||||
- name: Trigger fleek deployment
|
||||
# release to ipfs happens only on mainnet (represented by main branch) for trading
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' }}
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
||||
run: |
|
||||
if [[ "${{ env.IS_MAINNET_RELEASE }}" = "true" ]]; then
|
||||
if echo ${{ github.ref }} | grep -q main; then
|
||||
# display info about app
|
||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
@@ -266,7 +268,7 @@ jobs:
|
||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
||||
https://api.fleek.co/graphql
|
||||
|
||||
elif [[ "${{ env.IS_TESTNET_RELEASE }}" = "true" ]]; then
|
||||
elif echo ${{ github.ref }} | grep -q release/testnet; then
|
||||
# display info about app
|
||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
@@ -281,7 +283,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Check out ipfs-redirect
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' }}
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'testnet') ) }}
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'vegaprotocol/ipfs-redirect'
|
||||
@@ -290,7 +292,7 @@ jobs:
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
|
||||
- name: Update interstitial page to point to the new console
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' }}
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'testnet') ) }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
run: |
|
||||
@@ -312,11 +314,11 @@ jobs:
|
||||
git config --global user.name "vega-ci-bot"
|
||||
|
||||
# update CID files
|
||||
if [[ "${{ env.IS_MAINNET_RELEASE }}" = "true" ]]; then
|
||||
if echo ${{ github.ref }} | grep -q main; then
|
||||
echo $new_hash > cidv0-mainnet.txt
|
||||
echo $new_cid > cidv1-mainnet.txt
|
||||
git add cidv0-mainnet.txt cidv1-mainnet.txt
|
||||
elif [[ "${{ env.IS_TESTNET_RELEASE }}" = "true" ]]; then
|
||||
elif echo ${{ github.ref }} | grep -q release/testnet; then
|
||||
echo $new_hash > cidv0-fairground.txt
|
||||
echo $new_cid > cidv1-fairground.txt
|
||||
git add cidv0-fairground.txt cidv1-fairground.txt
|
||||
|
||||
@@ -16,10 +16,5 @@ NX_EXPLORER_NETWORK_PARAMETERS=1
|
||||
NX_EXPLORER_PARTIES=1
|
||||
NX_EXPLORER_VALIDATORS=1
|
||||
|
||||
CYPRESS_VEGA_URL=http://localhost:3008/graphql
|
||||
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
||||
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||
CYPRESS_VEGA_URL=http://localhost:3008/graphql
|
||||
|
||||
@@ -1,130 +1,19 @@
|
||||
context('Market page', { tags: '@regression' }, function () {
|
||||
//Tests set to skip until market bug for capsule checkpoint is fixed
|
||||
context.skip('Market page', { tags: '@regression' }, function () {
|
||||
describe('Verify elements on page', function () {
|
||||
const marketHeaders = 'markets-heading';
|
||||
const createdMarketId =
|
||||
'2eab0e66545a789047561bc5a2e5cbc3b19eb708da41104e3cac2474ee36c4d4';
|
||||
const marketHeaders = '[data-testid="markets-header"]';
|
||||
const marketNavigation = 'a[href="/markets"]';
|
||||
|
||||
before('Create market', function () {
|
||||
it('Markets page is displayed', function () {
|
||||
cy.visit('/');
|
||||
cy.createMarket();
|
||||
cy.get(marketNavigation).click();
|
||||
cy.common_validate_blocks_data_displayed(marketHeaders);
|
||||
});
|
||||
|
||||
beforeEach('Get market id', function () {
|
||||
cy.navigate_to('markets');
|
||||
cy.get('[col-id="id"]').eq(1).invoke('text').as('createdMarketId');
|
||||
});
|
||||
|
||||
it('Market displayed on market page', function () {
|
||||
cy.navigate_to('markets');
|
||||
cy.getByTestId(marketHeaders).should('be.visible');
|
||||
cy.get(`[row-id="${this.createdMarketId}"]`)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get_element_by_col_id('code').should('have.text', 'TEST.24h');
|
||||
cy.get_element_by_col_id('name').should('have.text', 'Test market 1');
|
||||
cy.get_element_by_col_id('state').should('have.text', 'Pending');
|
||||
cy.get_element_by_col_id('asset').should('have.text', 'fUSDC');
|
||||
cy.get_element_by_col_id('id').should(
|
||||
'have.text',
|
||||
this.createdMarketId
|
||||
);
|
||||
cy.get_element_by_col_id('actions')
|
||||
.find('a')
|
||||
.should('have.attr', 'href', `/markets/${this.createdMarketId}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to go to market details page', function () {
|
||||
cy.navigate_to('markets');
|
||||
cy.get_element_by_col_id('actions').eq(1).click();
|
||||
cy.getByTestId(marketHeaders).should('have.text', 'Test market 1');
|
||||
cy.validate_element_from_table('Name', 'Test market 1');
|
||||
cy.validate_element_from_table('Market ID', this.createdMarketId);
|
||||
cy.validate_element_from_table('Trading Mode', 'Opening auction');
|
||||
cy.validate_element_from_table('Market Decimal Places', '5');
|
||||
cy.validate_element_from_table('Position Decimal Places', '5');
|
||||
cy.validate_element_from_table('Settlement Asset Decimal Places', '5');
|
||||
// Instrument
|
||||
cy.validate_element_from_table('Market Name', 'Test market 1');
|
||||
cy.validate_element_from_table('Code', 'TEST.24h');
|
||||
cy.validate_element_from_table('Product Type', 'Future');
|
||||
cy.validate_element_from_table('Quote Name', 'fUSDC');
|
||||
// Settlement Asset
|
||||
cy.validate_element_from_table('Quote Name', 'fUSDC');
|
||||
cy.validate_element_from_table('Symbol', 'fUSDC');
|
||||
cy.validate_element_from_table('Decimals', '5');
|
||||
cy.validate_element_from_table('Quantum', '0.00');
|
||||
cy.validate_element_from_table('Status', 'Enabled');
|
||||
cy.validate_element_from_table('Max faucet amount', '10,000,000.00');
|
||||
cy.validate_element_from_table(
|
||||
'Infrastructure fee account balance',
|
||||
'0.00'
|
||||
);
|
||||
cy.validate_element_from_table(
|
||||
'Global reward pool account balance',
|
||||
'0.00'
|
||||
);
|
||||
// Metadata
|
||||
cy.validate_element_from_table('Sector', 'tech');
|
||||
cy.validate_element_from_table('Source', 'docs.vega.xyz');
|
||||
// Risk model
|
||||
cy.validate_element_from_table('Tau', '0.0001140771161');
|
||||
cy.validate_element_from_table('Risk Aversion Parameter', '0.01');
|
||||
// Risk parameters
|
||||
// cy.validate_element_from_table('R', '0.016')
|
||||
cy.validate_element_from_table('Sigma', '0.5');
|
||||
// Risk factors
|
||||
cy.validate_element_from_table('Short', '0.0143218738374871');
|
||||
cy.validate_element_from_table('Long', '0.0141450471498822');
|
||||
// Price monitoring settings 1
|
||||
cy.validate_element_from_table('Horizon Secs', '43,200');
|
||||
cy.validate_element_from_table('Probability', '1');
|
||||
cy.validate_element_from_table('Auction Extension Secs', '600');
|
||||
// Liquidity Monitoring
|
||||
cy.validate_element_from_table('Triggering Ratio', '0.7');
|
||||
cy.validate_element_from_table('Time Window', '3,600');
|
||||
cy.validate_element_from_table('Scaling Factor', '10');
|
||||
// Liquidity
|
||||
cy.validate_element_from_table('Target Stake', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Supplied Stake', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Market Value Proxy', '0.00 fUSDC');
|
||||
// Liquidity price range
|
||||
cy.validate_element_from_table(
|
||||
'Liquidity Price Range',
|
||||
'1,000.00% of mid price'
|
||||
);
|
||||
cy.validate_element_from_table('Lowest Price', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Highest Price', '0.00 fUSDC');
|
||||
|
||||
cy.getByTestId('oracle-spec-links')
|
||||
.should('have.attr', 'href')
|
||||
.and(
|
||||
'contain',
|
||||
'/oracles/bf242aa5c9f64fcbb77808aa8582e73711519f4b35264eb797a80f1803590a24'
|
||||
);
|
||||
|
||||
// Able to view Json
|
||||
cy.contains('View JSON').click();
|
||||
cy.get('.language-json').should('exist');
|
||||
});
|
||||
|
||||
// Skipping due to resize observer loop limit error
|
||||
it.skip('Markets page displayed on mobile', function () {
|
||||
it('Markets page displayed on mobile', function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.navigate_to('markets', true);
|
||||
cy.getByTestId(marketHeaders).should('be.visible');
|
||||
cy.get(`[row-id="${createdMarketId}"]`)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get_element_by_col_id('code').should('have.text', 'TEST.24h');
|
||||
cy.get_element_by_col_id('name').should('have.text', 'Test market 1');
|
||||
cy.get_element_by_col_id('state').should('have.text', 'Pending');
|
||||
cy.get_element_by_col_id('asset').should('have.text', 'fUSDC');
|
||||
cy.get_element_by_col_id('id').should('have.text', createdMarketId);
|
||||
cy.get_element_by_col_id('actions')
|
||||
.find('a')
|
||||
.should('have.attr', 'href', `/markets/${createdMarketId}`);
|
||||
});
|
||||
cy.get(marketNavigation).click();
|
||||
cy.common_validate_blocks_data_displayed(marketHeaders);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ context.skip('Transactions page', function () {
|
||||
.first()
|
||||
.click({ force: true });
|
||||
} else {
|
||||
cy.log('Unable to find any transactions on page');
|
||||
cy.slack('Unable to find any transactions on page');
|
||||
cy.screenshot();
|
||||
}
|
||||
});
|
||||
@@ -78,7 +78,7 @@ context.skip('Transactions page', function () {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cy.log('Unable to find any transactions on page');
|
||||
cy.slack('Unable to find any transactions on page');
|
||||
cy.screenshot();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,11 +7,7 @@ context('Validator page', { tags: '@smoke' }, function () {
|
||||
it('should be able to see validator tiles', function () {
|
||||
cy.getNodes().then((nodes) => {
|
||||
nodes.forEach((node) => {
|
||||
if (node.rankingScore.performanceScore > 0) {
|
||||
cy.get(`[validator-id="${node.id}"]`).should('be.visible');
|
||||
} else {
|
||||
cy.get(`[validator-id="${node.id}"]`).should('not.exist');
|
||||
}
|
||||
cy.get(`[validator-id="${node.id}"]`).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ Cypress.Commands.add('switchToMobile', () => {
|
||||
Cypress.Commands.add('common_switch_to_mobile_and_click_toggle', function () {
|
||||
cy.viewport('iphone-x');
|
||||
cy.visit('/');
|
||||
cy.get('[data-testid="button-menu-drawer"]').click();
|
||||
cy.get('[data-testid="open-menu"]').click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('monitor_clipboard', () => {
|
||||
@@ -88,42 +88,3 @@ Cypress.Commands.add('convert_number_to_max_four_decimal', (number) => {
|
||||
maximumFractionDigits: 4,
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('navigate_to', (page, mobileView = false) => {
|
||||
const navigation = {
|
||||
transactions: '/txs',
|
||||
blocks: '/blocks',
|
||||
oracles: '/oracles',
|
||||
validators: '/validators',
|
||||
parties: '/parties',
|
||||
assets: '/assets',
|
||||
markets: '/markets',
|
||||
governanceProposals: '/governance',
|
||||
networkParameters: '/network-parameters',
|
||||
genesisParameters: '/genesis',
|
||||
};
|
||||
|
||||
const topLevelRoutes = ['transactions', 'blocks', 'oracles', 'validators'];
|
||||
|
||||
cy.getByTestId('navigation').within(() => {
|
||||
if (!topLevelRoutes.includes(page) && mobileView === false) {
|
||||
cy.getByTestId('other').first().click();
|
||||
}
|
||||
cy.get(`[href="${navigation[page]}"]`).first().click();
|
||||
});
|
||||
cy.url().should('include', navigation[page]);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('get_element_by_col_id', (elementName) => {
|
||||
cy.get(`[col-id="${elementName}"]`);
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
'validate_element_from_table',
|
||||
(tableRowName, tableRowValue) => {
|
||||
cy.contains(tableRowName)
|
||||
.parentsUntil("[data-testid='key-value-table-row']")
|
||||
.siblings()
|
||||
.should('have.text', tableRowValue);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# App configuration variables
|
||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
||||
NX_VEGA_ENV=DEVNET
|
||||
|
||||
@@ -4,7 +4,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/mainnet-mirror/vegawallet-mainnet-mirror.toml
|
||||
NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql
|
||||
NX_VEGA_ENV=MAINNET_MIRROR
|
||||
NX_VEGA_ENV=MAINNET-MIRROR
|
||||
NX_BLOCK_EXPLORER=https://be.mainnet-mirror.vega.rocks/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/spec-update-v0.72.0-preview.2/specs/v0.72.0-preview.2/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
|
||||
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.71.4/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ const defaultOptions = {} as const;
|
||||
export type ExplorerGovernanceAssetQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerGovernanceAssetQuery = { __typename?: 'Query', networkParameter?: { __typename?: 'NetworkParameter', value: string } | null };
|
||||
export type ExplorerGovernanceAssetQuery = { __typename: 'Query', networkParameter?: { __typename: 'NetworkParameter', value: string } | null };
|
||||
|
||||
|
||||
export const ExplorerGovernanceAssetDocument = gql`
|
||||
|
||||
@@ -8,12 +8,12 @@ export type ExplorerEpochQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerEpochQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, timestamps: { __typename?: 'EpochTimestamps', start?: any | null, end?: any | null, firstBlock: string, lastBlock?: string | null } } };
|
||||
export type ExplorerEpochQuery = { __typename: 'Query', epoch: { __typename: 'Epoch', id: string, timestamps: { __typename: 'EpochTimestamps', start?: any | null, end?: any | null, firstBlock: string, lastBlock?: string | null } } };
|
||||
|
||||
export type ExplorerFutureEpochQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerFutureEpochQuery = { __typename?: 'Query', networkParameter?: { __typename?: 'NetworkParameter', value: string } | null, epoch: { __typename?: 'Epoch', id: string, timestamps: { __typename?: 'EpochTimestamps', start?: any | null } } };
|
||||
export type ExplorerFutureEpochQuery = { __typename: 'Query', networkParameter?: { __typename: 'NetworkParameter', value: string } | null, epoch: { __typename: 'Epoch', id: string, timestamps: { __typename: 'EpochTimestamps', start?: any | null } } };
|
||||
|
||||
|
||||
export const ExplorerEpochDocument = gql`
|
||||
|
||||
@@ -95,10 +95,7 @@ export const Header = () => {
|
||||
{mainItems.map(routeToNavigationItem)}
|
||||
{groupedItems && groupedItems.length > 0 && (
|
||||
<NavigationItem>
|
||||
<NavigationTrigger
|
||||
isActive={Boolean(isOnOther)}
|
||||
data-testid="other"
|
||||
>
|
||||
<NavigationTrigger isActive={Boolean(isOnOther)}>
|
||||
{t('Other')}
|
||||
</NavigationTrigger>
|
||||
<NavigationContent>
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type ExplorerMarketQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } } } } | null };
|
||||
export type ExplorerMarketQuery = { __typename: 'Query', market?: { __typename: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', name: string, product: { __typename: 'Future', quoteName: string, settlementAsset: { __typename: 'Asset', decimals: number } } } } } | null };
|
||||
|
||||
|
||||
export const ExplorerMarketDocument = gql`
|
||||
|
||||
@@ -8,7 +8,7 @@ export type ExplorerNodeQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerNodeQuery = { __typename?: 'Query', node?: { __typename?: 'Node', id: string, name: string, status: Types.NodeStatus } | null };
|
||||
export type ExplorerNodeQuery = { __typename: 'Query', node?: { __typename: 'Node', id: string, name: string, status: Types.NodeStatus } | null };
|
||||
|
||||
|
||||
export const ExplorerNodeDocument = gql`
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type ExplorerProposalQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerProposalQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null };
|
||||
export type ExplorerProposalQuery = { __typename: 'Query', proposal?: { __typename: 'Proposal', id?: string | null, rationale: { __typename: 'ProposalRationale', title: string, description: string } } | null };
|
||||
|
||||
|
||||
export const ExplorerProposalDocument = gql`
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerDeterministicOrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } };
|
||||
export type ExplorerDeterministicOrderFieldsFragment = { __typename: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename: 'Party', id: string }, market: { __typename: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', name: string, product: { __typename: 'Future', quoteName: string } } } } };
|
||||
|
||||
export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
|
||||
orderId: Types.Scalars['ID'];
|
||||
@@ -11,7 +11,7 @@ export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerDeterministicOrderQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } } };
|
||||
export type ExplorerDeterministicOrderQuery = { __typename: 'Query', orderByID: { __typename: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename: 'Party', id: string }, market: { __typename: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', name: string, product: { __typename: 'Future', quoteName: string } } } } } };
|
||||
|
||||
export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
|
||||
fragment ExplorerDeterministicOrderFields on Order {
|
||||
|
||||
@@ -137,7 +137,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
|
||||
hide: window.innerWidth <= BREAKPOINT_MD,
|
||||
headerName: t('Enactment date'),
|
||||
field: 'terms.enactmentDatetime',
|
||||
valueFormatter: ({
|
||||
valueFormatte: ({
|
||||
value,
|
||||
}: VegaValueFormatterParams<
|
||||
ProposalListFieldsFragment,
|
||||
|
||||
@@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerStatsFieldsFragment = { __typename?: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string };
|
||||
export type ExplorerStatsFieldsFragment = { __typename: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string };
|
||||
|
||||
export type ExplorerStatsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerStatsQuery = { __typename?: 'Query', statistics: { __typename?: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string } };
|
||||
export type ExplorerStatsQuery = { __typename: 'Query', statistics: { __typename: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string } };
|
||||
|
||||
export const ExplorerStatsFieldsFragmentDoc = gql`
|
||||
fragment ExplorerStatsFields on Statistics {
|
||||
|
||||
@@ -8,7 +8,7 @@ export type ExplorerNodeVoteQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerNodeVoteQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null, deposit?: { __typename?: 'Deposit', id: string, status: Types.DepositStatus, createdTimestamp: any, creditedTimestamp?: any | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null };
|
||||
export type ExplorerNodeVoteQuery = { __typename: 'Query', withdrawal?: { __typename: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, txHash?: string | null, asset: { __typename: 'Asset', id: string, name: string, decimals: number }, party: { __typename: 'Party', id: string } } | null, deposit?: { __typename: 'Deposit', id: string, status: Types.DepositStatus, createdTimestamp: any, creditedTimestamp?: any | null, txHash?: string | null, asset: { __typename: 'Asset', id: string, name: string, decimals: number }, party: { __typename: 'Party', id: string } } | null };
|
||||
|
||||
|
||||
export const ExplorerNodeVoteDocument = gql`
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type ExplorerSettlementAssetForMarketQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerSettlementAssetForMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number } | null };
|
||||
export type ExplorerSettlementAssetForMarketQuery = { __typename: 'Query', market?: { __typename: 'Market', id: string, decimalPlaces: number } | null };
|
||||
|
||||
|
||||
export const ExplorerSettlementAssetForMarketDocument = gql`
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export interface TxDetailsOrderIcebergDetailsProps {
|
||||
iceberg: components['schemas']['v1IcebergOpts'];
|
||||
size: components['schemas']['v1OrderSubmission']['size'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
.iceberg .sub {
|
||||
vertical-align: bottom;
|
||||
color: #954F01;
|
||||
}
|
||||
|
||||
.iceberg .sup {
|
||||
vertical-align: top;
|
||||
color: #515E1E;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Visualises the iceberg details of an order, showing the minimum visible size,
|
||||
* the full size and the peak size.
|
||||
*/
|
||||
export const TxOrderIcebergDetails = ({
|
||||
iceberg,
|
||||
size,
|
||||
}: TxDetailsOrderIcebergDetailsProps) => {
|
||||
return (
|
||||
<div
|
||||
className="inline-block iceberg bg-vega-blue-300 border-vega-blue-350 border-[1px] text-[70%] font-mono py-[2px] pl-2 pr-3 height-[1em] leading-[1em] cursor-pointer"
|
||||
style={{ clipPath: 'polygon(10% 0%, 100% 0%, 90% 100%, 0% 100%)' }}
|
||||
>
|
||||
<Tooltip description={t('Iceberg: Minimum visible size')}>
|
||||
<span className="align-bottom text-vega-orange-650">
|
||||
{iceberg.minimumVisibleSize || '-'}
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip description={t('Iceberg: Total size')}>
|
||||
<span className="text-sm text-vega-blue-600 mx-3">{size}</span>
|
||||
</Tooltip>
|
||||
<Tooltip description={t('Iceberg: Visible peak')}>
|
||||
<span className="align-top text-vega-yellow-600">
|
||||
{iceberg.peakSize || '-'}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type ExplorerProposalStatusQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerProposalStatusQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, rejectionReason?: Types.ProposalRejectionReason | null } | null };
|
||||
export type ExplorerProposalStatusQuery = { __typename: 'Query', proposal?: { __typename: 'Proposal', id?: string | null, state: Types.ProposalState, rejectionReason?: Types.ProposalRejectionReason | null } | null };
|
||||
|
||||
|
||||
export const ExplorerProposalStatusDocument = gql`
|
||||
|
||||
+2
-2
@@ -8,14 +8,14 @@ export type ExplorerNewAssetSignatureBundleQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerNewAssetSignatureBundleQuery = { __typename?: 'Query', erc20ListAssetBundle?: { __typename?: 'Erc20ListAssetBundle', signatures: string, nonce: string } | null, asset?: { __typename?: 'Asset', status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } | null };
|
||||
export type ExplorerNewAssetSignatureBundleQuery = { __typename: 'Query', erc20ListAssetBundle?: { __typename: 'Erc20ListAssetBundle', signatures: string, nonce: string } | null, asset?: { __typename: 'Asset', status: Types.AssetStatus, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } | null };
|
||||
|
||||
export type ExplorerUpdateAssetSignatureBundleQueryVariables = Types.Exact<{
|
||||
id: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerUpdateAssetSignatureBundleQuery = { __typename?: 'Query', erc20SetAssetLimitsBundle: { __typename?: 'ERC20SetAssetLimitsBundle', signatures: string, nonce: string }, asset?: { __typename?: 'Asset', status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } | null };
|
||||
export type ExplorerUpdateAssetSignatureBundleQuery = { __typename: 'Query', erc20SetAssetLimitsBundle: { __typename: 'ERC20SetAssetLimitsBundle', signatures: string, nonce: string }, asset?: { __typename: 'Asset', status: Types.AssetStatus, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } | null };
|
||||
|
||||
|
||||
export const ExplorerNewAssetSignatureBundleDocument = gql`
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ const defaultOptions = {} as const;
|
||||
export type ExplorerBundleSignersQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerBundleSignersQuery = { __typename?: 'Query', networkParameter?: { __typename?: 'NetworkParameter', value: string } | null, nodesConnection: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, name: string, status: Types.NodeStatus, ethereumAddress: string, pubkey: string, tmPubkey: string } } | null> | null } };
|
||||
export type ExplorerBundleSignersQuery = { __typename: 'Query', networkParameter?: { __typename: 'NetworkParameter', value: string } | null, nodesConnection: { __typename: 'NodesConnection', edges?: Array<{ __typename: 'NodeEdge', node: { __typename: 'Node', id: string, name: string, status: Types.NodeStatus, ethereumAddress: string, pubkey: string, tmPubkey: string } } | null> | null } };
|
||||
|
||||
|
||||
export const ExplorerBundleSignersDocument = gql`
|
||||
|
||||
+12
-34
@@ -6,32 +6,10 @@ import {
|
||||
SPECIAL_CASE_NETWORK_ID,
|
||||
} from '../../../../links/party-link/party-link';
|
||||
import SizeInAsset from '../../../../size-in-asset/size-in-asset';
|
||||
import { AccountTypeMapping } from '@vegaprotocol/types';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
import { headerClasses, wrapperClasses } from '../transfer-details';
|
||||
import type { components } from '../../../../../../types/explorer';
|
||||
|
||||
type Transfer = components['schemas']['commandsv1Transfer'];
|
||||
type AccountTypes = components['schemas']['vegaAccountType'];
|
||||
|
||||
const AccountType: Record<AccountTypes, string> = {
|
||||
ACCOUNT_TYPE_UNSPECIFIED: 'Unspecified',
|
||||
ACCOUNT_TYPE_INSURANCE: 'Insurance',
|
||||
ACCOUNT_TYPE_SETTLEMENT: 'Settlement',
|
||||
ACCOUNT_TYPE_MARGIN: 'Margin',
|
||||
ACCOUNT_TYPE_GENERAL: 'General',
|
||||
ACCOUNT_TYPE_FEES_INFRASTRUCTURE: 'Infrastructure',
|
||||
ACCOUNT_TYPE_FEES_LIQUIDITY: 'Liquidity',
|
||||
ACCOUNT_TYPE_FEES_MAKER: 'Maker',
|
||||
ACCOUNT_TYPE_BOND: 'Bond',
|
||||
ACCOUNT_TYPE_EXTERNAL: 'External',
|
||||
ACCOUNT_TYPE_GLOBAL_INSURANCE: 'Global Insurance',
|
||||
ACCOUNT_TYPE_GLOBAL_REWARD: 'Global Reward',
|
||||
ACCOUNT_TYPE_PENDING_TRANSFERS: 'Pending Transfers',
|
||||
ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES: 'Maker Paid Fees',
|
||||
ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES: 'Maker Received Fees',
|
||||
ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: 'LP Received Fees',
|
||||
ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS: 'Market Proposers',
|
||||
ACCOUNT_TYPE_HOLDING: 'Holding',
|
||||
};
|
||||
import type { Transfer } from '../transfer-details';
|
||||
|
||||
interface TransferParticipantsProps {
|
||||
transfer: Transfer;
|
||||
@@ -52,22 +30,22 @@ export function TransferParticipants({
|
||||
}: TransferParticipantsProps) {
|
||||
// This mapping is required as the global account types require a type to be set, while
|
||||
// the underlying protobufs allow for every field to be undefined.
|
||||
const fromAcct: AccountTypes =
|
||||
const fromAcct =
|
||||
transfer.fromAccountType &&
|
||||
transfer.fromAccountType !== 'ACCOUNT_TYPE_UNSPECIFIED'
|
||||
? transfer.fromAccountType
|
||||
: 'ACCOUNT_TYPE_GENERAL';
|
||||
const fromAccountTypeLabel: string = transfer.fromAccountType
|
||||
? AccountType[fromAcct]
|
||||
? AccountType[transfer.fromAccountType]
|
||||
: AccountType.ACCOUNT_TYPE_GENERAL;
|
||||
const fromAccountTypeLabel = transfer.fromAccountType
|
||||
? AccountTypeMapping[fromAcct]
|
||||
: 'Unknown';
|
||||
|
||||
const toAcct: AccountTypes =
|
||||
const toAcct =
|
||||
transfer.toAccountType &&
|
||||
transfer.toAccountType !== 'ACCOUNT_TYPE_UNSPECIFIED'
|
||||
? transfer.toAccountType
|
||||
: 'ACCOUNT_TYPE_GENERAL';
|
||||
? AccountType[transfer.toAccountType]
|
||||
: AccountType.ACCOUNT_TYPE_GENERAL;
|
||||
const toAccountTypeLabel = transfer.fromAccountType
|
||||
? AccountType[toAcct]
|
||||
? AccountTypeMapping[toAcct]
|
||||
: 'Unknown';
|
||||
|
||||
return (
|
||||
|
||||
@@ -27,9 +27,9 @@ export function TransferRepeat({ recurring }: TransferRepeatProps) {
|
||||
<div className={wrapperClasses}>
|
||||
<h2 className={headerClasses}>{t('Active epochs')}</h2>
|
||||
<div className="relative block rounded-lg py-6 text-center p-6">
|
||||
<div>
|
||||
<p>
|
||||
<EpochOverview id={recurring.startEpoch} />
|
||||
</div>
|
||||
</p>
|
||||
<p className="leading-10 my-2">
|
||||
<IconForEpoch
|
||||
start={recurring.startEpoch}
|
||||
@@ -37,13 +37,13 @@ export function TransferRepeat({ recurring }: TransferRepeatProps) {
|
||||
current={data?.epoch.id}
|
||||
/>
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
{recurring.endEpoch ? (
|
||||
<EpochOverview id={recurring.endEpoch} />
|
||||
) : (
|
||||
<span>{t('Forever')}</span>
|
||||
)}
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { DispatchMetricLabels } from '@vegaprotocol/types';
|
||||
export type Metric = components['schemas']['vegaDispatchMetric'];
|
||||
export type Strategy = components['schemas']['vegaDispatchStrategy'];
|
||||
|
||||
const metricLabels: Record<Metric, string> = {
|
||||
const metricLabels = {
|
||||
DISPATCH_METRIC_UNSPECIFIED: 'Unknown metric',
|
||||
...DispatchMetricLabels,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TransferRepeat } from './blocks/transfer-repeat';
|
||||
import { TransferRewards } from './blocks/transfer-rewards';
|
||||
import { TransferParticipants } from './blocks/transfer-participants';
|
||||
|
||||
export type Recurring = components['schemas']['commandsv1RecurringTransfer'];
|
||||
export type Recurring = components['schemas']['v1RecurringTransfer'];
|
||||
export type Metric = components['schemas']['vegaDispatchMetric'];
|
||||
|
||||
export const wrapperClasses =
|
||||
|
||||
@@ -8,7 +8,6 @@ import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
|
||||
import DeterministicOrderDetails from '../../order-details/deterministic-order-details';
|
||||
import Hash from '../../links/hash';
|
||||
import { TxOrderPeggedReferenceRow } from './order/tx-order-peg';
|
||||
import { TxOrderIcebergDetails } from './order/tx-order-iceberg';
|
||||
|
||||
interface TxDetailsOrderProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -33,8 +32,6 @@ export const TxDetailsOrder = ({
|
||||
const marketId = txData.command.orderSubmission.marketId || '-';
|
||||
const reference = txData.command.orderSubmission.peggedOrder;
|
||||
const side = txData.command.orderSubmission.side;
|
||||
const iceberg = txData.command.orderSubmission.icebergOpts;
|
||||
const size = txData.command.orderSubmission.size;
|
||||
|
||||
let deterministicId = '';
|
||||
|
||||
@@ -77,14 +74,6 @@ export const TxDetailsOrder = ({
|
||||
marketId={marketId}
|
||||
/>
|
||||
) : null}
|
||||
{iceberg ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Iceberg details')}</TableCell>
|
||||
<TableCell>
|
||||
<TxOrderIcebergDetails iceberg={iceberg} size={size} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
</TableWithTbody>
|
||||
|
||||
{deterministicId.length > 0 ? (
|
||||
|
||||
@@ -16,7 +16,7 @@ interface StringMap {
|
||||
const displayString: StringMap = {
|
||||
OrderSubmission: 'Order Submission',
|
||||
'Submit Order': 'Order',
|
||||
OrderCancellation: 'Cancel order',
|
||||
OrderCancellation: 'Order Cancellation',
|
||||
OrderAmendment: 'Order Amendment',
|
||||
VoteSubmission: 'Vote Submission',
|
||||
WithdrawSubmission: 'Withdraw Submission',
|
||||
@@ -44,27 +44,8 @@ const displayString: StringMap = {
|
||||
ValidatorHeartbeat: 'Heartbeat',
|
||||
'Validator Heartbeat': 'Heartbeat',
|
||||
'Batch Market Instructions': 'Batch',
|
||||
'Stop Orders Submission': 'Stop',
|
||||
StopOrdersSubmission: 'Stop',
|
||||
StopOrdersCancellation: 'Cancel stop',
|
||||
'Stop Orders Cancellation': 'Cancel stop',
|
||||
};
|
||||
|
||||
export function getLabelForOrderType(
|
||||
orderType: string,
|
||||
command: components['schemas']['v1InputData']
|
||||
): string {
|
||||
if (command.orderSubmission) {
|
||||
if (command.orderSubmission.peggedOrder) {
|
||||
return 'Peg';
|
||||
}
|
||||
if (command.orderSubmission.icebergOpts) {
|
||||
return 'Iceberg';
|
||||
}
|
||||
}
|
||||
return 'Order';
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a proposal, will return a specific label
|
||||
* @param chainEvent
|
||||
@@ -136,8 +117,6 @@ export function getLabelForChainEvent(
|
||||
return t('Signer threshold');
|
||||
}
|
||||
return t('Multisig update');
|
||||
} else if (chainEvent.contractCall) {
|
||||
return t('Contract call');
|
||||
}
|
||||
return t('Chain Event');
|
||||
}
|
||||
@@ -166,7 +145,6 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
||||
'text-white dark:text-white bg-vega-dark-150 dark:bg-vega-dark-250';
|
||||
|
||||
// This will get unwieldy and should probably produce a different colour of tag
|
||||
// Note that colours are currently arbitrary
|
||||
if (type === 'Chain Event' && !!command?.chainEvent) {
|
||||
type = getLabelForChainEvent(command.chainEvent);
|
||||
colours = 'text-white dark-text-white bg-vega-pink dark:bg-vega-pink';
|
||||
@@ -178,9 +156,6 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
||||
type = getLabelForProposal(command.proposalSubmission);
|
||||
}
|
||||
colours = 'text-black bg-vega-yellow';
|
||||
} else if (type === 'Order' && command) {
|
||||
type = getLabelForOrderType(orderType, command);
|
||||
colours = 'text-white dark-text-white bg-vega-blue dark:bg-vega-blue';
|
||||
}
|
||||
|
||||
if (type === 'Vote on Proposal') {
|
||||
|
||||
@@ -3,14 +3,14 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerWithdrawalPropertiesFragment = { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null };
|
||||
export type ExplorerWithdrawalPropertiesFragment = { __typename: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename: 'Erc20WithdrawalDetails', receiverAddress: string } | null };
|
||||
|
||||
export type ExplorerWithdrawalQueryVariables = Types.Exact<{
|
||||
id: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerWithdrawalQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null } | null };
|
||||
export type ExplorerWithdrawalQuery = { __typename: 'Query', withdrawal?: { __typename: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename: 'Erc20WithdrawalDetails', receiverAddress: string } | null } | null };
|
||||
|
||||
export const ExplorerWithdrawalPropertiesFragmentDoc = gql`
|
||||
fragment ExplorerWithdrawalProperties on Withdrawal {
|
||||
|
||||
@@ -5,6 +5,8 @@ const windowOrDefault = (key: string) => {
|
||||
return (process.env[key] as string) || '';
|
||||
};
|
||||
|
||||
const truthy = ['1', 'true'];
|
||||
|
||||
export const ENV = {
|
||||
// Data sources
|
||||
// Environment
|
||||
@@ -18,6 +20,19 @@ export const ENV = {
|
||||
governanceUrl: windowOrDefault('NX_VEGA_GOVERNANCE_URL'),
|
||||
vegaRepoUrl: windowOrDefault('NX_VEGA_REPO_URL'),
|
||||
},
|
||||
flags: {
|
||||
assets: truthy.includes(windowOrDefault('NX_EXPLORER_ASSETS')),
|
||||
genesis: truthy.includes(windowOrDefault('NX_EXPLORER_GENESIS')),
|
||||
governance: truthy.includes(windowOrDefault('NX_EXPLORER_GOVERNANCE')),
|
||||
markets: truthy.includes(windowOrDefault('NX_EXPLORER_MARKETS')),
|
||||
oracles: truthy.includes(windowOrDefault('NX_EXPLORER_ORACLES')),
|
||||
txsList: truthy.includes(windowOrDefault('NX_EXPLORER_TXS_LIST')),
|
||||
networkParameters: truthy.includes(
|
||||
windowOrDefault('NX_EXPLORER_NETWORK_PARAMETERS')
|
||||
),
|
||||
parties: truthy.includes(windowOrDefault('NX_EXPLORER_PARTIES')),
|
||||
validators: truthy.includes(windowOrDefault('NX_EXPLORER_VALIDATORS')),
|
||||
},
|
||||
addresses: {
|
||||
feedback: windowOrDefault('NX_GITHUB_FEEDBACK_URL'),
|
||||
},
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ENV } from './env';
|
||||
|
||||
export default {
|
||||
...ENV.flags,
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { DATA_SOURCES } from '../../../config';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import type { TendermintBlocksResponse } from '../tendermint-blocks-response';
|
||||
import { RouteTitle } from '../../../components/route-title';
|
||||
import { TimeAgo } from '../../../components/time-ago';
|
||||
import {
|
||||
@@ -12,7 +14,7 @@ import { TxsPerBlock } from '../../../components/txs/txs-per-block';
|
||||
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { Routes } from '../../route-names';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useBlockInfo } from '@vegaprotocol/tendermint';
|
||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||
import { NodeLink } from '../../../components/links';
|
||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||
import EmptyList from '../../../components/empty-list/empty-list';
|
||||
@@ -22,7 +24,10 @@ const Block = () => {
|
||||
useDocumentTitle(['Blocks', `Block #${block}`]);
|
||||
const {
|
||||
state: { data: blockData, loading, error },
|
||||
} = useBlockInfo(Number(block));
|
||||
} = useFetch<TendermintBlocksResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${block}`,
|
||||
{ cache: 'force-cache' }
|
||||
);
|
||||
|
||||
return (
|
||||
<section>
|
||||
|
||||
@@ -3,21 +3,21 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerOracleDataSourceFragment = { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } };
|
||||
export type ExplorerOracleDataSourceFragment = { __typename: 'OracleSpec', dataSourceSpec: { __typename: 'ExternalDataSourceSpec', spec: { __typename: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename: 'DataSourceDefinition', sourceType: { __typename: 'DataSourceDefinitionExternal', sourceType: { __typename: 'DataSourceSpecConfiguration', signers?: Array<{ __typename: 'Signer', signer: { __typename: 'ETHAddress', address?: string | null } | { __typename: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename: 'Filter', key: { __typename: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename: 'DataSourceDefinitionInternal', sourceType: { __typename: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } };
|
||||
|
||||
export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
|
||||
export type ExplorerOracleDataConnectionFragment = { __typename: 'OracleSpec', dataConnection: { __typename: 'OracleDataConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename: 'OracleDataEdge', node: { __typename: 'OracleData', externalData: { __typename: 'ExternalData', data: { __typename: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename: 'Signer', signer: { __typename: 'ETHAddress', address?: string | null } | { __typename: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename: 'Property', name: string, value: string }> | null } } } } | null> | null } };
|
||||
|
||||
export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } } } | null> | null } | null };
|
||||
export type ExplorerOracleSpecsQuery = { __typename: 'Query', oracleSpecsConnection?: { __typename: 'OracleSpecsConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename: 'OracleSpecEdge', node: { __typename: 'OracleSpec', dataSourceSpec: { __typename: 'ExternalDataSourceSpec', spec: { __typename: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename: 'DataSourceDefinition', sourceType: { __typename: 'DataSourceDefinitionExternal', sourceType: { __typename: 'DataSourceSpecConfiguration', signers?: Array<{ __typename: 'Signer', signer: { __typename: 'ETHAddress', address?: string | null } | { __typename: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename: 'Filter', key: { __typename: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename: 'DataSourceDefinitionInternal', sourceType: { __typename: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } } } | null> | null } | null };
|
||||
|
||||
export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{
|
||||
id: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerOracleSpecByIdQuery = { __typename?: 'Query', oracleSpec?: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null };
|
||||
export type ExplorerOracleSpecByIdQuery = { __typename: 'Query', oracleSpec?: { __typename: 'OracleSpec', dataSourceSpec: { __typename: 'ExternalDataSourceSpec', spec: { __typename: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename: 'DataSourceDefinition', sourceType: { __typename: 'DataSourceDefinitionExternal', sourceType: { __typename: 'DataSourceSpecConfiguration', signers?: Array<{ __typename: 'Signer', signer: { __typename: 'ETHAddress', address?: string | null } | { __typename: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename: 'Filter', key: { __typename: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename: 'DataSourceDefinitionInternal', sourceType: { __typename: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } }, dataConnection: { __typename: 'OracleDataConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename: 'OracleDataEdge', node: { __typename: 'OracleData', externalData: { __typename: 'ExternalData', data: { __typename: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename: 'Signer', signer: { __typename: 'ETHAddress', address?: string | null } | { __typename: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null };
|
||||
|
||||
export const ExplorerOracleDataSourceFragmentDoc = gql`
|
||||
fragment ExplorerOracleDataSource on OracleSpec {
|
||||
|
||||
@@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerOracleForMarketsMarketFragment = { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } } };
|
||||
export type ExplorerOracleForMarketsMarketFragment = { __typename: 'Market', id: string, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', product: { __typename: 'Future', dataSourceSpecForSettlementData: { __typename: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename: 'DataSourceSpec', id: string } } } } };
|
||||
|
||||
export type ExplorerOracleFormMarketsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerOracleFormMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } } } }> } | null };
|
||||
export type ExplorerOracleFormMarketsQuery = { __typename: 'Query', marketsConnection?: { __typename: 'MarketConnection', edges: Array<{ __typename: 'MarketEdge', node: { __typename: 'Market', id: string, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', product: { __typename: 'Future', dataSourceSpecForSettlementData: { __typename: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename: 'DataSourceSpec', id: string } } } } } }> } | null };
|
||||
|
||||
export const ExplorerOracleForMarketsMarketFragmentDoc = gql`
|
||||
fragment ExplorerOracleForMarketsMarket on Market {
|
||||
|
||||
@@ -3,14 +3,14 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerPartyAssetsAccountsFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null };
|
||||
export type ExplorerPartyAssetsAccountsFragment = { __typename: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', name: string, product: { __typename: 'Future', quoteName: string } } } } | null };
|
||||
|
||||
export type ExplorerPartyAssetsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerPartyAssetsQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string, linkings: { __typename?: 'StakesConnection', edges?: Array<{ __typename?: 'StakeLinkingEdge', node: { __typename?: 'StakeLinking', amount: string } } | null> | null } }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null } } | null> | null } | null } }> } | null };
|
||||
export type ExplorerPartyAssetsQuery = { __typename: 'Query', partiesConnection?: { __typename: 'PartyConnection', edges: Array<{ __typename: 'PartyEdge', node: { __typename: 'Party', id: string, delegationsConnection?: { __typename: 'DelegationsConnection', edges?: Array<{ __typename: 'DelegationEdge', node: { __typename: 'Delegation', amount: string, epoch: number, node: { __typename: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename: 'StakingSummary', currentStakeAvailable: string, linkings: { __typename: 'StakesConnection', edges?: Array<{ __typename: 'StakeLinkingEdge', node: { __typename: 'StakeLinking', amount: string } } | null> | null } }, accountsConnection?: { __typename: 'AccountsConnection', edges?: Array<{ __typename: 'AccountEdge', node: { __typename: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename: 'TradableInstrument', instrument: { __typename: 'Instrument', name: string, product: { __typename: 'Future', quoteName: string } } } } | null } } | null> | null } | null } }> } | null };
|
||||
|
||||
export const ExplorerPartyAssetsAccountsFragmentDoc = gql`
|
||||
fragment ExplorerPartyAssetsAccounts on AccountBalance {
|
||||
|
||||
@@ -54,7 +54,7 @@ export const PartyBlockStake = ({
|
||||
{p?.stakingSummary.currentStakeAvailable ? (
|
||||
<KeyValueTable>
|
||||
<KeyValueTableRow noBorder={true}>
|
||||
<div>{t('Associated to key')}</div>
|
||||
<div>{t('Available stake')}</div>
|
||||
<div>
|
||||
<GovernanceAssetBalance
|
||||
price={p.stakingSummary.currentStakeAvailable}
|
||||
@@ -62,7 +62,7 @@ export const PartyBlockStake = ({
|
||||
</div>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow noBorder={true}>
|
||||
<div>{t('Staked to validator')}</div>
|
||||
<div>{t('Active stake')}</div>
|
||||
<div>
|
||||
<GovernanceAssetBalance price={linkedStake || '0'} />
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,7 @@ const Party = () => {
|
||||
text: t('Go back'),
|
||||
action: () => navigate(-1),
|
||||
className: 'py-1',
|
||||
size: 'small',
|
||||
size: 'sm',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Block } from './blocks/id';
|
||||
import { Blocks } from './blocks/home';
|
||||
import { Tx } from './txs/id';
|
||||
import { TxsList } from './txs/home';
|
||||
import flags from '../config/flags';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Routes } from './route-names';
|
||||
import { NetworkParameters } from './network-parameters';
|
||||
@@ -29,7 +30,6 @@ import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||
import { remove0x } from '@vegaprotocol/utils';
|
||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
||||
import { Disclaimer } from './pages/disclaimer';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
|
||||
export type Navigable = {
|
||||
path: string;
|
||||
@@ -59,7 +59,7 @@ type Route = RouteItem & {
|
||||
children?: RouteItem[];
|
||||
};
|
||||
|
||||
const partiesRoutes: Route[] = FLAGS.EXPLORER_PARTIES
|
||||
const partiesRoutes: Route[] = flags.parties
|
||||
? [
|
||||
{
|
||||
path: Routes.PARTIES,
|
||||
@@ -119,7 +119,7 @@ const partiesRoutes: Route[] = FLAGS.EXPLORER_PARTIES
|
||||
]
|
||||
: [];
|
||||
|
||||
const assetsRoutes: Route[] = FLAGS.EXPLORER_ASSETS
|
||||
const assetsRoutes: Route[] = flags.assets
|
||||
? [
|
||||
{
|
||||
path: Routes.ASSETS,
|
||||
@@ -147,7 +147,7 @@ const assetsRoutes: Route[] = FLAGS.EXPLORER_ASSETS
|
||||
]
|
||||
: [];
|
||||
|
||||
const genesisRoutes: Route[] = FLAGS.EXPLORER_GENESIS
|
||||
const genesisRoutes: Route[] = flags.genesis
|
||||
? [
|
||||
{
|
||||
path: Routes.GENESIS,
|
||||
@@ -163,7 +163,7 @@ const genesisRoutes: Route[] = FLAGS.EXPLORER_GENESIS
|
||||
]
|
||||
: [];
|
||||
|
||||
const governanceRoutes: Route[] = FLAGS.EXPLORER_GOVERNANCE
|
||||
const governanceRoutes: Route[] = flags.governance
|
||||
? [
|
||||
{
|
||||
path: Routes.GOVERNANCE,
|
||||
@@ -179,7 +179,7 @@ const governanceRoutes: Route[] = FLAGS.EXPLORER_GOVERNANCE
|
||||
]
|
||||
: [];
|
||||
|
||||
const marketsRoutes: Route[] = FLAGS.EXPLORER_MARKETS
|
||||
const marketsRoutes: Route[] = flags.markets
|
||||
? [
|
||||
{
|
||||
path: Routes.MARKETS,
|
||||
@@ -207,7 +207,7 @@ const marketsRoutes: Route[] = FLAGS.EXPLORER_MARKETS
|
||||
]
|
||||
: [];
|
||||
|
||||
const networkParametersRoutes: Route[] = FLAGS.EXPLORER_NETWORK_PARAMETERS
|
||||
const networkParametersRoutes: Route[] = flags.networkParameters
|
||||
? [
|
||||
{
|
||||
path: Routes.NETWORK_PARAMETERS,
|
||||
@@ -225,7 +225,7 @@ const networkParametersRoutes: Route[] = FLAGS.EXPLORER_NETWORK_PARAMETERS
|
||||
]
|
||||
: [];
|
||||
|
||||
const validators: Route[] = FLAGS.EXPLORER_VALIDATORS
|
||||
const validators: Route[] = flags.validators
|
||||
? [
|
||||
{
|
||||
path: Routes.VALIDATORS,
|
||||
|
||||
@@ -15,9 +15,6 @@ query ExplorerNodes {
|
||||
stakedByDelegates
|
||||
stakedTotal
|
||||
pendingStake
|
||||
rankingScore {
|
||||
performanceScore
|
||||
}
|
||||
epochData {
|
||||
total
|
||||
offline
|
||||
|
||||
@@ -6,7 +6,7 @@ const defaultOptions = {} as const;
|
||||
export type ExplorerNodeNamesQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerNodeNamesQuery = { __typename?: 'Query', nodesConnection: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, name: string, pubkey: string, tmPubkey: string, ethereumAddress: string } } | null> | null } };
|
||||
export type ExplorerNodeNamesQuery = { __typename: 'Query', nodesConnection: { __typename: 'NodesConnection', edges?: Array<{ __typename: 'NodeEdge', node: { __typename: 'Node', id: string, name: string, pubkey: string, tmPubkey: string, ethereumAddress: string } } | null> | null } };
|
||||
|
||||
|
||||
export const ExplorerNodeNamesDocument = gql`
|
||||
|
||||
@@ -6,7 +6,7 @@ const defaultOptions = {} as const;
|
||||
export type ExplorerNodesQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerNodesQuery = { __typename?: 'Query', nodesConnection: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, name: string, infoUrl: string, avatarUrl?: string | null, pubkey: string, tmPubkey: string, ethereumAddress: string, location: string, status: Types.NodeStatus, stakedByOperator: string, stakedByDelegates: string, stakedTotal: string, pendingStake: string, rankingScore: { __typename?: 'RankingScore', performanceScore: string }, epochData?: { __typename?: 'EpochData', total: number, offline: number, online: number } | null } } | null> | null } };
|
||||
export type ExplorerNodesQuery = { __typename: 'Query', nodesConnection: { __typename: 'NodesConnection', edges?: Array<{ __typename: 'NodeEdge', node: { __typename: 'Node', id: string, name: string, infoUrl: string, avatarUrl?: string | null, pubkey: string, tmPubkey: string, ethereumAddress: string, location: string, status: Types.NodeStatus, stakedByOperator: string, stakedByDelegates: string, stakedTotal: string, pendingStake: string, epochData?: { __typename: 'EpochData', total: number, offline: number, online: number } | null } } | null> | null } };
|
||||
|
||||
|
||||
export const ExplorerNodesDocument = gql`
|
||||
@@ -27,9 +27,6 @@ export const ExplorerNodesDocument = gql`
|
||||
stakedByDelegates
|
||||
stakedTotal
|
||||
pendingStake
|
||||
rankingScore {
|
||||
performanceScore
|
||||
}
|
||||
epochData {
|
||||
total
|
||||
offline
|
||||
|
||||
@@ -91,15 +91,7 @@ export const ValidatorsPage = () => {
|
||||
const { data: tmData } = useTendermintValidators(5000);
|
||||
const { data, loading, error, refetch } = useExplorerNodesQuery();
|
||||
|
||||
const validators = compact(
|
||||
data?.nodesConnection.edges
|
||||
?.map((e) => e?.node)
|
||||
.filter(
|
||||
(node) =>
|
||||
node?.rankingScore?.performanceScore &&
|
||||
new BigNumber(node.rankingScore.performanceScore).isGreaterThan(0)
|
||||
)
|
||||
);
|
||||
const validators = compact(data?.nodesConnection.edges?.map((e) => e?.node));
|
||||
|
||||
// voting power
|
||||
const powers = compact(tmData?.result.validators).map(
|
||||
|
||||
+72
-398
@@ -3,7 +3,7 @@
|
||||
* Do not make direct changes to the file.
|
||||
*/
|
||||
|
||||
/** OneOf type helpers */
|
||||
/** Type helpers */
|
||||
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
||||
type XOR<T, U> = T | U extends object
|
||||
? (Without<T, U> & U) | (Without<U, T> & T)
|
||||
@@ -41,8 +41,6 @@ export interface paths {
|
||||
};
|
||||
}
|
||||
|
||||
export type webhooks = Record<string, never>;
|
||||
|
||||
export interface components {
|
||||
schemas: {
|
||||
/**
|
||||
@@ -103,17 +101,6 @@ export interface components {
|
||||
| 'TIME_IN_FORCE_FOK'
|
||||
| 'TIME_IN_FORCE_GFA'
|
||||
| 'TIME_IN_FORCE_GFN';
|
||||
/**
|
||||
* @description - EXPIRY_STRATEGY_UNSPECIFIED: Never valid
|
||||
* - EXPIRY_STRATEGY_CANCELS: Stop order should be cancelled if the expiry time is reached.
|
||||
* - EXPIRY_STRATEGY_SUBMIT: Order should be submitted if the expiry time is reached.
|
||||
* @default EXPIRY_STRATEGY_UNSPECIFIED
|
||||
* @enum {string}
|
||||
*/
|
||||
readonly StopOrderExpiryStrategy:
|
||||
| 'EXPIRY_STRATEGY_UNSPECIFIED'
|
||||
| 'EXPIRY_STRATEGY_CANCELS'
|
||||
| 'EXPIRY_STRATEGY_SUBMIT';
|
||||
/**
|
||||
* @default METHOD_UNSPECIFIED
|
||||
* @enum {string}
|
||||
@@ -156,36 +143,6 @@ export interface components {
|
||||
/** Type of transaction */
|
||||
readonly type?: string;
|
||||
};
|
||||
/** Request for cancelling a recurring transfer */
|
||||
readonly commandsv1CancelTransfer: {
|
||||
/** @description Transfer ID of the transfer to cancel. */
|
||||
readonly transferId?: string;
|
||||
};
|
||||
/** Specific details for a one off transfer */
|
||||
readonly commandsv1OneOffTransfer: {
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Timestamp in Unix nanoseconds for when the transfer should be delivered into the receiver's account.
|
||||
*/
|
||||
readonly deliverOn?: string;
|
||||
};
|
||||
/** Specific details for a recurring transfer */
|
||||
readonly commandsv1RecurringTransfer: {
|
||||
/** @description Optional parameter defining how a transfer is dispatched. */
|
||||
readonly dispatchStrategy?: components['schemas']['vegaDispatchStrategy'];
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Last epoch at which this transfer shall be paid.
|
||||
*/
|
||||
readonly endEpoch?: string;
|
||||
/** @description Factor needs to be > 0. */
|
||||
readonly factor?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description First epoch from which this transfer shall be paid.
|
||||
*/
|
||||
readonly startEpoch?: string;
|
||||
};
|
||||
/** Transfer initiated by a party */
|
||||
readonly commandsv1Transfer: {
|
||||
/** @description Amount to be taken from the source account. This field is an unsigned integer scaled to the asset's decimal places. */
|
||||
@@ -197,8 +154,8 @@ export interface components {
|
||||
* should be taken.
|
||||
*/
|
||||
readonly fromAccountType?: components['schemas']['vegaAccountType'];
|
||||
readonly oneOff?: components['schemas']['commandsv1OneOffTransfer'];
|
||||
readonly recurring?: components['schemas']['commandsv1RecurringTransfer'];
|
||||
readonly oneOff?: components['schemas']['v1OneOffTransfer'];
|
||||
readonly recurring?: components['schemas']['v1RecurringTransfer'];
|
||||
/** @description Reference to be attached to the transfer. */
|
||||
readonly reference?: string;
|
||||
/** @description Public key of the destination account. */
|
||||
@@ -214,19 +171,8 @@ export interface components {
|
||||
};
|
||||
readonly protobufAny: {
|
||||
readonly '@type'?: string;
|
||||
[key: string]: unknown;
|
||||
[key: string]: unknown | undefined;
|
||||
};
|
||||
/**
|
||||
* @description `NullValue` is a singleton enumeration to represent the null value for the
|
||||
* `Value` type union.
|
||||
*
|
||||
* The JSON representation for `NullValue` is JSON `null`.
|
||||
*
|
||||
* - NULL_VALUE: Null value.
|
||||
* @default NULL_VALUE
|
||||
* @enum {string}
|
||||
*/
|
||||
readonly protobufNullValue: 'NULL_VALUE';
|
||||
/** Used to announce a node as a new pending validator */
|
||||
readonly v1AnnounceNode: {
|
||||
/** @description AvatarURL of the validator. */
|
||||
@@ -279,19 +225,18 @@ export interface components {
|
||||
readonly amendments?: readonly components['schemas']['v1OrderAmendment'][];
|
||||
/** @description List of order cancellations to be processed sequentially. */
|
||||
readonly cancellations?: readonly components['schemas']['v1OrderCancellation'][];
|
||||
/** @description List of stop order cancellations to be processed sequentially. */
|
||||
readonly stopOrdersCancellation?: readonly components['schemas']['v1StopOrdersCancellation'][];
|
||||
/** @description List of stop order submissions to be processed sequentially. */
|
||||
readonly stopOrdersSubmission?: readonly components['schemas']['v1StopOrdersSubmission'][];
|
||||
/** @description List of order submissions to be processed sequentially. */
|
||||
readonly submissions?: readonly components['schemas']['v1OrderSubmission'][];
|
||||
};
|
||||
/** Request for cancelling a recurring transfer */
|
||||
readonly v1CancelTransfer: {
|
||||
/** @description Transfer ID of the transfer to cancel. */
|
||||
readonly transferId?: string;
|
||||
};
|
||||
/** Event forwarded to the Vega network to provide information on events happening on other networks */
|
||||
readonly v1ChainEvent: {
|
||||
/** @description Built-in asset event. */
|
||||
readonly builtin?: components['schemas']['vegaBuiltinAssetEvent'];
|
||||
/** Arbitrary contract call */
|
||||
readonly contractCall?: components['schemas']['vegaEthContractCallEvent'];
|
||||
/** @description Ethereum ERC20 event. */
|
||||
readonly erc20?: components['schemas']['vegaERC20Event'];
|
||||
/** @description Ethereum ERC20 multisig event. */
|
||||
@@ -356,19 +301,6 @@ export interface components {
|
||||
/** Transaction corresponding to the hash */
|
||||
readonly transaction?: components['schemas']['blockexplorerapiv1Transaction'];
|
||||
};
|
||||
/** Iceberg order options */
|
||||
readonly v1IcebergOpts: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Minimum allowed remaining size of the order before it is replenished back to its peak size.
|
||||
*/
|
||||
readonly minimumVisibleSize?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Size of the order that is made visible and can be traded with during the execution of a single order.
|
||||
*/
|
||||
readonly peakSize?: string;
|
||||
};
|
||||
readonly v1InfoResponse: {
|
||||
/** Commit hash from which the data node was built */
|
||||
readonly commitHash?: string;
|
||||
@@ -393,7 +325,7 @@ export interface components {
|
||||
*/
|
||||
readonly blockHeight?: string;
|
||||
/** @description Command to request cancelling a recurring transfer. */
|
||||
readonly cancelTransfer?: components['schemas']['commandsv1CancelTransfer'];
|
||||
readonly cancelTransfer?: components['schemas']['v1CancelTransfer'];
|
||||
/**
|
||||
* @description Command used by a validator to submit an event forwarded to the Vega network to provide information
|
||||
* on events happening on other networks, to be used by a foreign chain
|
||||
@@ -449,10 +381,6 @@ export interface components {
|
||||
readonly protocolUpgradeProposal?: components['schemas']['v1ProtocolUpgradeProposal'];
|
||||
/** @description Command used by a validator to submit a floating point value. */
|
||||
readonly stateVariableProposal?: components['schemas']['v1StateVariableProposal'];
|
||||
/** @description Command to cancel stop orders. */
|
||||
readonly stopOrdersCancellation?: components['schemas']['v1StopOrdersCancellation'];
|
||||
/** @description Command to submit a pair of stop orders. */
|
||||
readonly stopOrdersSubmission?: components['schemas']['v1StopOrdersSubmission'];
|
||||
/** @description Command to submit a transfer. */
|
||||
readonly transfer?: components['schemas']['commandsv1Transfer'];
|
||||
/** @description Command to remove tokens delegated to a validator. */
|
||||
@@ -520,9 +448,9 @@ export interface components {
|
||||
readonly commitmentAmount?: string;
|
||||
/** @description Nominated liquidity fee factor, which is an input to the calculation of taker fees on the market, as per setting fees and rewarding liquidity providers. */
|
||||
readonly fee?: string;
|
||||
/** @description Market ID for the order. */
|
||||
/** @description Market ID for the order, required field. */
|
||||
readonly marketId?: string;
|
||||
/** @description Reference to be added to every order created out of this liquidity provision submission. */
|
||||
/** @description Reference to be added to every order created out of this liquidityProvisionSubmission. */
|
||||
readonly reference?: string;
|
||||
/** @description Set of liquidity sell orders to meet the liquidity provision obligation. */
|
||||
readonly sells?: readonly components['schemas']['vegaLiquidityOrder'][];
|
||||
@@ -602,6 +530,15 @@ export interface components {
|
||||
| 'TYPE_STAKE_TOTAL_SUPPLY'
|
||||
| 'TYPE_SIGNER_THRESHOLD_SET'
|
||||
| 'TYPE_GOVERNANCE_VALIDATE_ASSET';
|
||||
/** Specific details for a one off transfer */
|
||||
readonly v1OneOffTransfer: {
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Unix timestamp in nanoseconds. Time at which the
|
||||
* transfer should be delivered into the To account.
|
||||
*/
|
||||
readonly deliverOn?: string;
|
||||
};
|
||||
/** Command to submit new Oracle data from third party providers */
|
||||
readonly v1OracleDataSubmission: {
|
||||
/**
|
||||
@@ -659,12 +596,10 @@ export interface components {
|
||||
readonly v1OrderSubmission: {
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Timestamp in Unix nanoseconds for when the order will expire,
|
||||
* @description Timestamp for when the order will expire, in nanoseconds,
|
||||
* required field only for `Order.TimeInForce`.TIME_IN_FORCE_GTT`.
|
||||
*/
|
||||
readonly expiresAt?: string;
|
||||
/** @description Parameters used to specify an iceberg order. */
|
||||
readonly icebergOpts?: components['schemas']['v1IcebergOpts'];
|
||||
/** @description Market ID for the order, required field. */
|
||||
readonly marketId?: string;
|
||||
/** @description Used to specify the details for a pegged order. */
|
||||
@@ -764,6 +699,23 @@ export interface components {
|
||||
readonly v1PubKey: {
|
||||
readonly key?: string;
|
||||
};
|
||||
/** Specific details for a recurring transfer */
|
||||
readonly v1RecurringTransfer: {
|
||||
/** @description Optional parameter defining how a transfer is dispatched. */
|
||||
readonly dispatchStrategy?: components['schemas']['vegaDispatchStrategy'];
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Last epoch at which this transfer shall be paid.
|
||||
*/
|
||||
readonly endEpoch?: string;
|
||||
/** @description Factor needs to be > 0. */
|
||||
readonly factor?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description First epoch from which this transfer shall be paid.
|
||||
*/
|
||||
readonly startEpoch?: string;
|
||||
};
|
||||
/**
|
||||
* @description Signature to authenticate a transaction and to be verified by the Vega
|
||||
* network.
|
||||
@@ -780,7 +732,7 @@ export interface components {
|
||||
readonly version?: number;
|
||||
};
|
||||
readonly v1Signer: {
|
||||
/** @description In case of an open oracle - Ethereum address will be submitted. */
|
||||
/** In case of an open oracle - Ethereum address will be submitted */
|
||||
readonly ethAddress?: components['schemas']['v1ETHAddress'];
|
||||
/**
|
||||
* @description List of authorized public keys that signed the data for this
|
||||
@@ -794,55 +746,6 @@ export interface components {
|
||||
/** @description State value proposal details. */
|
||||
readonly proposal?: components['schemas']['vegaStateValueProposal'];
|
||||
};
|
||||
/** Price and expiry configuration for a stop order */
|
||||
readonly v1StopOrderSetup: {
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Optional expiry timestamp.
|
||||
*/
|
||||
readonly expiresAt?: string;
|
||||
/** @description Strategy to adopt if the expiry time is reached. */
|
||||
readonly expiryStrategy?: components['schemas']['StopOrderExpiryStrategy'];
|
||||
/** @description Order to be submitted once the trigger is breached. */
|
||||
readonly orderSubmission?: components['schemas']['v1OrderSubmission'];
|
||||
/** @description Fixed price at which the order will be submitted. */
|
||||
readonly price?: string;
|
||||
/** @description Trailing percentage at which the order will be submitted. */
|
||||
readonly trailingPercentOffset?: string;
|
||||
};
|
||||
/**
|
||||
* Cancel a stop order.
|
||||
* The following combinations are available:
|
||||
* Empty object will cancel all stop orders for the party
|
||||
* Market ID alone will cancel all stop orders in a market
|
||||
* Market ID and order ID will cancel a specific stop order in a market
|
||||
* If the stop order is part of an OCO, both stop orders will be cancelled
|
||||
*/
|
||||
readonly v1StopOrdersCancellation: {
|
||||
/** @description Optional market ID. */
|
||||
readonly marketId?: string;
|
||||
/** @description Optional order ID. */
|
||||
readonly stopOrderId?: string;
|
||||
};
|
||||
/**
|
||||
* Stop order submission submits stops orders.
|
||||
* It is possible to make a single stop order submission by
|
||||
* specifying a single direction,
|
||||
* or an OCO (One Cancels the Other) stop order submission
|
||||
* by specifying a configuration for both directions
|
||||
*/
|
||||
readonly v1StopOrdersSubmission: {
|
||||
/**
|
||||
* @description Stop order that will be triggered
|
||||
* if the price falls below a given trigger price.
|
||||
*/
|
||||
readonly fallsBelow?: components['schemas']['v1StopOrderSetup'];
|
||||
/**
|
||||
* @description Stop order that will be triggered
|
||||
* if the price rises above a given trigger price.
|
||||
*/
|
||||
readonly risesAbove?: components['schemas']['v1StopOrderSetup'];
|
||||
};
|
||||
readonly v1UndelegateSubmission: {
|
||||
/**
|
||||
* @description Optional, if not specified = ALL.
|
||||
@@ -919,7 +822,6 @@ export interface components {
|
||||
* - ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES: Per asset reward account for fees received by makers
|
||||
* - ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: Per asset reward account for fees received by liquidity providers
|
||||
* - ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS: Per asset reward account for market proposers when the market goes above some trading threshold
|
||||
* - ACCOUNT_TYPE_HOLDING: Per asset account for holding in-flight unfilled orders' funds
|
||||
* @default ACCOUNT_TYPE_UNSPECIFIED
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -940,8 +842,7 @@ export interface components {
|
||||
| 'ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES'
|
||||
| 'ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES'
|
||||
| 'ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES'
|
||||
| 'ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS'
|
||||
| 'ACCOUNT_TYPE_HOLDING';
|
||||
| 'ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS';
|
||||
/** Vega representation of an external asset */
|
||||
readonly vegaAssetDetails: {
|
||||
/** @description Vega built-in asset. */
|
||||
@@ -997,14 +898,6 @@ export interface components {
|
||||
/** @description Vega network internal asset ID. */
|
||||
readonly vegaAssetId?: string;
|
||||
};
|
||||
readonly vegaCancelTransfer: {
|
||||
/** Configuration for cancellation of a governance-initiated transfer */
|
||||
readonly changes?: components['schemas']['vegaCancelTransferConfiguration'];
|
||||
};
|
||||
readonly vegaCancelTransferConfiguration: {
|
||||
/** @description ID of the governance transfer proposal. */
|
||||
readonly transferId?: string;
|
||||
};
|
||||
/**
|
||||
* @description DataSourceDefinition represents the top level object that deals with data sources.
|
||||
* DataSourceDefinition can be external or internal, with whatever number of data sources are defined
|
||||
@@ -1019,7 +912,6 @@ export interface components {
|
||||
* It contains one of any of the defined `SourceType` variants.
|
||||
*/
|
||||
readonly vegaDataSourceDefinitionExternal: {
|
||||
readonly ethCall?: components['schemas']['vegaEthCallSpec'];
|
||||
readonly oracle?: components['schemas']['vegaDataSourceSpecConfiguration'];
|
||||
};
|
||||
/**
|
||||
@@ -1255,64 +1147,6 @@ export interface components {
|
||||
/** @description Address into which the bridge will release the funds. */
|
||||
readonly receiverAddress?: string;
|
||||
};
|
||||
/** @description Specifies a data source that derives its content from calling a read method on an Ethereum contract. */
|
||||
readonly vegaEthCallSpec: {
|
||||
/** @description The ABI of that contract. */
|
||||
readonly abi?: readonly Record<string, never>[];
|
||||
/** @description Ethereum address of the contract to call. */
|
||||
readonly address?: string;
|
||||
/**
|
||||
* @description List of arguments to pass to method call.
|
||||
* Protobuf 'Value' wraps an arbitrary JSON type that is mapped to an Ethereum type according to the ABI.
|
||||
*/
|
||||
readonly args?: readonly Record<string, never>[];
|
||||
/** @description Name of the method on the contract to call. */
|
||||
readonly method?: string;
|
||||
/** @description Conditions for determining when to call the contract method. */
|
||||
readonly trigger?: components['schemas']['vegaEthCallTrigger'];
|
||||
};
|
||||
/** @description Determines when the contract method should be called. */
|
||||
readonly vegaEthCallTrigger: {
|
||||
readonly timeTrigger?: components['schemas']['vegaEthTimeTrigger'];
|
||||
};
|
||||
/** Result of calling an arbitrary Ethereum contract method */
|
||||
readonly vegaEthContractCallEvent: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Ethereum block height.
|
||||
*/
|
||||
readonly blockHeight?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Ethereum block time in Unix seconds.
|
||||
*/
|
||||
readonly blockTime?: string;
|
||||
/**
|
||||
* Format: byte
|
||||
* @description Result of contract call, packed according to the ABI stored in the associated data source spec.
|
||||
*/
|
||||
readonly result?: string;
|
||||
/** @description ID of the data source spec that triggered this contract call. */
|
||||
readonly specId?: string;
|
||||
};
|
||||
/** @description Trigger for an Ethereum call based on the Ethereum block timestamp. Can be one-off or repeating. */
|
||||
readonly vegaEthTimeTrigger: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Repeat the call every n seconds after the inital call. If no time for initial call was specified, begin repeating immediately.
|
||||
*/
|
||||
readonly every?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Trigger when the Ethereum time is greater or equal to this time, in Unix seconds.
|
||||
*/
|
||||
readonly initial?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description If repeating, stop once Ethereum time is greater than this time, in Unix seconds. If not set, then repeat indefinitely.
|
||||
*/
|
||||
readonly until?: string;
|
||||
};
|
||||
/** Future product configuration */
|
||||
readonly vegaFutureProduct: {
|
||||
/** @description Binding between the data source spec and the settlement data. */
|
||||
@@ -1326,14 +1160,6 @@ export interface components {
|
||||
/** @description Asset ID for the product's settlement asset. */
|
||||
readonly settlementAsset?: string;
|
||||
};
|
||||
/**
|
||||
* @default GOVERNANCE_TRANSFER_TYPE_UNSPECIFIED
|
||||
* @enum {string}
|
||||
*/
|
||||
readonly vegaGovernanceTransferType:
|
||||
| 'GOVERNANCE_TRANSFER_TYPE_UNSPECIFIED'
|
||||
| 'GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING'
|
||||
| 'GOVERNANCE_TRANSFER_TYPE_BEST_EFFORT';
|
||||
/** Instrument configuration */
|
||||
readonly vegaInstrumentConfiguration: {
|
||||
/** @description Instrument code, human-readable shortcode used to describe the instrument. */
|
||||
@@ -1342,8 +1168,6 @@ export interface components {
|
||||
readonly future?: components['schemas']['vegaFutureProduct'];
|
||||
/** @description Instrument name. */
|
||||
readonly name?: string;
|
||||
/** @description Spot. */
|
||||
readonly spot?: components['schemas']['vegaSpotProduct'];
|
||||
};
|
||||
readonly vegaKeyValueBundle: {
|
||||
readonly key?: string;
|
||||
@@ -1434,14 +1258,14 @@ export interface components {
|
||||
/** @description Configuration of the new market. */
|
||||
readonly changes?: components['schemas']['vegaNewMarketConfiguration'];
|
||||
};
|
||||
/** Configuration for a new futures market on Vega */
|
||||
/** Configuration for a new market on Vega */
|
||||
readonly vegaNewMarketConfiguration: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Decimal places used for the new futures market, sets the smallest price increment on the book.
|
||||
* @description Decimal places used for the new market, sets the smallest price increment on the book.
|
||||
*/
|
||||
readonly decimalPlaces?: string;
|
||||
/** @description New futures market instrument configuration. */
|
||||
/** @description New market instrument configuration. */
|
||||
readonly instrument?: components['schemas']['vegaInstrumentConfiguration'];
|
||||
/** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */
|
||||
readonly linearSlippageFactor?: string;
|
||||
@@ -1454,11 +1278,11 @@ export interface components {
|
||||
* price levels over which automated liquidity provision orders will be deployed.
|
||||
*/
|
||||
readonly lpPriceRange?: string;
|
||||
/** @description Optional new futures market metadata, tags. */
|
||||
/** @description Optional new market metadata, tags. */
|
||||
readonly metadata?: readonly string[];
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Decimal places for order sizes, sets what size the smallest order / position on the futures market can be.
|
||||
* @description Decimal places for order sizes, sets what size the smallest order / position on the market can be.
|
||||
*/
|
||||
readonly positionDecimalPlaces?: string;
|
||||
/** @description Price monitoring parameters. */
|
||||
@@ -1467,80 +1291,6 @@ export interface components {
|
||||
readonly quadraticSlippageFactor?: string;
|
||||
/** @description Simple risk model parameters, valid only if MODEL_SIMPLE is selected. */
|
||||
readonly simple?: components['schemas']['vegaSimpleModelParams'];
|
||||
/** @description Successor configuration. If this proposal is meant to succeed a given market, then this should be set. */
|
||||
readonly successor?: components['schemas']['vegaSuccessorConfiguration'];
|
||||
};
|
||||
/** New spot market on Vega */
|
||||
readonly vegaNewSpotMarket: {
|
||||
/** @description Configuration of the new spot market. */
|
||||
readonly changes?: components['schemas']['vegaNewSpotMarketConfiguration'];
|
||||
};
|
||||
/** Configuration for a new spot market on Vega */
|
||||
readonly vegaNewSpotMarketConfiguration: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Decimal places used for the new spot market, sets the smallest price increment on the book.
|
||||
*/
|
||||
readonly decimalPlaces?: string;
|
||||
/** @description New spot market instrument configuration. */
|
||||
readonly instrument?: components['schemas']['vegaInstrumentConfiguration'];
|
||||
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
|
||||
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
|
||||
/** @description Optional new spot market metadata, tags. */
|
||||
readonly metadata?: readonly string[];
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Decimal places for order sizes, sets what size the smallest order / position on the spot market can be.
|
||||
*/
|
||||
readonly positionDecimalPlaces?: string;
|
||||
/** @description Price monitoring parameters. */
|
||||
readonly priceMonitoringParameters?: components['schemas']['vegaPriceMonitoringParameters'];
|
||||
/** @description Simple risk model parameters, valid only if MODEL_SIMPLE is selected. */
|
||||
readonly simple?: components['schemas']['vegaSimpleModelParams'];
|
||||
/** @description Specifies parameters related to target stake calculation. */
|
||||
readonly targetStakeParameters?: components['schemas']['vegaTargetStakeParameters'];
|
||||
};
|
||||
/** New governance transfer */
|
||||
readonly vegaNewTransfer: {
|
||||
/** @description Configuration for a new transfer. */
|
||||
readonly changes?: components['schemas']['vegaNewTransferConfiguration'];
|
||||
};
|
||||
readonly vegaNewTransferConfiguration: {
|
||||
/** Maximum amount to transfer */
|
||||
readonly amount?: string;
|
||||
/** ID of asset to transfer */
|
||||
readonly asset?: string;
|
||||
/**
|
||||
* Specifies the account to transfer to, depending on the account type:
|
||||
* Network treasury: leave empty
|
||||
* Party: party's public key
|
||||
* Market insurance pool: market ID
|
||||
*/
|
||||
readonly destination?: string;
|
||||
/** Specifies the account type to transfer to: reward pool, party, network insurance pool, market insurance pool */
|
||||
readonly destinationType?: components['schemas']['vegaAccountType'];
|
||||
/** Maximum fraction of the source account's balance to transfer as a decimal - i.e. 0.1 = 10% of the balance */
|
||||
readonly fractionOfBalance?: string;
|
||||
readonly oneOff?: components['schemas']['vegaOneOffTransfer'];
|
||||
readonly recurring?: components['schemas']['vegaRecurringTransfer'];
|
||||
/** If network treasury, field is empty, otherwise uses the market ID */
|
||||
readonly source?: string;
|
||||
/** Source account type, such as network treasury, market insurance pool */
|
||||
readonly sourceType?: components['schemas']['vegaAccountType'];
|
||||
/**
|
||||
* "All or nothing" or "best effort":
|
||||
* All or nothing: Transfers the specified amount or does not transfer anything
|
||||
* Best effort: Transfers the specified amount or the max allowable amount if this is less than the specified amount
|
||||
*/
|
||||
readonly transferType?: components['schemas']['vegaGovernanceTransferType'];
|
||||
};
|
||||
/** Specific details for a one off transfer */
|
||||
readonly vegaOneOffTransfer: {
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Timestamp in Unix nanoseconds for when the transfer should be delivered into the receiver's account.
|
||||
*/
|
||||
readonly deliverOn?: string;
|
||||
};
|
||||
/**
|
||||
* Type values for an order
|
||||
@@ -1619,8 +1369,6 @@ export interface components {
|
||||
};
|
||||
/** Terms for a governance proposal on Vega */
|
||||
readonly vegaProposalTerms: {
|
||||
/** @description Cancel a governance transfer. */
|
||||
readonly cancelTransfer?: components['schemas']['vegaCancelTransfer'];
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Timestamp as Unix time in seconds when voting closes for this proposal,
|
||||
@@ -1640,39 +1388,20 @@ export interface components {
|
||||
* and can be used to gauge community sentiment.
|
||||
*/
|
||||
readonly newFreeform?: components['schemas']['vegaNewFreeform'];
|
||||
/** @description Proposal change for creating new futures market on Vega. */
|
||||
/** @description Proposal change for creating new market on Vega. */
|
||||
readonly newMarket?: components['schemas']['vegaNewMarket'];
|
||||
/** @description Proposal change for creating new spot market on Vega. */
|
||||
readonly newSpotMarket?: components['schemas']['vegaNewSpotMarket'];
|
||||
/** @description Proposal change for a governance transfer. */
|
||||
readonly newTransfer?: components['schemas']['vegaNewTransfer'];
|
||||
/** @description Proposal change for updating an asset. */
|
||||
readonly updateAsset?: components['schemas']['vegaUpdateAsset'];
|
||||
/** @description Proposal change for modifying an existing futures market on Vega. */
|
||||
/** @description Proposal change for modifying an existing market on Vega. */
|
||||
readonly updateMarket?: components['schemas']['vegaUpdateMarket'];
|
||||
/** @description Proposal change for updating Vega network parameters. */
|
||||
readonly updateNetworkParameter?: components['schemas']['vegaUpdateNetworkParameter'];
|
||||
/** @description Proposal change for modifying an existing spot market on Vega. */
|
||||
readonly updateSpotMarket?: components['schemas']['vegaUpdateSpotMarket'];
|
||||
/**
|
||||
* Format: int64
|
||||
* @description Validation timestamp as Unix time in seconds.
|
||||
*/
|
||||
readonly validationTimestamp?: string;
|
||||
};
|
||||
/** Specific details for a recurring transfer */
|
||||
readonly vegaRecurringTransfer: {
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description Last epoch at which this transfer shall be paid.
|
||||
*/
|
||||
readonly endEpoch?: string;
|
||||
/**
|
||||
* Format: uint64
|
||||
* @description First epoch from which this transfer shall be paid.
|
||||
*/
|
||||
readonly startEpoch?: string;
|
||||
};
|
||||
readonly vegaScalarValue: {
|
||||
readonly value?: string;
|
||||
};
|
||||
@@ -1713,15 +1442,6 @@ export interface components {
|
||||
*/
|
||||
readonly probabilityOfTrading?: number;
|
||||
};
|
||||
/** Spot product configuration */
|
||||
readonly vegaSpotProduct: {
|
||||
/** @description Base asset ID. */
|
||||
readonly baseAsset?: string;
|
||||
/** @description Product name. */
|
||||
readonly name?: string;
|
||||
/** @description Quote asset ID. */
|
||||
readonly quoteAsset?: string;
|
||||
};
|
||||
readonly vegaStakeDeposited: {
|
||||
/** @description Amount deposited as an unsigned base 10 integer scaled to the asset's decimal places. */
|
||||
readonly amount?: string;
|
||||
@@ -1787,13 +1507,6 @@ export interface components {
|
||||
readonly scalarVal?: components['schemas']['vegaScalarValue'];
|
||||
readonly vectorVal?: components['schemas']['vegaVectorValue'];
|
||||
};
|
||||
/** @description Configuration required to turn a new market proposal in to a successor market proposal. */
|
||||
readonly vegaSuccessorConfiguration: {
|
||||
/** @description A decimal value between or equal to 0 and 1, specifying the fraction of the insurance pool balance that is carried over from the parent market to the successor. */
|
||||
readonly insurancePoolFraction?: string;
|
||||
/** @description ID of the market that the successor should take over from. */
|
||||
readonly parentMarketId?: string;
|
||||
};
|
||||
/** TargetStakeParameters contains parameters used in target stake calculation */
|
||||
readonly vegaTargetStakeParameters: {
|
||||
/**
|
||||
@@ -1834,14 +1547,14 @@ export interface components {
|
||||
};
|
||||
/** Update an existing market on Vega */
|
||||
readonly vegaUpdateMarket: {
|
||||
/** @description Updated configuration of the futures market. */
|
||||
/** @description Updated configuration of the market. */
|
||||
readonly changes?: components['schemas']['vegaUpdateMarketConfiguration'];
|
||||
/** @description Market ID the update is for. */
|
||||
readonly marketId?: string;
|
||||
};
|
||||
/** Configuration to update a futures market on Vega */
|
||||
/** Configuration to update a market on Vega */
|
||||
readonly vegaUpdateMarketConfiguration: {
|
||||
/** @description Updated futures market instrument configuration. */
|
||||
/** @description Updated market instrument configuration. */
|
||||
readonly instrument?: components['schemas']['vegaUpdateInstrumentConfiguration'];
|
||||
/** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */
|
||||
readonly linearSlippageFactor?: string;
|
||||
@@ -1854,7 +1567,7 @@ export interface components {
|
||||
* price levels over which automated liquidity provision orders will be deployed.
|
||||
*/
|
||||
readonly lpPriceRange?: string;
|
||||
/** @description Optional futures market metadata, tags. */
|
||||
/** @description Optional market metadata, tags. */
|
||||
readonly metadata?: readonly string[];
|
||||
/** @description Price monitoring parameters. */
|
||||
readonly priceMonitoringParameters?: components['schemas']['vegaPriceMonitoringParameters'];
|
||||
@@ -1868,26 +1581,6 @@ export interface components {
|
||||
/** @description The network parameter to update. */
|
||||
readonly changes?: components['schemas']['vegaNetworkParameter'];
|
||||
};
|
||||
/** Update an existing spot market on Vega */
|
||||
readonly vegaUpdateSpotMarket: {
|
||||
/** @description Updated configuration of the spot market. */
|
||||
readonly changes?: components['schemas']['vegaUpdateSpotMarketConfiguration'];
|
||||
/** @description Market ID the update is for. */
|
||||
readonly marketId?: string;
|
||||
};
|
||||
/** Configuration to update a spot market on Vega */
|
||||
readonly vegaUpdateSpotMarketConfiguration: {
|
||||
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
|
||||
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
|
||||
/** @description Optional spot market metadata, tags. */
|
||||
readonly metadata?: readonly string[];
|
||||
/** @description Price monitoring parameters. */
|
||||
readonly priceMonitoringParameters?: components['schemas']['vegaPriceMonitoringParameters'];
|
||||
/** @description Simple risk model parameters, valid only if MODEL_SIMPLE is selected. */
|
||||
readonly simple?: components['schemas']['vegaSimpleModelParams'];
|
||||
/** @description Specifies parameters related to target stake calculation. */
|
||||
readonly targetStakeParameters?: components['schemas']['vegaTargetStakeParameters'];
|
||||
};
|
||||
readonly vegaVectorValue: {
|
||||
readonly value?: readonly string[];
|
||||
};
|
||||
@@ -1916,12 +1609,12 @@ export interface components {
|
||||
export type external = Record<string, never>;
|
||||
|
||||
export interface operations {
|
||||
/**
|
||||
* Info
|
||||
* @description Get information about the block explorer.
|
||||
* Response contains a semver formatted version of the data node and the commit hash, from which the block explorer was built
|
||||
*/
|
||||
BlockExplorer_Info: {
|
||||
/**
|
||||
* Info
|
||||
* @description Get information about the block explorer.
|
||||
* Response contains a semver formatted version of the data node and the commit hash, from which the block explorer was built
|
||||
*/
|
||||
responses: {
|
||||
/** @description A successful response. */
|
||||
200: {
|
||||
@@ -1937,38 +1630,19 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* List transactions
|
||||
* @description List transactions from the Vega blockchain
|
||||
*/
|
||||
BlockExplorer_ListTransactions: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/**
|
||||
* @description Number of transactions to be returned from the blockchain.
|
||||
* This is deprecated, use first and last instead.
|
||||
*/
|
||||
/**
|
||||
* List transactions
|
||||
* @description List transactions from the Vega blockchain
|
||||
*/
|
||||
parameters?: {
|
||||
/** @description Number of transactions to be returned from the blockchain. */
|
||||
/** @description Optional cursor to paginate the request. */
|
||||
/** @description Optional cursor to paginate the request. */
|
||||
readonly query?: {
|
||||
limit?: number;
|
||||
/** @description Optional cursor to paginate the request. */
|
||||
before?: string;
|
||||
/** @description Optional cursor to paginate the request. */
|
||||
after?: string;
|
||||
/** @description Transaction command types filter, for listing transactions with specified command types. */
|
||||
cmdTypes?: readonly string[];
|
||||
/** @description Transaction command types exclusion filter, for listing all the transactions except the ones with specified command types. */
|
||||
excludeCmdTypes?: readonly string[];
|
||||
/** @description Party IDs filter, can be sender or receiver. */
|
||||
parties?: readonly string[];
|
||||
/**
|
||||
* @description Number of transactions to be returned from the blockchain. Use in conjunction with the `after` cursor to paginate forwards.
|
||||
* On its own, this will return the first `first` transactions.
|
||||
*/
|
||||
first?: number;
|
||||
/**
|
||||
* @description Number of transactions to be returned from the blockchain. Use in conjunction with the `before` cursor to paginate backwards.
|
||||
* On its own, this will return the last `last` transactions.
|
||||
*/
|
||||
last?: number;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@@ -1986,14 +1660,14 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get transaction
|
||||
* @description Get a transaction from the Vega blockchain
|
||||
*/
|
||||
BlockExplorer_GetTransaction: {
|
||||
/**
|
||||
* Get transaction
|
||||
* @description Get a transaction from the Vega blockchain
|
||||
*/
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Hash of the transaction */
|
||||
/** @description Hash of the transaction */
|
||||
readonly path: {
|
||||
hash: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,6 +15,5 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
|
||||
return {
|
||||
...config,
|
||||
plugins: [...additionalPlugins, ...config.plugins],
|
||||
ignoreWarnings: [/Failed to parse source map/],
|
||||
};
|
||||
});
|
||||
|
||||
@@ -320,8 +320,8 @@ context(
|
||||
// 3001-VOTE-076
|
||||
cy.getByTestId(connectToVegaWalletButton)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect Vega wallet');
|
||||
cy.getByTestId(connectToVegaWalletButton).click();
|
||||
.and('have.text', 'Connect Vega wallet')
|
||||
.click();
|
||||
cy.getByTestId('connector-jsonRpc').click();
|
||||
cy.getByTestId(vegaWalletNameElement).should('be.visible');
|
||||
cy.getByTestId(connectToVegaWalletButton).should('not.exist');
|
||||
|
||||
@@ -295,6 +295,7 @@ context(
|
||||
|
||||
// Will fail if run after 'Able to submit update market proposal and vote for proposal'
|
||||
// 3002-PROP-022
|
||||
// Skipping due to #4262
|
||||
it.skip('Unable to submit update market proposal without equity-like share in the market', function () {
|
||||
switchVegaWalletPubKey();
|
||||
stakingPageAssociateTokens('1');
|
||||
|
||||
@@ -144,7 +144,7 @@ context(
|
||||
closeStakingDialog();
|
||||
navigateTo(navigation.validators);
|
||||
cy.getByTestId(viewStakedByMeToggle).click();
|
||||
cy.getByTestId(userStakeBtn, epochTimeout).should('have.length', 2);
|
||||
cy.getByTestId(userStakeBtn).should('have.length', 2);
|
||||
});
|
||||
|
||||
it('Able to stake against a validator - using vega from vesting contract', function () {
|
||||
|
||||
@@ -11,7 +11,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
cy.getByTestId('home-proposals').within(() => {
|
||||
cy.get('[href="/proposals"]')
|
||||
.should('exist')
|
||||
.and('have.text', 'See all proposals');
|
||||
.and('have.text', 'Browse, vote, and propose');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
cy.getByTestId('menu-drawer').should('be.visible');
|
||||
});
|
||||
|
||||
it('should have link for proposal page', function () {
|
||||
it.skip('should have link for proposal page', function () {
|
||||
cy.getByTestId('menu-drawer').within(() => {
|
||||
cy.get('[href="/proposals"]')
|
||||
.should('exist')
|
||||
|
||||
@@ -161,7 +161,7 @@ context(
|
||||
);
|
||||
cy.getByTestId('protocol-upgrade-proposal-status').should(
|
||||
'have.text',
|
||||
'Approved by validators'
|
||||
'Approved by validators '
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -227,42 +227,5 @@ context(
|
||||
cy.getByTestId(networkUpgradeProposalListItem).should('not.exist');
|
||||
cy.getByTestId(closedProposalToggle).should('not.exist');
|
||||
});
|
||||
|
||||
it('should display network upgrade banner with estimate', function () {
|
||||
mockNetworkUpgradeProposal();
|
||||
cy.visit('/');
|
||||
cy.getByTestId('banners').within(() => {
|
||||
cy.get('div')
|
||||
.should('contain.text', 'The network will upgrade to v1 in ')
|
||||
.and(
|
||||
'contain.text',
|
||||
'Trading activity will be interrupted, manage your risk appropriately.'
|
||||
);
|
||||
cy.getByTestId('external-link')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/proposals/protocol-upgrade/v1');
|
||||
});
|
||||
|
||||
// estimate does not display possibly due to mocks or Cypress unless the proposal is clicked on several times
|
||||
// By default the application waits for 10 blocks until showing estimate - roughly 10 seconds
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(3000);
|
||||
navigateTo(navigation.proposals);
|
||||
cy.getByTestId(networkUpgradeProposalListItem)
|
||||
.first()
|
||||
.find('[data-testid="view-proposal-btn"]')
|
||||
.click();
|
||||
}
|
||||
cy.getByTestId('upgrade-proposal-estimate')
|
||||
.invoke('text')
|
||||
.as('displayedEstimate');
|
||||
cy.get('@displayedEstimate').then((estimateText) => {
|
||||
// Estimated time should automatically update every second
|
||||
cy.getByTestId('protocol-upgrade-time')
|
||||
.invoke('text')
|
||||
.should('not.eq', estimateText);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import {
|
||||
navigateTo,
|
||||
navigation,
|
||||
turnTelemetryOff,
|
||||
waitForSpinner,
|
||||
} from '../../support/common.functions';
|
||||
import {
|
||||
createTenDigitUnixTimeStampForSpecifiedDays,
|
||||
enterRawProposalBody,
|
||||
enterUniqueFreeFormProposalBody,
|
||||
goToMakeNewProposal,
|
||||
governanceProposalType,
|
||||
} from '../../support/governance.functions';
|
||||
@@ -46,11 +47,12 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
||||
.and('contain.text', 'USDC (fake)');
|
||||
});
|
||||
|
||||
it('Unable to submit proposal with public key', function () {
|
||||
it.skip('Unable to submit proposal with public key', function () {
|
||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
enterRawProposalBody(createTenDigitUnixTimeStampForSpecifiedDays(8));
|
||||
navigateTo(navigation.proposals);
|
||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||
enterUniqueFreeFormProposalBody('50', 'pub key proposal test');
|
||||
cy.getByTestId('dialog-content')
|
||||
.first()
|
||||
.within(() => {
|
||||
|
||||
@@ -78,7 +78,7 @@ context(
|
||||
cy.getByTestId('connector-jsonRpc')
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect Vega wallet');
|
||||
cy.getByTestId('connector-rest')
|
||||
cy.getByTestId('connector-hosted')
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Hosted Fairground wallet');
|
||||
});
|
||||
@@ -94,7 +94,7 @@ context(
|
||||
describe('when rest connector form opened', function () {
|
||||
before('click hosted wallet app button', function () {
|
||||
cy.getByTestId(connectorsList).within(() => {
|
||||
cy.getByTestId('connector-rest').click();
|
||||
cy.getByTestId('connector-hosted').click();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -174,8 +174,7 @@ export function clickOnValidatorFromList(
|
||||
cy.get(`[row-id="${validatorNumber}"]`)
|
||||
.should('be.visible')
|
||||
.find(stakeValidatorListName)
|
||||
.as('validatorOnList');
|
||||
cy.get('@validatorOnList').click();
|
||||
.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,6 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
LC_ALL="en_US.UTF-8"
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
@@ -19,11 +19,6 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
||||
|
||||
NX_TENDERMINT_URL=http://localhost:26617
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=false
|
||||
@@ -13,9 +13,3 @@ NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.n00.devnet1.vega.xyz/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
@@ -14,9 +14,3 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
|
||||
|
||||
NX_TENDERMINT_URL=https://be.vega.community
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=false
|
||||
@@ -1,8 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_ENV=MAINNET_MIRROR
|
||||
NX_VEGA_ENV=MAINNET-MIRROR
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/mainnet-mirror/vegawallet-mainnet-mirror.toml
|
||||
NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz","MAINNET_MIRROR":"https://governance.mainnet-mirror.vega.rocks","STAGNET1":"https://trading.stagnet1.vega.rocks"}'
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz","MAINNET-MIRROR":"https://governance.mainnet-mirror.vega.rocks","STAGNET1":"https://trading.stagnet1.vega.rocks"}'
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
@@ -13,9 +13,3 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-mirror-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
|
||||
|
||||
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=false
|
||||
@@ -9,9 +9,3 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
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_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
@@ -14,9 +14,3 @@ 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_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
@@ -11,9 +11,3 @@ NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
||||
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_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=false
|
||||
@@ -2,13 +2,14 @@ import * as Sentry from '@sentry/react';
|
||||
import { toBigNum } from '@vegaprotocol/utils';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet, useEagerConnect } from '@vegaprotocol/wallet';
|
||||
import { FLAGS, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { SplashError } from './components/splash-error';
|
||||
import { SplashLoader } from './components/splash-loader';
|
||||
import { Flags } from './config';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@@ -79,7 +80,7 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => {
|
||||
}
|
||||
};
|
||||
|
||||
if (!FLAGS.GOVERNANCE_NETWORK_DOWN) {
|
||||
if (!Flags.NETWORK_DOWN) {
|
||||
run();
|
||||
}
|
||||
}, [token, appDispatch, staking, vesting]);
|
||||
@@ -147,7 +148,7 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => {
|
||||
};
|
||||
|
||||
// Only begin polling if network limits flag is set, as this is a new API not yet on mainnet 7/3/22
|
||||
if (FLAGS.GOVERNANCE_NETWORK_LIMITS) {
|
||||
if (Flags.NETWORK_LIMITS) {
|
||||
getNetworkLimits();
|
||||
}
|
||||
|
||||
@@ -156,7 +157,7 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => {
|
||||
};
|
||||
}, [appDispatch, VEGA_URL, t]);
|
||||
|
||||
if (FLAGS.GOVERNANCE_NETWORK_DOWN) {
|
||||
if (Flags.NETWORK_DOWN) {
|
||||
return (
|
||||
<Splash>
|
||||
<SplashError />
|
||||
|
||||
@@ -2,8 +2,13 @@ import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
} from '../../contexts/app-state/app-state-context';
|
||||
|
||||
export const ConnectToVega = () => {
|
||||
const { appDispatch } = useAppState();
|
||||
const { t } = useTranslation();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
@@ -11,6 +16,10 @@ export const ConnectToVega = () => {
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
data-testid="connect-to-vega-wallet-btn"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './json-diff';
|
||||
@@ -1,30 +0,0 @@
|
||||
import { render, screen, cleanup } from '@testing-library/react';
|
||||
import { JsonDiff } from './json-diff';
|
||||
|
||||
describe('JsonDiff', () => {
|
||||
afterEach(cleanup);
|
||||
|
||||
it('renders without crashing', () => {
|
||||
render(<JsonDiff left={{}} right={{}} />);
|
||||
expect(screen.getByTestId('json-diff')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows the correct message when both objects are identical', () => {
|
||||
render(<JsonDiff left={{}} right={{}} />);
|
||||
expect(screen.getByText('Data is identical')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show the "identical" message when both objects are not identical', () => {
|
||||
render(
|
||||
<JsonDiff
|
||||
left={{
|
||||
name: 'test',
|
||||
}}
|
||||
right={{
|
||||
name: 'test2',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(screen.queryByText('Data is identical')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { formatters, create } from 'jsondiffpatch';
|
||||
import 'jsondiffpatch/dist/formatters-styles/html.css';
|
||||
import 'jsondiffpatch/dist/formatters-styles/annotated.css';
|
||||
|
||||
export type JsonValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| JsonValue[]
|
||||
| { [key: string]: JsonValue };
|
||||
|
||||
interface JsonDiffProps {
|
||||
left: JsonValue;
|
||||
right: JsonValue;
|
||||
objectHash?: (obj: unknown) => string | undefined;
|
||||
}
|
||||
|
||||
export const JsonDiff = ({ right, left, objectHash }: JsonDiffProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [html, setHtml] = useState<string | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
const delta = create({
|
||||
objectHash,
|
||||
}).diff(left, right);
|
||||
|
||||
if (delta) {
|
||||
const deltaHtml = formatters.html.format(delta, left);
|
||||
|
||||
formatters.html.hideUnchanged();
|
||||
|
||||
setHtml(deltaHtml);
|
||||
} else {
|
||||
setHtml(undefined);
|
||||
}
|
||||
}, [right, left, objectHash]);
|
||||
|
||||
return html ? (
|
||||
<div data-testid="json-diff" dangerouslySetInnerHTML={{ __html: html }} />
|
||||
) : (
|
||||
<p data-testid="json-diff">{t('dataIsIdentical')}</p>
|
||||
);
|
||||
};
|
||||
@@ -18,10 +18,6 @@ import { VegaWallet } from '../vega-wallet';
|
||||
import { useLocation, useMatch } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import { useTelemetryDialog } from '../telemetry-dialog/telemetry-dialog';
|
||||
import {
|
||||
ProtocolUpgradeCountdown,
|
||||
ProtocolUpgradeCountdownMode,
|
||||
} from '@vegaprotocol/proposals';
|
||||
|
||||
export const SettingsLink = () => {
|
||||
const { open, isOpen, close } = useTelemetryDialog();
|
||||
@@ -65,14 +61,7 @@ export const Nav = ({ theme }: Pick<NavigationProps, 'theme'>) => {
|
||||
appName="Governance"
|
||||
theme={theme}
|
||||
breakpoints={[458, 959]}
|
||||
actions={
|
||||
<>
|
||||
<SettingsLink />
|
||||
<ProtocolUpgradeCountdown
|
||||
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
actions={<SettingsLink />}
|
||||
>
|
||||
<NavigationList
|
||||
className="[.drawer-content_&]:border-b [.drawer-content_&]:border-b-vega-light-200 dark:[.drawer-content_&]:border-b-vega-dark-200 [.drawer-content_&]:pb-8 [.drawer-content_&]:mb-2"
|
||||
|
||||
@@ -4,11 +4,7 @@ import type { ReactNode } from 'react';
|
||||
import { AnnouncementBanner } from '@vegaprotocol/announcements';
|
||||
import { Nav } from '../nav';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import {
|
||||
ProtocolUpgradeCountdownMode,
|
||||
ProtocolUpgradeProposalNotification,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
interface AppLayoutProps {
|
||||
children: ReactNode;
|
||||
@@ -35,23 +31,8 @@ export const AppLayout = ({ children }: AppLayoutProps) => {
|
||||
/>
|
||||
)}
|
||||
<Nav theme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'} />
|
||||
<NotificationsContainer />
|
||||
</div>
|
||||
<div className={AppLayoutClasses}>{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const NotificationsContainer = () => {
|
||||
const { isReadOnly, pubKey, disconnect } = useVegaWallet();
|
||||
return (
|
||||
<div data-testid="banners">
|
||||
<ProtocolUpgradeProposalNotification
|
||||
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
|
||||
/>
|
||||
{isReadOnly ? (
|
||||
<ViewingAsBanner pubKey={pubKey} disconnect={disconnect} />
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import React from 'react';
|
||||
|
||||
export interface TemplateSidebarProps {
|
||||
@@ -6,18 +8,24 @@ export interface TemplateSidebarProps {
|
||||
}
|
||||
|
||||
export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
|
||||
const { isReadOnly, pubKey, disconnect } = useVegaWallet();
|
||||
return (
|
||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[1fr] lg:grid-cols-[1fr_450px]">
|
||||
<main className="max-w-[100vw] col-start-1 p-4 overflow-auto">
|
||||
{children}
|
||||
</main>
|
||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
||||
{sidebar.map((Component, i) => (
|
||||
<section className="mb-4 last:mb-0" key={i}>
|
||||
{Component}
|
||||
</section>
|
||||
))}
|
||||
</aside>
|
||||
</div>
|
||||
<>
|
||||
{isReadOnly ? (
|
||||
<ViewingAsBanner pubKey={pubKey} disconnect={disconnect} />
|
||||
) : null}
|
||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[1fr] lg:grid-cols-[1fr_450px]">
|
||||
<main className="max-w-[100vw] col-start-1 p-4 overflow-auto">
|
||||
{children}
|
||||
</main>
|
||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
||||
{sidebar.map((Component, i) => (
|
||||
<section className="mb-4 last:mb-0" key={i}>
|
||||
{Component}
|
||||
</section>
|
||||
))}
|
||||
</aside>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
} from '../../contexts/app-state/app-state-context';
|
||||
|
||||
interface VegaWalletContainerProps {
|
||||
children: (key: string) => React.ReactElement;
|
||||
}
|
||||
@@ -10,6 +15,7 @@ interface VegaWalletContainerProps {
|
||||
export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { appDispatch } = useAppState();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
@@ -19,6 +25,10 @@ export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
|
||||
<Button
|
||||
data-testid="connect-to-vega-wallet-btn"
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -13,6 +13,12 @@ export const VegaWalletDialogs = () => {
|
||||
<>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
onChangeOpen={(open) =>
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: open,
|
||||
})
|
||||
}
|
||||
riskMessage={<RiskMessage />}
|
||||
/>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type WalletDelegationFieldsFragment = { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } };
|
||||
export type WalletDelegationFieldsFragment = { __typename: 'Delegation', amount: string, epoch: number, node: { __typename: 'Node', id: string, name: string } };
|
||||
|
||||
export type DelegationsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
@@ -11,7 +11,7 @@ export type DelegationsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type DelegationsQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string }, party?: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } } } | null> | null } | null } | null };
|
||||
export type DelegationsQuery = { __typename: 'Query', epoch: { __typename: 'Epoch', id: string }, party?: { __typename: 'Party', id: string, delegationsConnection?: { __typename: 'DelegationsConnection', edges?: Array<{ __typename: 'DelegationEdge', node: { __typename: 'Delegation', amount: string, epoch: number, node: { __typename: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename: 'StakingSummary', currentStakeAvailable: string }, accountsConnection?: { __typename: 'AccountsConnection', edges?: Array<{ __typename: 'AccountEdge', node: { __typename: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } } } | null> | null } | null } | null };
|
||||
|
||||
export const WalletDelegationFieldsFragmentDoc = gql`
|
||||
fragment WalletDelegationFields on Delegation {
|
||||
|
||||
@@ -71,6 +71,7 @@ export const VegaWallet = () => {
|
||||
|
||||
const VegaWalletNotConnected = () => {
|
||||
const { t } = useTranslation();
|
||||
const { appDispatch } = useAppState();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
@@ -78,6 +79,10 @@ const VegaWalletNotConnected = () => {
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
fill={true}
|
||||
|
||||
@@ -25,10 +25,6 @@ export const ContractAddresses: {
|
||||
claimAddress: customClaimAddress ?? '0x0',
|
||||
lockedAddress: customLockedAddress ?? '0x0',
|
||||
},
|
||||
MAINNET_MIRROR: {
|
||||
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
|
||||
lockedAddress: '0x0', // TODO not deployed to this env
|
||||
},
|
||||
DEVNET: {
|
||||
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
|
||||
lockedAddress: '0x0', // TODO not deployed to this env
|
||||
@@ -67,6 +63,12 @@ export const ENV = {
|
||||
localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'),
|
||||
delegationsPagination: windowOrDefault('NX_DELEGATIONS_PAGINATION'),
|
||||
rest: windowOrDefault('NX_VEGA_REST_URL'),
|
||||
flags: {
|
||||
NETWORK_DOWN: TRUTHY.includes(windowOrDefault('NX_NETWORK_DOWN')),
|
||||
MOCK: TRUTHY.includes(windowOrDefault('NX_MOCKED')),
|
||||
FAIRGROUND: TRUTHY.includes(windowOrDefault('NX_FAIRGROUND')),
|
||||
NETWORK_LIMITS: TRUTHY.includes(windowOrDefault('NX_NETWORK_LIMITS')),
|
||||
},
|
||||
addresses:
|
||||
ContractAddresses[(envName === 'local' ? 'CUSTOM' : envName) as Networks],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ENV } from './env';
|
||||
|
||||
export const Flags = {
|
||||
...ENV.flags,
|
||||
};
|
||||
@@ -1 +1,2 @@
|
||||
export * from './flags';
|
||||
export * from './env';
|
||||
|
||||
@@ -28,6 +28,9 @@ export interface AppState {
|
||||
/** Total number of VEGA Tokens, both vesting and unlocked, associated for staking */
|
||||
totalAssociated: BigNumber;
|
||||
|
||||
/** Whether or not the connect to VEGA wallet overlay is open */
|
||||
vegaWalletOverlay: boolean;
|
||||
|
||||
/** Whether or not the manage VEGA wallet overlay is open */
|
||||
vegaWalletManageOverlay: boolean;
|
||||
|
||||
@@ -49,7 +52,9 @@ export enum AppStateActionType {
|
||||
SET_TOKEN,
|
||||
SET_ALLOWANCE,
|
||||
REFRESH_BALANCES,
|
||||
SET_VEGA_WALLET_OVERLAY,
|
||||
SET_VEGA_WALLET_MANAGE_OVERLAY,
|
||||
SET_DRAWER,
|
||||
REFRESH_ASSOCIATED_BALANCES,
|
||||
SET_ASSOCIATION_BREAKDOWN,
|
||||
SET_TRANSACTION_OVERLAY,
|
||||
@@ -64,10 +69,18 @@ export type AppStateAction =
|
||||
totalSupply: BigNumber;
|
||||
totalAssociated: BigNumber;
|
||||
}
|
||||
| {
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY;
|
||||
isOpen: boolean;
|
||||
}
|
||||
| {
|
||||
type: AppStateActionType.SET_VEGA_WALLET_MANAGE_OVERLAY;
|
||||
isOpen: boolean;
|
||||
}
|
||||
| {
|
||||
type: AppStateActionType.SET_DRAWER;
|
||||
isOpen: boolean;
|
||||
}
|
||||
| {
|
||||
type: AppStateActionType.SET_TRANSACTION_OVERLAY;
|
||||
isOpen: boolean;
|
||||
|
||||
@@ -14,6 +14,7 @@ const initialAppState: AppState = {
|
||||
totalAssociated: new BigNumber(0),
|
||||
decimals: 0,
|
||||
totalSupply: new BigNumber(0),
|
||||
vegaWalletOverlay: false,
|
||||
vegaWalletManageOverlay: false,
|
||||
transactionOverlay: false,
|
||||
bannerMessage: '',
|
||||
@@ -30,10 +31,23 @@ function appStateReducer(state: AppState, action: AppStateAction): AppState {
|
||||
totalAssociated: action.totalAssociated,
|
||||
};
|
||||
}
|
||||
case AppStateActionType.SET_VEGA_WALLET_OVERLAY: {
|
||||
return {
|
||||
...state,
|
||||
vegaWalletOverlay: action.isOpen,
|
||||
};
|
||||
}
|
||||
case AppStateActionType.SET_VEGA_WALLET_MANAGE_OVERLAY: {
|
||||
return {
|
||||
...state,
|
||||
vegaWalletManageOverlay: action.isOpen,
|
||||
vegaWalletOverlay: action.isOpen ? false : state.vegaWalletOverlay,
|
||||
};
|
||||
}
|
||||
case AppStateActionType.SET_DRAWER: {
|
||||
return {
|
||||
...state,
|
||||
vegaWalletOverlay: false,
|
||||
};
|
||||
}
|
||||
case AppStateActionType.SET_TRANSACTION_OVERLAY: {
|
||||
|
||||
@@ -166,7 +166,6 @@
|
||||
"proposedEnactment": "Proposed enactment",
|
||||
"Enacted": "Enacted",
|
||||
"enactedOn": "Enacted on",
|
||||
"enactedOn{{date}}": "Enacted on {{enactmentDate}}",
|
||||
"status": "Status",
|
||||
"state": "State",
|
||||
"shouldPass": "Should pass",
|
||||
@@ -186,7 +185,6 @@
|
||||
"proposedOn": "Proposed on",
|
||||
"proposedBy": "Proposed by",
|
||||
"toEnactOn": "Enacts on",
|
||||
"enactsOn{{date}}": "Enacts on {{enactmentDate}}",
|
||||
"closesOn": "Closes on",
|
||||
"closedOn": "Closed on",
|
||||
"errorDetails": "Error details",
|
||||
@@ -219,7 +217,6 @@
|
||||
"votingThresholdInfo": "If the token vote passes the participation threshold it will be the deciding vote. If not, the outcome will be determined by liquidity providers on this market.",
|
||||
"noGovernanceTokens": "You need some VEGA tokens to participate in governance",
|
||||
"youVoted": "You voted",
|
||||
"voted": "Voted",
|
||||
"changeVote": "Change vote",
|
||||
"txRequested": "Confirm transaction in wallet",
|
||||
"votePending": "Casting vote",
|
||||
@@ -631,6 +628,7 @@
|
||||
"pendingDescriptionLinkText": "set up and run a node on Vega",
|
||||
"pendingDescription2": ". A node can move from being a candidate into standby based on how much nomination it attracts, assuming it has proven reliability by sending heartbeats to the network.",
|
||||
"n/a": "N/A",
|
||||
"Set to": "Set to",
|
||||
"pass": "pass",
|
||||
"fail": "fail",
|
||||
"New asset": "New asset",
|
||||
@@ -790,7 +788,7 @@
|
||||
"overstakedPenalty": "Overstaked penalty",
|
||||
"multisigPenalty": "Multisig penalty",
|
||||
"homeProposalsIntro": "Decisions on the Vega network are on-chain, with tokenholders creating proposals that other tokenholders vote to approve or reject. Network upgrades are proposed and approved by validators.",
|
||||
"homeProposalsButtonText": "See all proposals",
|
||||
"homeProposalsButtonText": "Browse, vote, and propose",
|
||||
"homeValidatorsIntro": "Vega runs on a delegated proof of stake blockchain, where validators earn fees for validating block transactions. Tokenholders can nominate validators by staking tokens to them.",
|
||||
"homeValidatorsButtonText": "Browse, and stake",
|
||||
"homeRewardsIntro": "Track rewards you've earned for trading, liquidity provision, market creation, and staking.",
|
||||
@@ -839,21 +837,5 @@
|
||||
"RejectedProposals": "Rejected proposals",
|
||||
"networkGovernance": "Network governance",
|
||||
"networkUpgrades": "Network upgrades",
|
||||
"assetSpecification": "Asset specification",
|
||||
"viewDetails": "View details",
|
||||
"vegaGovernance": "Vega Governance",
|
||||
"latestProposals": "Latest proposals",
|
||||
"vegaToken": "VEGA Token",
|
||||
"majorityVotedForProposal": "majority voted for this proposal",
|
||||
"majorityNotVotedForProposal": "majority not voted for this proposal",
|
||||
"requiredMajorityVotedForProposal": "Required majority voted for this proposal",
|
||||
"requiredMajorityNotVotedForProposal": "Required majority not voted for this proposal",
|
||||
"minParticipationReached": "Min. participation reached",
|
||||
"minParticipationNotReached": "Min. participation not reached",
|
||||
"consensusNodes": "consensus nodes",
|
||||
"activeNodes": "active nodes",
|
||||
"Estimated time to upgrade": "Estimated time to upgrade",
|
||||
"Upgraded at": "Upgraded at",
|
||||
"dataIsIdentical": "Data is identical",
|
||||
"updatesToMarket": "Updates to market"
|
||||
"assetSpecification": "Asset specification"
|
||||
}
|
||||
|
||||
@@ -2,18 +2,15 @@ import {
|
||||
RestConnector,
|
||||
JsonRpcConnector,
|
||||
ViewConnector,
|
||||
InjectedConnector,
|
||||
} from '@vegaprotocol/wallet';
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
export const injected = new InjectedConnector();
|
||||
export const rest = new RestConnector();
|
||||
export const jsonRpc = new JsonRpcConnector();
|
||||
export const view = new ViewConnector(urlParams.get('address'));
|
||||
|
||||
export const Connectors = {
|
||||
injected,
|
||||
rest,
|
||||
jsonRpc,
|
||||
view,
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
getNotRejectedProposals,
|
||||
getNotRejectedProtocolUpgradeProposals,
|
||||
} from '../proposals/proposals/proposals-container';
|
||||
import { Heading, SubHeading } from '../../components/heading';
|
||||
import { Heading } from '../../components/heading';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { RouteChildProps } from '..';
|
||||
import type { ProposalFieldsFragment } from '../proposals/proposals/__generated__/Proposals';
|
||||
@@ -31,11 +31,6 @@ import {
|
||||
orderByDate,
|
||||
orderByUpgradeBlockHeight,
|
||||
} from '../proposals/components/proposals-list/proposals-list';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
|
||||
const nodesToShow = 6;
|
||||
|
||||
@@ -47,57 +42,33 @@ const HomeProposals = ({
|
||||
protocolUpgradeProposals: ProtocolUpgradeProposalFieldsFragment[];
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
params: networkParams,
|
||||
loading: networkParamsLoading,
|
||||
error: networkParamsError,
|
||||
} = useNetworkParams([
|
||||
NetworkParams.governance_proposal_market_requiredMajority,
|
||||
NetworkParams.governance_proposal_updateMarket_requiredMajority,
|
||||
NetworkParams.governance_proposal_updateMarket_requiredMajorityLP,
|
||||
NetworkParams.governance_proposal_asset_requiredMajority,
|
||||
NetworkParams.governance_proposal_updateAsset_requiredMajority,
|
||||
NetworkParams.governance_proposal_updateNetParam_requiredMajority,
|
||||
NetworkParams.governance_proposal_freeform_requiredMajority,
|
||||
]);
|
||||
|
||||
return (
|
||||
<AsyncRenderer
|
||||
loading={networkParamsLoading}
|
||||
error={networkParamsError}
|
||||
data={networkParams}
|
||||
>
|
||||
<section className="mb-16" data-testid="home-proposals">
|
||||
<Heading title={t('vegaGovernance')} />
|
||||
<h3 className="mb-6">{t('homeProposalsIntro')}</h3>
|
||||
<div className="mb-8">
|
||||
<ExternalLink href={ExternalLinks.GOVERNANCE_PAGE}>
|
||||
{t(`readMoreGovernance`)}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
<section className="mb-16" data-testid="home-proposals">
|
||||
<Heading title={t('Proposals')} />
|
||||
<h3 className="mb-6">{t('homeProposalsIntro')}</h3>
|
||||
<div className="flex items-center mb-8 gap-8">
|
||||
<Link to={`${Routes.PROPOSALS}`}>
|
||||
<Button size="md">{t('homeProposalsButtonText')}</Button>
|
||||
</Link>
|
||||
|
||||
<SubHeading title={t('latestProposals')} />
|
||||
<ul data-testid="home-proposal-list" className="grid gap-6">
|
||||
{protocolUpgradeProposals.map((proposal, index) => (
|
||||
<ProtocolUpgradeProposalsListItem key={index} proposal={proposal} />
|
||||
))}
|
||||
<ExternalLink href={ExternalLinks.GOVERNANCE_PAGE}>
|
||||
{t(`readMoreGovernance`)}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
<ul
|
||||
data-testid="home-proposal-list"
|
||||
className="grid md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2 gap-6"
|
||||
>
|
||||
{protocolUpgradeProposals.map((proposal, index) => (
|
||||
<ProtocolUpgradeProposalsListItem key={index} proposal={proposal} />
|
||||
))}
|
||||
|
||||
{proposals.map((proposal) => (
|
||||
<ProposalsListItem
|
||||
key={proposal.id}
|
||||
proposal={proposal}
|
||||
networkParams={networkParams}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-6">
|
||||
<Link to={`${Routes.PROPOSALS}`}>
|
||||
<Button size="md">{t('homeProposalsButtonText')}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</AsyncRenderer>
|
||||
{proposals.map((proposal) => (
|
||||
<ProposalsListItem key={proposal.id} proposal={proposal} />
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -115,8 +86,8 @@ const HomeNodes = ({
|
||||
const { t } = useTranslation();
|
||||
|
||||
const highlightedNodeData = [
|
||||
{ title: t('activeNodes'), length: activeNodes.length },
|
||||
{ title: t('consensusNodes'), length: consensusNodes.length },
|
||||
{ title: t('active nodes'), length: activeNodes.length },
|
||||
{ title: t('consensus nodes'), length: consensusNodes.length },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -262,7 +233,7 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
||||
[protocolUpgradeProposals]
|
||||
);
|
||||
|
||||
const totalProposalsDesired = 3;
|
||||
const totalProposalsDesired = 4;
|
||||
const protocolUpgradeProposalsToShow = sortedProtocolUpgradeProposals.slice(
|
||||
0,
|
||||
totalProposalsDesired
|
||||
@@ -277,8 +248,6 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
||||
|
||||
const activeNodes = removePaginationWrapper(
|
||||
validatorsData?.nodesConnection.edges
|
||||
).filter((node) =>
|
||||
new BigNumber(node.rankingScore.performanceScore).isGreaterThan(0)
|
||||
);
|
||||
|
||||
const trimmedActiveNodes = activeNodes?.slice(0, nodesToShow);
|
||||
@@ -318,7 +287,7 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
||||
</div>
|
||||
|
||||
<div data-testid="home-vega-token">
|
||||
<Heading title={t('vegaToken')} marginTop={false} />
|
||||
<Heading title={t('VEGA Token')} marginTop={false} />
|
||||
<h3 className="mb-6">{t('homeVegaTokenIntro')}</h3>
|
||||
<div className="flex items-center mb-8 gap-4">
|
||||
<Link to={Routes.WITHDRAWALS}>
|
||||
|
||||
+32
-10
@@ -1,4 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
@@ -17,32 +18,53 @@ export const CurrentProposalState = ({
|
||||
|
||||
switch (proposal?.state) {
|
||||
case ProposalState.STATE_ENACTED: {
|
||||
proposalStatus = t('voteState_Enacted');
|
||||
proposalStatus = (
|
||||
<>
|
||||
<span className="mr-2">{t('voteState_Enacted')}</span>
|
||||
<Icon name={'tick'} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_PASSED: {
|
||||
proposalStatus = t('voteState_Passed');
|
||||
proposalStatus = (
|
||||
<>
|
||||
<span className="mr-2">{t('voteState_Passed')}</span>
|
||||
<Icon name={'tick'} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_WAITING_FOR_NODE_VOTE: {
|
||||
proposalStatus = t('voteState_WaitingForNodeVote');
|
||||
proposalStatus = (
|
||||
<>
|
||||
<span className="mr-2">{t('voteState_WaitingForNodeVote')}</span>
|
||||
<Icon name={'time'} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_OPEN: {
|
||||
variant = 'primary' as ProposalInfoLabelVariant;
|
||||
proposalStatus = t('voteState_Open');
|
||||
proposalStatus = <>{t('voteState_Open')}</>;
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_DECLINED: {
|
||||
proposalStatus = t('voteState_Declined');
|
||||
proposalStatus = (
|
||||
<>
|
||||
<span className="mr-2">{t('voteState_Declined')}</span>
|
||||
<Icon name={'cross'} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_REJECTED: {
|
||||
proposalStatus = t('voteState_Rejected');
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_FAILED: {
|
||||
proposalStatus = t('voteState_Failed');
|
||||
proposalStatus = (
|
||||
<>
|
||||
<span className="mr-2">{t('voteState_Rejected')}</span>
|
||||
<Icon name={'warning-sign'} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -8,14 +8,14 @@ export type ProposalAssetQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ProposalAssetQuery = { __typename?: 'Query', asset?: { __typename?: 'Asset', status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } | null };
|
||||
export type ProposalAssetQuery = { __typename: 'Query', asset?: { __typename: 'Asset', status: Types.AssetStatus, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } | null };
|
||||
|
||||
export type AssetListBundleQueryVariables = Types.Exact<{
|
||||
assetId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type AssetListBundleQuery = { __typename?: 'Query', erc20ListAssetBundle?: { __typename?: 'Erc20ListAssetBundle', assetSource: string, vegaAssetId: string, nonce: string, signatures: string } | null };
|
||||
export type AssetListBundleQuery = { __typename: 'Query', erc20ListAssetBundle?: { __typename: 'Erc20ListAssetBundle', assetSource: string, vegaAssetId: string, nonce: string, signatures: string } | null };
|
||||
|
||||
|
||||
export const ProposalAssetDocument = gql`
|
||||
|
||||
+20
-80
@@ -1,66 +1,21 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import {
|
||||
ProposalRejectionReason,
|
||||
ProposalState,
|
||||
VoteValue,
|
||||
} from '@vegaprotocol/types';
|
||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
|
||||
import {
|
||||
generateNoVotes,
|
||||
generateProposal,
|
||||
generateYesVotes,
|
||||
} from '../../test-helpers/generate-proposals';
|
||||
import { ProposalHeader } from './proposal-header';
|
||||
import {
|
||||
lastWeek,
|
||||
nextWeek,
|
||||
mockNetworkParams,
|
||||
mockWalletContext,
|
||||
createUserVoteQueryMock,
|
||||
} from '../../test-helpers/mocks';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import type { MockedResponse } from '@apollo/client/testing';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
jest.mock('@vegaprotocol/proposals', () => ({
|
||||
...jest.requireActual('@vegaprotocol/proposals'),
|
||||
useSuccessorMarketProposalDetails: () => ({
|
||||
code: 'PARENT_CODE',
|
||||
parentMarketId: 'PARENT_ID',
|
||||
}),
|
||||
}));
|
||||
import { ProposalRejectionReason, ProposalState } from '@vegaprotocol/types';
|
||||
import { lastWeek, nextWeek } from '../../test-helpers/mocks';
|
||||
|
||||
const renderComponent = (
|
||||
proposal: ProposalQuery['proposal'],
|
||||
isListItem = true,
|
||||
mocks: MockedResponse[] = []
|
||||
) =>
|
||||
render(
|
||||
<AppStateProvider>
|
||||
<BrowserRouter>
|
||||
<MockedProvider mocks={mocks}>
|
||||
<VegaWalletContext.Provider value={mockWalletContext}>
|
||||
<ProposalHeader
|
||||
proposal={proposal}
|
||||
isListItem={isListItem}
|
||||
networkParams={mockNetworkParams}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
</BrowserRouter>
|
||||
</AppStateProvider>
|
||||
);
|
||||
isListItem = true
|
||||
) => render(<ProposalHeader proposal={proposal} isListItem={isListItem} />);
|
||||
|
||||
describe('Proposal header', () => {
|
||||
afterAll(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
it('Renders New market proposal', () => {
|
||||
const mockedFlags = jest.mocked(FLAGS);
|
||||
mockedFlags.SUCCESSOR_MARKETS = true;
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
rationale: {
|
||||
@@ -93,9 +48,6 @@ describe('Proposal header', () => {
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
'tGBP settled future.'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-successor-info')).toHaveTextContent(
|
||||
'PARENT_CODE'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders Update market proposal', () => {
|
||||
@@ -365,6 +317,22 @@ describe('Proposal header', () => {
|
||||
expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
|
||||
});
|
||||
|
||||
it('Renders proposal state: Declined - majority not reached', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_DECLINED,
|
||||
terms: {
|
||||
enactmentDatetime: lastWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
no: generateNoVotes(1, 1000000000000000000),
|
||||
yes: generateYesVotes(1, 1000000000000000000),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('proposal-status')).toHaveTextContent('Declined');
|
||||
});
|
||||
|
||||
it('Renders proposal state: Rejected', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
@@ -378,32 +346,4 @@ describe('Proposal header', () => {
|
||||
);
|
||||
expect(screen.getByTestId('proposal-status')).toHaveTextContent('Rejected');
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - user voted against', async () => {
|
||||
const proposal = generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
terms: {
|
||||
closingDatetime: nextWeek.toString(),
|
||||
},
|
||||
});
|
||||
renderComponent(proposal, true, [
|
||||
// @ts-ignore generateProposal always creates an id
|
||||
createUserVoteQueryMock(proposal.id, VoteValue.VALUE_NO),
|
||||
]);
|
||||
expect(await screen.findByTestId('user-voted-no')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - user voted for', async () => {
|
||||
const proposal = generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
terms: {
|
||||
closingDatetime: nextWeek.toString(),
|
||||
},
|
||||
});
|
||||
renderComponent(proposal, true, [
|
||||
// @ts-ignore generateProposal always creates an id
|
||||
createUserVoteQueryMock(proposal.id, VoteValue.VALUE_YES),
|
||||
]);
|
||||
expect(await screen.findByTestId('user-voted-yes')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+14
-66
@@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Lozenge, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import { shorten } from '@vegaprotocol/utils';
|
||||
import { Heading, SubHeading } from '../../../../components/heading';
|
||||
import type { ReactNode } from 'react';
|
||||
@@ -8,25 +8,15 @@ import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import { truncateMiddle } from '../../../../lib/truncate-middle';
|
||||
import { CurrentProposalState } from '../current-proposal-state';
|
||||
import { ProposalInfoLabel } from '../proposal-info-label';
|
||||
import { useUserVote } from '../vote-details/use-user-vote';
|
||||
import { ProposalVotingStatus } from '../proposal-voting-status';
|
||||
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters';
|
||||
import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import Routes from '../../../routes';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const ProposalHeader = ({
|
||||
proposal,
|
||||
networkParams,
|
||||
isListItem = true,
|
||||
}: {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
networkParams: Partial<NetworkParamsResult>;
|
||||
isListItem?: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { voteState } = useUserVote(proposal?.id);
|
||||
const change = proposal?.terms.change;
|
||||
|
||||
let details: ReactNode;
|
||||
@@ -43,9 +33,6 @@ export const ProposalHeader = ({
|
||||
fallbackTitle = t('NewMarketProposal');
|
||||
details = (
|
||||
<>
|
||||
{FLAGS.SUCCESSOR_MARKETS && (
|
||||
<SuccessorCode proposalId={proposal?.id} />
|
||||
)}
|
||||
<span>
|
||||
{t('Code')}: {change.instrument.code}.
|
||||
</span>{' '}
|
||||
@@ -132,35 +119,6 @@ export const ProposalHeader = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center justify-between gap-4 mb-6 text-sm">
|
||||
<div data-testid="proposal-type">
|
||||
<ProposalInfoLabel variant="secondary">
|
||||
{t(`${proposalType}`)}
|
||||
</ProposalInfoLabel>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-6">
|
||||
{(voteState === 'Yes' || voteState === 'No') && (
|
||||
<div
|
||||
className="flex items-center gap-2"
|
||||
data-testid={`user-voted-${voteState.toLowerCase()}`}
|
||||
>
|
||||
<div className="text-vega-green" data-testid="you-voted-icon">
|
||||
<VegaIcon name={VegaIconNames.VOTE} size={24} />
|
||||
</div>
|
||||
<div>
|
||||
{t('voted')}{' '}
|
||||
<span className="uppercase">{t(`voteState_${voteState}`)}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div data-testid="proposal-status">
|
||||
<CurrentProposalState proposal={proposal} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-testid="proposal-title">
|
||||
{isListItem ? (
|
||||
<header>
|
||||
@@ -175,33 +133,23 @@ export const ProposalHeader = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<div data-testid="proposal-type">
|
||||
<ProposalInfoLabel variant="secondary">
|
||||
{t(`${proposalType}`)}
|
||||
</ProposalInfoLabel>
|
||||
</div>
|
||||
|
||||
<div data-testid="proposal-status">
|
||||
<CurrentProposalState proposal={proposal} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{details && (
|
||||
<div
|
||||
data-testid="proposal-details"
|
||||
className="break-words mb-6 text-vega-light-200"
|
||||
>
|
||||
<div data-testid="proposal-details" className="break-words my-10">
|
||||
{details}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ProposalVotingStatus proposal={proposal} networkParams={networkParams} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const SuccessorCode = ({ proposalId }: { proposalId?: string | null }) => {
|
||||
const { t } = useTranslation();
|
||||
const successor = useSuccessorMarketProposalDetails(proposalId);
|
||||
|
||||
return successor.parentMarketId || successor.code ? (
|
||||
<span className="block" data-testid="proposal-successor-info">
|
||||
{t('Successor market to')}:{' '}
|
||||
<Link
|
||||
to={`${Routes.PROPOSALS}/${successor.parentMarketId}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
{successor.code || successor.parentMarketId}
|
||||
</Link>
|
||||
</span>
|
||||
) : null;
|
||||
};
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ export type ProposalInfoLabelVariant =
|
||||
| 'tertiary'
|
||||
| 'highlight';
|
||||
|
||||
const base = 'rounded-full px-3 py-1 font-alpha';
|
||||
const primary = 'bg-vega-green text-black';
|
||||
const secondary = 'bg-vega-dark-200 text-vega-light-200';
|
||||
const tertiary = 'bg-vega-dark-150 text-vega-light-200';
|
||||
const base = 'rounded-md px-2 py-1 font-alpha';
|
||||
const primary = 'bg-vega-light-150 text-black';
|
||||
const secondary = 'bg-vega-dark-200 text-white';
|
||||
const tertiary = 'bg-vega-dark-150 text-white';
|
||||
const highlight = 'bg-vega-yellow text-black';
|
||||
|
||||
const getClassname = (variant: ProposalInfoLabelVariant) => {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './proposal-market-changes';
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import {
|
||||
ProposalMarketChanges,
|
||||
applyImmutableKeysFromEarlierVersion,
|
||||
} from './proposal-market-changes';
|
||||
import type { JsonValue } from '../../../../components/json-diff';
|
||||
|
||||
describe('applyImmutableKeysFromEarlierVersion', () => {
|
||||
it('returns an empty object if any argument is not an object or null', () => {
|
||||
const earlierVersion: JsonValue = null;
|
||||
const updatedVersion: JsonValue = null;
|
||||
expect(
|
||||
applyImmutableKeysFromEarlierVersion(earlierVersion, updatedVersion)
|
||||
).toEqual({});
|
||||
});
|
||||
|
||||
it('overrides updatedVersion with values from earlierVersion for immutable keys', () => {
|
||||
const earlierVersion: JsonValue = {
|
||||
decimalPlaces: 2,
|
||||
positionDecimalPlaces: 3,
|
||||
instrument: {
|
||||
name: 'Instrument1',
|
||||
future: {
|
||||
settlementAsset: 'Asset1',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const updatedVersion: JsonValue = {
|
||||
decimalPlaces: 3, // should be overridden by 2
|
||||
positionDecimalPlaces: 4, // should be overridden by 3
|
||||
instrument: {
|
||||
name: 'Instrument2', // should be overridden by 'Instrument1'
|
||||
future: {
|
||||
settlementAsset: 'Asset2', // should be overridden by 'Asset1'
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const expected: JsonValue = {
|
||||
decimalPlaces: 2,
|
||||
positionDecimalPlaces: 3,
|
||||
instrument: {
|
||||
name: 'Instrument1',
|
||||
future: {
|
||||
settlementAsset: 'Asset1',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
applyImmutableKeysFromEarlierVersion(earlierVersion, updatedVersion)
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ProposalMarketChanges', () => {
|
||||
it('renders correctly', () => {
|
||||
const { getByTestId } = render(
|
||||
<ProposalMarketChanges
|
||||
originalProposal={{}}
|
||||
latestEnactedProposal={{}}
|
||||
updatedProposal={{}}
|
||||
/>
|
||||
);
|
||||
expect(getByTestId('proposal-market-changes')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('JsonDiff is not visible when showChanges is false', () => {
|
||||
const { queryByTestId } = render(
|
||||
<ProposalMarketChanges
|
||||
originalProposal={{}}
|
||||
latestEnactedProposal={{}}
|
||||
updatedProposal={{}}
|
||||
/>
|
||||
);
|
||||
expect(queryByTestId('json-diff')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('JsonDiff is visible when showChanges is true', async () => {
|
||||
const { getByTestId } = render(
|
||||
<ProposalMarketChanges
|
||||
originalProposal={{}}
|
||||
latestEnactedProposal={{}}
|
||||
updatedProposal={{}}
|
||||
/>
|
||||
);
|
||||
fireEvent.click(getByTestId('proposal-market-changes-toggle'));
|
||||
expect(getByTestId('json-diff')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import set from 'lodash/set';
|
||||
import get from 'lodash/get';
|
||||
import { JsonDiff } from '../../../../components/json-diff';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useState } from 'react';
|
||||
import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
|
||||
import { SubHeading } from '../../../../components/heading';
|
||||
import type { JsonValue } from '../../../../components/json-diff';
|
||||
|
||||
const immutableKeys = [
|
||||
'decimalPlaces',
|
||||
'positionDecimalPlaces',
|
||||
'instrument.name',
|
||||
'instrument.future.settlementAsset',
|
||||
];
|
||||
|
||||
export const applyImmutableKeysFromEarlierVersion = (
|
||||
earlierVersion: JsonValue,
|
||||
updatedVersion: JsonValue
|
||||
) => {
|
||||
if (
|
||||
typeof earlierVersion !== 'object' ||
|
||||
earlierVersion === null ||
|
||||
typeof updatedVersion !== 'object' ||
|
||||
updatedVersion === null
|
||||
) {
|
||||
// If either version is not an object or is null, return null or throw an error
|
||||
return {};
|
||||
}
|
||||
|
||||
const updatedVersionCopy = cloneDeep(updatedVersion);
|
||||
|
||||
// Overwrite the immutable keys in the updatedVersionCopy with the earlier values
|
||||
immutableKeys.forEach((key) => {
|
||||
set(updatedVersionCopy, key, get(earlierVersion, key));
|
||||
});
|
||||
|
||||
return updatedVersionCopy;
|
||||
};
|
||||
|
||||
interface ProposalMarketChangesProps {
|
||||
originalProposal: JsonValue;
|
||||
latestEnactedProposal: JsonValue | undefined;
|
||||
updatedProposal: JsonValue;
|
||||
}
|
||||
|
||||
export const ProposalMarketChanges = ({
|
||||
originalProposal,
|
||||
latestEnactedProposal,
|
||||
updatedProposal,
|
||||
}: ProposalMarketChangesProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [showChanges, setShowChanges] = useState(false);
|
||||
|
||||
return (
|
||||
<section data-testid="proposal-market-changes">
|
||||
<CollapsibleToggle
|
||||
toggleState={showChanges}
|
||||
setToggleState={setShowChanges}
|
||||
dataTestId={'proposal-market-changes-toggle'}
|
||||
>
|
||||
<SubHeading title={t('updatesToMarket')} />
|
||||
</CollapsibleToggle>
|
||||
|
||||
{showChanges && (
|
||||
<div className="mb-6">
|
||||
<JsonDiff
|
||||
left={latestEnactedProposal || originalProposal}
|
||||
right={
|
||||
latestEnactedProposal
|
||||
? applyImmutableKeysFromEarlierVersion(
|
||||
latestEnactedProposal,
|
||||
updatedProposal
|
||||
)
|
||||
: applyImmutableKeysFromEarlierVersion(
|
||||
originalProposal,
|
||||
updatedProposal
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './proposal-voting-status';
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
lastWeek,
|
||||
mockWalletContext,
|
||||
networkParamsQueryMock,
|
||||
nextWeek,
|
||||
mockNetworkParams,
|
||||
} from '../../test-helpers/mocks';
|
||||
import { ProposalVotingStatus } from './proposal-voting-status';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import type { MockedResponse } from '@apollo/client/testing';
|
||||
import {
|
||||
generateNoVotes,
|
||||
generateProposal,
|
||||
generateYesVotes,
|
||||
} from '../../test-helpers/generate-proposals';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { BigNumber } from '../../../../lib/bignumber';
|
||||
import type { AppState } from '../../../../contexts/app-state/app-state-context';
|
||||
|
||||
const mockTotalSupply = new BigNumber(100);
|
||||
// Note - giving a fixedTokenValue of 1 means a ratio of 1:1 votes to tokens, making sums easier :)
|
||||
const fixedTokenValue = 1000000000000000000;
|
||||
|
||||
const mockAppState: AppState = {
|
||||
totalAssociated: new BigNumber('50063005'),
|
||||
decimals: 18,
|
||||
totalSupply: mockTotalSupply,
|
||||
vegaWalletManageOverlay: false,
|
||||
transactionOverlay: false,
|
||||
bannerMessage: '',
|
||||
disconnectNotice: false,
|
||||
};
|
||||
|
||||
jest.mock('../../../../contexts/app-state/app-state-context', () => ({
|
||||
useAppState: () => ({
|
||||
appState: mockAppState,
|
||||
}),
|
||||
}));
|
||||
|
||||
const renderComponent = (
|
||||
proposal: ProposalQuery['proposal'],
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
mocks: MockedResponse<any>[] = [networkParamsQueryMock]
|
||||
) =>
|
||||
render(
|
||||
<Router>
|
||||
<MockedProvider mocks={mocks}>
|
||||
<VegaWalletContext.Provider value={mockWalletContext}>
|
||||
<ProposalVotingStatus
|
||||
proposal={proposal}
|
||||
networkParams={mockNetworkParams}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
</Router>
|
||||
);
|
||||
|
||||
describe('ProposalVotingStatus', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(0);
|
||||
});
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('Renders majority reached', () => {
|
||||
const yesVotes = 100;
|
||||
const noVotes = 0;
|
||||
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_PASSED,
|
||||
terms: {
|
||||
closingDatetime: lastWeek.toString(),
|
||||
enactmentDatetime: nextWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
__typename: 'ProposalVotes',
|
||||
yes: generateYesVotes(yesVotes, fixedTokenValue),
|
||||
no: generateNoVotes(noVotes, fixedTokenValue),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('majority-reached')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders majority not reached', () => {
|
||||
const yesVotes = 20;
|
||||
const noVotes = 80;
|
||||
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_PASSED,
|
||||
terms: {
|
||||
closingDatetime: lastWeek.toString(),
|
||||
enactmentDatetime: nextWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
__typename: 'ProposalVotes',
|
||||
yes: generateYesVotes(yesVotes, fixedTokenValue),
|
||||
no: generateNoVotes(noVotes, fixedTokenValue),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('majority-not-reached')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders participation reached', () => {
|
||||
const yesVotes = 1000;
|
||||
const noVotes = 0;
|
||||
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_PASSED,
|
||||
terms: {
|
||||
closingDatetime: lastWeek.toString(),
|
||||
enactmentDatetime: nextWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
__typename: 'ProposalVotes',
|
||||
yes: generateYesVotes(yesVotes, fixedTokenValue),
|
||||
no: generateNoVotes(noVotes, fixedTokenValue),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('participation-reached')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders participation not reached', () => {
|
||||
const yesVotes = 0;
|
||||
const noVotes = 0;
|
||||
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
terms: {
|
||||
closingDatetime: lastWeek.toString(),
|
||||
enactmentDatetime: nextWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
__typename: 'ProposalVotes',
|
||||
yes: generateYesVotes(yesVotes, fixedTokenValue),
|
||||
no: generateNoVotes(noVotes, fixedTokenValue),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('participation-not-reached')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
import classNames from 'classnames';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
import { BigNumber } from '../../../../lib/bignumber';
|
||||
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
|
||||
const statusClasses = (reached: boolean) =>
|
||||
classNames('flex items-center gap-2 px-4 py-2 rounded-md', {
|
||||
'bg-vega-green-700': reached,
|
||||
'bg-vega-red-700': !reached,
|
||||
});
|
||||
|
||||
const MajorityStatus = ({
|
||||
reached,
|
||||
requiredMajority,
|
||||
}: {
|
||||
reached: boolean;
|
||||
requiredMajority: string | null | undefined;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={statusClasses(reached)}
|
||||
data-testid="proposal-majority-status"
|
||||
>
|
||||
{reached ? <Icon name="tick" /> : <Icon name="cross" />}
|
||||
{reached ? (
|
||||
<div data-testid="majority-reached">
|
||||
{requiredMajority ? (
|
||||
<>
|
||||
{new BigNumber(requiredMajority).times(100).toString()}%{' '}
|
||||
{t('majorityVotedForProposal')}
|
||||
</>
|
||||
) : (
|
||||
t('requiredMajorityVotedForProposal')
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div data-testid="majority-not-reached">
|
||||
{requiredMajority ? (
|
||||
<>
|
||||
{new BigNumber(requiredMajority).times(100).toString()}%{' '}
|
||||
{t('majorityNotVotedForProposal')}
|
||||
</>
|
||||
) : (
|
||||
t('requiredMajorityNotVotedForProposal')
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ParticipationStatus = ({ reached }: { reached: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className={statusClasses(reached)}>
|
||||
{reached ? (
|
||||
<>
|
||||
<Icon name="tick" />
|
||||
<div data-testid="participation-reached">
|
||||
{t('minParticipationReached')}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Icon name="cross" />
|
||||
<div data-testid="participation-not-reached">
|
||||
{t('minParticipationNotReached')}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ProposalVotingStatus = ({
|
||||
proposal,
|
||||
networkParams,
|
||||
}: {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
networkParams: Partial<NetworkParamsResult>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { majorityMet, majorityLPMet, participationMet, participationLPMet } =
|
||||
useVoteInformation({
|
||||
proposal,
|
||||
});
|
||||
|
||||
if (!proposal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isUpdateMarket = proposal?.terms.change.__typename === 'UpdateMarket';
|
||||
|
||||
let requiredVotingMajority = null;
|
||||
let requiredVotingMajorityLP = null;
|
||||
|
||||
if (networkParams) {
|
||||
switch (proposal.terms.change.__typename) {
|
||||
case 'NewMarket':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_market_requiredMajority;
|
||||
break;
|
||||
case 'UpdateMarket':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_updateMarket_requiredMajority;
|
||||
requiredVotingMajorityLP =
|
||||
networkParams.governance_proposal_updateMarket_requiredMajorityLP;
|
||||
break;
|
||||
case 'NewAsset':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_asset_requiredMajority;
|
||||
break;
|
||||
case 'UpdateAsset':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_updateAsset_requiredMajority;
|
||||
break;
|
||||
case 'UpdateNetworkParameter':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_updateNetParam_requiredMajority;
|
||||
break;
|
||||
case 'NewFreeform':
|
||||
requiredVotingMajority =
|
||||
networkParams.governance_proposal_freeform_requiredMajority;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUpdateMarket) {
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<p>{t('Token vote')}</p>
|
||||
<div
|
||||
className="grid grid-cols-2 gap-4 items-center"
|
||||
data-testid="token-vote-statuses"
|
||||
>
|
||||
<MajorityStatus
|
||||
reached={majorityMet}
|
||||
requiredMajority={requiredVotingMajority}
|
||||
/>{' '}
|
||||
<ParticipationStatus reached={participationMet} />
|
||||
</div>
|
||||
|
||||
<p className="mt-4">{t('Liquidity provider vote')}</p>
|
||||
<div
|
||||
className="grid grid-cols-2 gap-4 items-center"
|
||||
data-testid="lp-vote-statuses"
|
||||
>
|
||||
<MajorityStatus
|
||||
reached={majorityLPMet}
|
||||
requiredMajority={requiredVotingMajorityLP}
|
||||
/>{' '}
|
||||
<ParticipationStatus reached={participationLPMet} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-4 items-center mb-6">
|
||||
<MajorityStatus
|
||||
reached={majorityMet}
|
||||
requiredMajority={requiredVotingMajority}
|
||||
/>{' '}
|
||||
<ParticipationStatus reached={participationMet} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -4,7 +4,6 @@ import { generateProposal } from '../../test-helpers/generate-proposals';
|
||||
import { Proposal } from './proposal';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { mockNetworkParams } from '../../test-helpers/mocks';
|
||||
|
||||
jest.mock('@vegaprotocol/network-parameters', () => ({
|
||||
...jest.requireActual('@vegaprotocol/network-parameters'),
|
||||
@@ -47,7 +46,6 @@ const renderComponent = (proposal: ProposalQuery['proposal']) => {
|
||||
<Proposal
|
||||
restData={{}}
|
||||
proposal={proposal as ProposalQuery['proposal']}
|
||||
networkParams={mockNetworkParams}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Icon, RoundedWrapper } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { AsyncRenderer, Icon, RoundedWrapper } from '@vegaprotocol/ui-toolkit';
|
||||
import { ProposalHeader } from '../proposal-detail-header/proposal-header';
|
||||
import { ProposalDescription } from '../proposal-description';
|
||||
import { ProposalChangeTable } from '../proposal-change-table';
|
||||
@@ -17,8 +21,6 @@ import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
||||
import type { AssetQuery } from '@vegaprotocol/assets';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { ProposalMarketChanges } from '../proposal-market-changes';
|
||||
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters';
|
||||
|
||||
export enum ProposalType {
|
||||
PROPOSAL_NEW_MARKET = 'PROPOSAL_NEW_MARKET',
|
||||
@@ -30,27 +32,28 @@ export enum ProposalType {
|
||||
}
|
||||
export interface ProposalProps {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
networkParams: Partial<NetworkParamsResult>;
|
||||
newMarketData?: MarketInfoWithData | null;
|
||||
assetData?: AssetQuery | null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
restData: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
originalMarketProposalRestData?: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
mostRecentlyEnactedAssociatedMarketProposal?: any;
|
||||
}
|
||||
|
||||
export const Proposal = ({
|
||||
proposal,
|
||||
networkParams,
|
||||
restData,
|
||||
newMarketData,
|
||||
assetData,
|
||||
originalMarketProposalRestData,
|
||||
mostRecentlyEnactedAssociatedMarketProposal,
|
||||
}: ProposalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { params, loading, error } = useNetworkParams([
|
||||
NetworkParams.governance_proposal_market_minVoterBalance,
|
||||
NetworkParams.governance_proposal_updateMarket_minVoterBalance,
|
||||
NetworkParams.governance_proposal_asset_minVoterBalance,
|
||||
NetworkParams.governance_proposal_updateAsset_minVoterBalance,
|
||||
NetworkParams.governance_proposal_updateNetParam_minVoterBalance,
|
||||
NetworkParams.governance_proposal_freeform_minVoterBalance,
|
||||
NetworkParams.spam_protection_voting_min_tokens,
|
||||
]);
|
||||
|
||||
if (!proposal) {
|
||||
return null;
|
||||
@@ -76,140 +79,122 @@ export const Proposal = ({
|
||||
let minVoterBalance = null;
|
||||
let proposalType = null;
|
||||
|
||||
if (networkParams) {
|
||||
if (params) {
|
||||
switch (proposal.terms.change.__typename) {
|
||||
case 'NewMarket':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_market_minVoterBalance;
|
||||
minVoterBalance = params.governance_proposal_market_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_NEW_MARKET;
|
||||
break;
|
||||
case 'UpdateMarket':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_updateMarket_minVoterBalance;
|
||||
params.governance_proposal_updateMarket_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_UPDATE_MARKET;
|
||||
break;
|
||||
case 'NewAsset':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_asset_minVoterBalance;
|
||||
minVoterBalance = params.governance_proposal_asset_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_NEW_ASSET;
|
||||
break;
|
||||
case 'UpdateAsset':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_updateAsset_minVoterBalance;
|
||||
params.governance_proposal_updateAsset_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_UPDATE_ASSET;
|
||||
break;
|
||||
case 'UpdateNetworkParameter':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_updateNetParam_minVoterBalance;
|
||||
params.governance_proposal_updateNetParam_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_NETWORK_PARAMETER;
|
||||
break;
|
||||
case 'NewFreeform':
|
||||
minVoterBalance =
|
||||
networkParams.governance_proposal_freeform_minVoterBalance;
|
||||
minVoterBalance = params.governance_proposal_freeform_minVoterBalance;
|
||||
proposalType = ProposalType.PROPOSAL_FREEFORM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section data-testid="proposal">
|
||||
<div className="flex items-center gap-1 mb-6">
|
||||
<Icon name={'chevron-left'} />
|
||||
<AsyncRenderer data={params} loading={loading} error={error}>
|
||||
<section data-testid="proposal">
|
||||
<div className="flex items-center gap-1">
|
||||
<Icon name={'chevron-left'} />
|
||||
|
||||
{proposal.state === ProposalState.STATE_REJECTED ? (
|
||||
<div data-testid="rejected-proposals-link">
|
||||
<Link className="underline" to={Routes.PROPOSALS_REJECTED}>
|
||||
{t('RejectedProposals')}
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div data-testid="all-proposals-link">
|
||||
<Link className="underline" to={Routes.PROPOSALS}>
|
||||
{t('AllProposals')}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ProposalHeader
|
||||
proposal={proposal}
|
||||
isListItem={false}
|
||||
networkParams={networkParams}
|
||||
/>
|
||||
|
||||
<div id="details">
|
||||
<div className="my-10">
|
||||
<ProposalChangeTable proposal={proposal} />
|
||||
{proposal.state === ProposalState.STATE_REJECTED ? (
|
||||
<div data-testid="rejected-proposals-link">
|
||||
<Link className="underline" to={Routes.PROPOSALS_REJECTED}>
|
||||
{t('RejectedProposals')}
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div data-testid="all-proposals-link">
|
||||
<Link className="underline" to={Routes.PROPOSALS}>
|
||||
{t('AllProposals')}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ProposalHeader proposal={proposal} isListItem={false} />
|
||||
|
||||
{proposal.terms.change.__typename === 'NewAsset' &&
|
||||
proposal.terms.change.source.__typename === 'ERC20' &&
|
||||
proposal.id ? (
|
||||
<ListAsset
|
||||
assetId={proposal.id}
|
||||
withdrawalThreshold={proposal.terms.change.source.withdrawThreshold}
|
||||
lifetimeLimit={proposal.terms.change.source.lifetimeLimit}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<div className="mb-4">
|
||||
<ProposalDescription description={proposal.rationale.description} />
|
||||
</div>
|
||||
|
||||
{newMarketData && (
|
||||
<div className="mb-4">
|
||||
<ProposalMarketData marketData={newMarketData} />
|
||||
<div id="details">
|
||||
<div className="my-10">
|
||||
<ProposalChangeTable proposal={proposal} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{proposal.terms.change.__typename === 'UpdateMarket' && (
|
||||
<div className="mb-4">
|
||||
<ProposalMarketChanges
|
||||
originalProposal={
|
||||
originalMarketProposalRestData?.data?.proposal?.terms?.newMarket
|
||||
?.changes || {}
|
||||
}
|
||||
latestEnactedProposal={
|
||||
mostRecentlyEnactedAssociatedMarketProposal?.node?.proposal
|
||||
?.terms?.updateMarket?.changes || {}
|
||||
}
|
||||
updatedProposal={
|
||||
restData?.data?.proposal?.terms?.updateMarket?.changes || {}
|
||||
{proposal.terms.change.__typename === 'NewAsset' &&
|
||||
proposal.terms.change.source.__typename === 'ERC20' &&
|
||||
proposal.id ? (
|
||||
<ListAsset
|
||||
assetId={proposal.id}
|
||||
withdrawalThreshold={
|
||||
proposal.terms.change.source.withdrawThreshold
|
||||
}
|
||||
lifetimeLimit={proposal.terms.change.source.lifetimeLimit}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
) : null}
|
||||
|
||||
{(proposal.terms.change.__typename === 'NewAsset' ||
|
||||
proposal.terms.change.__typename === 'UpdateAsset') &&
|
||||
asset && (
|
||||
<div className="mb-4">
|
||||
<ProposalDescription description={proposal.rationale.description} />
|
||||
</div>
|
||||
|
||||
{newMarketData && (
|
||||
<div className="mb-4">
|
||||
<ProposalAssetDetails asset={asset} />
|
||||
<ProposalMarketData marketData={newMarketData} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-6">
|
||||
<ProposalJson proposal={restData?.data?.proposal} />
|
||||
</div>
|
||||
</div>
|
||||
{(proposal.terms.change.__typename === 'NewAsset' ||
|
||||
proposal.terms.change.__typename === 'UpdateAsset') &&
|
||||
asset && (
|
||||
<div className="mb-4">
|
||||
<ProposalAssetDetails asset={asset} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div id="voting">
|
||||
<div className="mb-10">
|
||||
<RoundedWrapper paddingBottom={true}>
|
||||
<VoteDetails
|
||||
<div className="mb-6">
|
||||
<ProposalJson proposal={restData?.data?.proposal} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="voting">
|
||||
<div className="mb-10">
|
||||
<RoundedWrapper paddingBottom={true}>
|
||||
<VoteDetails
|
||||
proposal={proposal}
|
||||
proposalType={proposalType}
|
||||
minVoterBalance={minVoterBalance}
|
||||
spamProtectionMinTokens={
|
||||
params?.spam_protection_voting_min_tokens
|
||||
}
|
||||
/>
|
||||
</RoundedWrapper>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<ProposalVotesTable
|
||||
proposal={proposal}
|
||||
proposalType={proposalType}
|
||||
minVoterBalance={minVoterBalance}
|
||||
spamProtectionMinTokens={
|
||||
networkParams?.spam_protection_voting_min_tokens
|
||||
}
|
||||
/>
|
||||
</RoundedWrapper>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<ProposalVotesTable proposal={proposal} proposalType={proposalType} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
||||
|
||||
+127
-11
@@ -5,7 +5,11 @@ import type { MockedResponse } from '@apollo/client/testing';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { format } from 'date-fns';
|
||||
import { ProposalRejectionReason, ProposalState } from '@vegaprotocol/types';
|
||||
import {
|
||||
ProposalRejectionReason,
|
||||
ProposalState,
|
||||
VoteValue,
|
||||
} from '@vegaprotocol/types';
|
||||
import {
|
||||
generateNoVotes,
|
||||
generateProposal,
|
||||
@@ -14,6 +18,7 @@ import {
|
||||
import { ProposalsListItemDetails } from './proposals-list-item-details';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import {
|
||||
mockPubkey,
|
||||
mockWalletContext,
|
||||
networkParamsQueryMock,
|
||||
fiveMinutes,
|
||||
@@ -23,6 +28,39 @@ import {
|
||||
nextWeek,
|
||||
} from '../../test-helpers/mocks';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import { UserVoteDocument } from '../vote-details/__generated__/Vote';
|
||||
import faker from 'faker';
|
||||
|
||||
const createUserVoteQueryMock = (
|
||||
proposalId: string | undefined | null,
|
||||
value: VoteValue
|
||||
) => ({
|
||||
request: {
|
||||
query: UserVoteDocument,
|
||||
variables: {
|
||||
partyId: mockPubkey.publicKey,
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
party: {
|
||||
votesConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
proposalId,
|
||||
vote: {
|
||||
value,
|
||||
datetime: faker.date.past().toISOString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const renderComponent = (
|
||||
proposal: ProposalQuery['proposal'],
|
||||
@@ -93,7 +131,7 @@ describe('Proposals list item details', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Update market proposal - Currently expected to pass by LP vote', () => {
|
||||
it('Renders proposal state: Update market proposal - set to pass by LP vote', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
@@ -115,11 +153,11 @@ describe('Proposals list item details', () => {
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Currently expected to pass by LP vote'
|
||||
'Set to pass by LP vote'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Update market proposal - Currently expected to pass by token vote', () => {
|
||||
it('Renders proposal state: Update market proposal - set to pass by token vote', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
@@ -141,11 +179,11 @@ describe('Proposals list item details', () => {
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Currently expected to pass by token vote'
|
||||
'Set to pass by token vote'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Update market proposal - Currently expected to fail', () => {
|
||||
it('Renders proposal state: Update market proposal - set to fail', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
@@ -166,9 +204,7 @@ describe('Proposals list item details', () => {
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Currently expected to fail'
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent('Set to fail');
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - 5 minutes left to vote', () => {
|
||||
@@ -213,6 +249,52 @@ describe('Proposals list item details', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - user voted for', async () => {
|
||||
const proposal = generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
terms: {
|
||||
closingDatetime: nextWeek.toString(),
|
||||
},
|
||||
});
|
||||
renderComponent(proposal, [
|
||||
networkParamsQueryMock,
|
||||
createUserVoteQueryMock(proposal?.id, VoteValue.VALUE_YES),
|
||||
]);
|
||||
expect(await screen.findByText('You voted For')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - user voted against', async () => {
|
||||
const proposal = generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
terms: {
|
||||
closingDatetime: nextWeek.toString(),
|
||||
},
|
||||
});
|
||||
renderComponent(proposal, [
|
||||
networkParamsQueryMock,
|
||||
createUserVoteQueryMock(proposal?.id, VoteValue.VALUE_NO),
|
||||
]);
|
||||
expect(await screen.findByText('You voted Against')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - participation not reached', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_OPEN,
|
||||
terms: {
|
||||
enactmentDatetime: nextWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
no: generateNoVotes(0),
|
||||
yes: generateYesVotes(0),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Participation not reached'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Open - majority not reached', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
@@ -227,7 +309,7 @@ describe('Proposals list item details', () => {
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Currently expected to fail'
|
||||
'Majority not reached'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -245,8 +327,42 @@ describe('Proposals list item details', () => {
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent('Set to pass');
|
||||
});
|
||||
|
||||
it('Renders proposal state: Declined - participation not reached', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_DECLINED,
|
||||
terms: {
|
||||
enactmentDatetime: lastWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
no: generateNoVotes(0),
|
||||
yes: generateYesVotes(0),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Currently expected to pass'
|
||||
'Participation not reached'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders proposal state: Declined - majority not reached', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
state: ProposalState.STATE_DECLINED,
|
||||
terms: {
|
||||
enactmentDatetime: lastWeek.toString(),
|
||||
},
|
||||
votes: {
|
||||
no: generateNoVotes(1, 1000000000000000000),
|
||||
yes: generateYesVotes(1, 1000000000000000000),
|
||||
},
|
||||
})
|
||||
);
|
||||
expect(screen.getByTestId('vote-status')).toHaveTextContent(
|
||||
'Majority not reached'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+106
-53
@@ -1,6 +1,9 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
import { useUserVote } from '../vote-details/use-user-vote';
|
||||
import { StatusPass } from '../current-proposal-status/current-proposal-status';
|
||||
import { format, formatDistanceToNowStrict } from 'date-fns';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import type { ReactNode } from 'react';
|
||||
@@ -11,100 +14,138 @@ import {
|
||||
import Routes from '../../../routes';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
|
||||
const MajorityNotReached = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
{t('Majority')} {t('not reached')}
|
||||
</>
|
||||
);
|
||||
};
|
||||
const ParticipationNotReached = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
{t('Participation')} {t('not reached')}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const ProposalsListItemDetails = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const state = proposal?.state;
|
||||
const { willPassByTokenVote, willPassByLPVote } = useVoteInformation({
|
||||
const {
|
||||
willPassByTokenVote,
|
||||
willPassByLPVote,
|
||||
majorityMet,
|
||||
participationMet,
|
||||
} = useVoteInformation({
|
||||
proposal,
|
||||
});
|
||||
const { t } = useTranslation();
|
||||
const { voteState } = useUserVote(proposal?.id);
|
||||
const isUpdateMarket = proposal?.terms.change.__typename === 'UpdateMarket';
|
||||
const updateMarketWillPass = willPassByTokenVote || willPassByLPVote;
|
||||
const updateMarketVotePassMethod = willPassByTokenVote
|
||||
? t('byTokenVote')
|
||||
: t('byLPVote');
|
||||
const nowToEnactmentInHours = differenceInHours(
|
||||
new Date(proposal?.terms.closingDatetime),
|
||||
new Date()
|
||||
);
|
||||
const isUpdateMarket = proposal?.terms.change.__typename === 'UpdateMarket';
|
||||
|
||||
let voteDetails: ReactNode;
|
||||
let voteStatus: ReactNode;
|
||||
|
||||
switch (state) {
|
||||
case ProposalState.STATE_ENACTED: {
|
||||
voteDetails =
|
||||
proposal?.terms.enactmentDatetime &&
|
||||
t('enactedOn{{date}}', {
|
||||
enactmentDate:
|
||||
proposal?.terms.enactmentDatetime &&
|
||||
format(
|
||||
new Date(proposal?.terms.enactmentDatetime),
|
||||
DATE_FORMAT_DETAILED
|
||||
),
|
||||
});
|
||||
voteDetails = proposal?.terms.enactmentDatetime && (
|
||||
<>
|
||||
{format(
|
||||
new Date(proposal?.terms.enactmentDatetime),
|
||||
DATE_FORMAT_DETAILED
|
||||
)}
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_PASSED: {
|
||||
voteDetails =
|
||||
proposal?.terms.change.__typename !== 'NewFreeform' &&
|
||||
t('enactsOn{{date}}', {
|
||||
enactmentDate:
|
||||
proposal?.terms.enactmentDatetime &&
|
||||
voteDetails = proposal?.terms.change.__typename !== 'NewFreeform' && (
|
||||
<>
|
||||
{t('toEnactOn')}{' '}
|
||||
{proposal?.terms.enactmentDatetime &&
|
||||
format(
|
||||
new Date(proposal.terms.enactmentDatetime),
|
||||
DATE_FORMAT_DETAILED
|
||||
),
|
||||
});
|
||||
)}
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_WAITING_FOR_NODE_VOTE: {
|
||||
voteDetails =
|
||||
proposal?.terms.change.__typename !== 'NewFreeform' &&
|
||||
t('enactsOn{{date}}', {
|
||||
enactmentDate:
|
||||
proposal?.terms.enactmentDatetime &&
|
||||
voteDetails = proposal?.terms.change.__typename !== 'NewFreeform' && (
|
||||
<>
|
||||
{t('toEnactOn')}{' '}
|
||||
{proposal?.terms.enactmentDatetime &&
|
||||
format(
|
||||
new Date(proposal.terms.enactmentDatetime),
|
||||
DATE_FORMAT_DETAILED
|
||||
),
|
||||
});
|
||||
)}
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_OPEN: {
|
||||
voteDetails = (
|
||||
<span className={nowToEnactmentInHours < 6 ? 'text-vega-pink' : ''}>
|
||||
{formatDistanceToNowStrict(new Date(proposal?.terms.closingDatetime))}{' '}
|
||||
{t('left to vote')}
|
||||
</span>
|
||||
);
|
||||
voteDetails = (voteState === 'Yes' && (
|
||||
<>
|
||||
{t('youVoted')} {t('voteState_Yes')}
|
||||
</>
|
||||
)) ||
|
||||
(voteState === 'No' && (
|
||||
<>
|
||||
{t('youVoted')} {t('voteState_No')}
|
||||
</>
|
||||
)) || (
|
||||
<>
|
||||
{formatDistanceToNowStrict(
|
||||
new Date(proposal?.terms.closingDatetime)
|
||||
)}{' '}
|
||||
{t('left to vote')}
|
||||
</>
|
||||
);
|
||||
voteStatus =
|
||||
(isUpdateMarket &&
|
||||
(updateMarketWillPass ? (
|
||||
<>
|
||||
{t('currentlySetTo')} {t('pass')} {updateMarketVotePassMethod}
|
||||
{t('Set to')}{' '}
|
||||
<StatusPass>
|
||||
{t('pass')} {updateMarketVotePassMethod}
|
||||
</StatusPass>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{t('currentlySetTo')} {t('fail')}
|
||||
{t('Set to')} {t('fail')}
|
||||
</>
|
||||
))) ||
|
||||
(!participationMet && <ParticipationNotReached />) ||
|
||||
(!majorityMet && <MajorityNotReached />) ||
|
||||
(willPassByTokenVote ? (
|
||||
<>
|
||||
{t('currentlySetTo')} {t('pass')}
|
||||
{t('Set to')} {t('pass')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{t('currentlySetTo')} {t('fail')}
|
||||
{t('Set to')} {t('fail')}
|
||||
</>
|
||||
));
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_DECLINED: {
|
||||
voteStatus =
|
||||
(!participationMet && <ParticipationNotReached />) ||
|
||||
(!majorityMet && <MajorityNotReached />);
|
||||
break;
|
||||
}
|
||||
case ProposalState.STATE_REJECTED: {
|
||||
voteStatus = proposal?.rejectionReason && (
|
||||
<>{t(ProposalRejectionReasonMapping[proposal.rejectionReason])}</>
|
||||
@@ -114,17 +155,29 @@ export const ProposalsListItemDetails = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-4 items-start text-sm">
|
||||
<div className="flex items-center gap-2 text-vega-light-300 mb-2">
|
||||
{voteDetails && <span data-testid="vote-details">{voteDetails}</span>}
|
||||
{voteDetails && voteStatus && <span>·</span>}
|
||||
{voteStatus && <span data-testid="vote-status">{voteStatus}</span>}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-[1fr_auto] mt-4 items-start gap-2 text-sm">
|
||||
{voteDetails && (
|
||||
<div
|
||||
className="col-start-1 row-start-2 text-vega-light-300"
|
||||
data-testid="vote-details"
|
||||
>
|
||||
{voteDetails}
|
||||
</div>
|
||||
)}
|
||||
{voteStatus && (
|
||||
<div
|
||||
className="col-start-2 row-start-1 justify-self-end"
|
||||
data-testid="vote-status"
|
||||
>
|
||||
{voteStatus}
|
||||
</div>
|
||||
)}
|
||||
{proposal?.id && (
|
||||
<Link to={`${Routes.PROPOSALS}/${proposal.id}`}>
|
||||
<Button data-testid="view-proposal-btn">{t('viewDetails')}</Button>
|
||||
</Link>
|
||||
<div className="col-start-2 row-start-2 justify-self-end">
|
||||
<Link to={`${Routes.PROPOSALS}/${proposal.id}`}>
|
||||
<Button data-testid="view-proposal-btn">{t('View')}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user