Compare commits

..
Author SHA1 Message Date
asiaznik 2d35cf0fc0 fix: trading tests 2023-11-08 17:18:27 +01:00
asiaznik 088838d1ca chore: display no program active message in tile 3 and 4 2023-11-08 16:34:00 +01:00
asiaznik cf66ba40ef fix(trading): fix adjusted fees calculation 2023-11-08 15:45:45 +01:00
asiaznik 955427c2ed fix(trading): fees page issues 2023-11-08 14:39:12 +01:00
308 changed files with 10891 additions and 15349 deletions
+1 -2
View File
@@ -73,8 +73,7 @@
"error",
{
"prefer": "type-imports",
"disallowTypeAnnotations": true,
"fixStyle": "inline-type-imports"
"disallowTypeAnnotations": true
}
],
"curly": ["error", "multi-line"]
+6 -6
View File
@@ -34,7 +34,7 @@ jobs:
${{ runner.os }}-cache-node-modules-
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
if: steps.cache.outputs.cache-hit != 'true'
with:
node-version-file: '.nvmrc'
@@ -57,7 +57,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
@@ -96,7 +96,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
@@ -128,7 +128,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
@@ -182,7 +182,7 @@ jobs:
run: |
if [[ "${{ github.base_ref }}" == "develop" ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "main" ]]; then
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
@@ -205,7 +205,7 @@ jobs:
console-e2e:
needs: [build-sources, check-e2e-needed]
name: '(CI) trading e2e python'
name: '(CI) console python'
uses: ./.github/workflows/console-test-run.yml
secrets: inherit
if: needs.check-e2e-needed.outputs.run-tests == 'true' && contains(needs.build-sources.outputs.projects, 'trading')
+20 -17
View File
@@ -10,7 +10,7 @@ on:
inputs:
console-test-branch:
type: choice
description: 'main: v0.72.14, develop: v0.73.4'
description: 'main: v0.72.14, develop: v0.73.0-preview7'
options:
- main
- develop
@@ -32,9 +32,9 @@ jobs:
# cache node modules
#----------------------------------------------
- name: setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
node-version: '16'
cache: yarn
- name: Cache node modules
@@ -153,19 +153,25 @@ jobs:
run: |
docker load --input /tmp/console-image.tar
docker image ls -a
#----------------------------------------------
# check-out frontend-monorepo
# check-out tests repo
#----------------------------------------------
- name: Checkout frontend-monorepo
- name: Checkout console test repo
uses: actions/checkout@v3
with:
ref: ${{ inputs.github-sha || github.sha }}
#----------------------------------------------
# get vega version
#----------------------------------------------
- name: Set VEGA_VERSION from .env
id: set_vega_version
run: echo "VEGA_VERSION=$(grep VEGA_VERSION apps/trading/e2e/.env | cut -d '=' -f2)" >> $GITHUB_ENV
repository: vegaprotocol/console-test
ref: ${{ needs.console-test-branch.outputs.console-branch }}
- name: Load console test envs
id: console-test-env
uses: falti/dotenv-action@v1.0.4
with:
path: '.env.${{ needs.console-test-branch.outputs.console-branch }}'
export-variables: true
keys-case: upper
log-variables: true
#----------------------------------------------
# ----- Setup python -----
#----------------------------------------------
@@ -188,25 +194,22 @@ jobs:
#----------------------------------------------
- name: Install dependencies
run: poetry install --no-interaction --no-root
working-directory: apps/trading/e2e
#----------------------------------------------
# install vega binaries
#----------------------------------------------
- name: Install vega binaries
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
working-directory: apps/trading/e2e
#----------------------------------------------
# install playwrightworking-directory: apps/trading/e2e
# install playwright
#----------------------------------------------
- name: install playwright
run: poetry run playwright install --with-deps chromium
working-directory: apps/trading/e2e
#----------------------------------------------
# run tests
#----------------------------------------------
- name: Run tests
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
working-directory: apps/trading/e2e
#----------------------------------------------
# upload traces
#----------------------------------------------
+3 -3
View File
@@ -18,11 +18,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node.js 20
- name: Use Node.js 16
id: Node
uses: actions/setup-node@v4
uses: actions/setup-node@v2
with:
node-version-file: '.nvmrc'
node-version: 16.15.1
- name: Run Cypress tests
uses: cypress-io/github-action@v4
-8
View File
@@ -57,14 +57,6 @@ jobs:
path: './frontend-monorepo'
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: './frontend-monorepo/.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
cache-dependency-path: './frontend-monorepo/yarn.lock'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
id: cache-node-modules
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
+3 -3
View File
@@ -18,13 +18,13 @@ jobs:
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
node-version: 16
- name: Install dependencies
run: |
rm package.json
rm package.json
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
- name: Check PR title
+1 -1
View File
@@ -93,7 +93,7 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
-9
View File
@@ -52,12 +52,3 @@ cypress.env.json
/apps/**/cypress/reports/
/apps/**/cypress/downloads/
/apps/**/fixtures/wallet/node**
#console-test
__pycache__/
apps/trading/e2e/logs/
apps/trading/e2e/.pytest_cache/
apps/trading/e2e/traces/
.nx/cache
+1 -1
View File
@@ -1 +1 @@
20.9.0
16.20.2
-5
View File
@@ -8,8 +8,3 @@ __generated___
apps/static/src/assets/devnet-tranches.json
apps/static/src/assets/mainnet-tranches.json
apps/static/src/assets/testnet-tranches.json
/apps/**/cypress/reports/
/apps/**/cypress/downloads/
/.nx/cache
-2
View File
@@ -1,4 +1,2 @@
* @vegaprotocol/frontend
apps/ @vegaprotocol/frontend-qa
libs/ @vegaprotocol/frontend-qa
*.graphql @vegaprotocol/core
+1 -1
View File
@@ -136,7 +136,7 @@ The [`docker`](./docker) subfolder has some docker configurations for easily set
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build). The multistage builds ensures consistent CPU architecture and build toolchains are used so that the result will be identical.
```bash
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=20.9.1 --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=16.5.1 --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
```
### Computing ipfs-hash of the build
+1 -3
View File
@@ -4,9 +4,7 @@
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"cypress/unsafe-to-chain-command": 0
}
"rules": {}
}
]
}
+1 -1
View File
@@ -17,7 +17,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/explorer-e2e/**/*.{js,ts}"]
+9 -2
View File
@@ -53,7 +53,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/explorer/**/*.{ts,tsx,js,jsx}"]
@@ -63,7 +63,14 @@
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/apps/explorer"],
"options": {
"jestConfig": "apps/explorer/jest.config.ts"
"jestConfig": "apps/explorer/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"generate-types": {
@@ -1,15 +1,15 @@
import { useMemo } from 'react';
import { type AssetFieldsFragment } from '@vegaprotocol/assets';
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
import { AssetTypeMapping, AssetStatusMapping } from '@vegaprotocol/assets';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { type AgGridReact } from 'ag-grid-react';
import type { AgGridReact } from 'ag-grid-react';
import { AgGrid } from '@vegaprotocol/datagrid';
import { type VegaICellRendererParams } from '@vegaprotocol/datagrid';
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
import { useRef, useLayoutEffect } from 'react';
import { BREAKPOINT_MD } from '../../config/breakpoints';
import { useNavigate } from 'react-router-dom';
import { type RowClickedEvent, ColDef } from 'ag-grid-community';
import type { RowClickedEvent, ColDef } from 'ag-grid-community';
type AssetsTableProps = {
data: AssetFieldsFragment[] | null;
@@ -91,6 +91,6 @@ describe('Market link component', () => {
};
const res = render(renderComponent('123', [mock]));
expect(await res.findByTitle('123')).toBeInTheDocument();
expect(await res.findByText('123')).toBeInTheDocument();
});
});
@@ -2,18 +2,18 @@ import { useMemo } from 'react';
import { getAsset, type MarketFieldsFragment } from '@vegaprotocol/markets';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { type AgGridReact } from 'ag-grid-react';
import { type ColDef } from 'ag-grid-community';
import type { AgGridReact } from 'ag-grid-react';
import type { ColDef } from 'ag-grid-community';
import { AgGrid } from '@vegaprotocol/datagrid';
import {
type VegaICellRendererParams,
type VegaValueGetterParams,
import type {
VegaICellRendererParams,
VegaValueGetterParams,
} from '@vegaprotocol/datagrid';
import { useRef, useLayoutEffect } from 'react';
import { BREAKPOINT_MD } from '../../config/breakpoints';
import { MarketStateMapping } from '@vegaprotocol/types';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { type RowClickedEvent } from 'ag-grid-community';
import type { RowClickedEvent } from 'ag-grid-community';
import { Link, useNavigate } from 'react-router-dom';
type MarketsTableProps = {
@@ -17,7 +17,7 @@ function renderAmendOrderDetails(
mocks: MockedResponse[]
) {
return render(
<MockedProvider mocks={mocks}>
<MockedProvider mocks={mocks} addTypename={false}>
<MemoryRouter>
<AmendOrderDetails version={version} id={id} amend={amend} />
</MemoryRouter>
@@ -44,18 +44,18 @@ function renderExistingAmend(
orderByID: {
__typename: 'Order',
id: '123',
type: Schema.OrderType.TYPE_LIMIT,
type: 'GTT',
status: Schema.OrderStatus.STATUS_ACTIVE,
version: version ? version.toString() : '',
version: version,
createdAt: '123',
updatedAt: '456',
expiresAt: '789',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
price: '200',
side: Schema.Side.SIDE_BUY,
side: 'BUY',
peggedOrder: null,
remaining: '99',
rejectionReason: Schema.OrderRejectionReason.ORDER_ERROR_NOT_FOUND,
rejectionReason: 'rejection',
reference: '123',
size: '100',
party: {
@@ -65,15 +65,18 @@ function renderExistingAmend(
market: {
__typename: 'Market',
id: '789',
state: Schema.MarketState.STATE_ACTIVE,
state: 'STATUS_ACTIVE',
positionDecimalPlaces: 2,
decimalPlaces: 0,
decimalPlaces: '5',
tradableInstrument: {
instrument: {
name: 'test',
product: {
__typename: 'Future',
quoteName: '123',
settlementAsset: {
decimals: 8,
},
},
},
},
@@ -94,18 +97,18 @@ function renderExistingAmend(
orderByID: {
__typename: 'Order',
id: '123',
type: Schema.OrderType.TYPE_LIMIT,
type: 'GTT',
status: Schema.OrderStatus.STATUS_ACTIVE,
version: '100',
version: 100,
createdAt: '123',
updatedAt: '456',
expiresAt: '789',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
peggedOrder: null,
price: '200',
side: Schema.Side.SIDE_BUY,
side: 'BUY',
remaining: '99',
rejectionReason: Schema.OrderRejectionReason.ORDER_ERROR_NOT_FOUND,
rejectionReason: 'rejection',
reference: '123',
size: '200',
party: {
@@ -114,16 +117,19 @@ function renderExistingAmend(
},
market: {
__typename: 'Market',
id: '8888',
state: Schema.MarketState.STATE_ACTIVE,
id: 'amend-to-order-latest-version',
state: 'STATUS_ACTIVE',
positionDecimalPlaces: 2,
decimalPlaces: 0,
decimalPlaces: '5',
tradableInstrument: {
instrument: {
name: 'amend-to-order-latest-version-test',
product: {
__typename: 'Future',
quoteName: '123',
settlementAsset: {
decimals: 8,
},
},
},
},
@@ -136,13 +142,13 @@ function renderExistingAmend(
request: {
query: ExplorerMarketDocument,
variables: {
id: '8888',
id: '789',
},
},
result: {
data: {
market: {
id: '8888',
id: '789',
decimalPlaces: 5,
positionDecimalPlaces: 2,
state: 'irrelevant-test-data',
@@ -219,10 +225,12 @@ describe('Amend order details', () => {
it('Fetches latest version when version is not specified', async () => {
const amend: Amend = {
price: '123',
price: '-7879',
};
const res = renderExistingAmend('123', undefined, amend);
expect(await res.findByText('test-label')).toBeInTheDocument();
expect(
await res.findByText('amend-to-order-latest-version')
).toBeInTheDocument();
});
});
@@ -46,10 +46,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
<div className={wrapperClasses}>
<div className="mb-12 lg:mb-0">
<div className="relative block rounded-lg px-3 py-6 md:px-6 lg:-mr-7">
<h2 className="display-5 mb-4 text-3xl font-bold">
<h2 className="text-3xl font-bold mb-4 display-5">
{t('Order not found')}
</h2>
<p className="mb-12 text-gray-500">
<p className="text-gray-500 mb-12">
{t('No order created from this transaction')}
</p>
</div>
@@ -68,24 +68,24 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
<div className={wrapperClasses}>
<div className="mb-12 lg:mb-0">
<div className="relative block px-3 py-6 md:px-6 lg:-mr-7">
<h2 className="display-5 mb-4 text-3xl font-bold">
<h2 className="text-3xl font-bold mb-4 display-5">
{t('Edits to ')}
{sideText[o.side]}
{t(' order')}
</h2>
<div className="mb-4 text-gray-500">
<p className="text-gray-500 mb-4">
In <MarketLink id={o.market.id} />, updated at{' '}
<Time date={o.updatedAt} />.
</div>
</p>
<div className="grid gap-x-6 md:grid-cols-4">
<div className="grid md:grid-cols-4 gap-x-6">
{amend.sizeDelta && amend.sizeDelta !== '0' ? (
<div className="mb-12 md:mb-0">
<h2 className="text-dark mb-4 text-2xl font-bold">
<h2 className="text-2xl font-bold text-dark mb-4">
{t('New size')}
</h2>
<h5
className={`mb-0 text-lg font-medium capitalize text-gray-500 ${getSideDeltaColour(
className={`text-lg font-medium text-gray-500 mb-0 capitalize ${getSideDeltaColour(
amend.sizeDelta
)}`}
>
@@ -96,10 +96,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
{amend.price && amend.price !== '0' ? (
<div className="">
<h2 className="text-dark mb-4 text-2xl font-bold">
<h2 className="text-2xl font-bold text-dark mb-4">
{t('New price')}
</h2>
<h5 className="mb-0 text-lg font-medium text-gray-500">
<h5 className="text-lg font-medium text-gray-500 mb-0">
<PriceInMarket price={amend.price} marketId={o.market.id} />
</h5>
</div>
@@ -108,10 +108,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
{amend.peggedReference &&
amend.peggedReference !== 'PEGGED_REFERENCE_UNSPECIFIED' ? (
<div className="">
<h2 className="text-dark mb-4 text-2xl font-bold">
<h2 className="text-2xl font-bold text-dark mb-4">
{t('New reference')}
</h2>
<h5 className="mb-0 text-lg font-medium text-gray-500">
<h5 className="text-lg font-medium text-gray-500 mb-0">
{peggedReference[amend.peggedReference]}
</h5>
</div>
@@ -119,10 +119,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
{amend.peggedOffset ? (
<div className="">
<h2 className="text-dark mb-4 text-2xl font-bold">
<h2 className="text-2xl font-bold text-dark mb-4">
{t('New offset')}
</h2>
<h5 className="mb-0 text-lg font-medium text-gray-500">
<h5 className="text-lg font-medium text-gray-500 mb-0">
{amend.peggedOffset}
</h5>
</div>
@@ -1,14 +1,14 @@
import { type ProposalListFieldsFragment } from '@vegaprotocol/proposals';
import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
import { VoteProgress } from '@vegaprotocol/proposals';
import { type AgGridReact } from 'ag-grid-react';
import type { AgGridReact } from 'ag-grid-react';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { AgGrid } from '@vegaprotocol/datagrid';
import {
type VegaICellRendererParams,
type VegaValueFormatterParams,
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
import { type RowClickedEvent, ColDef } from 'ag-grid-community';
import type { RowClickedEvent, ColDef } from 'ag-grid-community';
import { getDateTimeFormat } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
@@ -105,7 +105,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
? new BigNumber(0)
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
return (
<div className="flex h-full items-center justify-center pt-2 uppercase">
<div className="flex items-center justify-center h-full pt-2 uppercase">
<VoteProgress
threshold={requiredMajorityPercentage}
progress={yesPercentage}
@@ -3,8 +3,8 @@ import { DATA_SOURCES } from '../../../config';
import { t } from '@vegaprotocol/i18n';
import { useFetch } from '@vegaprotocol/react-helpers';
import { TxDetailsOrder } from './tx-order';
import { type BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import { type TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsHeartbeat } from './tx-hearbeat';
import { TxDetailsGeneric } from './tx-generic';
import { TxDetailsBatch } from './tx-batch';
@@ -1,7 +1,7 @@
import { Table, TableRow } from '../table';
import { t } from '@vegaprotocol/i18n';
import { useFetch } from '@vegaprotocol/react-helpers';
import { type BlockExplorerTransactions } from '../../routes/types/block-explorer-response';
import type { BlockExplorerTransactions } from '../../routes/types/block-explorer-response';
import { getTxsDataUrl } from '../../hooks/get-txs-data-url';
import { AsyncRenderer, Loader } from '@vegaprotocol/ui-toolkit';
import EmptyList from '../empty-list/empty-list';
@@ -22,7 +22,7 @@ export const TxsPerBlock = ({ blockHeight, txCount }: TxsPerBlockProps) => {
return (
<AsyncRenderer data={data} error={error} loading={!!loading}>
{data && data.transactions.length > 0 ? (
<div className="mb-28 overflow-x-auto whitespace-nowrap">
<div className="overflow-x-auto whitespace-nowrap mb-28">
<Table>
<thead>
<TableRow modifier="bordered" className="font-mono">
+5 -5
View File
@@ -1,14 +1,14 @@
import { useSearchParams } from 'react-router-dom';
import { type URLSearchParamsInit } from 'react-router-dom';
import type { URLSearchParamsInit } from 'react-router-dom';
import { useCallback } from 'react';
import { useFetch } from '@vegaprotocol/react-helpers';
import {
type BlockExplorerTransactionResult,
type BlockExplorerTransactions,
import type {
BlockExplorerTransactionResult,
BlockExplorerTransactions,
} from '../routes/types/block-explorer-response';
import isNumber from 'lodash/isNumber';
import { AllFilterOptions } from '../components/txs/tx-filter';
import { type FilterOption } from '../components/txs/tx-filter';
import type { FilterOption } from '../components/txs/tx-filter';
import { BE_TXS_PER_REQUEST, getTxsDataUrl } from './get-txs-data-url';
export function getTypeFilters(filters?: Set<FilterOption>) {
@@ -9,13 +9,11 @@ import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
import { useState } from 'react';
import { PageTitle } from '../../components/page-helpers/page-title';
type Params = { assetId: string };
export const AssetPage = () => {
useDocumentTitle(['Assets']);
useScrollToLocation();
const { assetId } = useParams<Params>();
const { assetId } = useParams<{ assetId: string }>();
const { data, loading, error } = useAssetDataProvider(assetId || '');
const title = data ? data.name : error ? t('Asset not found') : '';
@@ -43,7 +41,7 @@ export const AssetPage = () => {
loading={loading}
error={error}
>
<div className="relative h-full">
<div className="h-full relative">
<AssetDetailsTable asset={data as AssetFieldsFragment} />
</div>
</AsyncRenderer>
@@ -1,8 +1,8 @@
import { useCallback, useState } from 'react';
import { DATA_SOURCES } from '../../../config';
import {
type BlockMeta,
type TendermintBlockchainResponse,
import type {
BlockMeta,
TendermintBlockchainResponse,
} from '../tendermint-blockchain-response';
import { RouteTitle } from '../../../components/route-title';
import { BlocksRefetch } from '../../../components/blocks';
@@ -17,10 +17,8 @@ import { NodeLink } from '../../../components/links';
import { useDocumentTitle } from '../../../hooks/use-document-title';
import EmptyList from '../../../components/empty-list/empty-list';
type Params = { block: string };
const Block = () => {
const { block } = useParams<Params>();
const { block } = useParams<{ block: string }>();
useDocumentTitle(['Blocks', `Block #${block}`]);
const {
state: { data: blockData, loading, error },
@@ -31,7 +29,7 @@ const Block = () => {
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
<AsyncRenderer data={blockData} error={error} loading={!!loading}>
<>
<div className="mb-8 grid grid-cols-2 gap-2">
<div className="grid grid-cols-2 gap-2 mb-8">
<Link
data-testid="previous-block"
to={`/${Routes.BLOCKS}/${Number(block) - 1}`}
@@ -3,7 +3,7 @@ import { useFetch } from '@vegaprotocol/react-helpers';
import { RouteTitle } from '../../components/route-title';
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import { DATA_SOURCES } from '../../config';
import { type TendermintGenesisResponse } from './tendermint-genesis-response';
import type { TendermintGenesisResponse } from './tendermint-genesis-response';
import { useDocumentTitle } from '../../hooks/use-document-title';
const Genesis = () => {
@@ -11,12 +11,10 @@ import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
import { PageTitle } from '../../components/page-helpers/page-title';
type Params = { marketId: string };
export const MarketPage = () => {
useScrollToLocation();
const { marketId } = useParams<Params>();
const { marketId } = useParams<{ marketId: string }>();
const { data, loading, error } = useDataProvider({
dataProvider: marketInfoWithDataProvider,
@@ -1,10 +1,8 @@
import { getNodes } from '@vegaprotocol/utils';
import { MarketLink } from '../../../components/links';
import { TableRow, TableCell, TableHeader } from '../../../components/table';
import {
useExplorerOracleFormMarketsQuery,
type ExplorerOracleForMarketsMarketFragment,
} from '../__generated__/OraclesForMarkets';
import type { ExplorerOracleForMarketsMarketFragment } from '../__generated__/OraclesForMarkets';
import { useExplorerOracleFormMarketsQuery } from '../__generated__/OraclesForMarkets';
interface OracleMarketsProps {
id: string;
@@ -9,10 +9,8 @@ import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import filter from 'recursive-key-filter';
import { TruncateInline } from '../../../components/truncate/truncate';
type Params = { id: string };
export const Oracle = () => {
const { id } = useParams<Params>();
const { id } = useParams<{ id: string }>();
useDocumentTitle(['Oracle', `Oracle #${truncateByChars(id || '1', 5, 5)}`]);
@@ -6,10 +6,8 @@ import { useDocumentTitle } from '../../../../hooks/use-document-title';
import { PartyAccounts } from '../components/party-accounts';
type Params = { party: string };
const PartyAccountsByAsset = () => {
const { party } = useParams<Params>();
const { party } = useParams<{ party: string }>();
useDocumentTitle(['Public keys', party || '-']);
const partyId = toNonHex(party ? party : '');
@@ -19,13 +19,11 @@ import type { FilterOption } from '../../../components/txs/tx-filter';
import { AllFilterOptions, TxsFilter } from '../../../components/txs/tx-filter';
import { useSearchParams } from 'react-router-dom';
type Params = { party: string };
const Party = () => {
const [params] = useSearchParams();
const [filters, setFilters] = useState(new Set(AllFilterOptions));
const { party } = useParams<Params>();
const { party } = useParams<{ party: string }>();
useDocumentTitle(['Public keys', party || '-']);
const navigate = useNavigate();
@@ -62,7 +60,7 @@ const Party = () => {
if (!isValidPartyId(partyId)) {
return (
<div className="mx-auto max-w-sm">
<div className="max-w-sm mx-auto">
<Notification
message={t('Invalid party ID')}
intent={Intent.Danger}
@@ -86,7 +84,7 @@ const Party = () => {
truncateEnd={visibleChars}
/>
<div className="grid w-full grid-flow-row grid-cols-1 md:grid-flow-col md:grid-cols-2 md:space-x-4">
<div className="grid md:grid-flow-col grid-flow-row md:space-x-4 grid-cols-1 md:grid-cols-2 w-full">
<PartyBlockAccounts
accountError={AccountError}
accountLoading={AccountLoading}
@@ -4,15 +4,13 @@ import { useFetch } from '@vegaprotocol/react-helpers';
import { DATA_SOURCES } from '../../../config';
import { RenderFetched } from '../../../components/render-fetched';
import { TxDetails } from './tx-details';
import { type BlockExplorerTransaction } from '../../../routes/types/block-explorer-response';
import type { BlockExplorerTransaction } from '../../../routes/types/block-explorer-response';
import { toNonHex } from '../../../components/search/detect-search';
import { PageHeader } from '../../../components/page-header';
import { useDocumentTitle } from '../../../hooks/use-document-title';
type Params = { txHash: string };
const Tx = () => {
const { txHash } = useParams<Params>();
const { txHash } = useParams<{ txHash: string }>();
const hash = txHash ? toNonHex(txHash) : '';
let errorMessage: string | undefined = undefined;
+1 -5
View File
@@ -2,11 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["node"]
},
"files": [
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
+1 -7
View File
@@ -3,13 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node",
"@testing-library/jest-dom",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": [
"**/*.test.ts",
+2 -4
View File
@@ -1,12 +1,10 @@
{
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "cypress"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"cypress/unsafe-to-chain-command": 0
}
"rules": {}
}
]
}
+1 -1
View File
@@ -17,7 +17,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/governance-e2e/**/*.{js,ts}"]
@@ -31,7 +31,7 @@ import {
switchVegaWalletPubKey,
vegaWalletSetSpecifiedApprovalAmount,
} from '../../support/wallet-functions';
import { type testFreeformProposal } from '../../support/common-interfaces';
import type { testFreeformProposal } from '../../support/common-interfaces';
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
import {
createGovernanceTransferProposalTxBody,
@@ -61,7 +61,6 @@ const marketProposalType = 'proposal-type';
describe(
'Governance flow for proposal details',
{ tags: '@slow' },
// @ts-ignore clash between jest and cypress
function () {
before('connect wallets and set approval limit', function () {
cy.visit('/');
@@ -79,7 +78,6 @@ describe(
getProposalInformationFromTable('ID').invoke('text').as('parentMarketId');
});
// @ts-ignore clash between jest and cypress
beforeEach('visit proposals tab', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -325,7 +323,6 @@ describe(
});
});
cy.VegaWalletSubmitProposal(
// @ts-ignore this is any
createSuccessorMarketProposalTxBody(this.parentMarketId)
);
navigateTo(navigation.proposals);
@@ -337,7 +334,6 @@ describe(
cy.getByTestId(proposalTermsToggle).click();
cy.get('.language-json').within(() => {
cy.get('.hljs-attr').should('contain.text', 'parentMarketId');
// @ts-ignore this is any
cy.get('.hljs-string').should('contain.text', this.parentMarketId);
cy.get('.hljs-attr').should('contain.text', 'insurancePoolFraction');
cy.get('.hljs-string').should('contain.text', '0.75');
@@ -356,7 +352,6 @@ describe(
validateProposalDetailsDiff(
'Parent Market ID',
proposalChangeType.ADDED,
// @ts-ignore this is any
this.parentMarketId
);
validateProposalDetailsDiff(
@@ -455,7 +450,6 @@ describe(
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
// @ts-ignore this is any
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
@@ -472,7 +466,6 @@ describe(
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
// @ts-ignore this is any
.and('eq', this.parentMarketId);
});
});
@@ -483,7 +476,6 @@ describe(
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
// @ts-ignore this is any
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
@@ -497,7 +489,6 @@ describe(
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
// @ts-ignore this is any
.and('eq', this.parentMarketId);
});
});
@@ -508,7 +499,6 @@ describe(
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
submitUniqueRawProposal({
proposalBody: proposalPath,
// @ts-ignore this is any
updateMarketId: this.parentMarketId,
enactmentTimestamp: enactmentTimestamp,
closingTimestamp: closingTimestamp,
@@ -528,7 +518,6 @@ describe(
cy.getByTestId('proposal-update-market-state').within(() => {
getProposalInformationFromTable('Market ID')
.invoke('text')
// @ts-ignore this is any
.and('eq', this.parentMarketId);
getProposalDetailsValue('Termination Price').should(
'contain.text',
@@ -37,7 +37,6 @@ context(
vegaWalletSetSpecifiedApprovalAmount('1000');
});
// @ts-ignore clash between jest and cypress
beforeEach('visit proposals', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -34,7 +34,7 @@ import {
vegaWalletTeardown,
} from '../../support/wallet-functions';
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
import { type testFreeformProposal } from '../../support/common-interfaces';
import type { testFreeformProposal } from '../../support/common-interfaces';
const vegaWalletStakedBalances = 'vega-wallet-balance-staked-validators';
const vegaWalletAssociatedBalance = 'associated-amount';
@@ -78,7 +78,6 @@ context(
vegaWalletSetSpecifiedApprovalAmount('1000');
});
// @ts-ignore clash between jest and cypress
beforeEach('visit governance tab', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -302,7 +301,6 @@ context(
cy.getByTestId(voteButtons).should('not.exist');
cy.getByTestId('min-proposal-requirements').should(
'have.text',
// @ts-ignore this is any
`You must have at least ${this.minVoterBalance} VEGA associated to vote on this proposal`
);
});
@@ -70,7 +70,6 @@ context(
vegaWalletSetSpecifiedApprovalAmount('1000');
});
// @ts-ignore clash between jest and cypress
beforeEach('visit governance tab', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -217,7 +216,6 @@ context(
// 3003-PMAN-001
it(
'Able to submit valid new market proposal',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
const proposalTitle = 'Test new market proposal';
@@ -633,7 +631,6 @@ context(
);
cy.fixture('/proposals/successor-market').then((newMarketProposal) => {
newMarketProposal.changes.successor.parentMarketId =
// @ts-ignore clash between jest and cypress
this.parentMarketId;
const newMarketPayload = JSON.stringify(newMarketProposal);
cy.getByTestId(newProposalTerms).type(newMarketPayload, {
@@ -661,7 +658,6 @@ context(
.should('have.text', 'Successor market to: TEST.24h')
.find('a')
.should('have.attr', 'href')
// @ts-ignore clash between jest and cypress
.and('contain', this.parentMarketId);
});
});
@@ -1,4 +1,4 @@
import { type testFreeformProposal } from '../../support/common-interfaces';
import type { testFreeformProposal } from '../../support/common-interfaces';
import {
navigateTo,
navigation,
@@ -33,14 +33,12 @@ const voteMajorityNotMet = 'token-majority-not-met';
const voteMajorityMet = 'token-majority-met';
const votesForPercentage = 'votes-for-percentage';
// @ts-ignore clash between jest and cypress
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
before('connect wallets and set approval limit', function () {
vegaWalletSetSpecifiedApprovalAmount('1000');
cy.visit('/');
});
// @ts-ignore clash between jest and cypress
beforeEach('visit proposals tab', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -108,7 +106,6 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
it('Newly created proposals list - shows open proposals in an open state', function () {
// 3001-VOTE-004
// 3001-VOTE-035
// @ts-ignore clash between jest and cypress
createRawProposal(this.minProposerBalance);
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
getProposalFromTitle(rawProposal.rationale.title).within(() => {
@@ -64,7 +64,6 @@ context(
describe('Eth wallet - contains VEGA tokens', function () {
beforeEach(
// @ts-ignore clash between jest and cypress
'teardown wallet & drill into a specific validator',
function () {
cy.clearLocalStorage();
@@ -238,7 +237,6 @@ context(
// 1002-STKE-041 1002-STKE-053
it(
'Able to remove part of a stake against a validator',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
ensureSpecifiedUnstakedTokensAreAssociated('4');
@@ -52,7 +52,6 @@ context(
describe('Eth wallet - contains VEGA tokens', function () {
beforeEach(
// @ts-ignore clash between jest and cypress
'teardown wallet & drill into a specific validator',
function () {
cy.clearLocalStorage();
@@ -68,7 +67,6 @@ context(
it(
'Able to associate tokens - from wallet',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
//1004-ASSO-003
@@ -48,7 +48,6 @@ context(
depositAsset(usdcEthAddress, '1000', 5);
});
// @ts-ignore clash between jest and cypress
beforeEach('Navigate to withdrawal page', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -102,7 +101,6 @@ context(
// eslint-disable-next-line
it.skip(
'Able to withdraw asset: -eth wallet connected -withdraw funds button',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
// fill in withdrawal form
@@ -25,7 +25,6 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
);
});
// @ts-ignore clash between jest and cypress
beforeEach('visit home page', function () {
cy.clearLocalStorage();
turnTelemetryOff();
@@ -52,7 +52,6 @@ context(
.invoke('text')
.then(($newPageNumber) => {
const newPageNumber = Number($newPageNumber.slice(5));
// @ts-ignore clash between jest and cypress
expect(newPageNumber).to.be.greaterThan(currentPageNumber);
cy.getByTestId('goto-previous-page').click();
cy.getByTestId('page-info').should(
@@ -44,7 +44,6 @@ context('Validators Page - verify elements on page', function () {
cy.mockChainId();
});
// @ts-ignore clash between jest and cypress
describe('with wallets disconnected', { tags: '@smoke' }, function () {
it('Should have validators tab highlighted', function () {
verifyTabHighlighted(navigation.validators);
@@ -77,7 +76,6 @@ context('Validators Page - verify elements on page', function () {
describe(
'Should be able to see validator list from the staking page',
{ tags: '@regression' },
// @ts-ignore clash between jest and cypress
function () {
// 1002-STKE-050
it('Should be able to see validator names', function () {
@@ -182,7 +180,6 @@ context('Validators Page - verify elements on page', function () {
describe(
'Should be able to see static information about a validator',
{ tags: '@smoke' },
// @ts-ignore clash between jest and cypress
function () {
before('connect wallets and click on validator', function () {
cy.mockChainId();
@@ -198,7 +198,6 @@ context(
});
})
.then(function () {
// @ts-ignore clash between jest and cypress
expect(parseFloat(this.value).toFixed(1)).to.equal(
(Math.round((this.locked + this.unlocked) * 100) / 100).toFixed(
1
@@ -271,7 +270,6 @@ context(
});
})
.then(function () {
// @ts-ignore clash between jest and cypress
expect(this.value).to.equal(this.locked + this.unlocked);
});
});
@@ -105,7 +105,6 @@ context(
// 0002-WCON-008
it(
'should have truncated account number visible',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
cy.get(walletContainer).within(() => {
@@ -126,7 +125,6 @@ context(
it(
'should have Vega Associated currency value visible',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
cy.get(walletContainer).within(() => {
@@ -137,19 +135,14 @@ context(
}
);
it(
'should have Unstaked value visible',
// @ts-ignore clash between jest and cypress
{ tags: '@smoke' },
function () {
cy.get(walletContainer).within(() => {
cy.get(vegaUnstaked)
.should('be.visible')
.invoke('text')
.and('not.be.empty');
});
}
);
it('should have Unstaked value visible', { tags: '@smoke' }, function () {
cy.get(walletContainer).within(() => {
cy.get(vegaUnstaked)
.should('be.visible')
.invoke('text')
.and('not.be.empty');
});
});
it('should have Governance button visible', function () {
cy.get(walletContainer).within(() => {
@@ -306,7 +299,6 @@ context(
.siblings(txTimeout)
.should((elementAmount) => {
const displayedAmount = parseFloat(elementAmount.text());
// @ts-ignore clash between jest and cypress
expect(displayedAmount).be.gte(expectedAmount);
});
+9 -2
View File
@@ -56,7 +56,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/governance/**/*.{ts,tsx,js,jsx}"]
@@ -66,7 +66,14 @@
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/apps/governance"],
"options": {
"jestConfig": "apps/governance/jest.config.ts"
"jestConfig": "apps/governance/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"build-netlify": {
@@ -10,7 +10,7 @@ import noIcon from '../../images/token-no-icon.png';
import vegaBlack from '../../images/vega_black.png';
import vegaVesting from '../../images/vega_vesting.png';
import { BigNumber } from '../../lib/bignumber';
import { type WalletCardAssetProps } from '../wallet-card';
import type { WalletCardAssetProps } from '../wallet-card';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useContracts } from '../../contexts/contracts/contracts-context';
import * as Schema from '@vegaprotocol/types';
@@ -21,12 +21,12 @@ import {
toBigNum,
} from '@vegaprotocol/utils';
import { useAppState } from '../../contexts/app-state/app-state-context';
import {
DelegationsDocument,
type DelegationsQuery,
type DelegationsQueryVariables,
type WalletDelegationFieldsFragment,
import type {
DelegationsQuery,
DelegationsQueryVariables,
WalletDelegationFieldsFragment,
} from './__generated__/Delegations';
import { DelegationsDocument } from './__generated__/Delegations';
import { isPartyNotFoundError } from '../../lib/party';
export const usePollForDelegations = () => {
@@ -44,7 +44,6 @@ export const usePollForDelegations = () => {
const [delegatedNodes, setDelegatedNodes] = React.useState<
{
nodeId: string;
// eslint-disable-next-line
name: string;
hasStakePending: boolean;
currentEpochStake?: BigNumber;
@@ -9,7 +9,7 @@ import { useWeb3React } from '@web3-react/core';
import React from 'react';
import { SplashLoader } from '../../components/splash-loader';
import { type ContractsContextShape } from './contracts-context';
import type { ContractsContextShape } from './contracts-context';
import { ContractsContext } from './contracts-context';
import { createDefaultProvider } from '../../lib/web3-connectors';
import { useEthereumConfig } from '@vegaprotocol/web3';
@@ -1,4 +1,4 @@
import { type CollateralBridge } from '@vegaprotocol/smart-contracts';
import type { CollateralBridge } from '@vegaprotocol/smart-contracts';
import * as Schema from '@vegaprotocol/types';
import { Button } from '@vegaprotocol/ui-toolkit';
import { useBridgeContract, useEthereumTransaction } from '@vegaprotocol/web3';
@@ -88,7 +88,7 @@ export const ListAsset = ({
assetData.erc20ListAssetBundle;
return (
<div className="mb-8">
<h3 className="mb-2 text-xl">{t('ListAsset')}</h3>
<h3 className="text-xl mb-2">{t('ListAsset')}</h3>
<p className="pr-8">{t('ListAssetDescription')}</p>
<EthWalletContainer>
<Button
@@ -4,7 +4,7 @@ import { VoteValue } from '@vegaprotocol/types';
import { useEffect, useState } from 'react';
import { useUserVoteQuery } from './__generated__/Vote';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import { type FinalizedVote } from '@vegaprotocol/proposals';
import type { FinalizedVote } from '@vegaprotocol/proposals';
export enum VoteState {
NotCast = 'NotCast',
@@ -5,17 +5,15 @@ import { useTranslation } from 'react-i18next';
import { SplashLoader } from '../../../components/splash-loader';
import { ProposalsList } from '../components/proposals-list';
import { useProposalsQuery } from './__generated__/Proposals';
import { getNodes, removePaginationWrapper } from '@vegaprotocol/utils';
import {
ProposalState,
ProtocolUpgradeProposalStatus,
} from '@vegaprotocol/types';
import { type NodeConnection, type NodeEdge } from '@vegaprotocol/utils';
import {
useProposalsQuery,
type ProposalFieldsFragment,
} from './__generated__/Proposals';
import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import type { NodeConnection, NodeEdge } from '@vegaprotocol/utils';
import type { ProposalFieldsFragment } from './__generated__/Proposals';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals';
import { FLAGS } from '@vegaprotocol/environment';
@@ -5,9 +5,9 @@ import * as faker from 'faker';
import isArray from 'lodash/isArray';
import mergeWith from 'lodash/mergeWith';
import { type PartialDeep } from 'type-fest';
import { type ProposalQuery } from '../proposal/__generated__/Proposal';
import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import type { PartialDeep } from 'type-fest';
import type { ProposalQuery } from '../proposal/__generated__/Proposal';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
export function generateProtocolUpgradeProposal(
override: PartialDeep<ProtocolUpgradeProposalFieldsFragment> = {}
@@ -22,13 +22,11 @@ interface UserBalances {
balance: BigNumber;
}
type Params = { address: string };
export const RedemptionInformation = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const tranches = useTranches((state) => state.tranches);
const { address } = useParams<Params>();
const { address } = useParams<{ address: string }>();
const [userBalances, setUserBalances] = useState<null | UserBalances>();
const getUsersBalances = useGetUserBalances(address);
useEffect(() => {
@@ -86,7 +84,7 @@ export const RedemptionInformation = () => {
i18nKey="noVestingTokens"
components={{
tranchesLink: (
<Link className="text-white underline" to={Routes.SUPPLY} />
<Link className="underline text-white" to={Routes.SUPPLY} />
),
}}
/>
@@ -162,7 +160,7 @@ export const RedemptionInformation = () => {
intent={Intent.Warning}
>
<p>{t('Find out more about Staking.')}</p>
<Link to={Routes.VALIDATORS} className="text-white underline">
<Link to={Routes.VALIDATORS} className="underline text-white">
{t('Stake VEGA tokens')}
</Link>
</Callout>
@@ -21,10 +21,9 @@ import RoutesConfig from '../routes';
interface FormFields {
address: string;
}
type Params = { address: string };
const RedemptionRouter = () => {
const { address } = useParams<Params>();
const { address } = useParams<{ address: string }>();
const navigate = useNavigate();
const { t } = useTranslation();
const validatePubkey = useCallback(
@@ -90,7 +89,7 @@ const RedemptionRouter = () => {
{t('View connected Eth Wallet')}
</Button>
)}
<p className="flex justify-center py-4">{t('OR')}</p>
<p className="py-4 flex justify-center">{t('OR')}</p>
<form
onSubmit={handleSubmit(onSubmit)}
data-testid="view-connector-form"
@@ -21,8 +21,6 @@ import { EthConnectPrompt } from '../../../components/eth-connect-prompt';
import { useUserTrancheBalances } from '../hooks';
import { useAppState } from '../../../contexts/app-state/app-state-context';
type Params = { id: string };
export const RedeemFromTranche = () => {
const { account: address } = useWeb3React();
const { vesting } = useContracts();
@@ -36,7 +34,7 @@ export const RedeemFromTranche = () => {
tranches: state.tranches,
getTranches: state.getTranches,
}));
const { id } = useParams<Params>();
const { id } = useParams<{ id: string }>();
const numberId = Number(id);
const tranche = React.useMemo(
() => tranches?.find(({ tranche_id }) => tranche_id === numberId) || null,
@@ -88,7 +86,7 @@ export const RedeemFromTranche = () => {
i18nKey="noVestingTokens"
components={{
tranchesLink: (
<Link className="text-white underline" to={Routes.SUPPLY} />
<Link className="underline text-white" to={Routes.SUPPLY} />
),
}}
/>
@@ -130,13 +128,13 @@ export const RedeemFromTranche = () => {
components={{
stakingLink: (
<Link
className="text-white underline"
className="underline text-white"
to={Routes.VALIDATORS}
/>
),
governanceLink: (
<Link
className="text-white underline"
className="underline text-white"
to={Routes.PROPOSALS}
/>
),
@@ -11,12 +11,12 @@ import { useTransaction } from '../../../hooks/use-transaction';
import { useAppState } from '../../../contexts/app-state/app-state-context';
import { removeDecimal, removePaginationWrapper } from '@vegaprotocol/utils';
import * as Schema from '@vegaprotocol/types';
import {
PartyStakeLinkingsDocument,
type LinkingsFieldsFragment,
type PartyStakeLinkingsQuery,
type PartyStakeLinkingsQueryVariables,
import type {
LinkingsFieldsFragment,
PartyStakeLinkingsQuery,
PartyStakeLinkingsQueryVariables,
} from './__generated__/PartyStakeLinkings';
import { PartyStakeLinkingsDocument } from './__generated__/PartyStakeLinkings';
export const useAddStake = (
address: string,
@@ -26,9 +26,9 @@ import {
ValidatorRenderer,
VotingPowerRenderer,
} from './shared';
import { type AgGridReact } from 'ag-grid-react';
import { type ColDef, type RowHeightParams } from 'ag-grid-community';
import { type ValidatorsTableProps } from './shared';
import type { AgGridReact } from 'ag-grid-react';
import type { ColDef, RowHeightParams } from 'ag-grid-community';
import type { ValidatorsTableProps } from './shared';
import {
formatNumber,
formatNumberPercentage,
@@ -83,19 +83,19 @@ const TopThirdCellRenderer = (
e.preventDefault();
setHideTopThird(false);
}}
className="grid h-full w-full grid-cols-[60px_1fr] overflow-scroll px-0 py-4 text-center text-sm text-white"
className="grid grid-cols-[60px_1fr] w-full h-full py-4 px-0 text-sm text-white text-center overflow-scroll"
>
<div className="px-3 text-left text-xs">
<div className="px-3 text-xs text-left">
{params?.data?.rankingDisplay}
</div>
<div className="whitespace-normal px-3">
<div className="px-3 whitespace-normal">
<div className="mb-4">
<Button
data-testid="show-all-validators"
rightIcon={
<Icon
name="arrow-right"
className="mr-2 fill-current align-text-top"
className="mr-2 align-text-top fill-current"
/>
}
className="inline-flex items-center"
@@ -22,9 +22,9 @@ import {
PendingStakeRenderer,
VotingPowerRenderer,
} from './shared';
import { type AgGridReact } from 'ag-grid-react';
import { type ColDef } from 'ag-grid-community';
import { type ValidatorsTableProps } from './shared';
import type { AgGridReact } from 'ag-grid-react';
import type { ColDef } from 'ag-grid-community';
import type { ValidatorsTableProps } from './shared';
import {
formatNumber,
formatNumberPercentage,
@@ -28,14 +28,12 @@ interface StakingNodeProps {
previousEpochData?: PreviousEpochQuery;
}
type Params = { node: string };
export const StakingNode = ({ data, previousEpochData }: StakingNodeProps) => {
const { pubKey: vegaKey } = useVegaWallet();
const {
appState: { decimals },
} = useAppState();
const { node } = useParams<Params>();
const { node } = useParams<{ node: string }>();
const { t } = useTranslation();
const { nodeInfo, currentEpoch, delegations } = React.useMemo(
@@ -16,12 +16,10 @@ import Routes from '../routes';
import { TrancheLabel } from './tranche-label';
import { useTranches } from '../../lib/tranches/tranches-store';
type Params = { trancheId: string; address: string };
export const Tranche = () => {
const tranches = useTranches((state) => state.tranches);
const { t } = useTranslation();
const { trancheId } = useParams<Params>();
const { trancheId } = useParams<{ trancheId: string; address: string }>();
const { chainId } = useWeb3React();
const tranche = tranches?.find(
(tranche) => trancheId && parseInt(trancheId) === tranche.tranche_id
@@ -43,7 +41,7 @@ export const Tranche = () => {
}
/>
<div
className="flex justify-between gap-x-4 px-4 py-2"
className="flex justify-between gap-x-4 py-2 px-4"
data-testid="redeemed-tranche-tokens"
>
<span>{t('alreadyRedeemed')}</span>
+1 -5
View File
@@ -2,11 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["node"]
},
"files": [
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
+1 -7
View File
@@ -3,13 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node",
"@testing-library/jest-dom",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": [
"**/*.test.ts",
+14 -14
View File
@@ -3,20 +3,20 @@
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=\$npm_package_version
NX_REPOSITORY_URL=\$REPOSITORY_URL
NX_BRANCH=\$BRANCH
NX_PULL_REQUEST=\$PULL_REQUEST
NX_HEAD=\$HEAD
NX_COMMIT_REF=\$COMMIT_REF
NX_CONTEXT=\$CONTEXT
NX_REVIEW_ID=\$REVIEW_ID
NX_INCOMING_HOOK_TITLE=\$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=\$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=\$INCOMING_HOOK_BODY
NX_URL=\$URL
NX_DEPLOY_URL=\$DEPLOY_URL
NX_DEPLOY_PRIME_URL=\$DEPLOY_PRIME_URL
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
NX_VEGA_ENV = 'TESTNET'
NX_VEGA_URL="https://api.n07.testnet.vega.xyz/graphql"
@@ -65,7 +65,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": [
@@ -79,7 +79,14 @@
"{workspaceRoot}/coverage/apps/liquidity-provision-dashboard"
],
"options": {
"jestConfig": "apps/liquidity-provision-dashboard/jest.config.ts"
"jestConfig": "apps/liquidity-provision-dashboard/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"build-netlify": {
@@ -1,5 +1,5 @@
import { DApp, useLinks } from '@vegaprotocol/environment';
import { type Market } from '@vegaprotocol/liquidity';
import type { Market } from '@vegaprotocol/liquidity';
import {
displayChange,
formatWithAsset,
@@ -12,7 +12,7 @@ import {
toBigNum,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { type VegaValueFormatterParams } from '@vegaprotocol/datagrid';
import type { VegaValueFormatterParams } from '@vegaprotocol/datagrid';
import { PriceChangeCell } from '@vegaprotocol/datagrid';
import type * as Schema from '@vegaprotocol/types';
import {
@@ -21,10 +21,10 @@ import {
HealthBar,
TooltipCellComponent,
} from '@vegaprotocol/ui-toolkit';
import {
type GetRowIdParams,
type RowClickedEvent,
type ColDef,
import type {
GetRowIdParams,
RowClickedEvent,
ColDef,
} from 'ag-grid-community';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
@@ -253,7 +253,7 @@ export const MarketList = () => {
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<div
className="w-full grow"
className="grow w-full"
style={{ minHeight: 500, overflow: 'hidden' }}
>
<Grid
@@ -60,21 +60,19 @@ const useMarketDetails = (marketId: string | undefined) => {
};
};
type Params = { marketId: string };
export const Detail = () => {
const { marketId } = useParams<Params>();
const { marketId } = useParams<{ marketId: string }>();
const { data, loading, error } = useMarketDetails(marketId);
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<div className="bg-greys-light-100 px-16 pb-12 pt-14">
<div className="mx-auto max-w-screen-xl">
<div className="px-16 pt-14 pb-12 bg-greys-light-100">
<div className="max-w-screen-xl mx-auto">
<Header name={data.name} symbol={data.symbol} />
</div>
</div>
<div className="px-16">
<div className="mx-auto max-w-screen-xl">
<div className="max-w-screen-xl mx-auto">
<div className="py-12">
{marketId && (
<Market
@@ -88,7 +86,7 @@ export const Detail = () => {
)}
</div>
<div>
<h2 className="font-alpha calt mb-4 text-2xl">
<h2 className="font-alpha calt text-2xl mb-4">
{t('Current Liquidity Provision')}
</h2>
<LPProvidersGrid
@@ -1,11 +1,11 @@
import { useCallback, useMemo } from 'react';
import { type GetRowIdParams, type ColDef } from 'ag-grid-community';
import type { GetRowIdParams, ColDef } from 'ag-grid-community';
import { t } from '@vegaprotocol/i18n';
import {
type LiquidityProviderFeeShareFieldsFragment,
type LiquidityProvisionFieldsFragment,
import type {
LiquidityProviderFeeShareFieldsFragment,
LiquidityProvisionFieldsFragment,
} from '@vegaprotocol/liquidity';
import { formatWithAsset } from '@vegaprotocol/liquidity';
@@ -1,9 +1,9 @@
import { useRef, useCallback, useEffect } from 'react';
import { AgGridReact } from 'ag-grid-react';
import {
type AgGridReactProps,
type AgReactUiProps,
type AgGridReact as AgGridReactType,
import type {
AgGridReactProps,
AgReactUiProps,
AgGridReact as AgGridReactType,
} from 'ag-grid-react';
import classNames from 'classnames';
import 'ag-grid-community/styles/ag-grid.css';
@@ -34,7 +34,7 @@ export const Grid = ({ isRowClickable, ...props }: Props) => {
return (
<AgGridReact
className={classNames('ag-theme-alpine font-alpha calt h-full', {
className={classNames('ag-theme-alpine h-full font-alpha calt', {
'row-hover': isRowClickable,
})}
rowHeight={92}
@@ -2,11 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["node"]
},
"files": [
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
@@ -3,13 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node",
"@testing-library/jest-dom",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
],
"types": ["jest", "node", "@testing-library/jest-dom"],
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
+9 -2
View File
@@ -53,7 +53,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/multisig-signer/**/*.{ts,tsx,js,jsx}"]
@@ -63,7 +63,14 @@
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/apps/multisig-signer"],
"options": {
"jestConfig": "apps/multisig-signer/jest.config.ts"
"jestConfig": "apps/multisig-signer/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"build-netlify": {
@@ -11,12 +11,12 @@ import {
Loader,
} from '@vegaprotocol/ui-toolkit';
import { useContracts } from '../../config/contracts/contracts-context';
import { type FormEvent } from 'react';
import {
type AddSignerBundle,
type AddSignerBundleVariables,
import type { FormEvent } from 'react';
import type {
AddSignerBundle,
AddSignerBundleVariables,
} from '../__generated__/AddSignerBundle';
import { type MultisigControl } from '@vegaprotocol/smart-contracts';
import type { MultisigControl } from '@vegaprotocol/smart-contracts';
export const ADD_SIGNER_QUERY = gql`
query AddSignerBundle($nodeId: ID!) {
@@ -11,12 +11,12 @@ import {
Loader,
} from '@vegaprotocol/ui-toolkit';
import { useContracts } from '../../config/contracts/contracts-context';
import { type FormEvent } from 'react';
import {
type RemoveSignerBundle,
type RemoveSignerBundleVariables,
import type { FormEvent } from 'react';
import type {
RemoveSignerBundle,
RemoveSignerBundleVariables,
} from '../__generated__/RemoveSignerBundle';
import { type MultisigControl } from '@vegaprotocol/smart-contracts';
import type { MultisigControl } from '@vegaprotocol/smart-contracts';
const REMOVE_SIGNER_QUERY = gql`
query RemoveSignerBundle($nodeId: ID!) {
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { MultisigControl } from '@vegaprotocol/smart-contracts';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { type ContractsContextShape } from './contracts-context';
import type { ContractsContextShape } from './contracts-context';
import { ContractsContext } from './contracts-context';
import { useEthereumConfig } from '@vegaprotocol/web3';
import { useEnvironment } from '@vegaprotocol/environment';
+1 -5
View File
@@ -2,11 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["node"]
},
"files": [
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
+1 -7
View File
@@ -3,13 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node",
"@testing-library/jest-dom",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": [
"**/*.test.ts",
+1 -3
View File
@@ -4,9 +4,7 @@
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"cypress/unsafe-to-chain-command": 0
}
"rules": {}
},
{
"files": ["src/plugins/index.js"],
+1 -1
View File
@@ -20,7 +20,7 @@
}
},
"lint": {
"executor": "@nx/eslint:lint",
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/trading-e2e/**/*.{js,ts}"]
@@ -26,7 +26,7 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
cy.getByTestId('tab-deposits').should('not.be.empty');
});
it.skip('should see QR code modal for WalletConnect', () => {
it('should see QR code modal for WalletConnect', () => {
// 0004-EWAL-003
cy.getByTestId('Deposits').click();
@@ -35,7 +35,7 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
cy.getByTestId('web3-connector-list').should('exist');
cy.getByTestId('web3-connector-WalletConnect').click();
// testing if exists rather than visible because of the long loading time
cy.get('#w3m-modal').should('exist');
cy.get('w3m-modal').should('exist');
});
it('able to disconnect eth wallet', () => {
+1 -1
View File
@@ -5,7 +5,7 @@
"next",
"next/core-web-vitals"
],
"ignorePatterns": ["!**/*", "__generated__", ".next", "setup-tests.ts"],
"ignorePatterns": ["!**/*", "__generated__", ".next"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
@@ -17,7 +17,7 @@ import { useReferral } from './hooks/use-referral';
import { Routes } from '../../lib/links';
import { useTransactionEventSubscription } from '@vegaprotocol/web3';
import { t } from '@vegaprotocol/i18n';
import { Statistics, useStats } from './referral-statistics';
import { Statistics } from './referral-statistics';
import { useReferralProgram } from './hooks/use-referral-program';
const RELOAD_DELAY = 3000;
@@ -132,8 +132,6 @@ export const ApplyCodeForm = () => {
}),
});
const { epochsValue, nextBenefitTierValue } = useStats({ program });
// go to main page when successfully applied
useEffect(() => {
if (status === 'successful') {
@@ -198,10 +196,6 @@ export const ApplyCodeForm = () => {
};
};
const nextBenefitTierEpochsValue = nextBenefitTierValue
? nextBenefitTierValue.epochs - epochsValue
: 0;
return (
<>
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
@@ -244,12 +238,7 @@ export const ApplyCodeForm = () => {
) : null}
{previewData ? (
<div className="mt-10">
<h2 className="text-2xl mb-5">
{t(
'You are joining the group shown, but will not have access to benefits until you have completed at least %s epochs.',
[nextBenefitTierEpochsValue.toString()]
)}
</h2>
<h2 className="text-2xl mb-5">{t('You are joining')}</h2>
<Statistics data={previewData} program={program} as="referee" />
</div>
) : null}
@@ -25,7 +25,7 @@ import compact from 'lodash/compact';
import { useReferralProgram } from './hooks/use-referral-program';
import { useStakeAvailable } from './hooks/use-stake-available';
import sortBy from 'lodash/sortBy';
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
import { useLayoutEffect, useRef, useState } from 'react';
import { useCurrentEpochInfoQuery } from './hooks/__generated__/Epoch';
import BigNumber from 'bignumber.js';
import { t } from '@vegaprotocol/i18n';
@@ -59,20 +59,21 @@ export const ReferralStatistics = () => {
return <CreateCodeContainer />;
};
export const useStats = ({
export const Statistics = ({
data,
program,
as,
}: {
data?: NonNullable<ReturnType<typeof useReferral>['data']>;
data: NonNullable<ReturnType<typeof useReferral>['data']>;
program: ReturnType<typeof useReferralProgram>;
as?: 'referrer' | 'referee';
as: 'referrer' | 'referee';
}) => {
const { benefitTiers } = program;
const { benefitTiers, details } = program;
const { data: epochData } = useCurrentEpochInfoQuery();
const { stakeAvailable } = useStakeAvailable();
const { data: statsData } = useReferralSetStatsQuery({
variables: {
code: data?.code || '',
code: data.code,
},
skip: !data?.code,
fetchPolicy: 'cache-and-network',
@@ -80,12 +81,19 @@ export const useStats = ({
const currentEpoch = Number(epochData?.epoch.id);
const compactNumFormat = new Intl.NumberFormat(getUserLocale(), {
minimumFractionDigits: 0,
maximumFractionDigits: 2,
notation: 'compact',
compactDisplay: 'short',
});
const stats =
statsData?.referralSetStats.edges &&
compact(removePaginationWrapper(statsData.referralSetStats.edges));
const refereeInfo = data?.referee;
const refereeInfo = data.referee;
const refereeStats = stats?.find(
(r) => r.partyId === data?.referee?.refereeId
(r) => r.partyId === data.referee?.refereeId
);
const statsAvailable = stats && stats.length > 0 && stats[0];
@@ -128,60 +136,6 @@ export const useStats = ({
? nextBenefitTierValue.epochs - epochsValue
: 0;
return {
baseCommissionValue,
runningVolumeValue,
referrerVolumeValue,
multiplier,
finalCommissionValue,
discountFactorValue,
currentBenefitTierValue,
nextBenefitTierValue,
epochsValue,
nextBenefitTierVolumeValue,
nextBenefitTierEpochsValue,
};
};
export const Statistics = ({
data,
program,
as,
}: {
data: NonNullable<ReturnType<typeof useReferral>['data']>;
program: ReturnType<typeof useReferralProgram>;
as: 'referrer' | 'referee';
}) => {
const {
baseCommissionValue,
runningVolumeValue,
referrerVolumeValue,
multiplier,
finalCommissionValue,
discountFactorValue,
currentBenefitTierValue,
epochsValue,
nextBenefitTierVolumeValue,
nextBenefitTierEpochsValue,
} = useStats({ data, program, as });
const isApplyCodePreview = useMemo(
() => data.referee === null,
[data.referee]
);
const { benefitTiers } = useReferralProgram();
const { stakeAvailable } = useStakeAvailable();
const { details } = program;
const compactNumFormat = new Intl.NumberFormat(getUserLocale(), {
minimumFractionDigits: 0,
maximumFractionDigits: 2,
notation: 'compact',
compactDisplay: 'short',
});
const baseCommissionTile = (
<StatTile
title={t('Base commission rate')}
@@ -275,18 +229,11 @@ export const Statistics = ({
const currentBenefitTierTile = (
<StatTile title={t('Current tier')}>
{isApplyCodePreview
? currentBenefitTierValue?.tier || benefitTiers[0]?.tier || 'None'
: currentBenefitTierValue?.tier || 'None'}
{currentBenefitTierValue?.tier || 'None'}
</StatTile>
);
const discountFactorTile = (
<StatTile title={t('Discount')}>
{isApplyCodePreview
? benefitTiers[0].discountFactor * 100
: discountFactorValue * 100}
%
</StatTile>
<StatTile title={t('Discount')}>{discountFactorValue * 100}%</StatTile>
);
const runningVolumeTile = (
<StatTile
@@ -318,11 +265,11 @@ export const Statistics = ({
<>
<div className="grid grid-rows-1 gap-5 grid-cols-1 md:grid-cols-3">
{currentBenefitTierTile}
{runningVolumeTile}
{discountFactorTile}
{codeTile}
</div>
<div className="grid grid-rows-1 gap-5 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
{discountFactorTile}
{runningVolumeTile}
{nextTierVolumeTile}
{epochsTile}
{nextTierEpochsTile}
+4 -23
View File
@@ -3,7 +3,6 @@ import { Switch, ToastPositionSetter } from '@vegaprotocol/ui-toolkit';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
import type { ReactNode } from 'react';
import classNames from 'classnames';
export const Settings = () => {
const { theme, setTheme } = useThemeSwitcher();
@@ -32,18 +31,6 @@ export const Settings = () => {
<SettingsGroup label={t('Toast location')}>
<ToastPositionSetter />
</SettingsGroup>
<SettingsGroup inline={false} label={t('App information')}>
<dl className="text-sm grid grid-cols-2 gap-1">
{process.env.GIT_TAG && (
<>
<dt className="text-muted">{t('Version')}</dt>
<dd>{process.env.GIT_TAG}</dd>
</>
)}
<dt className="text-muted">{t('Git commit hash')}</dt>
<dd className="break-words">{process.env.GIT_COMMIT}</dd>
</dl>
</SettingsGroup>
</div>
);
};
@@ -52,22 +39,16 @@ const SettingsGroup = ({
label,
helpText,
children,
inline = true,
}: {
label: string;
children: ReactNode;
helpText?: string;
inline?: boolean;
children: ReactNode;
}) => {
return (
<div
className={classNames('mb-4 gap-2', {
'flex items-start justify-between gap-2': inline,
})}
>
<div className={classNames({ 'w-3/4': inline, 'mb-2': !inline })}>
<div className="flex justify-between items-start mb-4">
<div className="w-3/4">
<label className="text-sm">{label}</label>
{helpText && <p className="text-xs text-muted">{helpText}</p>}
{helpText && <p className="text-muted text-xs">{helpText}</p>}
</div>
{children}
</div>
-2
View File
@@ -1,2 +0,0 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
VEGA_VERSION=v0.73.4
-2
View File
@@ -1,2 +0,0 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:develop
VEGA_VERSION=v0.73.4
-2
View File
@@ -1,2 +0,0 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:main
VEGA_VERSION=v0.73.4
-136
View File
@@ -1,136 +0,0 @@
# Trading Market-Sim End-To-End Tests
This direcotry contains end-to-end tests for the trading application using vega-market-sim. This README will guide you through setting up your environment and running the tests.
## Prerequisites
- [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer)
- [Docker](https://www.docker.com/)
- [Python versions ">=3.9,<3.11"](https://www.python.org/)
## Getting Started
1. **Install Poetry**: Follow the instructions on the [official Poetry website](https://python-poetry.org/docs/#installing-with-the-official-installer).
2. **Install Docker**: Follow the instructions on the [official Docker website](https://docs.docker.com/desktop/).
3. **Install Python**: Follow the instructions on the [official Python website](https://www.python.org/)
**ensure you install a version between 3.9 and 3.11.**
4. **Start up a Poetry environment**: Execute the commands below to configure the Poetry environment.
### Ensure you are in the tests folder before running commands
```bash
poetry shell
```
5. **Install python dependencies**
```bash
poetry install
```
6. **Install Playwright Browsers**: Execute the command below to browsers for Playwright.
```bash
playwright install chromium
```
7. **Download necessary binaries**:
Use the following command within your Python environment. The `--force` flag ensures the binaries are overwritten, and the `--version` specifies the desired version. e.g. `v0.73.4`
```bash
python -m vega_sim.tools.load_binaries --force --version $VEGA_VERSION
```
8. **Pull the desired Docker image**
```bash
docker pull vegaprotocol/trading:develop
```
9. **Run tests**: Poetry/Python will serve the app from docker
### Update the .env file with the correct trading image.
```bash
poetry run pytest
```
### Docker images
Pull the desired image:
**Testnet**
```bash
docker pull vegaprotocol/trading:develop
```
**Mainnet**
```bash
docker pull vegaprotocol/trading:main
```
Find all available images on [Docker Hub](https://hub.docker.com/r/vegaprotocol/trading/tags).
#### Create a Docker Image of Your Locally Built Trading App
To build your Docker image, use the following commands:
```bash
yarn nx build trading ./docker/prepare-dist.sh
```
```bash
docker build -f docker/node-outside-docker.Dockerfile --build-arg APP=trading --build-arg ENV_NAME=stagnet1 -t vegaprotocol/trading:latest .
```
## Running Tests 🧪
Before running make sure the docker daemon is runnign so that the app can be served.
To run a specific test, use the `-k` option followed by the name of the test.
Run all tests:
```bash
poetry run pytest
```
Run a targeted test:
```bash
poetry run pytest -k "test_name" -s
```
Run from anywhere:
```bash
yarn trading:test -- "test_name" -s
```
## Running Tests in Parallel 🔢
To run tests in parallel, use the `--numprocesses auto` option. The `--dist loadfile` setting ensures that multiple runners are not assigned to a single test file.
### From within the e2e folder:
```bash
poetry run pytest -s --numprocesses auto --dist loadfile
```
### From anywhere:
```bash
yarn trading:test:all
```
# Things to know
If you "intellisense" isn't working follow these steps:
1. ```bash
poetry run which python
```
2. Then open the command menu in vscode (cmd + shift + p) and type `select interpreter` , press enter, select enter interpreter path press enter then paste in the output from that above command you should get the right python again
-38
View File
@@ -1,38 +0,0 @@
from collections import namedtuple
from playwright.sync_api import Page
from vega_sim.null_service import VegaServiceNull
from typing import Optional
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
ASSET_NAME = "tDAI"
def wait_for_toast_confirmation(page: Page, timeout: int = 30000):
page.wait_for_function("""
document.querySelector('[data-testid="toast-content"]') &&
document.querySelector('[data-testid="toast-content"]').innerText.includes('AWAITING CONFIRMATION')
""", timeout=timeout)
def create_and_faucet_wallet(
vega: VegaServiceNull,
wallet: WalletConfig,
symbol: Optional[str] = None,
amount: float = 1e4,
):
asset_id = vega.find_asset_id(symbol=symbol if symbol is not None else ASSET_NAME)
vega.create_key(wallet.name)
vega.mint(wallet.name, asset_id, amount)
def next_epoch(vega: VegaServiceNull):
forwards = 0
epoch_seq = vega.statistics().epoch_seq
while epoch_seq == vega.statistics().epoch_seq:
vega.wait_fn(1)
forwards += 1
if forwards > 2 * 10 * 60:
raise Exception(
"Epoch not started after forwarding the duration of two epochs."
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
-65
View File
@@ -1,65 +0,0 @@
from typing import List, Tuple, Optional
from vega_sim.service import VegaService, PeggedOrder
def submit_order(
vega: VegaService,
wallet_name: str,
market_id: str,
side: str,
volume: float,
price: float,
peak_size: Optional[float] = None,
minimum_visible_size: Optional[float] = None,
):
return vega.submit_order(
trading_key=wallet_name,
market_id=market_id,
time_in_force="TIME_IN_FORCE_GTC",
order_type="TYPE_LIMIT",
side=side,
volume=volume,
price=price,
peak_size=peak_size,
minimum_visible_size=minimum_visible_size,
)
def submit_multiple_orders(
vega: VegaService,
wallet_name: str,
market_id: str,
side: str,
volume_price_pair: List[Tuple[float, float]],
):
for volume, price in volume_price_pair:
submit_order(vega, wallet_name, market_id, side, volume, price)
def submit_liquidity(vega: VegaService, wallet_name: str, market_id: str):
vega.submit_simple_liquidity(
key_name=wallet_name,
market_id=market_id,
commitment_amount=10000,
fee=0.000,
is_amendment=False,
)
vega.submit_order(
market_id=market_id,
trading_key=wallet_name,
side="SIDE_BUY",
order_type="TYPE_LIMIT",
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=1),
wait=False,
time_in_force="TIME_IN_FORCE_GTC",
volume=99,
)
vega.submit_order(
market_id=market_id,
trading_key=wallet_name,
side="SIDE_SELL",
order_type="TYPE_LIMIT",
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=1),
wait=False,
time_in_force="TIME_IN_FORCE_GTC",
volume=99,
)
-9
View File
@@ -1,9 +0,0 @@
import os
from dotenv import load_dotenv
load_dotenv()
console_image_name = os.getenv(
"CONSOLE_IMAGE_NAME", default="vegaprotocol/trading:latest"
)
vega_version = os.getenv("VEGA_VERSION", default="latest")
-243
View File
@@ -1,243 +0,0 @@
import logging
import pytest
import os
import json
import requests
import time
import docker
import http.server
import socketserver
from threading import Thread
from contextlib import contextmanager
from vega_sim.null_service import VegaServiceNull
from playwright.sync_api import Browser, Page
from config import console_image_name, vega_version
from fixtures.market import (
setup_simple_market,
setup_opening_auction_market,
setup_continuous_market,
)
import sys
# Workaround for current xdist issue with displaying live logs from multiple workers
# https://github.com/pytest-dev/pytest-xdist/issues/402
sys.stdout = sys.stderr
docker_client = docker.from_env()
logger = logging.getLogger()
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call):
outcome = "passed" if call.excinfo is None else "failed"
item.config.cache.set(item.nodeid, outcome)
def pytest_configure(config):
worker_id = os.environ.get("PYTEST_XDIST_WORKER")
if worker_id is not None:
log_dir = os.path.join(os.getcwd(), "logs")
log_name = f"tests_{worker_id}.log"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
logging.basicConfig(
format=config.getini("log_file_format"),
datefmt=config.getini("log_file_date_format"),
filename=os.path.join(log_dir, log_name),
level=config.getini("log_file_level"),
)
class CustomHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
# Set the path to your website's directory here
if self.path == '/':
self.path = 'dist/apps/trading/exported/index.html'
return http.server.SimpleHTTPRequestHandler.do_GET(self)
# Start VegaServiceNull
@contextmanager
def init_vega(request=None):
default_seconds = 1
seconds_per_block = default_seconds
if request and hasattr(request, "param"):
seconds_per_block = request.param
logger.info(
"Starting VegaServiceNull",
extra={"worker_id": os.environ.get("PYTEST_XDIST_WORKER")},
)
logger.info(f"Using console image: {console_image_name}")
logger.info(f"Using vega version: {vega_version}")
with VegaServiceNull(
run_with_console=False,
launch_graphql=False,
retain_log_files=True,
use_full_vega_wallet=True,
store_transactions=True,
transactions_per_block=1000,
seconds_per_block=seconds_per_block,
) as vega:
try:
container = docker_client.containers.run(
console_image_name, detach=True, ports={"80/tcp": vega.console_port}
)
# docker setup
logger.info(
f"Container {container.id} started",
extra={"worker_id": os.environ.get("PYTEST_XDIST_WORKER")},
)
yield vega
except docker.errors.APIError as e:
logger.info(f"Container creation failed.")
logger.info(e)
raise e
finally:
logger.info(f"Stopping container {container.id}")
container.stop()
# Remove the container
logger.info(f"Removing container {container.id}")
container.remove()
@contextmanager
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest):
with browser.new_context(
viewport={"width": 1920, "height": 1080},
base_url=f"http://localhost:{vega.console_port}",
) as context, context.new_page() as page:
context.tracing.start(screenshots=True, snapshots=True, sources=True)
try:
# Wait for the console to be up and running before any tests are run
attempts = 0
while attempts < 100:
try:
code = requests.get(
f"http://localhost:{vega.console_port}/"
).status_code
if code == 200:
break
except requests.exceptions.ConnectionError as e:
attempts += 1
if attempts < 100:
time.sleep(0.1)
continue
else:
raise e
# Set window._env_ so built app uses datanode from vega market sim
env = json.dumps(
{
"VEGA_URL": f"http://localhost:{vega.data_node_rest_port}/graphql",
"VEGA_WALLET_URL": f"http://localhost:{vega.wallet_port}",
}
)
window_env = f"window._env_ = Object.assign({{}}, window._env_, {env})"
page.add_init_script(script=window_env)
yield page
finally:
if not os.path.exists("traces"):
os.makedirs("traces")
# Check whether this test failed or passed
outcome = request.config.cache.get(request.node.nodeid, None)
if outcome != "passed":
try:
trace_path = os.path.join("traces", request.node.name + "trace.zip")
context.tracing.stop(path=trace_path)
except Exception as e:
logger.error(f"Failed to save trace: {e}")
@pytest.fixture
def vega(request):
with init_vega(request) as vega:
yield vega
@pytest.fixture
def page(vega, browser, request):
with init_page(vega, browser, request) as page_instance:
yield page_instance
# Set auth token so eager connection for MarketSim wallet is successful
def auth_setup(vega: VegaServiceNull, page: Page):
DEFAULT_WALLET_NAME = "MarketSim" # This is the default wallet name within VegaServiceNull and CANNOT be changed
# Calling get_keypairs will internally call _load_tokens for the given wallet
keypairs = vega.wallet.get_keypairs(DEFAULT_WALLET_NAME)
wallet_api_token = vega.wallet.login_tokens[DEFAULT_WALLET_NAME]
# Set token to localStorage so eager connect hook picks it up and immediately connects
wallet_config = json.dumps(
{
"token": f"VWT {wallet_api_token}",
"connector": "jsonRpc",
"url": f"http://localhost:{vega.wallet_port}",
}
)
storage_javascript = [
# Store wallet config so eager connection is initiated
f"localStorage.setItem('vega_wallet_config', '{wallet_config}');",
# Ensure wallet ris dialog doesnt show, otherwise eager connect wont work
"localStorage.setItem('vega_wallet_risk_accepted', 'true');",
# Ensure initial risk dialog doesnt show
"localStorage.setItem('vega_risk_accepted', 'true');",
]
script = "".join(storage_javascript)
page.add_init_script(script)
return {
"wallet": DEFAULT_WALLET_NAME,
"wallet_api_token": wallet_api_token,
"public_key": keypairs["Key 1"],
}
@pytest.fixture(scope="function")
def auth(vega: VegaServiceNull, page: Page):
return auth_setup(vega, page)
# Set 'risk accepted' flag, so that the risk dialog doesn't show up
def risk_accepted_setup(page: Page):
onboarding_config = json.dumps({"state": {"dismissed": True}, "version": 0})
storage_javascript = [
"localStorage.setItem('vega_risk_accepted', 'true');",
f"localStorage.setItem('vega_onboarding', '{onboarding_config}');",
"localStorage.setItem('vega_telemetry_approval', 'false');",
"localStorage.setItem('vega_telemetry_viewed', 'true');",
]
script = "".join(storage_javascript)
page.add_init_script(script)
@pytest.fixture(scope="function")
def risk_accepted(page: Page):
risk_accepted_setup(page)
@pytest.fixture(scope="function")
def simple_market(vega, request):
kwargs = {}
if hasattr(request, "param"):
kwargs.update(request.param)
return setup_simple_market(vega, **kwargs)
@pytest.fixture(scope="function")
def opening_auction_market(vega):
return setup_opening_auction_market(vega)
@pytest.fixture(scope="function")
def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.fixture(scope="function")
def proposed_market(vega):
return setup_simple_market(vega, approve_proposal=False)
-156
View File
@@ -1,156 +0,0 @@
from collections import namedtuple
from vega_sim.service import VegaService
from actions.vega import submit_multiple_orders, submit_order, submit_liquidity
import logging
logger = logging.getLogger()
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
mint_amount: float = 10e5
market_name = "BTC:DAI_2023"
def setup_simple_market(
vega: VegaService,
approve_proposal=True,
custom_market_name=market_name,
custom_asset_name="tDAI",
custom_asset_symbol="tDAI",
):
for wallet in wallets:
vega.create_key(wallet.name)
vega.mint(
MM_WALLET.name,
asset="VOTE",
amount=mint_amount,
)
vega.update_network_parameter(
MM_WALLET.name, parameter="market.fee.factors.makerFee", new_value="0.1"
)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
vega.create_asset(
MM_WALLET.name,
name=custom_asset_name,
symbol=custom_asset_symbol,
decimals=5,
max_faucet_amount=1e10,
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
tdai_id = vega.find_asset_id(symbol=custom_asset_symbol)
logger.info(f"Created asset: {custom_asset_symbol}")
vega.mint(
"Key 1",
asset=tdai_id,
amount=mint_amount,
)
vega.mint(
MM_WALLET.name,
asset=tdai_id,
amount=mint_amount,
)
vega.mint(
MM_WALLET2.name,
asset=tdai_id,
amount=mint_amount,
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
market_id = vega.create_simple_market(
custom_market_name,
proposal_key=MM_WALLET.name,
settlement_asset_id=tdai_id,
termination_key=TERMINATE_WALLET.name,
market_decimals=5,
approve_proposal=approve_proposal,
forward_time_to_enactment=approve_proposal,
)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
return market_id
def setup_simple_successor_market(
vega: VegaService, parent_market_id, tdai_id, market_name, approve_proposal=True
):
market_id = vega.create_simple_market(
market_name,
proposal_key=MM_WALLET.name,
settlement_asset_id=tdai_id,
termination_key=MM_WALLET2.name,
market_decimals=5,
approve_proposal=approve_proposal,
forward_time_to_enactment=approve_proposal,
parent_market_id=parent_market_id,
parent_market_insurance_pool_fraction=0.5,
)
submit_liquidity(vega, MM_WALLET.name, market_id)
submit_multiple_orders(
vega, MM_WALLET.name, market_id, "SIDE_SELL", [[1, 110], [1, 105]]
)
submit_multiple_orders(
vega, MM_WALLET2.name, market_id, "SIDE_BUY", [[1, 90], [1, 95]]
)
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 1, 110)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
return market_id
def setup_opening_auction_market(vega: VegaService, market_id: str = None, **kwargs):
if market_id is None or market_id not in vega.all_markets():
market_id = setup_simple_market(vega, **kwargs)
submit_liquidity(vega, MM_WALLET.name, market_id)
submit_multiple_orders(
vega, MM_WALLET.name, market_id, "SIDE_SELL", [[1, 110], [1, 105]]
)
submit_multiple_orders(
vega, MM_WALLET2.name, market_id, "SIDE_BUY", [[1, 90], [1, 95]]
)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
return market_id
def setup_continuous_market(vega: VegaService, market_id: str = None, **kwargs):
if market_id is None or market_id not in vega.all_markets():
market_id = setup_opening_auction_market(vega, **kwargs)
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 1, 110)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
return market_id

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