feat: add market termination warning banner - resolve conflicts
This commit is contained in:
@@ -5,6 +5,7 @@ on:
|
||||
branches:
|
||||
- release/*
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
@@ -178,10 +179,33 @@ jobs:
|
||||
# with:
|
||||
# github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
cypress:
|
||||
check-e2e-needed:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-sources
|
||||
name: '(CI) check if e2e needed'
|
||||
outputs:
|
||||
run-tests: ${{ steps.check-test.outputs.e2e-needed }}
|
||||
steps:
|
||||
- name: Check branch
|
||||
id: check-test
|
||||
run: |
|
||||
if [[ "${{ github.base_ref }}" == "develop" ]]; then
|
||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.base_ref }}" == "main" ]]; then
|
||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
|
||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "e2e-needed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Print result
|
||||
run: |
|
||||
echo "e2e-needed: ${{ steps.check-test.outputs.e2e-needed }}"
|
||||
|
||||
cypress:
|
||||
needs: [build-sources, check-e2e-needed]
|
||||
name: '(CI) cypress'
|
||||
# if: ${{ needs.build-sources.outputs.projects-e2e != '[]' }}
|
||||
if: ${{ needs.check-e2e-needed.outputs.run-tests == 'true' }}
|
||||
uses: ./.github/workflows/cypress-run.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
|
||||
@@ -21,12 +21,19 @@ 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
|
||||
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
|
||||
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "runner=self-hosted-runner" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Print runner
|
||||
run: echo ${{ steps.step.outputs.runner }}
|
||||
|
||||
e2e:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -78,6 +85,7 @@ jobs:
|
||||
- name: Run Vegacapsule network and Vega wallet
|
||||
id: setup-vega
|
||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||
timeout-minutes: 10
|
||||
|
||||
######
|
||||
## Run some tests
|
||||
|
||||
@@ -6,6 +6,8 @@ on:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- reopened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
lint_pr:
|
||||
|
||||
@@ -30,12 +30,18 @@ jobs:
|
||||
echo IS_IPFS_RELEASE=false >> $GITHUB_ENV
|
||||
echo IS_S3_RELEASE=false >> $GITHUB_ENV
|
||||
echo IS_DEV_IMAGE=false >> $GITHUB_ENV
|
||||
echo IS_MAIN_IMAGE=false >> $GITHUB_ENV
|
||||
|
||||
- name: Is dev image
|
||||
if: ${{ contains(github.ref, 'develop') && github.event_name == 'push' && matrix.app == 'trading' }}
|
||||
if: ${{ github.ref_name == 'develop' && github.event_name == 'push' && matrix.app == 'trading' }}
|
||||
run: |
|
||||
echo IS_DEV_IMAGE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is main image
|
||||
if: ${{ github.ref_name == 'main' && github.event_name == 'push' && matrix.app == 'trading' }}
|
||||
run: |
|
||||
echo IS_MAIN_IMAGE=true >> $GITHUB_ENV
|
||||
|
||||
- name: Is PR
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
@@ -57,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' }}
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' && github.ref_name != 'main'}}
|
||||
run: |
|
||||
echo IS_S3_RELEASE=true >> $GITHUB_ENV
|
||||
|
||||
@@ -81,7 +87,7 @@ jobs:
|
||||
|
||||
- name: Log in to the Container registry (docker hub)
|
||||
uses: docker/login-action@v2
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -179,7 +185,7 @@ jobs:
|
||||
uses: docker/build-push-action@v3
|
||||
continue-on-error: true
|
||||
id: dockerhub-push
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
|
||||
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
|
||||
with:
|
||||
context: .
|
||||
file: docker/node-outside-docker.Dockerfile
|
||||
@@ -189,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' || '' }}
|
||||
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
|
||||
@@ -216,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' || '' }}
|
||||
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
|
||||
|
||||
@@ -87,7 +87,13 @@ context('Market page', { tags: '@regression' }, function () {
|
||||
// Liquidity
|
||||
cy.validate_element_from_table('Target Stake', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Supplied Stake', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Market Value Proxy', '0.00 fUSDC');
|
||||
// Liquidity price range
|
||||
cy.validate_element_from_table(
|
||||
'Liquidity Price Range',
|
||||
'1,000.00% of mid price'
|
||||
);
|
||||
cy.validate_element_from_table('Lowest Price', '0.00 fUSDC');
|
||||
cy.validate_element_from_table('Highest Price', '0.00 fUSDC');
|
||||
cy.getByTestId('oracle-spec-links')
|
||||
.should('have.attr', 'href')
|
||||
.and(
|
||||
|
||||
@@ -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();
|
||||
cy.getByTestId('node-url-custom').click({ force: true });
|
||||
|
||||
cy.getByTestId(customNodeBtn).within(() => {
|
||||
cy.get('input').clear().type('fakeUrl');
|
||||
|
||||
@@ -49,6 +49,37 @@ 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 {
|
||||
|
||||
+34
-3
@@ -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' } } | { __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', 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 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' } } | { __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', 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 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' } } | { __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', 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 const ExplorerOracleDataConnectionFragmentDoc = gql`
|
||||
fragment ExplorerOracleDataConnection on OracleSpec {
|
||||
@@ -72,6 +72,37 @@ 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,7 +8,9 @@ import { useScrollToLocation } from '../../../hooks/scroll-to-location';
|
||||
import filter from 'recursive-key-filter';
|
||||
|
||||
const Oracles = () => {
|
||||
const { data, loading, error } = useExplorerOracleSpecsQuery();
|
||||
const { data, loading, error } = useExplorerOracleSpecsQuery({
|
||||
errorPolicy: 'ignore',
|
||||
});
|
||||
|
||||
useDocumentTitle(['Oracles']);
|
||||
useScrollToLocation();
|
||||
|
||||
@@ -22,6 +22,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,17 @@ 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 () {
|
||||
@@ -298,9 +309,6 @@ 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)
|
||||
@@ -309,14 +317,9 @@ describe(
|
||||
cy.getByTestId(viewProposalButton).click();
|
||||
});
|
||||
});
|
||||
getProposalInformationFromTable('ID')
|
||||
.invoke('text')
|
||||
.as('parentMarketId')
|
||||
.then(() => {
|
||||
cy.VegaWalletSubmitProposal(
|
||||
createSuccessorMarketProposalTxBody(this.parentMarketId)
|
||||
);
|
||||
});
|
||||
cy.VegaWalletSubmitProposal(
|
||||
createSuccessorMarketProposalTxBody(this.parentMarketId)
|
||||
);
|
||||
navigateTo(navigation.proposals);
|
||||
cy.reload();
|
||||
getProposalFromTitle('Test successor market proposal details').within(
|
||||
@@ -434,5 +437,87 @@ describe(
|
||||
'Minimum 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'
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -310,7 +310,9 @@ context(
|
||||
closeStakingDialog();
|
||||
navigateTo(navigation.validators);
|
||||
clickOnValidatorFromList(0);
|
||||
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click();
|
||||
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click({
|
||||
force: true,
|
||||
});
|
||||
cy.getByTestId(stakeTokenAmountInputBox).type('-0.1');
|
||||
cy.contains('Waiting for next epoch to start', epochTimeout);
|
||||
cy.getByTestId(stakeTokenSubmitButton)
|
||||
@@ -331,7 +333,7 @@ context(
|
||||
closeStakingDialog();
|
||||
navigateTo(navigation.validators);
|
||||
clickOnValidatorFromList(0);
|
||||
cy.getByTestId(stakeRemoveStakeRadioButton).click();
|
||||
cy.getByTestId(stakeRemoveStakeRadioButton).click({ force: true });
|
||||
cy.getByTestId(stakeTokenAmountInputBox).type('4');
|
||||
cy.contains('Waiting for next epoch to start', epochTimeout);
|
||||
cy.getByTestId(stakeTokenSubmitButton)
|
||||
|
||||
@@ -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();
|
||||
cy.getByTestId('node-url-custom').click({ force: true });
|
||||
cy.get('input').should('exist');
|
||||
cy.getByTestId('connect').should('be.disabled');
|
||||
cy.getByTestId('icon-cross').click();
|
||||
|
||||
@@ -11,7 +11,6 @@ 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';
|
||||
@@ -38,17 +37,11 @@ const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
context('Validators Page - verify elements on page', function () {
|
||||
before('navigate to validators page', () => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
cy.visit('/validators');
|
||||
});
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
});
|
||||
|
||||
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
||||
@@ -189,10 +182,7 @@ context('Validators Page - verify elements on page', function () {
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
before('connect wallets and click on validator', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
cy.visit('/validators');
|
||||
cy.connectVegaWallet();
|
||||
clickOnValidatorFromList(0);
|
||||
|
||||
@@ -4,8 +4,6 @@ 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';
|
||||
@@ -88,10 +86,7 @@ context(
|
||||
|
||||
describe('when vega wallet connected', function () {
|
||||
before('connect vega wallet', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
cy.visit('/');
|
||||
cy.wait('@ChainId');
|
||||
cy.connectVegaWallet();
|
||||
@@ -276,10 +271,7 @@ context(
|
||||
];
|
||||
|
||||
before('faucet assets to connected vega wallet', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
for (const { id, amount } of assets) {
|
||||
vegaWalletFaucetAssetsWithoutCheck(id, amount, vegaWalletPublicKey);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ export function submitUniqueRawProposal(proposalFields: {
|
||||
proposalBody?: string;
|
||||
proposalTitle?: string;
|
||||
proposalDescription?: string;
|
||||
updateMarketId?: string;
|
||||
closingTimestamp?: number;
|
||||
enactmentTimestamp?: number;
|
||||
submit?: boolean;
|
||||
@@ -71,6 +72,10 @@ 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 (
|
||||
|
||||
@@ -9,8 +9,6 @@ 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();
|
||||
|
||||
@@ -29,10 +27,7 @@ before(() => {
|
||||
// // Ensuring the telemetry modal doesn't disrupt the tests
|
||||
turnTelemetryOff();
|
||||
// Mock chainId fetch which happens on every page for wallet connection
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.mockChainId();
|
||||
// Self stake validators so they are displayed
|
||||
cy.validatorsSelfDelegate();
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
cy.get(removeStakeRadioButton, epochTimeout).click({ force: true });
|
||||
cy.get(tokenAmountInputBox).type(stake);
|
||||
waitForBeginningOfEpoch();
|
||||
cy.get(tokenSubmitButton)
|
||||
@@ -70,9 +70,13 @@ export function stakingPageAssociateTokens(
|
||||
cy.highlight(`Associating ${amount} tokens from ${type}`);
|
||||
cy.get(ethWalletAssociateButton).first().click();
|
||||
if (type === 'wallet') {
|
||||
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
|
||||
cy.get(associateWalletRadioButton, { timeout: 30000 }).click({
|
||||
force: true,
|
||||
});
|
||||
} else if (type === 'contract') {
|
||||
cy.get(associateContractRadioButton, { timeout: 30000 }).click();
|
||||
cy.get(associateContractRadioButton, { timeout: 30000 }).click({
|
||||
force: true,
|
||||
});
|
||||
} else {
|
||||
cy.highlight(`${type} is not association option`);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ NX_FAIRGROUND=false
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_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
|
||||
|
||||
@@ -34,3 +35,4 @@ NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=false
|
||||
NX_UPDATE_MARKET_STATE=false
|
||||
NX_GOVERNANCE_TRANSFERS=false
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ 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
|
||||
@@ -22,3 +23,4 @@ NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_GOVERNANCE_TRANSFERS=true
|
||||
|
||||
@@ -15,6 +15,7 @@ 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
|
||||
|
||||
@@ -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,
|
||||
VegaWalletProvider,
|
||||
} from '@vegaprotocol/wallet';
|
||||
} from '@vegaprotocol/web3';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||
import {
|
||||
|
||||
@@ -888,5 +888,7 @@
|
||||
"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"
|
||||
"HowToProposeRawStep3": "3. Submit on-chain below",
|
||||
"proposalTransferDetails": "New governance transfer details",
|
||||
"proposalCancelTransferDetails": "Cancel governance transfer details"
|
||||
}
|
||||
|
||||
+53
-1
@@ -7,12 +7,17 @@ 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 { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
|
||||
import {
|
||||
useCancelTransferProposalDetails,
|
||||
useNewTransferProposalDetails,
|
||||
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,
|
||||
@@ -147,6 +152,20 @@ 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 (
|
||||
@@ -224,3 +243,36 @@ 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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './proposal-transfer-details';
|
||||
export * from './proposal-cancel-transfer-details';
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -20,6 +20,11 @@ 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'];
|
||||
@@ -99,9 +104,37 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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">
|
||||
@@ -187,6 +220,8 @@ export const Proposal = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{governanceTransferDetails}
|
||||
|
||||
<div className="mb-10">
|
||||
<RoundedWrapper paddingBottom={true}>
|
||||
<UserVote
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
||||
getProposalDialogTitle,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import type { ProposalEventFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import type { DialogProps } from '@vegaprotocol/wallet';
|
||||
import type { DialogProps } from '@vegaprotocol/proposals';
|
||||
|
||||
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/wallet';
|
||||
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import type { VoteState } from './use-user-vote';
|
||||
|
||||
+1
-1
@@ -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/wallet';
|
||||
import { VegaTxStatus } from '@vegaprotocol/proposals';
|
||||
|
||||
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/wallet';
|
||||
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
|
||||
|
||||
interface VoteButtonsContainerProps {
|
||||
voteState: VoteState | null;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { VoteState } from './use-user-vote';
|
||||
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
|
||||
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
|
||||
|
||||
interface VoteTransactionDialogProps {
|
||||
voteState: VoteState;
|
||||
|
||||
@@ -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();
|
||||
cy.getByTestId('node-url-custom').click({ force: true });
|
||||
cy.getByTestId('connect').should('be.disabled');
|
||||
cy.get("input[placeholder='https://']")
|
||||
.focus()
|
||||
|
||||
@@ -11,102 +11,8 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
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', () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
// 7001-COLL-009
|
||||
cy.get('[col-id="used"]').contains('1.01').click();
|
||||
const headers = ['Market', 'Account type', 'Balance', 'Margin health'];
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
testOrderAmendment,
|
||||
} from '../support/order-validation';
|
||||
|
||||
const orderSymbol = 'market.tradableInstrument.instrument.code';
|
||||
const orderSymbol = 'instrument-code';
|
||||
const orderSize = 'size';
|
||||
const orderType = 'type';
|
||||
const orderStatus = 'status';
|
||||
@@ -229,10 +229,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
});
|
||||
cy.getByTestId(`order-status-${orderId}`).should('have.text', 'Filled');
|
||||
cy.get('[col-id="market.tradableInstrument.instrument.code"]').contains(
|
||||
'[title="Future"]',
|
||||
'Futr'
|
||||
);
|
||||
cy.get(`[col-id="${orderSymbol}"]`).contains('[title="Future"]', 'Futr');
|
||||
});
|
||||
|
||||
it('must see a rejected order', () => {
|
||||
|
||||
+2
-83
@@ -1,92 +1,11 @@
|
||||
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.skip(
|
||||
'account validation',
|
||||
describe(
|
||||
'vega wallet - prompt',
|
||||
{ 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(() => {
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
assetQuery,
|
||||
assetsQuery,
|
||||
candlesQuery,
|
||||
chainIdQuery,
|
||||
chartQuery,
|
||||
depositsQuery,
|
||||
estimateFeesQuery,
|
||||
@@ -25,7 +24,6 @@ import {
|
||||
estimatePositionQuery,
|
||||
positionsQuery,
|
||||
proposalListQuery,
|
||||
statisticsQuery,
|
||||
tradesQuery,
|
||||
withdrawalsQuery,
|
||||
protocolUpgradeProposalsQuery,
|
||||
@@ -91,8 +89,6 @@ const mockTradingPage = (
|
||||
tradingMode?: Schema.MarketTradingMode,
|
||||
trigger?: Schema.AuctionTrigger
|
||||
) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'NodeCheck', statisticsQuery());
|
||||
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
@@ -218,6 +214,7 @@ export const addMockTradingPage = () => {
|
||||
trigger,
|
||||
oracleStatus
|
||||
) => {
|
||||
cy.mockChainId();
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, state, tradingMode, trigger);
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ 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
|
||||
|
||||
@@ -15,6 +15,7 @@ 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
|
||||
|
||||
@@ -16,6 +16,7 @@ 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,7 @@ 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
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import MarketPage from '../market';
|
||||
|
||||
export const ClosedMarketPage = () => {
|
||||
return <MarketPage closed />;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { ClosedMarketPage as default } from './closed-market';
|
||||
@@ -9,9 +9,10 @@ import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
import { TradeGrid } from './trade-grid';
|
||||
import { TradePanels } from './trade-panels';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links } from '../../lib/links';
|
||||
import { Links, Routes } 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
|
||||
@@ -56,7 +57,7 @@ const TitleUpdater = ({
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MarketPage = () => {
|
||||
export const MarketPage = ({ closed }: { closed?: boolean }) => {
|
||||
const { marketId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
@@ -70,16 +71,33 @@ export const MarketPage = () => {
|
||||
const { data, error, loading } = useMarket(marketId);
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.id && data.id !== lastMarketId) {
|
||||
if (
|
||||
data?.state &&
|
||||
[
|
||||
MarketState.STATE_SETTLED,
|
||||
MarketState.STATE_TRADING_TERMINATED,
|
||||
].includes(data.state) &&
|
||||
currentRouteId !== Routes.CLOSED_MARKETS &&
|
||||
marketId
|
||||
) {
|
||||
navigate(Links.CLOSED_MARKETS(marketId));
|
||||
}
|
||||
}, [data?.state, currentRouteId, navigate, marketId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.id && data.id !== lastMarketId && !closed) {
|
||||
update({ marketId: data.id });
|
||||
}
|
||||
}, [update, lastMarketId, data?.id]);
|
||||
}, [update, lastMarketId, data?.id, closed]);
|
||||
|
||||
useEffect(() => {
|
||||
if (largeScreen && view === undefined) {
|
||||
setViews({ type: ViewType.Order }, currentRouteId);
|
||||
setViews(
|
||||
{ type: closed ? ViewType.Info : ViewType.Order },
|
||||
currentRouteId
|
||||
);
|
||||
}
|
||||
}, [setViews, view, currentRouteId, largeScreen]);
|
||||
}, [setViews, view, currentRouteId, largeScreen, closed]);
|
||||
|
||||
const pinnedAsset = data && getAsset(data);
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ const MainGrid = memo(
|
||||
</Tab>
|
||||
) : null}
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
<TradingViews.fills.component marketId={marketId} />
|
||||
<TradingViews.fills.component />
|
||||
</Tab>
|
||||
<Tab
|
||||
id="accounts"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { act, render, screen, within } from '@testing-library/react';
|
||||
import { act, render, screen, waitFor, within } from '@testing-library/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { Closed } from './closed';
|
||||
import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types';
|
||||
@@ -300,9 +300,11 @@ describe('Closed', () => {
|
||||
].includes(m.node.state);
|
||||
});
|
||||
|
||||
// check rows length is correct
|
||||
const rows = container.getAllByRole('row');
|
||||
expect(rows).toHaveLength(expectedRows.length);
|
||||
await waitFor(() => {
|
||||
// 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,6 +22,8 @@ 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,
|
||||
@@ -125,6 +127,7 @@ const ClosedMarketsDataGrid = ({
|
||||
rowData: Row[];
|
||||
error: Error | undefined;
|
||||
}) => {
|
||||
const handleOnSelect = useClosedMarketClickHandler();
|
||||
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
|
||||
|
||||
const colDefs = useMemo(() => {
|
||||
@@ -281,6 +284,27 @@ 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);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,12 +10,10 @@ import classNames from 'classnames';
|
||||
import { Navigate, useSearchParams } from 'react-router-dom';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Button } from './buttons';
|
||||
import {
|
||||
useTransactionEventSubscription,
|
||||
useVegaWallet,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { 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<
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const FillsContainer = ({ marketId }: { marketId?: string }) => {
|
||||
export const FillsContainer = () => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
@@ -31,7 +31,6 @@ export const FillsContainer = ({ marketId }: { marketId?: string }) => {
|
||||
return (
|
||||
<FillsManager
|
||||
partyId={pubKey}
|
||||
marketId={marketId}
|
||||
onMarketClick={onMarketClick}
|
||||
gridProps={gridStoreCallbacks}
|
||||
/>
|
||||
|
||||
@@ -23,6 +23,10 @@ export const LayoutWithSidebar = () => {
|
||||
<div className="col-span-full">
|
||||
<Routes>
|
||||
<Route path="markets/:marketId" element={<MarketHeader />} />
|
||||
<Route
|
||||
path="markets/all/closed/:marketId"
|
||||
element={<MarketHeader />}
|
||||
/>
|
||||
<Route path="liquidity/:marketId" element={<LiquidityHeader />} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,6 @@ import {
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { ExternalLink, Indicator } from '@vegaprotocol/ui-toolkit';
|
||||
import { DocsLinks } from '@vegaprotocol/environment';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { useCheckLiquidityStatus } from '@vegaprotocol/liquidity';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
@@ -31,12 +27,8 @@ export const LiquidityHeader = () => {
|
||||
const assetDecimalPlaces = asset?.decimals || 0;
|
||||
const symbol = asset?.symbol;
|
||||
|
||||
const { params } = useNetworkParams([
|
||||
NetworkParams.market_liquidity_stakeToCcyVolume,
|
||||
NetworkParams.market_liquidity_targetstake_triggering_ratio,
|
||||
]);
|
||||
const triggeringRatio =
|
||||
params.market_liquidity_targetstake_triggering_ratio || '1';
|
||||
market?.liquidityMonitoringParameters.triggeringRatio || '1';
|
||||
|
||||
const { percentage, status } = useCheckLiquidityStatus({
|
||||
suppliedStake: suppliedStake || 0,
|
||||
|
||||
@@ -61,7 +61,6 @@ describe('MarketSelectorItem', () => {
|
||||
indicativeVolume: '100',
|
||||
marketState: MarketState.STATE_ACTIVE,
|
||||
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketValueProxy: '100',
|
||||
markPrice: '50000',
|
||||
midPrice: '100',
|
||||
staticMidPrice: '100',
|
||||
|
||||
@@ -126,10 +126,12 @@ export const MarketSelector = ({
|
||||
onSelect={onSelect}
|
||||
noItems={
|
||||
filter.product === Product.Perpetual
|
||||
? t('Perpetual markets coming soon.')
|
||||
? t('No perpetual markets.')
|
||||
: filter.product === Product.Spot
|
||||
? t('Spot markets coming soon.')
|
||||
: t('No markets')
|
||||
: filter.product === Product.Future
|
||||
? t('No future markets.')
|
||||
: t('No markets.')
|
||||
}
|
||||
allProducts={allProducts}
|
||||
/>
|
||||
|
||||
@@ -7,6 +7,8 @@ import * as Schema from '@vegaprotocol/types';
|
||||
import { HeaderStat } from '../header';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import * as constants from '../constants';
|
||||
import { DocsLinks } from '@vegaprotocol/environment';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const MarketState = ({ market }: { market: Market | null }) => {
|
||||
const [marketState, setMarketState] = useState<Schema.MarketState | null>(
|
||||
@@ -90,5 +92,20 @@ const getMarketStateTooltip = (state: Schema.MarketState | null) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (state === Schema.MarketState.STATE_SUSPENDED_VIA_GOVERNANCE) {
|
||||
return (
|
||||
<p>
|
||||
{t(
|
||||
`This market has been suspended via a governance vote and can be resumed or terminated by further votes.`
|
||||
)}
|
||||
{DocsLinks && (
|
||||
<ExternalLink href={DocsLinks.MARKET_LIFECYCLE} className="ml-1">
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
@@ -28,14 +28,20 @@ export interface OrderContainerProps {
|
||||
filter?: Filter;
|
||||
}
|
||||
|
||||
const AUTO_SIZE_COLUMNS = ['instrument-code'];
|
||||
|
||||
export const OrdersContainer = ({ filter }: OrderContainerProps) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||
const { gridState, updateGridState } = useOrderListGridState(filter);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridState, (newState) => {
|
||||
updateGridState(filter, newState);
|
||||
});
|
||||
const gridStoreCallbacks = useDataGridEvents(
|
||||
gridState,
|
||||
(newState) => {
|
||||
updateGridState(filter, newState);
|
||||
},
|
||||
AUTO_SIZE_COLUMNS
|
||||
);
|
||||
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
|
||||
@@ -10,6 +10,8 @@ import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
const AUTO_SIZE_COLUMNS = ['marketCode'];
|
||||
|
||||
export const PositionsContainer = ({ allKeys }: { allKeys?: boolean }) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const { pubKey, pubKeys, isReadOnly } = useVegaWallet();
|
||||
@@ -17,7 +19,11 @@ export const PositionsContainer = ({ allKeys }: { allKeys?: boolean }) => {
|
||||
const showClosed = usePositionsStore((store) => store.showClosedMarkets);
|
||||
const gridStore = usePositionsStore((store) => store.gridStore);
|
||||
const updateGridStore = usePositionsStore((store) => store.updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridStore, updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(
|
||||
gridStore,
|
||||
updateGridStore,
|
||||
AUTO_SIZE_COLUMNS
|
||||
);
|
||||
|
||||
if (!pubKey) {
|
||||
return (
|
||||
|
||||
@@ -135,6 +135,21 @@ export const Sidebar = () => {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="markets/all/closed/:marketId"
|
||||
element={
|
||||
<>
|
||||
<AssetSidebarButtons />
|
||||
<SidebarDivider />
|
||||
<SidebarButton
|
||||
view={ViewType.Info}
|
||||
icon={VegaIconNames.BREAKDOWN}
|
||||
tooltip={t('Market specification')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</nav>
|
||||
<nav className={classNames(navClasses, 'ml-auto lg:mt-auto lg:ml-0')}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { WithdrawFormContainer } from '@vegaprotocol/withdraws';
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/web3';
|
||||
|
||||
export const WithdrawContainer = ({ assetId }: { assetId?: string }) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
@@ -20,3 +20,16 @@ export const useMarketLiquidityClickHandler = () => {
|
||||
window.open(`/#/liquidity/${selectedId}`, metaKey ? '_blank' : '_self');
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const useClosedMarketClickHandler = (replace = false) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (selectedId: string, metaKey?: boolean) => {
|
||||
const link = Links.CLOSED_MARKETS(selectedId);
|
||||
if (metaKey) {
|
||||
window.open(`/#${link}`, '_blank');
|
||||
} else {
|
||||
navigate(link, { replace });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import trimEnd from 'lodash/trimEnd';
|
||||
export const Routes = {
|
||||
HOME: '/',
|
||||
MARKETS: '/markets/all',
|
||||
CLOSED_MARKETS: '/markets/all/closed/:marketId',
|
||||
MARKET: '/markets/:marketId',
|
||||
LIQUIDITY: '/liquidity/:marketId',
|
||||
PORTFOLIO: '/portfolio',
|
||||
@@ -28,6 +29,8 @@ export const Links: ConsoleLinks = {
|
||||
MARKET: (marketId: string) =>
|
||||
trimEnd(Routes.MARKET.replace(':marketId', marketId)),
|
||||
MARKETS: () => Routes.MARKETS,
|
||||
CLOSED_MARKETS: (marketId: string) =>
|
||||
trimEnd(Routes.CLOSED_MARKETS.replace(':marketId', marketId)),
|
||||
PORTFOLIO: () => Routes.PORTFOLIO,
|
||||
LIQUIDITY: (marketId: string) =>
|
||||
trimEnd(Routes.LIQUIDITY.replace(':marketId', marketId)),
|
||||
|
||||
@@ -5,6 +5,7 @@ const MARKET_TEMPLATE = [
|
||||
MarketState.STATE_ACTIVE,
|
||||
MarketState.STATE_SUSPENDED,
|
||||
MarketState.STATE_PENDING,
|
||||
MarketState.STATE_SUSPENDED_VIA_GOVERNANCE,
|
||||
];
|
||||
|
||||
export const isMarketActive = (state: MarketState) => {
|
||||
|
||||
@@ -4,10 +4,12 @@ import type { AppProps } from 'next/app';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
useEagerConnect as useVegaEagerConnect,
|
||||
useVegaTransactionManager,
|
||||
useVegaTransactionUpdater,
|
||||
useVegaWallet,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import {
|
||||
useVegaTransactionManager,
|
||||
useVegaTransactionUpdater,
|
||||
} from '@vegaprotocol/web3';
|
||||
import {
|
||||
useEagerConnect as useEthereumEagerConnect,
|
||||
useEthTransactionManager,
|
||||
|
||||
@@ -26,6 +26,7 @@ import { FLAGS } from '@vegaprotocol/environment';
|
||||
// These must remain dynamically imported as pennant cannot be compiled by nextjs due to ESM
|
||||
// Using dynamic imports is a workaround for this until pennant is published as ESM
|
||||
const MarketPage = lazy(() => import('../client-pages/market'));
|
||||
const ClosedMarketPage = lazy(() => import('../client-pages/closed-market'));
|
||||
const Portfolio = lazy(() => import('../client-pages/portfolio'));
|
||||
|
||||
const NotFound = () => (
|
||||
@@ -101,6 +102,11 @@ export const routerConfig: RouteObject[] = compact([
|
||||
element: <MarketPage />,
|
||||
id: Routes.MARKET,
|
||||
},
|
||||
{
|
||||
path: 'all/closed/:marketId',
|
||||
element: <ClosedMarketPage />,
|
||||
id: Routes.CLOSED_MARKETS,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import { AccountsActionsDropdown } from './accounts-actions-dropdown';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
describe('AccountsActionsDropdown', () => {
|
||||
let onClickDeposit: jest.Mock;
|
||||
let onClickWithdraw: jest.Mock;
|
||||
let onClickBreakdown: jest.Mock;
|
||||
let onClickTransfer: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
onClickDeposit = jest.fn();
|
||||
onClickWithdraw = jest.fn();
|
||||
onClickBreakdown = jest.fn();
|
||||
onClickTransfer = jest.fn();
|
||||
});
|
||||
|
||||
it('should render dropdown items correctly', async () => {
|
||||
// 7001-COLL-005
|
||||
// 7001-COLL-006
|
||||
// 1003-TRAN-001
|
||||
render(
|
||||
<AccountsActionsDropdown
|
||||
assetId="testAssetId"
|
||||
assetContractAddress="testAssetContractAddress"
|
||||
onClickDeposit={onClickDeposit}
|
||||
onClickWithdraw={onClickWithdraw}
|
||||
onClickBreakdown={onClickBreakdown}
|
||||
onClickTransfer={onClickTransfer}
|
||||
/>
|
||||
);
|
||||
|
||||
await userEvent.click(screen.getByTestId('icon-kebab'));
|
||||
|
||||
expect(screen.getByTestId('deposit')).toHaveTextContent('Deposit');
|
||||
expect(screen.getByTestId('withdraw')).toHaveTextContent('Withdraw');
|
||||
expect(screen.getByTestId('transfer')).toHaveTextContent('Transfer');
|
||||
expect(screen.getByTestId('breakdown')).toHaveTextContent(
|
||||
'View usage breakdown'
|
||||
);
|
||||
expect(screen.getByText('View asset details')).toBeInTheDocument();
|
||||
expect(screen.getByText('Copy asset ID')).toBeInTheDocument();
|
||||
expect(screen.getByText('View on Etherscan')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call callback functions on click', async () => {
|
||||
render(
|
||||
<AccountsActionsDropdown
|
||||
assetId="testAssetId"
|
||||
assetContractAddress="testAssetContractAddress"
|
||||
onClickDeposit={onClickDeposit}
|
||||
onClickWithdraw={onClickWithdraw}
|
||||
onClickBreakdown={onClickBreakdown}
|
||||
onClickTransfer={onClickTransfer}
|
||||
/>
|
||||
);
|
||||
|
||||
await userEvent.click(screen.getByTestId('icon-kebab'));
|
||||
await userEvent.click(screen.getByTestId('deposit'));
|
||||
expect(onClickDeposit).toHaveBeenCalledTimes(1);
|
||||
|
||||
await userEvent.click(screen.getByTestId('icon-kebab'));
|
||||
await userEvent.click(screen.getByTestId('withdraw'));
|
||||
expect(onClickWithdraw).toHaveBeenCalledTimes(1);
|
||||
|
||||
await userEvent.click(screen.getByTestId('icon-kebab'));
|
||||
await userEvent.click(screen.getByTestId('transfer'));
|
||||
expect(onClickTransfer).toHaveBeenCalledTimes(1);
|
||||
|
||||
await userEvent.click(screen.getByTestId('icon-kebab'));
|
||||
await userEvent.click(screen.getByTestId('breakdown'));
|
||||
expect(onClickBreakdown).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
@@ -26,6 +26,13 @@ const singleRowData = [singleRow];
|
||||
|
||||
describe('AccountsTable', () => {
|
||||
it('should render correct columns', async () => {
|
||||
// 7001-COLL-001
|
||||
// 7001-COLL-002
|
||||
// 7001-COLL-003
|
||||
// 7001-COLL-004
|
||||
// 7001-COLL-007
|
||||
// 1003-TRAN-001
|
||||
// 7001-COLL-012
|
||||
await act(async () => {
|
||||
render(
|
||||
<AccountTable
|
||||
|
||||
@@ -37,6 +37,7 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
|
||||
headerName: t('Market'),
|
||||
field: 'market.tradableInstrument.instrument.code',
|
||||
minWidth: 200,
|
||||
sort: 'desc',
|
||||
cellRenderer: ({
|
||||
value,
|
||||
data,
|
||||
@@ -140,6 +141,7 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
|
||||
tooltipShowDelay={500}
|
||||
defaultColDef={defaultColDef}
|
||||
columnDefs={coldefs}
|
||||
domLayout="autoHeight"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import type { Transfer } from '@vegaprotocol/wallet';
|
||||
import { useVegaTransactionStore, useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/web3';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { accountsDataProvider } from './accounts-data-provider';
|
||||
import { TransferForm } from './transfer-form';
|
||||
|
||||
@@ -258,21 +258,21 @@ export const TransferForm = ({
|
||||
)}
|
||||
</TradingFormGroup>
|
||||
<div className="mb-4">
|
||||
<TradingCheckbox
|
||||
name="include-transfer-fee"
|
||||
disabled={!transferAmount}
|
||||
label={
|
||||
<Tooltip
|
||||
description={t(
|
||||
`The fee will be taken from the amount you are transferring.`
|
||||
)}
|
||||
>
|
||||
<div>{t('Include transfer fee')}</div>
|
||||
</Tooltip>
|
||||
}
|
||||
checked={includeFee}
|
||||
onCheckedChange={() => setIncludeFee(!includeFee)}
|
||||
/>
|
||||
<Tooltip
|
||||
description={t(
|
||||
`The fee will be taken from the amount you are transferring.`
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<TradingCheckbox
|
||||
name="include-transfer-fee"
|
||||
disabled={!transferAmount}
|
||||
label={t('Include transfer fee')}
|
||||
checked={includeFee}
|
||||
onCheckedChange={() => setIncludeFee(!includeFee)}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{transferAmount && fee && (
|
||||
<TransferFee
|
||||
|
||||
@@ -62,6 +62,20 @@ const WrappedAssetDetailsDialog = ({ assetId }: { assetId: string }) => (
|
||||
);
|
||||
|
||||
describe('AssetDetailsDialog', () => {
|
||||
// 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
|
||||
it('should show no data message given unknown asset symbol', async () => {
|
||||
render(<WrappedAssetDetailsDialog assetId={'UNKNOWN_FOR_SURE'} />);
|
||||
expect((await screen.findByTestId('splash')).textContent).toContain(
|
||||
|
||||
@@ -22,7 +22,6 @@ export * from '../markets/src/lib/oracle-spec-data-connection.mock';
|
||||
export * from '../orders/src/lib/components/order-data-provider/orders.mock';
|
||||
export * from '../positions/src/lib/positions.mock';
|
||||
export * from '../network-parameters/src/network-params.mock';
|
||||
export * from '../wallet/src/connect-dialog/chain-id.mock';
|
||||
export * from '../positions/src/lib/estimate-position.mock';
|
||||
export * from '../trades/src/lib/trades.mock';
|
||||
export * from '../withdraws/src/lib/withdrawal.mock';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { addGetTestIdcommand } from './lib/commands/get-by-test-id';
|
||||
import { addMockGQLCommand } from './lib/mock-gql';
|
||||
import { addMockGQLCommand, addMockStatistics } from './lib/mock-gql';
|
||||
import { addMockSubscription } from './lib/mock-ws';
|
||||
import { addMockWalletCommand } from './lib/mock-rest';
|
||||
import { addMockWeb3ProviderCommand } from './lib/commands/mock-web3-provider';
|
||||
@@ -28,6 +28,7 @@ import { addMockChainId } from './lib/commands/mock-chain-id';
|
||||
|
||||
addGetTestIdcommand();
|
||||
addMockGQLCommand();
|
||||
addMockStatistics();
|
||||
addMockSubscription();
|
||||
addMockWalletCommand();
|
||||
addMockWeb3ProviderCommand();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { aliasGQLQuery } from '../mock-gql';
|
||||
// eslint-disable-next-line @nx/enforce-module-boundaries
|
||||
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
||||
import { statisticsQuery } from '@vegaprotocol/mock';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
@@ -12,11 +12,26 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
const chainId = 'test-id';
|
||||
|
||||
export function addMockChainId() {
|
||||
Cypress.Commands.add('mockChainId', () => {
|
||||
const result = {
|
||||
statistics: {
|
||||
chainId,
|
||||
},
|
||||
};
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'NodeCheck', statisticsQuery(result));
|
||||
});
|
||||
cy.mockStatistics((req) => {
|
||||
req.reply({
|
||||
statusCode: 200,
|
||||
body: result,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Chainable<Subject> {
|
||||
mockGQL(handler: RouteHandler): void;
|
||||
mockStatistics(handler: RouteHandler): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +41,16 @@ const extractVariables = (req: CyHttpMessages.IncomingHttpRequest): object => {
|
||||
);
|
||||
};
|
||||
|
||||
export function addMockStatistics() {
|
||||
Cypress.Commands.add('mockStatistics', (handler: RouteHandler) => {
|
||||
cy.intercept(
|
||||
'GET',
|
||||
Cypress.env('VEGA_URL').replace('graphql', 'statistics'),
|
||||
handler
|
||||
).as('ChainId');
|
||||
});
|
||||
}
|
||||
|
||||
export function addMockGQLCommand() {
|
||||
Cypress.Commands.add('mockGQL', (handler: RouteHandler) => {
|
||||
cy.intercept('POST', Cypress.env('VEGA_URL'), handler).as('GQL');
|
||||
|
||||
@@ -5,8 +5,6 @@ import type { MutableRefObject } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
|
||||
const GRID_EVENT_DEBOUNCE_TIME = 500;
|
||||
|
||||
const gridProps = {
|
||||
rowData: [{ id: 1 }],
|
||||
columnDefs: [
|
||||
@@ -18,25 +16,29 @@ const gridProps = {
|
||||
],
|
||||
style: { width: 500, height: 300 },
|
||||
};
|
||||
const GRID_EVENT_DEBOUNCE_TIME = 300;
|
||||
let gridRef: MutableRefObject<AgGridReact | null>;
|
||||
function TestComponent({
|
||||
hookParams,
|
||||
}: {
|
||||
hookParams: Parameters<typeof useDataGridEvents>;
|
||||
}) {
|
||||
const hookCallbacks = useDataGridEvents(...hookParams);
|
||||
gridRef = useRef<AgGridReact | null>(null);
|
||||
return <AgGridThemed gridRef={gridRef} {...gridProps} {...hookCallbacks} />;
|
||||
}
|
||||
|
||||
// Not using render hook so I can pass event callbacks
|
||||
// to a rendered grid
|
||||
function setup(...args: Parameters<typeof useDataGridEvents>) {
|
||||
let gridRef;
|
||||
|
||||
function TestComponent() {
|
||||
const hookCallbacks = useDataGridEvents(...args);
|
||||
gridRef = useRef<AgGridReact | null>(null);
|
||||
return <AgGridThemed gridRef={gridRef} {...gridProps} {...hookCallbacks} />;
|
||||
}
|
||||
render(<TestComponent />);
|
||||
return gridRef as unknown as MutableRefObject<AgGridReact>;
|
||||
return render(<TestComponent hookParams={args} />);
|
||||
}
|
||||
|
||||
describe('useDataGridEvents', () => {
|
||||
const originalWarn = console.warn;
|
||||
|
||||
beforeAll(() => {
|
||||
gridRef = undefined;
|
||||
jest.useFakeTimers();
|
||||
|
||||
// disabling some ag grid warnings that are caused by test setup only
|
||||
@@ -55,15 +57,15 @@ describe('useDataGridEvents', () => {
|
||||
columnState: undefined,
|
||||
};
|
||||
|
||||
const result = setup(initialState, callback);
|
||||
setup(initialState, callback);
|
||||
|
||||
// column state was not updated, so the default width provided by the
|
||||
// col def should be set
|
||||
expect(result.current.columnApi.getColumnState()[0].width).toEqual(
|
||||
expect(gridRef.current?.columnApi.getColumnState()[0].width).toEqual(
|
||||
gridProps.columnDefs[0].width
|
||||
);
|
||||
// no filters set
|
||||
expect(result.current.api.getFilterModel()).toEqual({});
|
||||
expect(gridRef.current?.api.getFilterModel()).toEqual({});
|
||||
|
||||
// Set filter
|
||||
const idFilter = {
|
||||
@@ -72,7 +74,7 @@ describe('useDataGridEvents', () => {
|
||||
type: 'equals',
|
||||
};
|
||||
await act(async () => {
|
||||
result.current.api.setFilterModel({
|
||||
gridRef.current?.api.setFilterModel({
|
||||
id: idFilter,
|
||||
});
|
||||
});
|
||||
@@ -88,7 +90,7 @@ describe('useDataGridEvents', () => {
|
||||
},
|
||||
});
|
||||
callback.mockClear();
|
||||
expect(result.current.api.getFilterModel()['id']).toEqual(idFilter);
|
||||
expect(gridRef.current?.api.getFilterModel()['id']).toEqual(idFilter);
|
||||
});
|
||||
|
||||
it('applies grid state on ready', async () => {
|
||||
@@ -105,11 +107,11 @@ describe('useDataGridEvents', () => {
|
||||
columnState: [colState],
|
||||
};
|
||||
|
||||
const result = setup(initialState, jest.fn());
|
||||
setup(initialState, jest.fn());
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.api.getFilterModel()['id']).toEqual(idFilter);
|
||||
expect(result.current.columnApi.getColumnState()[0]).toEqual(
|
||||
expect(gridRef.current?.api.getFilterModel()['id']).toEqual(idFilter);
|
||||
expect(gridRef.current?.columnApi.getColumnState()[0]).toEqual(
|
||||
expect.objectContaining(colState)
|
||||
);
|
||||
});
|
||||
@@ -122,13 +124,13 @@ describe('useDataGridEvents', () => {
|
||||
columnState: undefined,
|
||||
};
|
||||
|
||||
const result = setup(initialState, callback);
|
||||
setup(initialState, callback);
|
||||
|
||||
const newWidth = 400;
|
||||
|
||||
// Set col width multiple times
|
||||
await act(async () => {
|
||||
result.current.columnApi.setColumnWidth('id', newWidth);
|
||||
gridRef.current?.columnApi.setColumnWidth('id', newWidth);
|
||||
});
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
@@ -139,4 +141,23 @@ describe('useDataGridEvents', () => {
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('columns for autosizing should be handle', () => {
|
||||
const callback = jest.fn();
|
||||
const initialState = {
|
||||
filterModel: undefined,
|
||||
columnState: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = setup(initialState, callback, ['id']);
|
||||
jest.spyOn(gridRef.current?.columnApi, 'autoSizeColumns');
|
||||
rerender(<TestComponent hookParams={[initialState, callback, ['id']]} />);
|
||||
act(() => {
|
||||
gridRef.current?.api.setRowData([{ id: 'test-id' }]);
|
||||
jest.advanceTimersByTime(GRID_EVENT_DEBOUNCE_TIME);
|
||||
});
|
||||
expect(gridRef.current?.columnApi.autoSizeColumns).toHaveBeenCalledWith([
|
||||
'id',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
FilterChangedEvent,
|
||||
FirstDataRenderedEvent,
|
||||
SortChangedEvent,
|
||||
GridReadyEvent,
|
||||
} from 'ag-grid-community';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
@@ -17,7 +18,8 @@ type State = {
|
||||
|
||||
export const useDataGridEvents = (
|
||||
state: State,
|
||||
callback: (data: State) => void
|
||||
callback: (data: State) => void,
|
||||
autoSizeColumns?: string[]
|
||||
) => {
|
||||
/**
|
||||
* Callback for filter events
|
||||
@@ -78,7 +80,7 @@ export const useDataGridEvents = (
|
||||
* State only applied if found, otherwise columns sized to fit available space
|
||||
*/
|
||||
const onGridReady = useCallback(
|
||||
({ api, columnApi }: FirstDataRenderedEvent) => {
|
||||
({ api, columnApi }: GridReadyEvent) => {
|
||||
if (!api || !columnApi) return;
|
||||
|
||||
if (state.columnState) {
|
||||
@@ -97,6 +99,16 @@ export const useDataGridEvents = (
|
||||
[state]
|
||||
);
|
||||
|
||||
const onFirstDataRendered = useCallback(
|
||||
({ columnApi }: FirstDataRenderedEvent) => {
|
||||
if (!columnApi) return;
|
||||
if (!state?.columnState && autoSizeColumns?.length) {
|
||||
columnApi.autoSizeColumns(autoSizeColumns);
|
||||
}
|
||||
},
|
||||
[state, autoSizeColumns]
|
||||
);
|
||||
|
||||
return {
|
||||
onGridReady,
|
||||
// these events don't use the 'finished' flag
|
||||
@@ -106,5 +118,6 @@ export const useDataGridEvents = (
|
||||
// these trigger a lot so this callback uses the 'finished' flag
|
||||
onColumnMoved: onDebouncedColumnChange,
|
||||
onColumnResized: onDebouncedColumnChange,
|
||||
onFirstDataRendered,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/web3';
|
||||
import {
|
||||
isStopOrderType,
|
||||
useDealTicketFormValues,
|
||||
|
||||
@@ -273,7 +273,7 @@ export const DealTicketMarginDetails = ({
|
||||
key={'value-dropdown'}
|
||||
className="flex items-center justify-between w-full gap-2"
|
||||
>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-1 text-left">
|
||||
<Tooltip description={MARGIN_DIFF_TOOLTIP_TEXT(assetSymbol)}>
|
||||
<span className="text-muted">{t('Margin required')}</span>
|
||||
</Tooltip>
|
||||
|
||||
@@ -494,16 +494,16 @@ const TimeInForce = ({
|
||||
);
|
||||
|
||||
const ReduceOnly = () => (
|
||||
<Checkbox
|
||||
name="reduce-only"
|
||||
checked={true}
|
||||
disabled={true}
|
||||
label={
|
||||
<Tooltip description={<span>{t(REDUCE_ONLY_TOOLTIP)}</span>}>
|
||||
<>{t('Reduce only')}</>
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
<Tooltip description={<span>{t(REDUCE_ONLY_TOOLTIP)}</span>}>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="reduce-only"
|
||||
checked={true}
|
||||
disabled={true}
|
||||
label={t('Reduce only')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
const NotionalAndFees = ({
|
||||
|
||||
@@ -264,7 +264,11 @@ export const DealTicket = ({
|
||||
orders,
|
||||
collateralAvailable:
|
||||
marginAccountBalance || generalAccountBalance ? balance : undefined,
|
||||
skip: !normalizedOrder,
|
||||
skip:
|
||||
!normalizedOrder ||
|
||||
(normalizedOrder.type !== Schema.OrderType.TYPE_MARKET &&
|
||||
(!normalizedOrder.price || normalizedOrder.price === '0')) ||
|
||||
normalizedOrder.size === '0',
|
||||
});
|
||||
|
||||
const assetSymbol = getAsset(market).symbol;
|
||||
@@ -544,62 +548,62 @@ export const DealTicket = ({
|
||||
name="postOnly"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Checkbox
|
||||
name="post-only"
|
||||
checked={!disablePostOnlyCheckbox && field.value}
|
||||
disabled={disablePostOnlyCheckbox}
|
||||
onCheckedChange={(postOnly) => {
|
||||
field.onChange(postOnly);
|
||||
setValue('reduceOnly', false);
|
||||
}}
|
||||
label={
|
||||
<Tooltip
|
||||
description={
|
||||
<span>
|
||||
{disablePostOnlyCheckbox
|
||||
? t(
|
||||
'"Post only" can not be used on "Fill or Kill" or "Immediate or Cancel" orders.'
|
||||
)
|
||||
: t(
|
||||
'"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.'
|
||||
)}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<span className="text-xs">{t('Post only')}</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>
|
||||
{disablePostOnlyCheckbox
|
||||
? t(
|
||||
'"Post only" can not be used on "Fill or Kill" or "Immediate or Cancel" orders.'
|
||||
)
|
||||
: t(
|
||||
'"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.'
|
||||
)}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="post-only"
|
||||
checked={!disablePostOnlyCheckbox && field.value}
|
||||
disabled={disablePostOnlyCheckbox}
|
||||
onCheckedChange={(postOnly) => {
|
||||
field.onChange(postOnly);
|
||||
setValue('reduceOnly', false);
|
||||
}}
|
||||
label={t('Post only')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="reduceOnly"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Checkbox
|
||||
name="reduce-only"
|
||||
checked={!disableReduceOnlyCheckbox && field.value}
|
||||
disabled={disableReduceOnlyCheckbox}
|
||||
onCheckedChange={(reduceOnly) => {
|
||||
field.onChange(reduceOnly);
|
||||
setValue('postOnly', false);
|
||||
}}
|
||||
label={
|
||||
<Tooltip
|
||||
description={
|
||||
<span>
|
||||
{disableReduceOnlyCheckbox
|
||||
? t(
|
||||
'"Reduce only" can be used only with non-persistent orders, such as "Fill or Kill" or "Immediate or Cancel".'
|
||||
)
|
||||
: t(REDUCE_ONLY_TOOLTIP)}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<span className="text-xs">{t('Reduce only')}</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>
|
||||
{disableReduceOnlyCheckbox
|
||||
? t(
|
||||
'"Reduce only" can be used only with non-persistent orders, such as "Fill or Kill" or "Immediate or Cancel".'
|
||||
)
|
||||
: t(REDUCE_ONLY_TOOLTIP)}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="reduce-only"
|
||||
checked={!disableReduceOnlyCheckbox && field.value}
|
||||
disabled={disableReduceOnlyCheckbox}
|
||||
onCheckedChange={(reduceOnly) => {
|
||||
field.onChange(reduceOnly);
|
||||
setValue('postOnly', false);
|
||||
}}
|
||||
label={t('Reduce only')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
@@ -610,26 +614,26 @@ export const DealTicket = ({
|
||||
name="iceberg"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Checkbox
|
||||
name="iceberg"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={disableIcebergCheckbox}
|
||||
label={
|
||||
<Tooltip
|
||||
description={
|
||||
<p>
|
||||
{t(`Trade only a fraction of the order size at once.
|
||||
<Tooltip
|
||||
description={
|
||||
<p>
|
||||
{t(`Trade only a fraction of the order size at once.
|
||||
After the peak size of the order has traded, the size is reset. This is repeated until the order is cancelled, expires, or its full volume trades away.
|
||||
For example, an iceberg order with a size of 1000 and a peak size of 100 will effectively be split into 10 orders with a size of 100 each.
|
||||
Note that the full volume of the order is not hidden and is still reflected in the order book.`)}
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<span className="text-xs">{t('Iceberg')}</span>
|
||||
</Tooltip>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="iceberg"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={disableIcebergCheckbox}
|
||||
label={t('Iceberg')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -25,11 +25,11 @@ export const KeyValue = ({
|
||||
}: KeyValuePros) => {
|
||||
const displayValue = `${formattedValue ?? '-'} ${symbol || ''}`;
|
||||
const valueElement = onClick ? (
|
||||
<button onClick={onClick} className="font-mono">
|
||||
<button onClick={onClick} className="font-mono ml-auto">
|
||||
{displayValue}
|
||||
</button>
|
||||
) : (
|
||||
<div className="font-mono">{displayValue}</div>
|
||||
<div className="font-mono ml-auto">{displayValue}</div>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
@@ -40,12 +40,12 @@ export const KeyValue = ({
|
||||
}`}
|
||||
key={typeof label === 'string' ? label : 'value-dropdown'}
|
||||
className={classnames(
|
||||
'text-xs flex justify-between items-center gap-4 flex-wrap',
|
||||
'text-xs flex justify-between items-center gap-4 flex-wrap text-right',
|
||||
{ 'ml-2': indent }
|
||||
)}
|
||||
>
|
||||
<Tooltip description={labelDescription}>
|
||||
<div className="text-muted">{label}</div>
|
||||
<div className="text-muted text-left">{label}</div>
|
||||
</Tooltip>
|
||||
<Tooltip description={`${value ?? '-'} ${symbol || ''}`}>
|
||||
{valueElement}
|
||||
|
||||
@@ -114,6 +114,20 @@ export const TradingModeTooltip = ({
|
||||
</section>
|
||||
);
|
||||
}
|
||||
case Schema.MarketTradingMode.TRADING_MODE_SUSPENDED_VIA_GOVERNANCE: {
|
||||
return (
|
||||
<section data-testid="trading-mode-suspended-via-governance">
|
||||
{t(
|
||||
`This market has been suspended via a governance vote and can be resumed or terminated by further votes.`
|
||||
)}
|
||||
{DocsLinks && (
|
||||
<ExternalLink href={DocsLinks.MARKET_LIFECYCLE} className="ml-1">
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
case Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION: {
|
||||
switch (trigger) {
|
||||
case Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET: {
|
||||
|
||||
@@ -30,9 +30,11 @@ export const usePositionEstimate = ({
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
if (skip) {
|
||||
setEstimates(undefined);
|
||||
} else if (data) {
|
||||
setEstimates(data);
|
||||
}
|
||||
}, [data]);
|
||||
}, [data, skip]);
|
||||
return estimates;
|
||||
};
|
||||
|
||||
@@ -11,6 +11,9 @@ export function generateMarket(override?: PartialDeep<Market>): Market {
|
||||
positionDecimalPlaces: 1,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
state: Schema.MarketState.STATE_ACTIVE,
|
||||
liquidityMonitoringParameters: {
|
||||
triggeringRatio: '1',
|
||||
},
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
close: '',
|
||||
|
||||
@@ -423,6 +423,12 @@ function compileFeatureFlags(): FeatureFlags {
|
||||
process.env['NX_UPDATE_MARKET_STATE']
|
||||
) as string
|
||||
),
|
||||
GOVERNANCE_TRANSFERS: TRUTHY.includes(
|
||||
windowOrDefault(
|
||||
'NX_GOVERNANCE_TRANSFERS',
|
||||
process.env['NX_GOVERNANCE_TRANSFERS']
|
||||
) as string
|
||||
),
|
||||
};
|
||||
const EXPLORER_FLAGS = {
|
||||
EXPLORER_ASSETS: TRUTHY.includes(
|
||||
|
||||
@@ -80,6 +80,7 @@ export const DocsLinks = VEGA_DOCS_URL
|
||||
LIQUIDITY: `${VEGA_DOCS_URL}/concepts/liquidity/provision`,
|
||||
WITHDRAWAL_LIMITS: `${VEGA_DOCS_URL}/concepts/assets/deposits-withdrawals#withdrawal-limits`,
|
||||
VALIDATOR_SCORES_REWARDS: `${VEGA_DOCS_URL}/concepts/vega-chain/validator-scores-and-rewards`,
|
||||
MARKET_LIFECYCLE: `${VEGA_DOCS_URL}/concepts/trading-on-vega/market-lifecycle`,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ export type CosmicElevatorFlags = Pick<
|
||||
| 'METAMASK_SNAPS'
|
||||
| 'REFERRALS'
|
||||
| 'UPDATE_MARKET_STATE'
|
||||
| 'GOVERNANCE_TRANSFERS'
|
||||
>;
|
||||
export type Configuration = z.infer<typeof tomlConfigSchema>;
|
||||
export const CUSTOM_NODE_KEY = 'custom' as const;
|
||||
|
||||
@@ -80,6 +80,7 @@ const COSMIC_ELEVATOR_FLAGS = {
|
||||
METAMASK_SNAPS: z.optional(z.boolean()),
|
||||
REFERRALS: z.optional(z.boolean()),
|
||||
UPDATE_MARKET_STATE: z.optional(z.boolean()),
|
||||
GOVERNANCE_TRANSFERS: z.optional(z.boolean()),
|
||||
};
|
||||
|
||||
const EXPLORER_FLAGS = {
|
||||
|
||||
@@ -9,14 +9,12 @@ import { fillsWithMarketProvider } from './fills-data-provider';
|
||||
|
||||
interface FillsManagerProps {
|
||||
partyId: string;
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
gridProps: ReturnType<typeof useDataGridEvents>;
|
||||
}
|
||||
|
||||
export const FillsManager = ({
|
||||
partyId,
|
||||
marketId,
|
||||
onMarketClick,
|
||||
gridProps,
|
||||
}: FillsManagerProps) => {
|
||||
@@ -24,9 +22,6 @@ export const FillsManager = ({
|
||||
const filter: Schema.TradesFilter | Schema.TradesSubscriptionFilter = {
|
||||
partyIds: [partyId],
|
||||
};
|
||||
if (marketId) {
|
||||
filter.marketIds = [marketId];
|
||||
}
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: fillsWithMarketProvider,
|
||||
update: ({ data }) => {
|
||||
|
||||
@@ -42,6 +42,9 @@ export const generateFill = (override?: PartialDeep<Trade>) => {
|
||||
decimalPlaces: 5,
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
liquidityMonitoringParameters: {
|
||||
triggeringRatio: '1',
|
||||
},
|
||||
fees: {
|
||||
__typename: 'Fees',
|
||||
factors: {
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+4
-6
@@ -3,23 +3,23 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarketDataUpdateFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
export type MarketDataUpdateFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
|
||||
export type MarketDataUpdateSubscriptionVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketDataUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null }> };
|
||||
export type MarketDataUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null }> };
|
||||
|
||||
export type MarketDataFieldsFragment = { __typename?: 'MarketData', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, market: { __typename?: 'Market', id: string }, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
export type MarketDataFieldsFragment = { __typename?: 'MarketData', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, market: { __typename?: 'Market', id: string }, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
|
||||
export type MarketDataQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, market: { __typename?: 'Market', id: string }, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null } | null } }> } | null };
|
||||
export type MarketDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, lastTradedPrice: string, market: { __typename?: 'Market', id: string }, productData?: { __typename?: 'PerpetualData', fundingRate?: string | null, fundingPayment?: string | null, externalTwap?: string | null, internalTwap?: string | null } | null, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null } | null } }> } | null };
|
||||
|
||||
export const MarketDataUpdateFieldsFragmentDoc = gql`
|
||||
fragment MarketDataUpdateFields on ObservableMarketData {
|
||||
@@ -46,7 +46,6 @@ export const MarketDataUpdateFieldsFragmentDoc = gql`
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
@@ -94,7 +93,6 @@ export const MarketDataFieldsFragmentDoc = gql`
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
|
||||
+5
-2
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user