Compare commits

..
309 changed files with 2988 additions and 6541 deletions
@@ -82,38 +82,3 @@ jobs:
https://${{ env.IPFS_V1 }}.ipfs.dweb.link/
https://${{ env.IPFS_V1 }}.ipfs.cf-ipfs.com/
ipfs://${{ env.IPFS_V0 }}/
- name: Ensure 'Released' label exists
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
REPO="${{ github.repository }}"
LABEL_EXIST=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$REPO/labels/Released")
if [[ "$LABEL_EXIST" == *"Not Found"* ]]; then
curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-X POST "https://api.github.com/repos/$REPO/labels" \
-d '{"name": "Released", "color": "FFFFFF"}'
fi
- name: Extract issues from release notes
id: extract-issues
run: |
ISSUES=$(echo "${{ github.event.release.body }}" | grep -o -E '#[0-9]+' | tr -d '#' | jq -R . | jq -cs .)
echo "Issues to label: $ISSUES"
echo "::set-output name=issue_numbers::$ISSUES"
- name: Add 'Released' label to issues
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ISSUE_NUMBERS="${{ steps.extract-issues.outputs.issue_numbers }}"
REPO="${{ github.repository }}"
for ISSUE in $(echo "$ISSUE_NUMBERS" | jq -r '.[]'); do
curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-X POST "https://api.github.com/repos/$REPO/issues/$ISSUE/labels" \
-d '{"labels": ["Released"]}'
done
+10 -34
View File
@@ -5,7 +5,6 @@ on:
branches:
- release/*
- develop
- main
pull_request:
types:
- opened
@@ -170,48 +169,25 @@ jobs:
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
preview_tools: ${{ env.PREVIEW_TOOLS }}
check-e2e-needed:
runs-on: ubuntu-latest
needs: build-sources
name: '(CI) check if e2e needed'
outputs:
run-tests: ${{ steps.check-test.outputs.e2e-needed }}
steps:
- name: Check branch
id: check-test
run: |
if [[ "${{ github.base_ref }}" == "develop" ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "main" ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
else
echo "e2e-needed=false" >> $GITHUB_OUTPUT
fi
- name: Print result
run: |
echo "e2e-needed: ${{ steps.check-test.outputs.e2e-needed }}"
# console-e2e:
# needs: build-sources
# name: '(CI) console python'
# uses: ./.github/workflows/console-test-run.yml
# secrets: inherit
# if: ${{ contains(fromJSON(needs.build-sources.outputs.projects), 'trading') && github.event_name == 'pull_request' }}
# with:
# github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
cypress:
needs: [build-sources, check-e2e-needed]
needs: build-sources
name: '(CI) cypress'
if: ${{ needs.check-e2e-needed.outputs.run-tests == 'true' }}
# if: ${{ needs.build-sources.outputs.projects-e2e != '[]' }}
uses: ./.github/workflows/cypress-run.yml
secrets: inherit
with:
projects: ${{ needs.build-sources.outputs.projects-e2e }}
tags: '@smoke'
console-e2e:
needs: [build-sources, check-e2e-needed]
name: '(CI) console python'
uses: ./.github/workflows/console-test-run.yml
secrets: inherit
if: needs.check-e2e-needed.outputs.run-tests == 'true' && contains(needs.build-sources.outputs.projects, 'trading')
with:
github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
publish-dist:
needs: build-sources
name: '(CD) publish dist'
-29
View File
@@ -1,29 +0,0 @@
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#managing-caches
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
+45 -117
View File
@@ -1,5 +1,8 @@
name: (CI) Console tests
env:
VEGA_VERSION: v0.72.14
on:
workflow_call:
inputs:
@@ -16,9 +19,9 @@ on:
- develop
jobs:
create-docker-image:
name: Create docker image for console-test
runs-on: ubuntu-22.04
run-tests:
name: run-tests
runs-on: 8-cores
timeout-minutes: 20
steps:
#----------------------------------------------
@@ -55,105 +58,23 @@ jobs:
#----------------------------------------------
# build trading
#----------------------------------------------
- name: Build trading app
- name: Build affected spec
run: |
yarn env-cmd -f ./apps/trading/.env.stagnet1 yarn nx export trading
DIST_LOCATION=dist/apps/trading/exported
mv $DIST_LOCATION dist-result
tree dist-result
#----------------------------------------------
# export trading app docker image
# run trading server
#----------------------------------------------
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export to local Docker
id: docker_build
uses: docker/build-push-action@v5
with:
context: .
file: docker/node-outside-docker.Dockerfile
load: true
build-args: |
APP=trading
ENV_NAME=stagnet1
tags: ci/trading:local
outputs: type=docker,dest=/tmp/console-image.tar
- name: Verify docker image created
- name: Run trading server
run: |
echo ${{ steps.docker_build.outputs.digest }}
echo ${{ steps.docker_build.outputs.imageid }}
- name: Upload docker image for console-test usage
uses: actions/upload-artifact@v3
with:
name: console-image
path: /tmp/console-image.tar
console-test-branch:
name: Choose console-test branch to run on
runs-on: ubuntu-22.04
timeout-minutes: 5
outputs:
console-branch: ${{ steps.output-step.outputs.branch }}
steps:
- name: Workflow dispatch input
id: dispatch-step
if: github.event_name == 'workflow_dispatch'
run: echo "branch=${{ inputs.console-test-branch }}" >> $GITHUB_OUTPUT
- name: Print Workflow dispatch input
if: github.event_name == 'workflow_dispatch'
run: echo ${{ steps.dispatch-step.outputs.branch }}
- name: Workflow_call input
id: workflow_call-step
if: github.event_name != 'workflow_dispatch'
run: |
if [[ "${{ github.base_ref }}" == "main" ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "develop" && "${{ github.ref_name }}" == "main" ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
else
echo "branch=develop" >> $GITHUB_OUTPUT
fi
- name: Print Workflow_call input
if: github.event_name != 'workflow_dispatch'
run: echo ${{ steps.workflow_call-step.outputs.branch }}
- name: Set output
id: output-step
run: echo "branch=${{ steps.dispatch-step.outputs.branch || steps.workflow_call-step.outputs.branch }}" >> $GITHUB_OUTPUT
- name: Print final output
run: echo ${{ steps.output-step.outputs.branch }}
run-tests:
name: run-tests
runs-on: 8-cores
needs: [create-docker-image, console-test-branch]
timeout-minutes: 20
steps:
docker run -d -p 80:4200 -v $PWD/docker/nginx.conf:/etc/nginx/conf.d/default.conf -v $PWD/dist/apps/trading/exported:/usr/share/nginx/html nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
sleep 5
docker ps
#----------------------------------------------
# load docker image
# check if container persists between runs
#----------------------------------------------
- name: Download docker image from previous job
uses: actions/download-artifact@v3
with:
name: console-image
path: /tmp
- name: Load Docker image
- name: Check server
run: |
docker load --input /tmp/console-image.tar
docker image ls -a
docker ps
#----------------------------------------------
# check-out tests repo
#----------------------------------------------
@@ -161,55 +82,62 @@ jobs:
uses: actions/checkout@v3
with:
repository: vegaprotocol/console-test
ref: ${{ needs.console-test-branch.outputs.console-branch }}
ref: ${{ inputs.console-test-branch }}
path: './console-test'
- name: Load console test envs
id: console-test-env
uses: falti/dotenv-action@v1.0.4
with:
path: '.env.${{ needs.console-test-branch.outputs.console-branch }}'
path: './console-test/.env.${{ inputs.console-test-branch }}'
export-variables: true
keys-case: upper
log-variables: true
#----------------------------------------------
# ----- Setup python -----
#----------------------------------------------
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
#----------------------------------------------
# ----- install & configure poetry -----
#----------------------------------------------
- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
virtualenvs-path: .venv
#----------------------------------------------
# install python dependencies
# install dependencies
#----------------------------------------------
- name: Install dependencies
working-directory: ./console-test
run: poetry install --no-interaction --no-root
#----------------------------------------------
# install vega binaries
# find vega binaries path
#----------------------------------------------
- name: Find vega binaries path
id: vega_bin_path
working-directory: ./console-test
run: echo path=$(poetry run python -c "import vega_sim; print(vega_sim.vega_bin_path)") >> $GITHUB_OUTPUT
#----------------------------------------------
# vega binaries cache
#----------------------------------------------
- name: Vega binaries cache
uses: actions/cache@v3
id: vega_binaries_cache
with:
path: ${{ steps.vega_bin_path.outputs.path }}
key: ${{ runner.os }}-vega-binaries-${{ env.VEGA_VERSION }}
#----------------------------------------------
# install vega binaries
#----------------------------------------------
- name: Install vega binaries
working-directory: ./console-test
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
#----------------------------------------------
# install playwright
#----------------------------------------------
- name: install playwright
run: poetry run playwright install --with-deps chromium
working-directory: ./console-test
#----------------------------------------------
# run tests
#----------------------------------------------
- name: Run tests
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
working-directory: ./console-test
run: poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
- name: Check files
run: |
ls -al .
ls -al console-test
#----------------------------------------------
# upload traces
#----------------------------------------------
+3 -4
View File
@@ -21,11 +21,11 @@ jobs:
- name: Check branch
id: step
run: |
if [[ "${{ github.base_ref }}" == "main" ]]; then
if [ ${{ github.base_ref }} == 'main' ]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "develop" && "${{ github.ref_name }}" == "main" ]]; then
elif [ ${{ github.base_ref }} == 'develop' ] && [ ${{ github.ref_name }} == 'main' ]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
elif [ ${{ github.event_name }} == 'push' ] && [ ${{ contains(github.ref_name, 'release/mainnet') }} ]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
else
echo "runner=self-hosted-runner" >> $GITHUB_OUTPUT
@@ -85,7 +85,6 @@ jobs:
- name: Run Vegacapsule network and Vega wallet
id: setup-vega
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
timeout-minutes: 10
######
## Run some tests
+3 -3
View File
@@ -63,7 +63,7 @@ jobs:
echo IS_IPFS_RELEASE=true >> $GITHUB_ENV
- name: Is S3 Release
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' && github.ref_name != 'main'}}
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' }}
run: |
echo IS_S3_RELEASE=true >> $GITHUB_ENV
@@ -195,7 +195,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' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true && main' || '' }}
- name: Publish dist as docker image (ghcr - retry)
uses: docker/build-push-action@v3
@@ -222,7 +222,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' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true && main' || '' }}
# bucket creation in github.com/vegaprotocol/terraform//frontend
- name: Publish dist to s3
@@ -36,7 +36,7 @@ context('Market page', { tags: '@regression' }, function () {
it('Able to go to market details page', function () {
cy.navigate_to('markets');
cy.contains('Test market 1').click();
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);
@@ -90,7 +90,7 @@ context('Market page', { tags: '@regression' }, function () {
// Liquidity price range
cy.validate_element_from_table(
'Liquidity Price Range',
'95.00% of mid price'
'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');
@@ -40,7 +40,7 @@ context.skip('Node switcher', { tags: '@regression' }, function () {
const errorTypeTxt = 'Error: invalid url';
const nodeErrorTxt = 'fakeUrl is not a valid url.';
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId('node-url-custom').click();
cy.getByTestId(customNodeBtn).within(() => {
cy.get('input').clear().type('fakeUrl');
@@ -3,7 +3,6 @@ import type { MarketInfoWithData } from '@vegaprotocol/markets';
import {
LiquidityPriceRangeInfoPanel,
LiquiditySLAParametersInfoPanel,
MarginScalingFactorsPanel,
PriceMonitoringBoundsInfoPanel,
SuccessionLineInfoPanel,
getDataSourceSpecForSettlementData,
@@ -18,6 +17,7 @@ import {
OracleInfoPanel,
RiskFactorsInfoPanel,
RiskModelInfoPanel,
RiskParametersInfoPanel,
SettlementAssetInfoPanel,
} from '@vegaprotocol/markets';
import { MarketInfoTable } from '@vegaprotocol/markets';
@@ -69,8 +69,8 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
<MetadataInfoPanel market={market} />
<h2 className={headerClassName}>{t('Risk model')}</h2>
<RiskModelInfoPanel market={market} />
<h2 className={headerClassName}>{t('Margin scaling factors')}</h2>
<MarginScalingFactorsPanel market={market} />
<h2 className={headerClassName}>{t('Risk parameters')}</h2>
<RiskParametersInfoPanel market={market} />
<h2 className={headerClassName}>{t('Risk factors')}</h2>
<RiskFactorsInfoPanel market={market} />
{(market.data?.priceMonitoringBounds || []).map((trigger, i) => (
@@ -49,37 +49,6 @@ fragment ExplorerOracleDataSource on OracleSpec {
}
... on DataSourceDefinitionExternal {
sourceType {
... on EthCallSpec {
abi
args
method
requiredConfirmations
address
normalisers {
name
expression
}
trigger {
trigger {
... on EthTimeTrigger {
initial
every
until
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
... on DataSourceSpecConfiguration {
signers {
signer {
+3 -34
View File
@@ -5,19 +5,19 @@ import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', 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 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, 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> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec' } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, 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> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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> | 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec' } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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> | 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, 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> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec' } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', 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 ExplorerOracleDataConnectionFragmentDoc = gql`
fragment ExplorerOracleDataConnection on OracleSpec {
@@ -72,37 +72,6 @@ export const ExplorerOracleDataSourceFragmentDoc = gql`
}
... on DataSourceDefinitionExternal {
sourceType {
... on EthCallSpec {
abi
args
method
requiredConfirmations
address
normalisers {
name
expression
}
trigger {
trigger {
... on EthTimeTrigger {
initial
every
until
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
... on DataSourceSpecConfiguration {
signers {
signer {
@@ -8,9 +8,7 @@ import { useScrollToLocation } from '../../../hooks/scroll-to-location';
import filter from 'recursive-key-filter';
const Oracles = () => {
const { data, loading, error } = useExplorerOracleSpecsQuery({
errorPolicy: 'ignore',
});
const { data, loading, error } = useExplorerOracleSpecsQuery();
useDocumentTitle(['Oracles']);
useScrollToLocation();
-5
View File
@@ -22,11 +22,6 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
NX_SUCCESSOR_MARKETS=true
NX_PRODUCT_PERPETUALS=true
NX_REFERRALS=true
NX_UPDATE_MARKET_STATE=true
NX_GOVERNANCE_TRANSFERS=true
NX_VOLUME_DISCOUNTS=true
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
-2
View File
@@ -6,5 +6,3 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true
-2
View File
@@ -6,5 +6,3 @@ NX_ETHERSCAN_URL=https://etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_PRODUCT_PERPETUALS=false
NX_UPDATE_MARKET_STATE=false
NX_REFERRALS=false
NX_VOLUME_DISCOUNTS=false
-2
View File
@@ -6,5 +6,3 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true
@@ -0,0 +1,21 @@
{
"rationale": {
"title": "Add USDT Coin (USDT)",
"description": "Proposal to add USDT Coin (USDT) as an asset"
},
"terms": {
"newAsset": {
"changes": {
"name": "USDT Coin",
"symbol": "USDT",
"decimals": "18",
"quantum": "1",
"erc20": {
"contractAddress": "0xb404c51bbc10dcbe948077f18a4b8e553d160084"
}
}
},
"closingTimestamp": 1662374250,
"enactmentTimestamp": 1662460650
}
}
@@ -1,15 +0,0 @@
{
"rationale": {
"title": "Governance cancel transfer proposal",
"description": "Rejected cancel transfer proposal"
},
"terms": {
"cancelTransfer": {
"changes": {
"transferId": "invalid transfer id"
}
},
"closingTimestamp": 0,
"enactmentTimestamp": 0
}
}
@@ -1,16 +0,0 @@
{
"rationale": {
"title": "Market resume test",
"description": "E2E test for market resume proposal"
},
"terms": {
"updateMarketState": {
"changes": {
"marketId": "b33bb4157e12355db22e41f277ddd0c10104dec29a4d6960bbcb96d186c40cbd",
"updateType": "MARKET_STATE_UPDATE_TYPE_RESUME"
}
},
"closingTimestamp": 0,
"enactmentTimestamp": 0
}
}
@@ -1,16 +0,0 @@
{
"rationale": {
"title": "Market suspended test",
"description": "E2E test for market suspended proposal"
},
"terms": {
"updateMarketState": {
"changes": {
"marketId": "",
"updateType": "MARKET_STATE_UPDATE_TYPE_SUSPEND"
}
},
"closingTimestamp": 0,
"enactmentTimestamp": 0
}
}
@@ -1,17 +0,0 @@
{
"rationale": {
"title": "Market terminate test",
"description": "E2E test for market terminate proposal"
},
"terms": {
"updateMarketState": {
"changes": {
"marketId": "",
"updateType": "MARKET_STATE_UPDATE_TYPE_TERMINATE",
"price": "100"
}
},
"closingTimestamp": 0,
"enactmentTimestamp": 0
}
}
@@ -0,0 +1,85 @@
{
"instrument": {
"code": "Token.24h",
"future": {
"quoteName": "fBTC",
"dataSourceSpecForSettlementData": {
"external": {
"oracle": {
"signers": [
{
"pubKey": {
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "prices.BTC.value",
"type": "TYPE_INTEGER"
},
"conditions": [
{
"operator": "OPERATOR_GREATER_THAN",
"value": "0"
}
]
}
]
}
}
},
"dataSourceSpecForTradingTermination": {
"external": {
"oracle": {
"signers": [
{
"pubKey": {
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{
"operator": "OPERATOR_GREATER_THAN_OR_EQUAL",
"value": "1648684800000000000"
}
]
}
]
}
}
},
"dataSourceSpecBinding": {
"settlementDataProperty": "prices.BTC.value",
"tradingTerminationProperty": "trading.terminated.ETH5"
}
}
},
"metadata": ["sector:energy", "sector:food", "source:docs.vega.xyz"],
"priceMonitoringParameters": {
"triggers": [
{
"horizon": "43200",
"probability": "0.9999999",
"auctionExtension": "600"
}
]
},
"logNormal": {
"tau": 0.0001140771161,
"riskAversionParameter": 0.001,
"params": {
"mu": 0,
"r": 0.016,
"sigma": 0.3
}
}
}
@@ -27,16 +27,12 @@ import {
} from '../../../../governance-e2e/src/support/staking.functions';
import { ethereumWalletConnect } from '../../../../governance-e2e/src/support/wallet-eth.functions';
import {
depositAsset,
switchVegaWalletPubKey,
vegaWalletSetSpecifiedApprovalAmount,
} from '../../support/wallet-functions';
import type { testFreeformProposal } from '../../support/common-interfaces';
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
import {
createGovernanceTransferProposalTxBody,
createSuccessorMarketProposalTxBody,
} from '../../support/proposal.functions';
import { createSuccessorMarketProposalTxBody } from '../../support/proposal.functions';
const proposalListItem = '[data-testid="proposals-list-item"]';
const participationNotMet = 'token-participation-not-met';
@@ -55,7 +51,6 @@ const openProposals = 'open-proposals';
const viewProposalButton = 'view-proposal-btn';
const proposalTermsToggle = 'proposal-json-toggle';
const marketDataToggle = 'proposal-market-data-toggle';
const governanceTransferToggle = 'proposal-transfer-details';
const marketProposalType = 'proposal-type';
describe(
@@ -65,17 +60,6 @@ describe(
before('connect wallets and set approval limit', function () {
cy.visit('/');
ethereumWalletConnect();
cy.createMarket();
navigateTo(navigation.proposals);
cy.getByTestId('closed-proposals').within(() => {
cy.contains('Add Lorem Ipsum market')
.parentsUntil(proposalListItem)
.last()
.within(() => {
cy.getByTestId(viewProposalButton).click();
});
});
getProposalInformationFromTable('ID').invoke('text').as('parentMarketId');
});
beforeEach('visit proposals tab', function () {
@@ -314,6 +298,9 @@ describe(
});
it('Able to see successor market details with new and updated values', function () {
cy.createMarket();
cy.reload();
waitForSpinner();
cy.getByTestId('closed-proposals').within(() => {
cy.contains('Add Lorem Ipsum market')
.parentsUntil(proposalListItem)
@@ -322,9 +309,14 @@ describe(
cy.getByTestId(viewProposalButton).click();
});
});
cy.VegaWalletSubmitProposal(
createSuccessorMarketProposalTxBody(this.parentMarketId)
);
getProposalInformationFromTable('ID')
.invoke('text')
.as('parentMarketId')
.then(() => {
cy.VegaWalletSubmitProposal(
createSuccessorMarketProposalTxBody(this.parentMarketId)
);
});
navigateTo(navigation.proposals);
cy.reload();
getProposalFromTitle('Test successor market proposal details').within(
@@ -438,165 +430,9 @@ describe(
'contain.text',
'0.3'
);
getProposalDetailsValue('Min Probability Of Trading LP Orders').should(
'contain.text',
'1e-8'
);
});
it('Able to see suspended market proposal', function () {
const proposalPath = 'src/fixtures/proposals/suspend-market-raw.json';
const enactmentTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
});
getProposalFromTitle('Market suspended test').within(() => {
cy.getByTestId(marketProposalType).should(
'have.text',
'Suspend market'
);
cy.getByTestId(viewProposalButton).click();
});
cy.getByTestId(marketProposalType).should('have.text', 'Suspend market');
cy.getByTestId(marketDataToggle).click();
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
.and('eq', this.parentMarketId);
});
});
it('Able to see resume market proposal', function () {
const proposalPath = 'src/fixtures/proposals/resume-market-raw.json';
const enactmentTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
});
getProposalFromTitle('Market resume test').within(() => {
cy.getByTestId(marketProposalType).should('have.text', 'Resume market');
cy.getByTestId(viewProposalButton).click();
});
cy.getByTestId(marketProposalType).should('have.text', 'Resume market');
cy.getByTestId(marketDataToggle).click();
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
.and('eq', this.parentMarketId);
});
});
it('Able to see terminate market proposal', function () {
const proposalPath = 'src/fixtures/proposals/terminate-market-raw.json';
const enactmentTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
});
getProposalFromTitle('Market terminate test').within(() => {
cy.getByTestId(marketProposalType).should(
'have.text',
'Terminate market'
);
cy.getByTestId(viewProposalButton).click();
});
cy.getByTestId(marketProposalType).should(
'have.text',
'Terminate market'
);
cy.getByTestId(marketDataToggle).click();
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
.and('eq', this.parentMarketId);
getProposalDetailsValue('Termination Price').should(
'contain.text',
'0.001 fUSDC'
);
});
});
it('Able to see governance transfer proposal', function () {
const vegaAssetAddress = '0x67175Da1D5e966e40D11c4B2519392B2058373de';
depositAsset(vegaAssetAddress, '1000', 18);
cy.getByTestId('currency-title', Cypress.env('txTimeout')).should(
'contain.text',
'Collateral'
);
cy.VegaWalletTopUpNetworkAccount('100');
cy.VegaWalletSubmitProposal(createGovernanceTransferProposalTxBody());
cy.reload();
getProposalFromTitle('Governance transfer proposal').within(() => {
cy.getByTestId(marketProposalType).should('have.text', 'NewTransfer');
cy.getByTestId(viewProposalButton).click();
});
cy.getByTestId(marketProposalType).should('have.text', 'NewTransfer');
cy.getByTestId(governanceTransferToggle).click();
cy.getByTestId('proposal-transfer-details-table').within(() => {
getProposalInformationFromTable('Source Type')
.invoke('text')
.and('eq', 'Network Treasury');
getProposalInformationFromTable('Destination')
.invoke('text')
.and('eq', Cypress.env('vegaWalletPublicKey'));
getProposalInformationFromTable('Asset')
.invoke('text')
.and('eq', 'VEGA');
getProposalInformationFromTable('Fraction Of Balance')
.invoke('text')
.and('eq', '50%');
getProposalInformationFromTable('Amount')
.invoke('text')
.and('eq', '100.00');
getProposalInformationFromTable('Transfer Type')
.invoke('text')
.and('eq', 'All or nothing');
getProposalInformationFromTable('Kind')
.invoke('text')
.and('eq', 'One off');
});
});
it(' Able to see cancel transfer proposal - rejected', function () {
const proposalPath = 'src/fixtures/proposals/cancel-transfer-raw.json';
const enactmentTimestamp =
createTenDigitUnixTimeStampForSpecifiedDays(11);
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(10);
submitUniqueRawProposal({
proposalBody: proposalPath,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
submit: false,
});
cy.getByTestId('proposal-submit').should('be.visible').click();
cy.getByTestId('dialog-title').should('have.text', 'Proposal rejected');
cy.getByTestId('icon-cross').last().click();
navigateTo(navigation.proposals);
cy.get('[href="/proposals/rejected"]').click();
getProposalFromTitle('Governance cancel transfer proposal').within(() => {
cy.getByTestId(marketProposalType).should(
'have.text',
'CancelTransfer'
);
cy.getByTestId(viewProposalButton).click();
});
cy.getByTestId(marketProposalType).should('have.text', 'CancelTransfer');
getProposalInformationFromTable('Error details')
.invoke('text')
.and('eq', 'Governance transfer invalid transfer id not found');
getProposalInformationFromTable('transferId')
.invoke('text')
.and('eq', 'invalid transfer id');
getProposalDetailsValue(
'Minimum Probability Of Trading LP Orders'
).should('contain.text', '1e-8');
});
}
);
@@ -310,9 +310,7 @@ context(
closeStakingDialog();
navigateTo(navigation.validators);
clickOnValidatorFromList(0);
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click({
force: true,
});
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click();
cy.getByTestId(stakeTokenAmountInputBox).type('-0.1');
cy.contains('Waiting for next epoch to start', epochTimeout);
cy.getByTestId(stakeTokenSubmitButton)
@@ -333,7 +331,7 @@ context(
closeStakingDialog();
navigateTo(navigation.validators);
clickOnValidatorFromList(0);
cy.getByTestId(stakeRemoveStakeRadioButton).click({ force: true });
cy.getByTestId(stakeRemoveStakeRadioButton).click();
cy.getByTestId(stakeTokenAmountInputBox).type('4');
cy.contains('Waiting for next epoch to start', epochTimeout);
cy.getByTestId(stakeTokenSubmitButton)
@@ -424,7 +422,7 @@ context(
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
});
it.skip('Associating wallet tokens - when some already staked - auto stakes tokens to staked validator', function () {
it('Associating wallet tokens - when some already staked - auto stakes tokens to staked validator', function () {
// 1002-STKE-004
stakingPageAssociateTokens('3');
verifyUnstakedBalance(3.0);
@@ -438,7 +436,7 @@ context(
verifyStakedBalance(7.0);
});
it.skip('Associating vesting contract tokens - when some already staked - auto stakes tokens to staked validator', function () {
it('Associating vesting contract tokens - when some already staked - auto stakes tokens to staked validator', function () {
// 1002-STKE-004
stakingPageAssociateTokens('3', { type: 'contract' });
verifyUnstakedBalance(3.0);
@@ -452,7 +450,7 @@ context(
verifyStakedBalance(7.0);
});
it.skip('Associating vesting contract tokens - when wallet tokens already staked - auto stakes tokens to staked validator', function () {
it('Associating vesting contract tokens - when wallet tokens already staked - auto stakes tokens to staked validator', function () {
// 1002-STKE-004
stakingPageAssociateTokens('3', { type: 'wallet' });
verifyUnstakedBalance(3.0);
@@ -466,7 +464,7 @@ context(
verifyStakedBalance(7.0);
});
it.skip('Associating tokens - with multiple validators already staked - auto stakes to staked validators - abiding by existing stake ratio', function () {
it('Associating tokens - with multiple validators already staked - auto stakes to staked validators - abiding by existing stake ratio', function () {
// 1002-STKE-004
stakingPageAssociateTokens('6');
verifyUnstakedBalance(6.0);
@@ -156,7 +156,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
cy.getByTestId('subscription-cell').should('have.text', 'Yes');
});
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId('node-url-custom').click();
cy.get('input').should('exist');
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('icon-cross').click();
@@ -74,12 +74,25 @@ context(
});
it('should be able to see a working link for - find out more about Vega governance', function () {
// 3001-VOTE-001 // 3002-PROP-001
// 3001-VOTE-001
cy.getByTestId(proposalDocumentationLink)
.should('be.visible')
.and('have.text', 'Find out more about Vega governance')
.and('have.attr', 'href')
.and('equal', governanceDocsUrl);
// 3002-PROP-001
cy.request(governanceDocsUrl)
.its('body')
.then((body) => {
if (!body.includes('Govern the network')) {
assert.include(
body,
'Govern the network',
`Checking that governance link destination includes 'Govern the network' text`
);
}
});
});
// 3007-PNE-021
@@ -11,6 +11,7 @@ import {
waitForBeginningOfEpoch,
} from '../../support/staking.functions';
import { previousEpochData } from '../../fixtures/mocks/previous-epoch';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
const guideLink = 'staking-guide-link';
const validatorTitle = 'validator-node-title';
@@ -37,11 +38,17 @@ const txTimeout = Cypress.env('txTimeout');
context('Validators Page - verify elements on page', function () {
before('navigate to validators page', () => {
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.visit('/validators');
});
beforeEach(() => {
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
});
describe('with wallets disconnected', { tags: '@smoke' }, function () {
@@ -182,7 +189,10 @@ context('Validators Page - verify elements on page', function () {
{ tags: '@smoke' },
function () {
before('connect wallets and click on validator', function () {
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.visit('/validators');
cy.connectVegaWallet();
clickOnValidatorFromList(0);
@@ -4,6 +4,8 @@ import {
vegaWalletFaucetAssetsWithoutCheck,
vegaWalletTeardown,
} from '../../support/wallet-functions';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
const walletContainer = 'aside [data-testid="vega-wallet"]';
const walletHeader = '[data-testid="wallet-header"] h1';
@@ -86,7 +88,10 @@ context(
describe('when vega wallet connected', function () {
before('connect vega wallet', function () {
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.visit('/');
cy.wait('@ChainId');
cy.connectVegaWallet();
@@ -271,7 +276,10 @@ context(
];
before('faucet assets to connected vega wallet', function () {
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
for (const { id, amount } of assets) {
vegaWalletFaucetAssetsWithoutCheck(id, amount, vegaWalletPublicKey);
}
@@ -54,7 +54,6 @@ export function submitUniqueRawProposal(proposalFields: {
proposalBody?: string;
proposalTitle?: string;
proposalDescription?: string;
updateMarketId?: string;
closingTimestamp?: number;
enactmentTimestamp?: number;
submit?: boolean;
@@ -72,10 +71,6 @@ export function submitUniqueRawProposal(proposalFields: {
if (proposalFields.proposalDescription) {
rawProposal.rationale.description = proposalFields.proposalDescription;
}
if (proposalFields.updateMarketId) {
rawProposal.terms.updateMarketState.changes.marketId =
proposalFields.updateMarketId;
}
if (proposalFields.closingTimestamp) {
rawProposal.terms.closingTimestamp = proposalFields.closingTimestamp;
} else if (
+6 -1
View File
@@ -9,6 +9,8 @@ import './wallet-functions.ts';
import './proposal.functions.ts';
import 'cypress-mochawesome-reporter/register';
import registerCypressGrep from '@cypress/grep';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
import { turnTelemetryOff } from './common.functions.ts';
registerCypressGrep();
@@ -27,7 +29,10 @@ before(() => {
// // Ensuring the telemetry modal doesn't disrupt the tests
turnTelemetryOff();
// Mock chainId fetch which happens on every page for wallet connection
cy.mockChainId();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
// Self stake validators so they are displayed
cy.validatorsSelfDelegate();
});
@@ -1,10 +1,9 @@
import { addDays, addSeconds, millisecondsToSeconds } from 'date-fns';
import { addSeconds, millisecondsToSeconds } from 'date-fns';
import type { ProposalSubmissionBody } from '@vegaprotocol/wallet';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { upgradeProposalsData } from '../fixtures/mocks/network-upgrade';
import { proposalsData } from '../fixtures/mocks/proposals';
import { nodeData } from '../fixtures/mocks/nodes';
import { AccountType, GovernanceTransferType } from '@vegaprotocol/types';
export function createUpdateNetworkProposalTxBody(): ProposalSubmissionBody {
const MIN_CLOSE_SEC = 5;
@@ -359,46 +358,6 @@ export function createSuccessorMarketProposalTxBody(
};
}
export function createGovernanceTransferProposalTxBody(): ProposalSubmissionBody {
const MIN_CLOSE_SEC = 5;
const MIN_ENACT_SEC = 7;
const closingDate = addDays(new Date(), MIN_CLOSE_SEC);
const enactmentDate = addDays(closingDate, MIN_ENACT_SEC);
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
const destination = Cypress.env('vegaWalletPublicKey');
return {
proposalSubmission: {
rationale: {
title: 'Governance transfer proposal',
description: 'E2E test for transfer proposal test',
},
terms: {
newTransfer: {
changes: {
fractionOfBalance: '0.5',
amount: '100' + '0'.repeat(18),
sourceType: AccountType.ACCOUNT_TYPE_NETWORK_TREASURY,
source: '',
transferType:
GovernanceTransferType.GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING,
destinationType: AccountType.ACCOUNT_TYPE_GENERAL,
destination,
asset:
'b4f2726571fbe8e33b442dc92ed2d7f0d810e21835b7371a7915a365f07ccd9b',
oneOff: {
deliverOn: '0',
},
},
},
closingTimestamp,
enactmentTimestamp,
},
},
};
}
export function mockNetworkUpgradeProposal() {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'Nodes', nodeData);
@@ -46,7 +46,7 @@ export function stakingValidatorPageAddStake(stake: string) {
export function stakingValidatorPageRemoveStake(stake: string) {
cy.highlight(`Removing a stake of ${stake}`);
cy.get(removeStakeRadioButton, epochTimeout).click({ force: true });
cy.get(removeStakeRadioButton, epochTimeout).click();
cy.get(tokenAmountInputBox).type(stake);
waitForBeginningOfEpoch();
cy.get(tokenSubmitButton)
@@ -70,13 +70,9 @@ export function stakingPageAssociateTokens(
cy.highlight(`Associating ${amount} tokens from ${type}`);
cy.get(ethWalletAssociateButton).first().click();
if (type === 'wallet') {
cy.get(associateWalletRadioButton, { timeout: 30000 }).click({
force: true,
});
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
} else if (type === 'contract') {
cy.get(associateContractRadioButton, { timeout: 30000 }).click({
force: true,
});
cy.get(associateContractRadioButton, { timeout: 30000 }).click();
} else {
cy.highlight(`${type} is not association option`);
}
@@ -41,9 +41,6 @@ export async function depositAsset(
) {
// Approve asset
const faucet = new Token(assetEthAddress, signer);
// Wait needed to allow Eth chain to catch up
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(4000);
cy.wrap(
faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(decimalPlaces + 1)),
transactionTimeout
-4
View File
@@ -8,7 +8,6 @@ NX_FAIRGROUND=false
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_WALLET_URL=http://localhost:1789
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
@@ -35,6 +34,3 @@ NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_PRODUCT_PERPETUALS=false
NX_UPDATE_MARKET_STATE=false
NX_REFERRALS=false
NX_GOVERNANCE_TRANSFERS=false
NX_VOLUME_DISCOUNTS=false
-2
View File
@@ -35,5 +35,3 @@ NX_SUCCESSOR_MARKETS=false
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true
-2
View File
@@ -27,5 +27,3 @@ NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true
+1 -3
View File
@@ -17,7 +17,7 @@ NX_VEGA_REST_URL=https://api.vega.community/api/v2/
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
@@ -26,5 +26,3 @@ NX_SUCCESSOR_MARKETS=false
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=false
NX_UPDATE_MARKET_STATE=false
NX_REFERRALS=false
NX_VOLUME_DISCOUNTS=false
-2
View File
@@ -25,5 +25,3 @@ NX_SUCCESSOR_MARKETS=false
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=false
NX_UPDATE_MARKET_STATE=false
NX_REFERRALS=false
NX_VOLUME_DISCOUNTS=false
-4
View File
@@ -10,7 +10,6 @@ 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_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
@@ -23,6 +22,3 @@ NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_GOVERNANCE_TRANSFERS=true
NX_VOLUME_DISCOUNTS=true
-3
View File
@@ -15,7 +15,6 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
@@ -28,5 +27,3 @@ NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true
-2
View File
@@ -24,5 +24,3 @@ NX_SUCCESSOR_MARKETS=false
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=false
NX_UPDATE_MARKET_STATE=false
NX_REFERRALS=false
NX_VOLUME_DISCOUNTS=false
-1
View File
@@ -1,5 +1,4 @@
/* eslint-disable */
process.env.TZ = 'GMT';
export default {
displayName: 'governance',
preset: '../../jest.preset.js',
+2 -2
View File
@@ -26,11 +26,11 @@ import {
} from '@vegaprotocol/web3';
import { Web3Provider } from '@vegaprotocol/web3';
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import {
useVegaTransactionManager,
useVegaTransactionUpdater,
} from '@vegaprotocol/web3';
VegaWalletProvider,
} from '@vegaprotocol/wallet';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { useEthereumConfig } from '@vegaprotocol/web3';
import {
+1 -27
View File
@@ -709,8 +709,6 @@
"NewMarketProposal": "New market proposal",
"UpdateMarketProposal": "Update market proposal",
"UpdateMarketStateProposal": "Update market state proposal",
"UpdateReferralProgramProposal": "Update referral program proposal",
"UpdateVolumeDiscountProgramProposal": "Update volume discount program proposal",
"MarketChange": "Market change",
"MarketStateChange": "Market state change",
"MarketDetails": "Market details",
@@ -734,8 +732,6 @@
"NewMarketSpotProduct": "New market - spot",
"UpdateMarket": "Update market",
"UpdateMarketState": "Update market state",
"UpdateReferralProgram": "Update referral program",
"UpdateVolumeDiscountProgram": "Update volume discount program",
"NewAsset": "New asset",
"UpdateAsset": "Update asset",
"AssetID": "Asset ID",
@@ -892,27 +888,5 @@
"HowToPropose": "How to make a proposal",
"HowToProposeRawStep1": "1. Sense check your proposal with the community on the forum:",
"HowToProposeRawStep2": "2. Use the appropriate proposal template in the docs:",
"HowToProposeRawStep3": "3. Submit on-chain below",
"proposalTransferDetails": "New governance transfer details",
"proposalCancelTransferDetails": "Cancel governance transfer details",
"BenefitTiers": "Benefit tiers",
"BenefitTierMinimumEpochs": "Minimum epochs",
"BenefitTierMinimumEpochsDescription": "The minimum number of epochs the party needs to be in the referral set to be eligible for the benefit",
"BenefitTierMinimumRunningNotionalTakerVolume": "Minimum running notional taker volume",
"BenefitTierMinimumRunningNotionalTakerVolumeDescription": "The minimum running notional for the given benefit tier",
"BenefitTierReferralDiscountFactor": "Referral discount factor",
"BenefitTierReferralDiscountFactorDescription": "The proportion of the referee's taker fees to be discounted",
"BenefitTierReferralRewardFactor": "Referral reward factor",
"BenefitTierReferralRewardFactorDescription": "The proportion of the referee's taker fees to be rewarded to the referrer",
"StakingTiers": "Staking tiers",
"StakingTierMinimumStakedTokens": "Minimum staked tokens",
"StakingTierMinimumStakedTokensDescription": "Required number of governance tokens ($VEGA) a referrer must have staked to receive the multiplier",
"StakingTierReferralRewardMultiplier": "Referral reward multiplier",
"StakingTierReferralRewardMultiplierDescription": "Multiplier applied to the referral reward factor when calculating referral rewards due to the referrer",
"WindowLength": "Window length",
"WindowLengthDescription": "Number of epochs over which to evaluate a referral set's running volume",
"EndOfProgramTimestamp": "End of program",
"EndOfProgramTimestampDescription": "Time after which when the current epoch ends, the programs will end and benefits will be disabled.",
"BenefitTierVolumeDiscountFactor": "Volume discount factor",
"BenefitTierVolumeDiscountFactorDescription": "Discount given to those in this benefit tier"
"HowToProposeRawStep3": "3. Submit on-chain below"
}
@@ -188,8 +188,6 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
variables: {
includeNewMarketProductFields: !!FLAGS.PRODUCT_PERPETUALS,
includeUpdateMarketStates: !!FLAGS.UPDATE_MARKET_STATE,
includeUpdateReferralPrograms: !!FLAGS.REFERRALS,
includeUpdateVolumeDiscountPrograms: !!FLAGS.VOLUME_DISCOUNTS,
},
});
@@ -7,17 +7,12 @@ 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 {
useCancelTransferProposalDetails,
useNewTransferProposalDetails,
useSuccessorMarketProposalDetails,
} from '@vegaprotocol/proposals';
import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
import { FLAGS } from '@vegaprotocol/environment';
import Routes from '../../../routes';
import { Link } from 'react-router-dom';
import type { VoteState } from '../vote-details/use-user-vote';
import { VoteBreakdown } from '../vote-breakdown';
import { GovernanceTransferKindMapping } from '@vegaprotocol/types';
export const ProposalHeader = ({
proposal,
@@ -98,16 +93,6 @@ export const ProposalHeader = ({
);
break;
}
case 'UpdateReferralProgram': {
proposalType = 'UpdateReferralProgram';
fallbackTitle = t('UpdateReferralProgramProposal');
break;
}
case 'UpdateVolumeDiscountProgram': {
proposalType = 'UpdateVolumeDiscountProgram';
fallbackTitle = t('UpdateVolumeDiscountProgramProposal');
break;
}
case 'NewAsset': {
proposalType = 'NewAsset';
fallbackTitle = t('NewAssetProposal');
@@ -162,20 +147,6 @@ export const ProposalHeader = ({
);
break;
}
case 'NewTransfer':
proposalType = 'NewTransfer';
fallbackTitle = t('NewTransferProposal');
details = FLAGS.GOVERNANCE_TRANSFERS ? (
<NewTransferSummary proposalId={proposal?.id} />
) : null;
break;
case 'CancelTransfer':
proposalType = 'CancelTransfer';
fallbackTitle = t('CancelTransferProposal');
details = FLAGS.GOVERNANCE_TRANSFERS ? (
<CancelTransferSummary proposalId={proposal?.id} />
) : null;
break;
}
return (
@@ -253,36 +224,3 @@ const SuccessorCode = ({ proposalId }: { proposalId?: string | null }) => {
</span>
) : null;
};
const NewTransferSummary = ({ proposalId }: { proposalId?: string | null }) => {
const { t } = useTranslation();
const details = useNewTransferProposalDetails(proposalId);
if (!details) return null;
return (
<span>
{GovernanceTransferKindMapping[details.kind.__typename]}{' '}
{t('transfer from')} <Lozenge>{truncateMiddle(details.source)}</Lozenge>{' '}
{t('to')} <Lozenge>{truncateMiddle(details.destination)}</Lozenge>
</span>
);
};
const CancelTransferSummary = ({
proposalId,
}: {
proposalId?: string | null;
}) => {
const { t } = useTranslation();
const details = useCancelTransferProposalDetails(proposalId);
if (!details) return null;
return (
<span>
{t('Cancel transfer: ')}{' '}
<Lozenge>{truncateMiddle(details.transferId)}</Lozenge>
</span>
);
};
@@ -12,12 +12,12 @@ import {
PriceMonitoringBoundsInfoPanel,
RiskFactorsInfoPanel,
RiskModelInfoPanel,
RiskParametersInfoPanel,
SettlementAssetInfoPanel,
getDataSourceSpecForSettlementSchedule,
getDataSourceSpecForSettlementData,
getDataSourceSpecForTradingTermination,
getSigners,
MarginScalingFactorsPanel,
} from '@vegaprotocol/markets';
import {
Button,
@@ -219,10 +219,8 @@ export const ProposalMarketData = ({
parentMarket={parentMarketData}
/>
<h2 className={marketDataHeaderStyles}>
{t('Margin scaling factors')}
</h2>
<MarginScalingFactorsPanel
<h2 className={marketDataHeaderStyles}>{t('Risk parameters')}</h2>
<RiskParametersInfoPanel
market={marketData}
parentMarket={parentMarketData}
/>
@@ -1 +0,0 @@
export * from './proposal-referral-program-details';
@@ -1,161 +0,0 @@
import { render, screen } from '@testing-library/react';
import {
formatMinimumRunningNotionalTakerVolume,
formatReferralDiscountFactor,
formatReferralRewardFactor,
formatMinimumStakedTokens,
formatReferralRewardMultiplier,
ProposalReferralProgramDetails,
} from './proposal-referral-program-details';
import { generateProposal } from '../../test-helpers/generate-proposals';
jest.mock('../../../../contexts/app-state/app-state-context', () => ({
useAppState: () => ({
appState: {
decimals: 2,
},
}),
}));
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(0);
});
afterEach(() => {
jest.useRealTimers();
});
describe('ProposalReferralProgramDetails helper functions', () => {
it('should format minimum running notional taker volume correctly', () => {
const input = '1000';
const formatted = formatMinimumRunningNotionalTakerVolume(input);
expect(formatted).toBe('1,000');
});
it('should format referral discount factor correctly', () => {
const input = '0.05';
const formatted = formatReferralDiscountFactor(input);
expect(formatted).toBe('5.00%');
});
it('should format referral reward factor correctly', () => {
const input = '0.1';
const formatted = formatReferralRewardFactor(input);
expect(formatted).toBe('10.00%');
});
it('should format minimum staked tokens correctly', () => {
const input = '15';
const decimals = 18;
const formatted = formatMinimumStakedTokens(input, decimals);
expect(formatted).toBe('0.000000000000000015');
});
it('should format referral reward multiplier correctly', () => {
const input = '3';
const formatted = formatReferralRewardMultiplier(input);
expect(formatted).toBe('3x');
});
});
const mockReferralProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateReferralProgram',
changes: {
benefitTiers: [
{
minimumEpochs: 6,
minimumRunningNotionalTakerVolume: '10000',
referralDiscountFactor: '0.001',
referralRewardFactor: '0.001',
},
{
minimumEpochs: 24,
minimumRunningNotionalTakerVolume: '500000',
referralDiscountFactor: '0.005',
referralRewardFactor: '0.005',
},
{
minimumEpochs: 48,
minimumRunningNotionalTakerVolume: '1000000',
referralDiscountFactor: '0.01',
referralRewardFactor: '0.01',
},
],
endOfProgramTimestamp: '2026-10-03T10:34:34Z',
windowLength: 3,
stakingTiers: [
{
minimumStakedTokens: '1',
referralRewardMultiplier: '1',
},
{
minimumStakedTokens: '2',
referralRewardMultiplier: '2',
},
{
minimumStakedTokens: '5',
referralRewardMultiplier: '3',
},
],
},
},
},
});
describe('<ProposalReferralProgramDetails />', () => {
it('should not render if proposal is null', () => {
render(<ProposalReferralProgramDetails proposal={null} />);
expect(
screen.queryByTestId('proposal-referral-program-details')
).toBeNull();
});
it('should not render if __typename is not UpdateReferralProgram', () => {
const updateMarketProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateMarket',
},
},
});
render(<ProposalReferralProgramDetails proposal={updateMarketProposal} />);
expect(
screen.queryByTestId('proposal-referral-program-details')
).toBeNull();
});
it('should not render if there are no relevant fields', () => {
const incompleteProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateReferralProgram',
changes: {},
},
},
});
render(<ProposalReferralProgramDetails proposal={incompleteProposal} />);
expect(
screen.queryByTestId('proposal-referral-program-details')
).toBeNull();
});
it('should render relevant fields if present', () => {
render(<ProposalReferralProgramDetails proposal={mockReferralProposal} />);
expect(
screen.getByTestId('proposal-referral-program-window-length')
).toBeInTheDocument();
expect(
screen.getByTestId('proposal-referral-program-end-of-program-timestamp')
).toBeInTheDocument();
expect(
screen.getByTestId('proposal-referral-program-benefit-tiers')
).toBeInTheDocument();
expect(
screen.getByTestId('proposal-referral-program-benefit-tiers')
).toBeInTheDocument();
});
});
@@ -1,233 +0,0 @@
import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import {
KeyValueTable,
KeyValueTableRow,
RoundedWrapper,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { formatNumber } from '../../../../lib/format-number';
import {
formatDateWithLocalTimezone,
formatNumberPercentage,
toBigNum,
} from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js';
import { useAppState } from '../../../../contexts/app-state/app-state-context';
interface ProposalReferralProgramDetailsProps {
proposal: ProposalQuery['proposal'];
}
export const formatEndOfProgramTimestamp = (value: string) => {
return formatDateWithLocalTimezone(new Date(value));
};
export const formatMinimumRunningNotionalTakerVolume = (value: string) => {
return formatNumber(toBigNum(value, 0), 0);
};
export const formatReferralDiscountFactor = (value: string) => {
return formatNumberPercentage(new BigNumber(value).times(100));
};
export const formatReferralRewardFactor = (value: string) => {
return formatNumberPercentage(new BigNumber(value).times(100));
};
export const formatMinimumStakedTokens = (value: string, decimals: number) => {
return formatNumber(toBigNum(value, decimals));
};
export const formatReferralRewardMultiplier = (value: string) => {
return `${value}x`;
};
export const ProposalReferralProgramDetails = ({
proposal,
}: ProposalReferralProgramDetailsProps) => {
const {
appState: { decimals },
} = useAppState();
const { t } = useTranslation();
if (proposal?.terms?.change?.__typename !== 'UpdateReferralProgram') {
return null;
}
const benefitTiers = proposal?.terms?.change?.changes?.benefitTiers;
const stakingTiers = proposal?.terms?.change?.changes?.stakingTiers;
const windowLength = proposal?.terms?.change?.changes?.windowLength;
const endOfProgramTimestamp =
proposal?.terms?.change?.changes?.endOfProgramTimestamp;
if (
!benefitTiers &&
!stakingTiers &&
!windowLength &&
!endOfProgramTimestamp
) {
return null;
}
return (
<div data-testid="proposal-referral-program-details">
<RoundedWrapper paddingBottom={true}>
{windowLength && (
<div data-testid="proposal-referral-program-window-length">
<KeyValueTable>
<KeyValueTableRow>
<Tooltip description={t('WindowLengthDescription')}>
<span>{t('WindowLength')}</span>
</Tooltip>
{windowLength}
</KeyValueTableRow>
</KeyValueTable>
</div>
)}
{endOfProgramTimestamp && (
<div
className="mb-6"
data-testid="proposal-referral-program-end-of-program-timestamp"
>
<KeyValueTable>
<KeyValueTableRow>
<Tooltip description={t('EndOfProgramTimestampDescription')}>
<span>{t('EndOfProgramTimestamp')}</span>
</Tooltip>
{formatEndOfProgramTimestamp(endOfProgramTimestamp)}
</KeyValueTableRow>
</KeyValueTable>
</div>
)}
{benefitTiers && (
<div
className="mb-6"
data-testid="proposal-referral-program-benefit-tiers"
>
<h3 className="mb-3 uppercase font-semibold text-lg">
{t('BenefitTiers')}
</h3>
<KeyValueTable>
{benefitTiers
.sort((a, b) => a.minimumEpochs - b.minimumEpochs)
.map((benefitTier, index) => (
<div className="mb-4" key={index}>
<h4 className="font-semibold uppercase">
Tier {index + 1}
</h4>
{benefitTier.minimumEpochs && (
<KeyValueTableRow>
<Tooltip
description={t('BenefitTierMinimumEpochsDescription')}
>
<span>{t('BenefitTierMinimumEpochs')}</span>
</Tooltip>
{benefitTier.minimumEpochs}
</KeyValueTableRow>
)}
{benefitTier.minimumRunningNotionalTakerVolume && (
<KeyValueTableRow>
<Tooltip
description={t(
'BenefitTierMinimumRunningNotionalTakerVolumeDescription'
)}
>
<span>
{t('BenefitTierMinimumRunningNotionalTakerVolume')}
</span>
</Tooltip>
{formatMinimumRunningNotionalTakerVolume(
benefitTier.minimumRunningNotionalTakerVolume
)}
</KeyValueTableRow>
)}
{benefitTier.referralDiscountFactor && (
<KeyValueTableRow>
<Tooltip
description={t(
'BenefitTierReferralDiscountFactorDescription'
)}
>
<span>{t('BenefitTierReferralDiscountFactor')}</span>
</Tooltip>
{formatReferralDiscountFactor(
benefitTier.referralDiscountFactor
)}
</KeyValueTableRow>
)}
{benefitTier.referralRewardFactor && (
<KeyValueTableRow>
<Tooltip
description={t(
'BenefitTierReferralRewardFactorDescription'
)}
>
<span>{t('BenefitTierReferralRewardFactor')}</span>
</Tooltip>
{formatReferralRewardFactor(
benefitTier.referralRewardFactor
)}
</KeyValueTableRow>
)}
</div>
))}
</KeyValueTable>
</div>
)}
{stakingTiers && (
<div data-testid="proposal-referral-program-staking-tiers">
<h3 className="mb-3 uppercase font-semibold text-lg">
{t('StakingTiers')}
</h3>
<KeyValueTable>
{stakingTiers
.sort(
(a, b) =>
Number(a.minimumStakedTokens) -
Number(b.minimumStakedTokens)
)
.map((stakingTier, index) => (
<div className="mb-4" key={index}>
{stakingTier.referralRewardMultiplier && (
<KeyValueTableRow>
<Tooltip
description={t(
'StakingTierReferralRewardMultiplierDescription'
)}
>
<span>
{t('StakingTierReferralRewardMultiplier')}
</span>
</Tooltip>
{formatReferralRewardMultiplier(
stakingTier.referralRewardMultiplier
)}
</KeyValueTableRow>
)}
{stakingTier.minimumStakedTokens && (
<KeyValueTableRow>
<Tooltip
description={t(
'StakingTierMinimumStakedTokensFactorDescription'
)}
>
<span>{t('StakingTierMinimumStakedTokens')}</span>
</Tooltip>
{formatMinimumStakedTokens(
stakingTier.minimumStakedTokens,
decimals
)}
</KeyValueTableRow>
)}
</div>
))}
</KeyValueTable>
</div>
)}
</RoundedWrapper>
</div>
);
};
@@ -1,2 +0,0 @@
export * from './proposal-transfer-details';
export * from './proposal-cancel-transfer-details';
@@ -1,37 +0,0 @@
import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import { useCancelTransferProposalDetails } from '@vegaprotocol/proposals';
import {
KeyValueTable,
KeyValueTableRow,
RoundedWrapper,
} from '@vegaprotocol/ui-toolkit';
import { SubHeading } from '../../../../components/heading';
export const ProposalCancelTransferDetails = ({
proposal,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}) => {
const { t } = useTranslation();
const details = useCancelTransferProposalDetails(proposal?.id);
if (!details) {
return null;
}
return (
<>
<SubHeading title={t('proposalCancelTransferDetails')} />
<RoundedWrapper paddingBottom={true}>
<KeyValueTable data-testid="proposal-cancel-transfer-details-table">
<KeyValueTableRow noBorder={true}>
{t('transferId')}
{details.transferId}
</KeyValueTableRow>
</KeyValueTable>
</RoundedWrapper>
</>
);
};
@@ -1,145 +0,0 @@
import { useState } from 'react';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
import { SubHeading } from '../../../../components/heading';
import { useTranslation } from 'react-i18next';
import {
KeyValueTable,
KeyValueTableRow,
RoundedWrapper,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { useNewTransferProposalDetails } from '@vegaprotocol/proposals';
import {
AccountTypeMapping,
DescriptionGovernanceTransferTypeMapping,
GovernanceTransferKindMapping,
GovernanceTransferTypeMapping,
} from '@vegaprotocol/types';
import {
addDecimalsFormatNumberQuantum,
formatDateWithLocalTimezone,
} from '@vegaprotocol/utils';
export const ProposalTransferDetails = ({
proposal,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}) => {
const { t } = useTranslation();
const [show, setShow] = useState(false);
const details = useNewTransferProposalDetails(proposal?.id);
if (!details) {
return null;
}
return (
<>
<CollapsibleToggle
toggleState={show}
setToggleState={setShow}
dataTestId="proposal-transfer-details"
>
<SubHeading title={t('proposalTransferDetails')} />
</CollapsibleToggle>
{show && (
<RoundedWrapper paddingBottom={true}>
<KeyValueTable data-testid="proposal-transfer-details-table">
{/* The source account */}
<KeyValueTableRow>
{t('Source')}
{details.source}
</KeyValueTableRow>
{/* The type of source account */}
<KeyValueTableRow>
{t('Source Type')}
{AccountTypeMapping[details.sourceType]}
</KeyValueTableRow>
{/* The destination account */}
<KeyValueTableRow>
{t('Destination')}
{details.destination}
</KeyValueTableRow>
{/* The type of destination account */}
<KeyValueTableRow>
{t('Destination Type')}
{AccountTypeMapping[details.destinationType]}
</KeyValueTableRow>
{/* The asset to transfer */}
<KeyValueTableRow>
{t('Asset')}
{details.asset.symbol}
</KeyValueTableRow>
{/*The fraction of the balance to be transfer */}
<KeyValueTableRow>
{t('Fraction Of Balance')}
{`${Number(details.fraction_of_balance) * 100}%`}
</KeyValueTableRow>
{/* The maximum amount to be transferred */}
<KeyValueTableRow>
{t('Amount')}
{addDecimalsFormatNumberQuantum(
details.amount,
details.asset.decimals,
details.asset.quantum
)}
</KeyValueTableRow>
{/* The type of the governance transfer */}
<KeyValueTableRow>
{t('Transfer Type')}
<Tooltip
description={
DescriptionGovernanceTransferTypeMapping[details.transferType]
}
>
<span>
{GovernanceTransferTypeMapping[details.transferType]}
</span>
</Tooltip>
</KeyValueTableRow>
{/* The type of governance transfer being made, i.e. a one-off or recurring trans */}
<KeyValueTableRow>
{t('Kind')}
{GovernanceTransferKindMapping[details.kind.__typename]}
</KeyValueTableRow>
{details.kind.__typename === 'OneOffGovernanceTransfer' &&
details.kind.deliverOn && (
<KeyValueTableRow noBorder={true}>
{t('Deliver On')}
{formatDateWithLocalTimezone(
new Date(details.kind.deliverOn)
)}
</KeyValueTableRow>
)}
{details.kind.__typename === 'RecurringGovernanceTransfer' && (
<>
<KeyValueTableRow noBorder={!details.kind.endEpoch}>
{t('Start On')}
<span>{details.kind.startEpoch}</span>
</KeyValueTableRow>
{details.kind.endEpoch && (
<KeyValueTableRow noBorder={true}>
{t('End on')}
{details.kind.endEpoch}
</KeyValueTableRow>
)}
</>
)}
</KeyValueTable>
</RoundedWrapper>
)}
</>
);
};
@@ -1 +0,0 @@
export * from './proposal-volume-discount-program-details';
@@ -1,114 +0,0 @@
import { render, screen } from '@testing-library/react';
import { ProposalVolumeDiscountProgramDetails } from './proposal-volume-discount-program-details';
import { generateProposal } from '../../test-helpers/generate-proposals';
jest.mock('../../../../contexts/app-state/app-state-context', () => ({
useAppState: () => ({
appState: {
decimals: 2,
},
}),
}));
const mockReferralProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateVolumeDiscountProgram',
benefitTiers: [
{
minimumRunningNotionalTakerVolume: '10000',
volumeDiscountFactor: '0.05',
},
{
minimumRunningNotionalTakerVolume: '50000',
volumeDiscountFactor: '0.1',
},
{
minimumRunningNotionalTakerVolume: '100000',
volumeDiscountFactor: '0.15',
},
{
minimumRunningNotionalTakerVolume: '250000',
volumeDiscountFactor: '0.2',
},
{
minimumRunningNotionalTakerVolume: '500000',
volumeDiscountFactor: '0.25',
},
{
minimumRunningNotionalTakerVolume: '1000000',
volumeDiscountFactor: '0.3',
},
{
minimumRunningNotionalTakerVolume: '1500000',
volumeDiscountFactor: '0.35',
},
{
minimumRunningNotionalTakerVolume: '2000000',
volumeDiscountFactor: '0.4',
},
],
endOfProgramTimestamp: '1970-01-01T00:00:01.791568493Z',
windowLength: 7,
},
},
});
describe('ProposalVolumeDiscountProgramDetails', () => {
it('should not render if proposal is null', () => {
render(<ProposalVolumeDiscountProgramDetails proposal={null} />);
expect(
screen.queryByTestId('proposal-volume-discount-program-details')
).toBeNull();
});
it('should not render if __typename is not UpdateVolumeDiscountProgram', () => {
const updateMarketProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateMarket',
},
},
});
render(
<ProposalVolumeDiscountProgramDetails proposal={updateMarketProposal} />
);
expect(
screen.queryByTestId('proposal-volume-discount-program-details')
).toBeNull();
});
it('should not render if there are no relevant fields', () => {
const incompleteProposal = generateProposal({
terms: {
change: {
__typename: 'UpdateVolumeDiscountProgram',
},
},
});
render(
<ProposalVolumeDiscountProgramDetails proposal={incompleteProposal} />
);
expect(
screen.queryByTestId('proposal-volume-discount-program-details')
).toBeNull();
});
it('should render relevant fields if present', () => {
render(
<ProposalVolumeDiscountProgramDetails proposal={mockReferralProposal} />
);
expect(
screen.getByTestId('proposal-volume-discount-program-window-length')
).toBeInTheDocument();
expect(
screen.getByTestId(
'proposal-volume-discount-program-end-of-program-timestamp'
)
).toBeInTheDocument();
expect(
screen.getByTestId('proposal-volume-discount-program-benefit-tiers')
).toBeInTheDocument();
});
});
@@ -1,130 +0,0 @@
import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import {
KeyValueTable,
KeyValueTableRow,
RoundedWrapper,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import {
formatEndOfProgramTimestamp,
formatMinimumRunningNotionalTakerVolume,
} from '../proposal-referral-program-details';
import { formatNumberPercentage } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js';
interface ProposalReferralProgramDetailsProps {
proposal: ProposalQuery['proposal'];
}
export const formatVolumeDiscountFactor = (value: string) => {
return formatNumberPercentage(new BigNumber(value).times(100));
};
export const ProposalVolumeDiscountProgramDetails = ({
proposal,
}: ProposalReferralProgramDetailsProps) => {
const { t } = useTranslation();
if (proposal?.terms?.change?.__typename !== 'UpdateVolumeDiscountProgram') {
return null;
}
const benefitTiers = proposal?.terms?.change?.benefitTiers;
const windowLength = proposal?.terms?.change?.windowLength;
const endOfProgramTimestamp = proposal?.terms?.change?.endOfProgramTimestamp;
if (!benefitTiers && !windowLength && !endOfProgramTimestamp) {
return null;
}
return (
<div data-testid="proposal-volume-discount-program-details">
<RoundedWrapper paddingBottom={true}>
{windowLength && (
<div data-testid="proposal-volume-discount-program-window-length">
<KeyValueTable>
<KeyValueTableRow>
<Tooltip description={t('WindowLengthDescription')}>
<span>{t('WindowLength')}</span>
</Tooltip>
{windowLength}
</KeyValueTableRow>
</KeyValueTable>
</div>
)}
{endOfProgramTimestamp && (
<div
className="mb-6"
data-testid="proposal-volume-discount-program-end-of-program-timestamp"
>
<KeyValueTable>
<KeyValueTableRow>
<Tooltip description={t('EndOfProgramTimestampDescription')}>
<span>{t('EndOfProgramTimestamp')}</span>
</Tooltip>
{formatEndOfProgramTimestamp(endOfProgramTimestamp)}
</KeyValueTableRow>
</KeyValueTable>
</div>
)}
{benefitTiers && (
<div
className="mb-6"
data-testid="proposal-volume-discount-program-benefit-tiers"
>
<h3 className="mb-3 uppercase font-semibold text-lg">
{t('BenefitTiers')}
</h3>
<KeyValueTable>
{benefitTiers
.sort(
(a, b) =>
Number(a.minimumRunningNotionalTakerVolume) -
Number(b.minimumRunningNotionalTakerVolume)
)
.map((benefitTier, index) => (
<div className="mb-4" key={index}>
<h4 className="font-semibold uppercase">
Tier {index + 1}
</h4>
{benefitTier.minimumRunningNotionalTakerVolume && (
<KeyValueTableRow>
<Tooltip
description={t(
'BenefitTierMinimumRunningNotionalTakerVolumeDescription'
)}
>
<span>
{t('BenefitTierMinimumRunningNotionalTakerVolume')}
</span>
</Tooltip>
{formatMinimumRunningNotionalTakerVolume(
benefitTier.minimumRunningNotionalTakerVolume
)}
</KeyValueTableRow>
)}
{benefitTier.volumeDiscountFactor && (
<KeyValueTableRow>
<Tooltip
description={t(
'BenefitTierVolumeDiscountFactorDescription'
)}
>
<span>{t('BenefitTierVolumeDiscountFactor')}</span>
</Tooltip>
{formatVolumeDiscountFactor(
benefitTier.volumeDiscountFactor
)}
</KeyValueTableRow>
)}
</div>
))}
</KeyValueTable>
</div>
)}
</RoundedWrapper>
</div>
);
};
@@ -6,8 +6,6 @@ import { ProposalDescription } from '../proposal-description';
import { ProposalChangeTable } from '../proposal-change-table';
import { ProposalJson } from '../proposal-json';
import { ProposalAssetDetails } from '../proposal-asset-details';
import { ProposalReferralProgramDetails } from '../proposal-referral-program-details';
import { ProposalVolumeDiscountProgramDetails } from '../proposal-volume-discount-program-details';
import { UserVote } from '../vote-details';
import { ListAsset } from '../list-asset';
import Routes from '../../../routes';
@@ -22,11 +20,6 @@ import { ProposalUpdateMarketState } from '../proposal-update-market-state';
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters';
import { useVoteSubmit } from '@vegaprotocol/proposals';
import { useUserVote } from '../vote-details/use-user-vote';
import {
ProposalCancelTransferDetails,
ProposalTransferDetails,
} from '../proposal-transfer';
import { FLAGS } from '@vegaprotocol/environment';
export interface ProposalProps {
proposal: ProposalQuery['proposal'];
@@ -106,46 +99,9 @@ export const Proposal = ({
minVoterBalance =
networkParams.governance_proposal_freeform_minVoterBalance;
break;
case 'NewTransfer':
// TODO: check minVoterBalance for 'NewTransfer'
minVoterBalance =
networkParams.governance_proposal_freeform_minVoterBalance;
break;
case 'CancelTransfer':
// TODO: check minVoterBalance for 'CancelTransfer'
minVoterBalance =
networkParams.governance_proposal_freeform_minVoterBalance;
break;
case 'UpdateReferralProgram':
minVoterBalance =
networkParams.governance_proposal_referralProgram_minVoterBalance;
break;
case 'UpdateVolumeDiscountProgram':
minVoterBalance =
networkParams.governance_proposal_VolumeDiscountProgram_minVoterBalance;
break;
}
}
// Show governance transfer details only if the GOVERNANCE_TRANSFERS flag is on.
const governanceTransferDetails = FLAGS.GOVERNANCE_TRANSFERS && (
<>
{proposal.terms.change.__typename === 'NewTransfer' && (
/** Governance New Transfer Details */
<div className="mb-4">
<ProposalTransferDetails proposal={proposal} />
</div>
)}
{proposal.terms.change.__typename === 'CancelTransfer' && (
/** Governance Cancel Transfer Details */
<div className="mb-4">
<ProposalCancelTransferDetails proposal={proposal} />
</div>
)}
</>
);
return (
<section data-testid="proposal">
<div className="flex items-center gap-1 mb-6">
@@ -231,20 +187,6 @@ export const Proposal = ({
</div>
)}
{proposal.terms.change.__typename === 'UpdateReferralProgram' && (
<div className="mb-4">
<ProposalReferralProgramDetails proposal={proposal} />
</div>
)}
{proposal.terms.change.__typename === 'UpdateVolumeDiscountProgram' && (
<div className="mb-4">
<ProposalVolumeDiscountProgramDetails proposal={proposal} />
</div>
)}
{governanceTransferDetails}
<div className="mb-10">
<RoundedWrapper paddingBottom={true}>
<UserVote
@@ -4,7 +4,7 @@ import {
getProposalDialogTitle,
} from '@vegaprotocol/proposals';
import type { ProposalEventFieldsFragment } from '@vegaprotocol/proposals';
import type { DialogProps } from '@vegaprotocol/proposals';
import type { DialogProps } from '@vegaprotocol/wallet';
interface ProposalFormTransactionDialogProps {
finalizedProposal: ProposalEventFieldsFragment | null;
@@ -6,7 +6,7 @@ import { ConnectToVega } from '../../../../components/connect-to-vega';
import { VoteButtonsContainer } from './vote-buttons';
import { SubHeading } from '../../../../components/heading';
import type { VoteValue } from '@vegaprotocol/types';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { VoteState } from './use-user-vote';
@@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/react';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { VoteState } from './use-user-vote';
import { VegaTxStatus } from '@vegaprotocol/proposals';
import { VegaTxStatus } from '@vegaprotocol/wallet';
describe('VoteTransactionDialog', () => {
const mockTransactionDialog = jest.fn(({ title, content }) => (
@@ -17,7 +17,7 @@ import { VoteState } from './use-user-vote';
import { ProposalMinRequirements, ProposalUserAction } from '../shared';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { useVoteButtonsQuery } from './__generated__/Stake';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
interface VoteButtonsContainerProps {
voteState: VoteState | null;
@@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
import { VoteState } from './use-user-vote';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
interface VoteTransactionDialogProps {
voteState: VoteState;
@@ -19,8 +19,6 @@ export const useProposalNetworkParams = ({
NetworkParams.governance_proposal_market_requiredMajority,
NetworkParams.governance_proposal_market_requiredParticipation,
NetworkParams.governance_proposal_updateAsset_requiredMajority,
NetworkParams.governance_proposal_referralProgram_requiredMajority,
NetworkParams.governance_proposal_referralProgram_requiredParticipation,
NetworkParams.governance_proposal_updateAsset_requiredParticipation,
NetworkParams.governance_proposal_asset_requiredMajority,
NetworkParams.governance_proposal_asset_requiredParticipation,
@@ -28,8 +26,6 @@ export const useProposalNetworkParams = ({
NetworkParams.governance_proposal_updateNetParam_requiredParticipation,
NetworkParams.governance_proposal_freeform_requiredMajority,
NetworkParams.governance_proposal_freeform_requiredParticipation,
NetworkParams.governance_proposal_VolumeDiscountProgram_requiredMajority,
NetworkParams.governance_proposal_VolumeDiscountProgram_requiredParticipation,
]);
const fallback = {
@@ -95,22 +91,6 @@ export const useProposalNetworkParams = ({
params.governance_proposal_freeform_requiredParticipation
),
};
case 'UpdateReferralProgram':
return {
requiredMajority:
params.governance_proposal_referralProgram_requiredMajority,
requiredParticipation: new BigNumber(
params.governance_proposal_referralProgram_requiredParticipation
),
};
case 'UpdateVolumeDiscountProgram':
return {
requiredMajority:
params.governance_proposal_VolumeDiscountProgram_requiredMajority,
requiredParticipation: new BigNumber(
params.governance_proposal_VolumeDiscountProgram_requiredParticipation
),
};
default:
return fallback;
}
@@ -43,50 +43,10 @@ fragment UpdateMarketState on Proposal {
}
}
fragment UpdateReferralProgram on Proposal {
terms {
change {
... on UpdateReferralProgram {
changes {
benefitTiers {
minimumEpochs
minimumRunningNotionalTakerVolume
referralDiscountFactor
referralRewardFactor
}
endOfProgramTimestamp
windowLength
stakingTiers {
minimumStakedTokens
referralRewardMultiplier
}
}
}
}
}
}
fragment UpdateVolumeDiscountProgram on Proposal {
terms {
change {
... on UpdateVolumeDiscountProgram {
benefitTiers {
minimumRunningNotionalTakerVolume
volumeDiscountFactor
}
endOfProgramTimestamp
windowLength
}
}
}
}
query Proposal(
$proposalId: ID!
$includeNewMarketProductField: Boolean!
$includeUpdateMarketState: Boolean!
$includeUpdateReferralProgram: Boolean!
$includeUpdateVolumeDiscountProgram: Boolean!
) {
proposal(id: $proposalId) {
id
@@ -104,9 +64,6 @@ query Proposal(
errorDetails
...NewMarketProductField @include(if: $includeNewMarketProductField)
...UpdateMarketState @include(if: $includeUpdateMarketState)
...UpdateReferralProgram @include(if: $includeUpdateReferralProgram)
...UpdateVolumeDiscountProgram
@include(if: $includeUpdateVolumeDiscountProgram)
terms {
closingDatetime
enactmentDatetime
File diff suppressed because one or more lines are too long
@@ -36,8 +36,6 @@ export const ProposalContainer = () => {
NetworkParams.governance_proposal_updateAsset_minVoterBalance,
NetworkParams.governance_proposal_updateNetParam_minVoterBalance,
NetworkParams.governance_proposal_freeform_minVoterBalance,
NetworkParams.governance_proposal_referralProgram_minVoterBalance,
NetworkParams.governance_proposal_VolumeDiscountProgram_minVoterBalance,
NetworkParams.spam_protection_voting_min_tokens,
NetworkParams.governance_proposal_market_requiredMajority,
NetworkParams.governance_proposal_updateMarket_requiredMajority,
@@ -46,8 +44,6 @@ export const ProposalContainer = () => {
NetworkParams.governance_proposal_updateAsset_requiredMajority,
NetworkParams.governance_proposal_updateNetParam_requiredMajority,
NetworkParams.governance_proposal_freeform_requiredMajority,
NetworkParams.governance_proposal_referralProgram_requiredMajority,
NetworkParams.governance_proposal_VolumeDiscountProgram_requiredMajority,
]);
const {
@@ -61,8 +57,6 @@ export const ProposalContainer = () => {
proposalId: params.proposalId || '',
includeNewMarketProductField: !!FLAGS.PRODUCT_PERPETUALS,
includeUpdateMarketState: !!FLAGS.UPDATE_MARKET_STATE,
includeUpdateReferralProgram: !!FLAGS.REFERRALS,
includeUpdateVolumeDiscountProgram: !!FLAGS.VOLUME_DISCOUNTS,
},
skip: !params.proposalId,
});
@@ -43,44 +43,6 @@ fragment UpdateMarketStates on Proposal {
}
}
fragment UpdateReferralPrograms on Proposal {
terms {
change {
... on UpdateReferralProgram {
changes {
benefitTiers {
minimumEpochs
minimumRunningNotionalTakerVolume
referralDiscountFactor
referralRewardFactor
}
endOfProgramTimestamp
windowLength
stakingTiers {
minimumStakedTokens
referralRewardMultiplier
}
}
}
}
}
}
fragment UpdateVolumeDiscountPrograms on Proposal {
terms {
change {
... on UpdateVolumeDiscountProgram {
benefitTiers {
minimumRunningNotionalTakerVolume
volumeDiscountFactor
}
endOfProgramTimestamp
windowLength
}
}
}
}
fragment ProposalFields on Proposal {
id
rationale {
@@ -165,8 +127,6 @@ fragment ProposalFields on Proposal {
query Proposals(
$includeNewMarketProductFields: Boolean!
$includeUpdateMarketStates: Boolean!
$includeUpdateReferralPrograms: Boolean!
$includeUpdateVolumeDiscountPrograms: Boolean!
) {
proposalsConnection {
edges {
@@ -174,9 +134,6 @@ query Proposals(
...ProposalFields
...NewMarketProductFields @include(if: $includeNewMarketProductFields)
...UpdateMarketStates @include(if: $includeUpdateMarketStates)
...UpdateReferralPrograms @include(if: $includeUpdateReferralPrograms)
...UpdateVolumeDiscountPrograms
@include(if: $includeUpdateVolumeDiscountPrograms)
}
}
}
@@ -7,21 +7,15 @@ export type NewMarketProductFieldsFragment = { __typename?: 'Proposal', terms: {
export type UpdateMarketStatesFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } } };
export type UpdateReferralProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram', changes: { __typename?: 'ReferralProgram', endOfProgramTimestamp: string, windowLength: number, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } } };
export type UpdateVolumeDiscountProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } } };
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } };
export type ProposalsQueryVariables = Types.Exact<{
includeNewMarketProductFields: Types.Scalars['Boolean'];
includeUpdateMarketStates: Types.Scalars['Boolean'];
includeUpdateReferralPrograms: Types.Scalars['Boolean'];
includeUpdateVolumeDiscountPrograms: Types.Scalars['Boolean'];
}>;
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', changes: { __typename?: 'ReferralProgram', endOfProgramTimestamp: string, windowLength: number, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
export const NewMarketProductFieldsFragmentDoc = gql`
fragment NewMarketProductFields on Proposal {
@@ -70,46 +64,6 @@ export const UpdateMarketStatesFragmentDoc = gql`
}
}
`;
export const UpdateReferralProgramsFragmentDoc = gql`
fragment UpdateReferralPrograms on Proposal {
terms {
change {
... on UpdateReferralProgram {
changes {
benefitTiers {
minimumEpochs
minimumRunningNotionalTakerVolume
referralDiscountFactor
referralRewardFactor
}
endOfProgramTimestamp
windowLength
stakingTiers {
minimumStakedTokens
referralRewardMultiplier
}
}
}
}
}
}
`;
export const UpdateVolumeDiscountProgramsFragmentDoc = gql`
fragment UpdateVolumeDiscountPrograms on Proposal {
terms {
change {
... on UpdateVolumeDiscountProgram {
benefitTiers {
minimumRunningNotionalTakerVolume
volumeDiscountFactor
}
endOfProgramTimestamp
windowLength
}
}
}
}
`;
export const ProposalFieldsFragmentDoc = gql`
fragment ProposalFields on Proposal {
id
@@ -193,24 +147,20 @@ export const ProposalFieldsFragmentDoc = gql`
}
`;
export const ProposalsDocument = gql`
query Proposals($includeNewMarketProductFields: Boolean!, $includeUpdateMarketStates: Boolean!, $includeUpdateReferralPrograms: Boolean!, $includeUpdateVolumeDiscountPrograms: Boolean!) {
query Proposals($includeNewMarketProductFields: Boolean!, $includeUpdateMarketStates: Boolean!) {
proposalsConnection {
edges {
node {
...ProposalFields
...NewMarketProductFields @include(if: $includeNewMarketProductFields)
...UpdateMarketStates @include(if: $includeUpdateMarketStates)
...UpdateReferralPrograms @include(if: $includeUpdateReferralPrograms)
...UpdateVolumeDiscountPrograms @include(if: $includeUpdateVolumeDiscountPrograms)
}
}
}
}
${ProposalFieldsFragmentDoc}
${NewMarketProductFieldsFragmentDoc}
${UpdateMarketStatesFragmentDoc}
${UpdateReferralProgramsFragmentDoc}
${UpdateVolumeDiscountProgramsFragmentDoc}`;
${UpdateMarketStatesFragmentDoc}`;
/**
* __useProposalsQuery__
@@ -226,8 +176,6 @@ ${UpdateVolumeDiscountProgramsFragmentDoc}`;
* variables: {
* includeNewMarketProductFields: // value for 'includeNewMarketProductFields'
* includeUpdateMarketStates: // value for 'includeUpdateMarketStates'
* includeUpdateReferralPrograms: // value for 'includeUpdateReferralPrograms'
* includeUpdateVolumeDiscountPrograms: // value for 'includeUpdateVolumeDiscountPrograms'
* },
* });
*/
@@ -49,8 +49,6 @@ export const ProposalsContainer = () => {
variables: {
includeNewMarketProductFields: !!FLAGS.PRODUCT_PERPETUALS,
includeUpdateMarketStates: !!FLAGS.UPDATE_MARKET_STATE,
includeUpdateReferralPrograms: !!FLAGS.REFERRALS,
includeUpdateVolumeDiscountPrograms: !!FLAGS.VOLUME_DISCOUNTS,
},
});
@@ -41,8 +41,6 @@ export const RejectedProposalsContainer = () => {
variables: {
includeNewMarketProductFields: !!FLAGS.PRODUCT_PERPETUALS,
includeUpdateMarketStates: !!FLAGS.UPDATE_MARKET_STATE,
includeUpdateReferralPrograms: !!FLAGS.REFERRALS,
includeUpdateVolumeDiscountPrograms: !!FLAGS.VOLUME_DISCOUNTS,
},
});
+147
View File
@@ -0,0 +1,147 @@
.pre-loader {
display: flex;
width: 100%;
min-height: 100vh;
justify-content: center;
align-items: center;
}
.pre-loader .loader-item {
width: 10px;
height: 10px;
background: #000;
}
.pre-loader .pre-loader-center {
align-items: center;
display: flex;
flex-direction: column;
}
.pre-loader .pre-loader-wrapper {
width: 50px;
height: 50px;
display: flex;
flex-wrap: wrap;
}
.pre-loader .loader-item:nth-child(0) {
animation-delay: 0ms;
animation-direction: reverse;
}
.pre-loader .loader-item:first-child {
animation-delay: -0.1s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(2) {
animation-delay: 0.3s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(3) {
animation-delay: -0.45s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(4) {
animation-delay: 1s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(5) {
animation-delay: -0.75s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(6) {
animation-delay: 0.9s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(7) {
animation-delay: -1.4s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(8) {
animation-delay: 1.6s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(9) {
animation-delay: -0.45s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(10) {
animation-delay: 1.5s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(11) {
animation-delay: -2.75s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(12) {
animation-delay: 1.2s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(13) {
animation-delay: -1.95s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(14) {
animation-delay: 2.8s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(15) {
animation-delay: -0.75s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(16) {
animation-delay: 4s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(17) {
animation-delay: -0.85s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(18) {
animation-delay: 1.8s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(19) {
animation-delay: -1.9s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(20) {
animation-delay: 5s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(21) {
animation-delay: -5.25s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(22) {
animation-delay: 4.4s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(23) {
animation-delay: -5.75s;
animation-direction: alternate;
}
.pre-loader .loader-item:nth-child(24) {
animation-delay: 4.8s;
animation-direction: reverse;
}
.pre-loader .loader-item:nth-child(25) {
animation-delay: -5s;
animation-direction: alternate;
}
.pre-loader .loader-item {
animation: flickering 0.4s linear infinite alternate;
}
@keyframes flickering {
0% {
opacity: 1;
}
25% {
opacity: 1;
}
26% {
opacity: 0;
}
to {
opacity: 0;
}
}
html.dark .pre-loader .loader-item {
background: #fff;
}
+58
View File
@@ -0,0 +1,58 @@
.pre-loader {
display: flex;
width: 100%;
min-height: 100vh;
justify-content: center;
align-items: center;
.loader-item {
width: 10px;
height: 10px;
background: black;
}
.pre-loader-center {
align-items: center;
display: flex;
flex-direction: column;
}
.pre-loader-wrapper {
width: 50px;
height: 50px;
display: flex;
flex-wrap: wrap;
}
@for $i from 0 through 25 {
.loader-item:nth-child(#{$i}) {
@if $i % 2 == 0 {
animation-delay: #{$i * 50 * random(5)}ms;
animation-direction: reverse;
} @else {
animation-delay: #{$i * -50 * random(5)}ms;
animation-direction: alternate;
}
}
}
.loader-item {
animation: flickering 0.4s linear alternate infinite;
}
@keyframes flickering {
0% {
opacity: 1;
}
25% {
opacity: 1;
}
26% {
opacity: 0;
}
100% {
opacity: 0;
}
}
}
html.dark {
.pre-loader {
.loader-item {
background: white;
}
}
}
@@ -61,7 +61,7 @@ describe('home', { tags: '@regression' }, () => {
// 0006-NETW-020
cy.getByTestId(nodeHealthTrigger).click();
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId('node-url-custom').click();
cy.getByTestId('connect').should('be.disabled');
cy.get("input[placeholder='https://']")
.focus()
@@ -58,7 +58,7 @@ describe('Market trading page', () => {
// 6002-MDET-003
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketPrice).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Mark Price');
cy.getByTestId(itemHeader).should('have.text', 'Price');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
@@ -0,0 +1,28 @@
import { MarketState } from '@vegaprotocol/types';
const oracleBannerDialogTrigger = 'oracle-banner-dialog-trigger';
const oracleBannerStatus = 'oracle-banner-status';
const oracleFullProfile = 'oracle-full-profile';
describe('oracle information', { tags: '@smoke' }, () => {
before(() => {
cy.setOnBoardingViewed();
cy.mockTradingPage(
MarketState.STATE_ACTIVE,
undefined,
undefined,
'COMPROMISED'
);
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('show oracle banner', () => {
cy.getByTestId(oracleBannerStatus).should('contain.text', 'COMPROMISED');
cy.getByTestId(oracleBannerDialogTrigger)
.should('contain.text', 'Show more')
.click();
cy.getByTestId(oracleFullProfile).should('exist');
});
});
@@ -0,0 +1,221 @@
import { checkSorting } from '@vegaprotocol/cypress';
const dialogClose = 'dialog-close';
describe('accounts', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockTradingPage();
cy.mockWeb3Provider();
cy.mockSubscription();
cy.setVegaWallet();
cy.visit('/#/markets/market-0');
});
it('renders accounts', () => {
// 7001-COLL-001
// 7001-COLL-002
// 7001-COLL-003
// 7001-COLL-004
// 7001-COLL-005
// 7001-COLL-006
// 7001-COLL-007
// 1003-TRAN-001
// 7001-COLL-012
const tradingAccountRowId = '[row-id="t-0"]';
cy.getByTestId('Collateral').click();
cy.getByTestId('tab-accounts').should('be.visible');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="asset.symbol"]')
.should('have.text', 'AST0');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="used"]')
.should('have.text', '1.01' + '1.00%');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="available"]')
.should('have.text', '100.00');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="total"]')
.should('have.text', '101.01');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="accounts-actions"]')
.should('have.text', '');
cy.getByTestId('tab-accounts')
.get('[col-id="accounts-actions"]')
.find('[data-testid="dropdown-menu"]')
.eq(1)
.click();
cy.getByTestId('deposit').should('be.visible');
cy.getByTestId('withdraw').should('be.visible');
cy.getByTestId('transfer').should('be.visible');
cy.getByTestId('breakdown').should('be.visible');
cy.getByTestId('Collateral').click({ force: true });
});
it('should open asset details dialog when clicked on symbol', () => {
// 7001-COLL-008
// 6501-ASSE-001
// 6501-ASSE-002
// 6501-ASSE-003
// 6501-ASSE-004
// 6501-ASSE-005
// 6501-ASSE-006
// 6501-ASSE-007
// 6501-ASSE-008
// 6501-ASSE-009
// 6501-ASSE-010
// 6501-ASSE-011
// 6501-ASSE-012
// 6501-ASSE-013
const titles = [
'ID',
'Type',
'Name',
'Symbol',
'Decimals',
'Quantum',
'Status',
'Contract address',
'Withdrawal threshold',
'Lifetime limit',
'Infrastructure fee account balance',
'Global reward pool account balance',
'Maker paid fees account balance',
'Maker received fees account balance',
'Liquidity provision fee reward account balance',
'Market proposer reward account balance',
];
cy.get('[col-id="asset.symbol"]').contains('tEURO').click();
cy.get('[data-testid$="_label"]').should('have.length', 16);
cy.get('[data-testid$="_label"]').each((element, index) => {
cy.wrap(element).should('have.text', titles[index]);
});
cy.getByTestId(dialogClose).click();
cy.getByTestId(dialogClose).should('not.exist');
});
it('should open usage breakdown dialog when clicked on used', () => {
// 7001-COLL-009
cy.get('[col-id="used"]').contains('1.01').click();
const headers = ['Market', 'Account type', 'Balance', 'Margin health'];
cy.getByTestId('usage-breakdown').within(($headers) => {
cy.wrap($headers)
.get('.ag-header-cell-text')
.each(($header, i) => {
cy.wrap($header).should('have.text', headers[i]);
});
});
cy.getByTestId(dialogClose).click();
});
describe('sorting by ag-grid columns should work well', () => {
before(() => {
const dialogs = Cypress.$('[data-testid="dialog-close"]:visible');
if (dialogs.length > 0) {
dialogs.each((btn) => {
cy.wrap(btn).click();
});
}
cy.contains('Loading...').should('not.exist');
});
// 7001-COLL-010
it('sorting by asset', () => {
cy.getByTestId('Collateral').click();
const marketsSortedDefault = ['tBTC', 'tEURO', 'tDAI', 'tBTC'];
const marketsSortedAsc = ['tBTC', 'tBTC', 'tDAI', 'tEURO'];
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
checkSorting(
'asset.symbol',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
);
});
it('sorting by total', () => {
cy.getByTestId('Collateral').click();
const marketsSortedDefault = [
'1,000.00002',
'1,000.01',
'1,000.00',
'1,000.00001',
];
const marketsSortedAsc = [
'1,000.00',
'1,000.00001',
'1,000.00002',
'1,000.01',
];
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
checkSorting(
'total',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
);
});
it('sorting by used', () => {
cy.getByTestId('Collateral').click();
// concat actual value with percentage value
// as cypress will pick up the entire cell contes
// textContent
const marketsSortedDefault = [
'0.00' + '0.00%',
'0.01' + '0.00%',
'0.00' + '0.00%',
'0.00' + '0.00%',
];
const marketsSortedAsc = [
'0.00' + '0.00%',
'0.00' + '0.00%',
'0.00' + '0.00%',
'0.01' + '0.00%',
];
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
checkSorting(
'used',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
);
});
it('sorting by available', () => {
cy.getByTestId('Collateral').click();
const marketsSortedDefault = [
'1,000.00002',
'1,000.00',
'1,000.00',
'1,000.00001',
];
const marketsSortedAsc = [
'1,000.00',
'1,000.00',
'1,000.00001',
'1,000.00002',
];
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
checkSorting(
'available',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
);
});
});
});
@@ -1,11 +1,92 @@
import * as Schema from '@vegaprotocol/types';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import {
accountsQuery,
amendGeneralAccountBalance,
amendMarginAccountBalance,
} from '@vegaprotocol/mock';
import type { OrderSubmission } from '@vegaprotocol/wallet';
import { createOrder } from '../support/create-order';
describe(
'vega wallet - prompt',
describe.skip(
'account validation',
{ tags: '@regression', testIsolation: true },
() => {
describe.skip('zero balance error', () => {
beforeEach(() => {
cy.setVegaWallet();
cy.mockTradingPage();
let accounts = accountsQuery();
accounts = amendMarginAccountBalance(accounts, 'market-0', '1000');
accounts = amendGeneralAccountBalance(accounts, 'market-0', '0');
cy.mockGQL((req) => {
aliasGQLQuery(req, 'Accounts', accounts);
});
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('should show an error if your balance is zero', () => {
const accounts = accountsQuery();
amendMarginAccountBalance(accounts, 'market-0', '0');
cy.mockGQL((req) => {
aliasGQLQuery(req, 'Accounts', accounts);
});
// 7002-SORD-060
cy.getByTestId('place-order').should('be.enabled');
// 7002-SORD-003
cy.getByTestId('deal-ticket-error-message-zero-balance').should(
'have.text',
'You need ' +
'tDAI' +
' in your wallet to trade in this market. See all your collateral.Make a deposit'
);
cy.getByTestId('deal-ticket-deposit-dialog-button').should('exist');
});
});
describe('not enough balance warning', () => {
beforeEach(() => {
cy.setVegaWallet();
cy.mockTradingPage();
let accounts = accountsQuery();
accounts = amendMarginAccountBalance(accounts, 'market-0', '1000');
accounts = amendGeneralAccountBalance(accounts, 'market-0', '1');
cy.mockGQL((req) => {
aliasGQLQuery(req, 'Accounts', accounts);
});
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.get('[data-testid="deal-ticket-form"]').then(($form) => {
if (!$form.length) {
cy.getByTestId('Order').click();
}
});
});
it('should display info and button for deposit', () => {
// 7002-SORD-003
// warning should show immediately
cy.getByTestId('deal-ticket-warning-margin').should(
'contain.text',
'You may not have enough margin available to open this position'
);
cy.getByTestId('deal-ticket-warning-margin').should(
'contain.text',
'You may not have enough margin available to open this position. 5.00 tDAI is currently required. You have only 0.01001 tDAI available.'
);
cy.getByTestId('deal-ticket-deposit-dialog-button').click();
cy.getByTestId('sidebar-content')
.find('h2')
.eq(0)
.should('have.text', 'Deposit');
});
});
describe('must submit order', { tags: '@smoke' }, () => {
// 7002-SORD-039
beforeEach(() => {
@@ -0,0 +1,186 @@
import {
TIFlist,
orderTIFDropDown,
toggleLimit,
toggleMarket,
} from '../support/deal-ticket';
const tooltipContent = 'tooltip-content';
const reduceOnly = 'reduce-only';
const postOnly = 'post-only';
describe('time in force validation', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.mockSubscription();
cy.clearAllLocalStorage();
cy.setOnBoardingViewed();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must have market order set up to IOC by default', function () {
// 7002-SORD-030
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
});
it('must have time in force set to GTC for limit order', function () {
// 7002-SORD-031
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTC')[0].text
);
});
it('selections should be remembered', () => {
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_FOK');
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTT')[0].text
);
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'FOK')[0].text
);
});
describe('limit order', () => {
before(() => {
cy.getByTestId(toggleLimit).click();
});
const validTIF = TIFlist;
validTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-025
// 7002-SORD-026
// 7002-SORD-027
// 7002-SORD-028
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
});
describe('market order', () => {
before(() => {
cy.getByTestId(toggleMarket).click();
});
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
const invalidTIF = TIFlist.filter(
(tif) => !['FOK', 'IOC'].includes(tif.code)
);
validTIF.forEach((tif) => {
// 7002-SORD-025
// 7002-SORD-026
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
invalidTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-027
// 7002-SORD-028
it(`must not be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).should('not.contain', tif.text);
});
});
});
describe('post and reduce - market order', () => {
before(() => {
cy.getByTestId(toggleMarket).click();
});
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
validTIF.forEach((tif) => {
// 7002-SORD-025
// 7002-SORD-026
it(`post and reduce order market for ${tif.code}`, function () {
// 7003-SORD-054
// 7003-SORD-055
// 7003-SORD-056
// 7003-SORD-057
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
cy.getByTestId(postOnly).should('be.disabled');
cy.getByTestId(reduceOnly).should('be.enabled');
});
});
});
describe('post and reduce - limit order', () => {
before(() => {
cy.getByTestId(toggleLimit).click();
});
const validTIFLimit = TIFlist.filter((tif) =>
['GFA', 'GFN', 'GTC', 'GTT'].includes(tif.code)
);
validTIFLimit.forEach((tif) => {
it(`post and reduce order for limit ${tif.code}`, function () {
// 7003-SORD-054
// 7003-SORD-055
// 7003-SORD-056
// 7003-SORD-057
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
cy.getByTestId(postOnly).should('be.enabled');
cy.getByTestId(reduceOnly).should('be.disabled');
});
});
it(`can see explanation of what post only and reduce only is/does`, function () {
// 7003-SORD-058
cy.get('[for="post-only"]').should('have.text', 'Post only').realHover();
cy.getByTestId(tooltipContent).should(
'contain.text',
`"Post only" will ensure the order is not filled immediately but is placed on the order book as a passive order. When the order is processed it is either stopped (if it would not be filled immediately), or placed in the order book as a passive order until the price taker matches with it.`
);
cy.get('[for="reduce-only"]')
.should('have.text', 'Reduce only')
.realHover();
cy.getByTestId(tooltipContent).should(
'contain.text',
`"Reduce only" can be used only with non-persistent orders, such as "Fill or Kill" or "Immediate or Cancel".`
);
});
});
});
@@ -0,0 +1,25 @@
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { partyAssetsQuery } from '@vegaprotocol/mock';
describe('Portfolio page', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'PartyAssets', partyAssetsQuery());
});
cy.mockTradingPage();
cy.mockSubscription();
cy.setVegaWallet();
});
describe('Ledger entries', () => {
it('Download form should be properly rendered', () => {
// 7007-LEEN-001
cy.visit('/#/portfolio');
cy.getByTestId('"Ledger entries"').click();
cy.getByTestId('tab-ledger-entries').within(($headers) => {
cy.wrap($headers)
.getByTestId('ledger-download-button')
.should('be.visible');
});
});
});
});
@@ -0,0 +1,94 @@
const colHeader = '.ag-header-cell-text';
const colIdPrice = '[col-id=price]';
const colIdSize = '[col-id=size]';
const colIdCreatedAt = '[col-id=createdAt]';
const tradesTab = 'Trades';
const tradesTable = 'tab-trades';
describe('trades', { tags: '@smoke' }, () => {
before(() => {
cy.mockTradingPage();
cy.mockSubscription();
cy.setOnBoardingViewed();
cy.intercept('POST', '/graphql', (req) => {
if (req.body.operationName === 'Trades') {
req.alias = '@Trades';
}
});
cy.visit('/#/markets/market-0');
cy.getByTestId(tradesTab).click();
cy.wait('@Trades');
});
it('show trades', () => {
// 6005-THIS-001
// 6005-THIS-002
cy.getByTestId(tradesTab).should('be.visible');
cy.getByTestId(tradesTable).should('be.visible');
cy.getByTestId(tradesTable).should('not.be.empty');
});
it('show trades prices', () => {
// 6005-THIS-003
cy.getByTestId(tradesTable)
.get(`${colIdPrice} ${colHeader}`)
.first()
.should('have.text', 'Price');
cy.getByTestId(tradesTable)
.get(colIdPrice)
.each(($tradePrice) => {
cy.wrap($tradePrice).invoke('text').should('not.be.empty');
});
});
it('show trades sizes', () => {
// 6005-THIS-004
cy.getByTestId(tradesTable)
.get(`${colIdSize} ${colHeader}`)
.first()
.should('have.text', 'Size');
cy.getByTestId(tradesTable)
.get(colIdSize)
.each(($tradeSize) => {
cy.wrap($tradeSize).invoke('text').should('not.be.empty');
});
});
it('show trades date and time', () => {
// 6005-THIS-005
cy.getByTestId(tradesTable) // order table shares identical col id
.find(`${colIdCreatedAt} ${colHeader}`)
.should('have.text', 'Created at');
const dateTimeRegex = /(\d{1,2}):(\d{1,2}):(\d{1,2})/gm;
cy.getByTestId(tradesTable)
.get(`.ag-center-cols-container ${colIdCreatedAt}`)
.each(($tradeDateTime) => {
cy.wrap($tradeDateTime).invoke('text').should('match', dateTimeRegex);
});
});
it('trades are sorted descending by datetime', () => {
// 6005-THIS-006
const dateTimes: Date[] = [];
cy.getByTestId(tradesTable)
.find(colIdCreatedAt)
.each(($tradeDateTime, index) => {
if (index != 0) {
//ignore header
dateTimes.push(new Date($tradeDateTime.text()));
}
})
.then(() => {
expect(dateTimes).to.deep.equal(
dateTimes.sort((a, b) => b.getTime() - a.getTime())
);
});
});
it('copy price to deal ticket form', () => {
// 6005-THIS-007
cy.getByTestId('order-type-Limit').click();
cy.get(colIdPrice).last().should('be.visible').click();
cy.getByTestId('order-price').should('have.value', '171.16898');
});
});
@@ -0,0 +1,91 @@
import { selectAsset } from '../support/helpers';
const amountField = 'input[name="amount"]';
const amountShortName = 'input[name="amount"] + div + span.text-xs';
const assetSelection = 'select-asset';
const assetBalance = 'asset-balance';
const assetOption = 'rich-select-option';
const openTransferButton = 'open-transfer';
const submitTransferBtn = '[type="submit"]';
const toAddressField = '[name="toAddress"]';
const transferForm = 'transfer-form';
const ASSET_SEPOLIA_TBTC = 2;
const collateralTab = 'Collateral';
const toastCloseBtn = 'toast-close';
const toastContent = 'toast-content';
describe('withdraw actions', { tags: '@smoke', testIsolation: true }, () => {
beforeEach(() => {
cy.mockWeb3Provider();
cy.mockTradingPage();
cy.mockSubscription();
cy.setVegaWallet();
cy.visit('/#/portfolio');
cy.getByTestId(collateralTab).click();
cy.getByTestId(openTransferButton).click();
cy.wait('@Accounts');
cy.wait('@Assets');
cy.mockVegaWalletTransaction();
});
it('key to key transfers by select key', () => {
// 1003-TRAN-001
// 1003-TRAN-006
// 1003-TRAN-007
// 1003-TRAN-008
// 1003-TRAN-009
// 1003-TRAN-010
// 1003-TRAN-023
cy.getByTestId(transferForm).should('be.visible');
cy.getByTestId(transferForm).find(toAddressField).select(1);
cy.getByTestId(assetSelection).click();
cy.getByTestId(assetOption);
cy.getByTestId(assetBalance).should('not.be.empty');
cy.getByTestId(assetOption).should('have.length.gt', 4);
let optionText: string;
cy.getByTestId(assetOption)
.eq(2)
.invoke('text')
.then((text: string) => {
optionText = text;
cy.getByTestId(assetOption).eq(2).click();
cy.getByTestId(assetSelection).should('have.text', optionText);
});
cy.getByTestId(transferForm)
.find(amountField)
.type('1', { delay: 100, force: true });
cy.getByTestId(transferForm).find(amountShortName).should('not.be.empty');
cy.getByTestId(transferForm).find(submitTransferBtn).click();
cy.getByTestId(toastContent).should(
'contain.text',
'Awaiting confirmation'
);
cy.getByTestId(toastCloseBtn).click();
});
it('key to key transfers by enter manual key', () => {
//1003-TRAN-005
cy.getByTestId(transferForm).should('be.visible');
cy.contains('Enter manually').click();
cy.getByTestId(transferForm)
.find(toAddressField)
.type('7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535');
selectAsset(ASSET_SEPOLIA_TBTC);
cy.getByTestId(transferForm)
.find(amountField)
.type('1', { delay: 100, force: true });
cy.getByTestId(transferForm).find(submitTransferBtn).click();
cy.getByTestId(toastContent).should(
'contain.text',
'Awaiting confirmation'
);
cy.getByTestId(toastCloseBtn).click();
});
});
+4 -1
View File
@@ -7,6 +7,7 @@ import {
assetQuery,
assetsQuery,
candlesQuery,
chainIdQuery,
chartQuery,
depositsQuery,
estimateFeesQuery,
@@ -24,6 +25,7 @@ import {
estimatePositionQuery,
positionsQuery,
proposalListQuery,
statisticsQuery,
tradesQuery,
withdrawalsQuery,
protocolUpgradeProposalsQuery,
@@ -89,6 +91,8 @@ const mockTradingPage = (
tradingMode?: Schema.MarketTradingMode,
trigger?: Schema.AuctionTrigger
) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'NodeCheck', statisticsQuery());
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
aliasGQLQuery(
req,
@@ -214,7 +218,6 @@ export const addMockTradingPage = () => {
trigger,
oracleStatus
) => {
cy.mockChainId();
cy.mockGQL((req) => {
mockTradingPage(req, state, tradingMode, trigger);
});
-1
View File
@@ -12,7 +12,6 @@ NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
-1
View File
@@ -15,7 +15,6 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
-1
View File
@@ -16,7 +16,6 @@ NX_VEGA_CONSOLE_URL=https://console.vega.xyz
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-mainnet/codfcglpplgmmlokgilfkpcjnmkbfiel
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-mainnet
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
+1 -1
View File
@@ -16,7 +16,7 @@ NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
-1
View File
@@ -17,7 +17,6 @@ NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
@@ -1,5 +0,0 @@
import MarketPage from '../market';
export const ClosedMarketPage = () => {
return <MarketPage closed />;
};
@@ -1 +0,0 @@
export { ClosedMarketPage as default } from './closed-market';
@@ -1,10 +1,9 @@
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { DocsLinks, useEnvironment } from '@vegaprotocol/environment';
import { ButtonLink, ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
import { useEnvironment } from '@vegaprotocol/environment';
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
import { MarketProposalNotification } from '@vegaprotocol/proposals';
import type { Market } from '@vegaprotocol/markets';
import {
addDecimalsFormatNumber,
fromNanoSeconds,
getExpiryDate,
getMarketExpiryDate,
@@ -15,12 +14,9 @@ import {
Last24hVolume,
getAsset,
getDataSourceSpecForSettlementSchedule,
isMarketInAuction,
marketInfoProvider,
useFundingPeriodsQuery,
useFundingRate,
useMarketTradingMode,
useExternalTwap,
} from '@vegaprotocol/markets';
import { MarketState as State } from '@vegaprotocol/types';
import { HeaderStat } from '../../components/header';
@@ -30,7 +26,6 @@ import { MarketState } from '../../components/market-state';
import { MarketLiquiditySupplied } from '../../components/liquidity-supplied';
import { useEffect, useState } from 'react';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { PriceCell } from '@vegaprotocol/datagrid';
interface MarketHeaderStatsProps {
market: Market;
@@ -43,8 +38,34 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
const asset = getAsset(market);
return (
<div className="flex gap-8">
<HeaderStat heading={t('Mark Price')} testId="market-price">
<>
{market.tradableInstrument.instrument.product.__typename === 'Future' && (
<HeaderStat
heading={t('Expiry')}
description={
<ExpiryTooltipContent
market={market}
explorerUrl={VEGA_EXPLORER_URL}
/>
}
testId="market-expiry"
>
<ExpiryLabel market={market} />
</HeaderStat>
)}
{market.tradableInstrument.instrument.product.__typename ===
'Perpetual' && (
<HeaderStat
heading={`${t('Funding')} / ${t('Countdown')}`}
testId="market-funding"
>
<div className="flex justify-between gap-2">
<FundingRate marketId={market.id} />
<FundingCountdown marketId={market.id} />
</div>
</HeaderStat>
)}
<HeaderStat heading={t('Price')} testId="market-price">
<MarketMarkPrice
marketId={market.id}
decimalPlaces={market.decimalPlaces}
@@ -87,64 +108,8 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
marketId={market.id}
assetDecimals={asset?.decimals || 0}
/>
{market.tradableInstrument.instrument.product.__typename === 'Future' && (
<HeaderStat
heading={t('Expiry')}
description={
<ExpiryTooltipContent
market={market}
explorerUrl={VEGA_EXPLORER_URL}
/>
}
testId="market-expiry"
>
<ExpiryLabel market={market} />
</HeaderStat>
)}
{market.tradableInstrument.instrument.product.__typename ===
'Perpetual' && (
<HeaderStat
heading={`${t('Funding Rate')} / ${t('Countdown')}`}
testId="market-funding"
>
<div className="flex justify-between gap-2">
<FundingRate marketId={market.id} />
<FundingCountdown marketId={market.id} />
</div>
</HeaderStat>
)}
{market.tradableInstrument.instrument.product.__typename ===
'Perpetual' && (
<HeaderStat
heading={`${t('Index Price')}`}
description={
<div className="p1">
{t(
'The external time weighted average price (TWAP) received from the data source defined in the data sourcing specification.'
)}
{DocsLinks && (
<ExternalLink
href={DocsLinks.ETH_DATA_SOURCES}
className="mt-2"
>
{t('Find out more')}
</ExternalLink>
)}
</div>
}
testId="index-price"
>
<IndexPrice
marketId={market.id}
decimalPlaces={
market.tradableInstrument.instrument.product.settlementAsset
.decimals
}
/>
</HeaderStat>
)}
<MarketProposalNotification marketId={market.id} />
</div>
</>
);
};
@@ -161,24 +126,6 @@ export const FundingRate = ({ marketId }: { marketId: string }) => {
);
};
export const IndexPrice = ({
marketId,
decimalPlaces,
}: {
marketId: string;
decimalPlaces?: number;
}) => {
const { data: externalTwap } = useExternalTwap(marketId);
return externalTwap && decimalPlaces ? (
<PriceCell
value={Number(externalTwap)}
valueFormatted={addDecimalsFormatNumber(externalTwap, decimalPlaces)}
/>
) : (
'-'
);
};
const useNow = () => {
const [now, setNow] = useState(Date.now());
useEffect(() => {
@@ -189,11 +136,9 @@ const useNow = () => {
};
const useEvery = (marketId: string) => {
const { data: marketTradingMode } = useMarketTradingMode(marketId);
const { data: marketInfo } = useDataProvider({
dataProvider: marketInfoProvider,
variables: { marketId },
skip: !marketTradingMode || isMarketInAuction(marketTradingMode),
});
let every: number | undefined = undefined;
const sourceType =
+17 -38
View File
@@ -3,16 +3,15 @@ import { addDecimalsFormatNumber, titlefy } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
import { useThrottledDataProvider } from '@vegaprotocol/data-provider';
import { ExternalLink, Loader, Splash } from '@vegaprotocol/ui-toolkit';
import { AsyncRenderer, ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
import { getAsset, marketDataProvider, useMarket } from '@vegaprotocol/markets';
import { useGlobalStore, usePageTitleStore } from '../../stores';
import { TradeGrid } from './trade-grid';
import { TradePanels } from './trade-panels';
import { useNavigate, useParams } from 'react-router-dom';
import { Links, Routes } from '../../lib/links';
import { Links } from '../../lib/links';
import { ViewType, useSidebar } from '../../components/sidebar';
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
import { MarketState } from '@vegaprotocol/types';
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
return markPrice && decimalPlaces
@@ -57,7 +56,7 @@ const TitleUpdater = ({
return null;
};
export const MarketPage = ({ closed }: { closed?: boolean }) => {
export const MarketPage = () => {
const { marketId } = useParams();
const navigate = useNavigate();
const currentRouteId = useGetCurrentRouteId();
@@ -68,36 +67,19 @@ export const MarketPage = ({ closed }: { closed?: boolean }) => {
const update = useGlobalStore((store) => store.update);
const lastMarketId = useGlobalStore((store) => store.marketId);
const { data, loading } = useMarket(marketId);
const { data, error, loading } = useMarket(marketId);
useEffect(() => {
if (
data?.state &&
[
MarketState.STATE_SETTLED,
MarketState.STATE_TRADING_TERMINATED,
].includes(data.state) &&
currentRouteId !== Routes.CLOSED_MARKETS &&
marketId
) {
navigate(Links.CLOSED_MARKETS(marketId));
}
}, [data?.state, currentRouteId, navigate, marketId]);
useEffect(() => {
if (data?.id && data.id !== lastMarketId && !closed) {
if (data?.id && data.id !== lastMarketId) {
update({ marketId: data.id });
}
}, [update, lastMarketId, data?.id, closed]);
}, [update, lastMarketId, data?.id]);
useEffect(() => {
if (largeScreen && view === undefined) {
setViews(
{ type: closed ? ViewType.Info : ViewType.Order },
currentRouteId
);
setViews({ type: ViewType.Order }, currentRouteId);
}
}, [setViews, view, currentRouteId, largeScreen, closed]);
}, [setViews, view, currentRouteId, largeScreen]);
const pinnedAsset = data && getAsset(data);
@@ -110,15 +92,7 @@ export const MarketPage = ({ closed }: { closed?: boolean }) => {
}
}, [largeScreen, data, pinnedAsset]);
if (loading) {
return (
<Splash>
<Loader />
</Splash>
);
}
if (!data) {
if (!data && marketId) {
return (
<Splash>
<span className="flex flex-col items-center gap-2">
@@ -128,7 +102,7 @@ export const MarketPage = ({ closed }: { closed?: boolean }) => {
<p className="justify-center text-sm">
{t(`Please choose another market from the`)}{' '}
<ExternalLink onClick={() => navigate(Links.MARKETS())}>
{t('market list')}
market list
</ExternalLink>
</p>
</span>
@@ -137,13 +111,18 @@ export const MarketPage = ({ closed }: { closed?: boolean }) => {
}
return (
<>
<AsyncRenderer
loading={loading}
error={error}
data={data || undefined}
noDataCondition={(data) => false}
>
<TitleUpdater
marketId={data?.id}
marketName={data?.tradableInstrument.instrument.name}
decimalPlaces={data?.decimalPlaces}
/>
{tradeView}
</>
</AsyncRenderer>
);
};
@@ -18,7 +18,6 @@ import { TradingViews } from './trade-views';
import {
MarketSuccessorBanner,
MarketSuccessorProposalBanner,
MarketTerminationBanner,
} from '../../components/market-banner';
import { FLAGS } from '@vegaprotocol/environment';
@@ -137,10 +136,7 @@ const MainGrid = memo(
</Tab>
) : null}
<Tab id="fills" name={t('Fills')}>
<TradingViews.fills.component />
</Tab>
<Tab id="funding-payments" name={t('Funding payments')}>
<TradingViews.fundingPayments.component />
<TradingViews.fills.component marketId={marketId} />
</Tab>
<Tab
id="accounts"
@@ -173,7 +169,6 @@ export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
<MarketSuccessorProposalBanner marketId={market?.id} />
</>
)}
<MarketTerminationBanner market={market} />
<OracleBanner marketId={market?.id || ''} />
</div>
<div className="min-h-0 p-0.5">
@@ -11,7 +11,6 @@ import classNames from 'classnames';
import {
MarketSuccessorBanner,
MarketSuccessorProposalBanner,
MarketTerminationBanner,
} from '../../components/market-banner';
import { FLAGS } from '@vegaprotocol/environment';
@@ -60,7 +59,6 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
<MarketSuccessorProposalBanner marketId={market?.id} />
</>
)}
<MarketTerminationBanner market={market} />
<OracleBanner marketId={market?.id || ''} />
</div>
<div>{renderMenu()}</div>
@@ -14,7 +14,6 @@ import { PositionsContainer } from '../../components/positions-container';
import { AccountsContainer } from '../../components/accounts-container';
import { LiquidityContainer } from '../../components/liquidity-container';
import { FundingContainer } from '../../components/funding-container';
import { FundingPaymentsContainer } from '../../components/funding-payments-container';
import type { OrderContainerProps } from '../../components/orders-container';
import { OrdersContainer } from '../../components/orders-container';
import { StopOrdersContainer } from '../../components/stop-orders-container';
@@ -56,10 +55,6 @@ export const TradingViews = {
label: 'Funding',
component: requiresMarket(FundingContainer),
},
fundingPayments: {
label: 'Funding Payments',
component: FundingPaymentsContainer,
},
orderbook: {
label: 'Orderbook',
component: requiresMarket(OrderbookContainer),
@@ -1,4 +1,4 @@
import { act, render, screen, waitFor, within } from '@testing-library/react';
import { act, render, screen, within } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { Closed } from './closed';
import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types';
@@ -300,11 +300,9 @@ describe('Closed', () => {
].includes(m.node.state);
});
await waitFor(() => {
// check rows length is correct
const rows = container.getAllByRole('row');
expect(rows).toHaveLength(expectedRows.length);
});
// check rows length is correct
const rows = container.getAllByRole('row');
expect(rows).toHaveLength(expectedRows.length);
// check that only included ids are shown
const cells = screen
@@ -22,8 +22,6 @@ import { SettlementPriceCell } from './settlement-price-cell';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { MarketCodeCell } from './market-code-cell';
import { MarketActionsDropdown } from './market-table-actions';
import type { CellClickedEvent } from 'ag-grid-community';
import { useClosedMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
type SettlementAsset = Pick<
Asset,
@@ -127,7 +125,6 @@ const ClosedMarketsDataGrid = ({
rowData: Row[];
error: Error | undefined;
}) => {
const handleOnSelect = useClosedMarketClickHandler();
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
const colDefs = useMemo(() => {
@@ -284,27 +281,6 @@ const ClosedMarketsDataGrid = ({
overlayNoRowsTemplate={error ? error.message : t('No markets')}
components={components}
rowHeight={45}
onCellClicked={({ data, column, event }: CellClickedEvent<Row>) => {
if (!data) return;
// prevent navigating to the market page if any of the below cells are clicked
// event.preventDefault or event.stopPropagation dont seem to apply for aggird
const colId = column.getColId();
if (
[
'settlementDate',
'settlementDataOracleId',
'settlementAsset',
'market-actions',
].includes(colId)
) {
return;
}
// @ts-ignore metaKey exists
handleOnSelect(data.id, event ? event.metaKey : false);
}}
/>
);
};
@@ -9,9 +9,7 @@ import { usePageTitleStore } from '../../stores';
import { AccountsContainer } from '../../components/accounts-container';
import { DepositsContainer } from '../../components/deposits-container';
import { FillsContainer } from '../../components/fills-container';
import { FundingPaymentsContainer } from '../../components/funding-payments-container';
import { PositionsContainer } from '../../components/positions-container';
import { PositionsMenu } from '../../components/positions-menu';
import { WithdrawalsContainer } from '../../components/withdrawals-container';
import { OrdersContainer } from '../../components/orders-container';
import { LedgerContainer } from '../../components/ledger-container';
@@ -70,11 +68,7 @@ export const Portfolio = () => {
<Tab id="account-history" name={t('Account history')}>
<AccountHistoryContainer />
</Tab>
<Tab
id="positions"
name={t('Positions')}
menu={<PositionsMenu />}
>
<Tab id="positions" name={t('Positions')}>
<PositionsContainer allKeys />
</Tab>
<Tab id="orders" name={t('Orders')}>
@@ -83,9 +77,6 @@ export const Portfolio = () => {
<Tab id="fills" name={t('Fills')}>
<FillsContainer />
</Tab>
<Tab id="funding-payments" name={t('Funding payments')}>
<FundingPaymentsContainer />
</Tab>
<Tab id="ledger-entries" name={t('Ledger entries')}>
<LedgerContainer />
</Tab>
@@ -10,10 +10,12 @@ import classNames from 'classnames';
import { Navigate, useSearchParams } from 'react-router-dom';
import { useEffect, useRef, useState } from 'react';
import { Button } from './buttons';
import { useVegaWallet } from '@vegaprotocol/wallet';
import {
useTransactionEventSubscription,
useVegaWallet,
} from '@vegaprotocol/wallet';
import { useReferral } from './hooks/use-referral';
import { Routes } from '../../lib/links';
import { useTransactionEventSubscription } from '@vegaprotocol/web3';
export const ApplyCodeForm = () => {
const [status, setStatus] = useState<
@@ -1,7 +1,6 @@
import type { InMemoryCacheConfig } from '@apollo/client';
import {
AppFailure,
AppLoader,
DocsLinks,
NetworkLoader,
NodeGuard,
@@ -10,10 +9,15 @@ import {
import { t } from '@vegaprotocol/i18n';
import { MaintenancePage } from '@vegaprotocol/ui-toolkit';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';
import { Web3Provider } from './web3-provider';
export const Bootstrapper = ({ children }: { children: ReactNode }) => {
export const DynamicLoader = dynamic(() => import('../preloader/preloader'), {
loading: () => <>Loading...</>,
});
export const AppLoader = ({ children }: { children: ReactNode }) => {
const {
error,
VEGA_URL,
@@ -43,13 +47,13 @@ export const Bootstrapper = ({ children }: { children: ReactNode }) => {
return (
<NetworkLoader
cache={cacheConfig}
skeleton={<AppLoader />}
skeleton={<DynamicLoader />}
failure={
<AppFailure title={t('Could not initialize app')} error={error} />
}
>
<NodeGuard
skeleton={<AppLoader />}
skeleton={<DynamicLoader />}
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
>
<Web3Provider>
@@ -1,2 +1,2 @@
export * from './bootstrapper';
export * from './app-loader';
export * from './web3-provider';

Some files were not shown because too many files have changed in this diff Show More