diff --git a/.github/workflows/ci-cd-trigger.yml b/.github/workflows/ci-cd-trigger.yml index bdb570d9b..92934255f 100644 --- a/.github/workflows/ci-cd-trigger.yml +++ b/.github/workflows/ci-cd-trigger.yml @@ -196,9 +196,9 @@ jobs: cypress: needs: [build-sources, check-e2e-needed] name: '(CI) cypress' - if: ${{ needs.check-e2e-needed.outputs.run-tests == 'true' }} uses: ./.github/workflows/cypress-run.yml secrets: inherit + if: needs.check-e2e-needed.outputs.run-tests == 'true' && (contains(needs.build-sources.outputs.projects, 'governance') || contains(needs.build-sources.outputs.projects, 'explorer')) with: projects: ${{ needs.build-sources.outputs.projects-e2e }} tags: '@smoke' @@ -287,6 +287,7 @@ jobs: steps: - run: | result="${{ needs.cypress.result }}" + echo "Result: $result" if [[ $result == "success" || $result == "skipped" ]]; then exit 0 else diff --git a/.verdaccio/config.yml b/.verdaccio/config.yml new file mode 100644 index 000000000..5d7b31229 --- /dev/null +++ b/.verdaccio/config.yml @@ -0,0 +1,28 @@ +# path to a directory with all packages +storage: ../tmp/local-registry/storage + +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.yarnpkg.com + maxage: 60m + +packages: + '**': + # give all users (including non-authenticated users) full access + # because it is a local registry + access: $all + publish: $all + unpublish: $all + + # if package is not available locally, proxy requests to npm registry + proxy: npmjs + +# log settings +logs: + type: stdout + format: pretty + level: warn + +publish: + allow_offline: true # set offline to true to allow publish offline diff --git a/apps/explorer/tailwind.config.js b/apps/explorer/tailwind.config.js index beac189d1..51a2045f1 100644 --- a/apps/explorer/tailwind.config.js +++ b/apps/explorer/tailwind.config.js @@ -1,7 +1,9 @@ const { join } = require('path'); const { createGlobPatternsForDependencies } = require('@nx/react/tailwind'); -const theme = require('../../libs/tailwindcss-config/src/theme'); -const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes'); +const { theme } = require('../../libs/tailwindcss-config/src/theme'); +const { + vegaCustomClasses, +} = require('../../libs/tailwindcss-config/src/vega-custom-classes'); module.exports = { content: [ diff --git a/apps/governance-e2e/src/integration/view/home.cy.ts b/apps/governance-e2e/src/integration/view/home.cy.ts index 47ce0e4a6..5a459b218 100644 --- a/apps/governance-e2e/src/integration/view/home.cy.ts +++ b/apps/governance-e2e/src/integration/view/home.cy.ts @@ -79,21 +79,21 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () { }); }); - it('should have information on active nodes', function () { + it.skip('should have information on active nodes', function () { cy.getByTestId('node-information') .first() .should('contain.text', '2') .and('contain.text', 'active nodes'); }); - it('should have information on consensus nodes', function () { + it.skip('should have information on consensus nodes', function () { cy.getByTestId('node-information') .last() .should('contain.text', '2') .and('contain.text', 'consensus nodes'); }); - it('should contain link to specific validators', function () { + it.skip('should contain link to specific validators', function () { cy.getByTestId('validators') .should('have.length', '2') .each(($validator) => { @@ -153,7 +153,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () { .invoke('text') .should('not.eq', currentBlockHeight); }); - cy.getByTestId('subscription-cell').should('have.text', 'Yes'); + cy.getByTestId('subscription-cell').should('be.be.visible'); }); cy.getByTestId('connect').should('be.disabled'); cy.getByTestId('node-url-custom').click({ force: true }); diff --git a/apps/governance/src/app-loader.tsx b/apps/governance/src/app-loader.tsx index 7f4196a96..9f148e1b7 100644 --- a/apps/governance/src/app-loader.tsx +++ b/apps/governance/src/app-loader.tsx @@ -26,9 +26,9 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => { const { token, staking, vesting } = useContracts(); const setAssociatedBalances = useRefreshAssociatedBalances(); const [balancesLoaded, setBalancesLoaded] = React.useState(false); - const vegaConnecting = useEagerConnect(); + const vegaWalletStatus = useEagerConnect(); - const loaded = balancesLoaded && !vegaConnecting; + const loaded = balancesLoaded && vegaWalletStatus !== 'connecting'; React.useEffect(() => { const run = async () => { @@ -169,3 +169,5 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => { } return {children}; }; + +AppLoader.displayName = 'AppLoader'; diff --git a/apps/governance/src/contexts/contracts/contracts-provider.tsx b/apps/governance/src/contexts/contracts/contracts-provider.tsx index 05cabcbf5..21add2196 100644 --- a/apps/governance/src/contexts/contracts/contracts-provider.tsx +++ b/apps/governance/src/contexts/contracts/contracts-provider.tsx @@ -111,3 +111,4 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => { ); }; +ContractsProvider.displayName = 'ContractsProvider'; diff --git a/apps/governance/tailwind.config.js b/apps/governance/tailwind.config.js index f3331619e..9f4de5379 100644 --- a/apps/governance/tailwind.config.js +++ b/apps/governance/tailwind.config.js @@ -1,9 +1,11 @@ const { join } = require('path'); const { createGlobPatternsForDependencies } = require('@nx/react/tailwind'); -const theme = require('../../libs/tailwindcss-config/src/theme'); -const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes'); +const { theme } = require('../../libs/tailwindcss-config/src/theme'); +const { + vegaCustomClasses, +} = require('../../libs/tailwindcss-config/src/vega-custom-classes'); -module.exports = { +export default { content: [ join(__dirname, 'src/**/*.{js,ts,jsx,tsx}'), 'libs/ui-toolkit/src/utils/shared.ts', diff --git a/apps/liquidity-provision-dashboard/.babelrc b/apps/liquidity-provision-dashboard/.babelrc deleted file mode 100644 index 88ee27b14..000000000 --- a/apps/liquidity-provision-dashboard/.babelrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "presets": [ - [ - "@nx/react/babel", - { - "runtime": "automatic" - } - ] - ], - "plugins": [] -} diff --git a/apps/liquidity-provision-dashboard/.browserslistrc b/apps/liquidity-provision-dashboard/.browserslistrc deleted file mode 100644 index f1d12df4f..000000000 --- a/apps/liquidity-provision-dashboard/.browserslistrc +++ /dev/null @@ -1,16 +0,0 @@ -# This file is used by: -# 1. autoprefixer to adjust CSS to support the below specified browsers -# 2. babel preset-env to adjust included polyfills -# -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries -# -# If you need to support different browsers in production, you may tweak the list below. - -last 1 Chrome version -last 1 Firefox version -last 2 Edge major versions -last 2 Safari major version -last 2 iOS major versions -Firefox ESR -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/apps/liquidity-provision-dashboard/.env b/apps/liquidity-provision-dashboard/.env deleted file mode 100644 index 5cc9dfb8c..000000000 --- a/apps/liquidity-provision-dashboard/.env +++ /dev/null @@ -1,28 +0,0 @@ -# React Environment Variables -# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env - -# 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_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" -NX_VEGA_WALLET_URL=http://localhost:1789 -NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 -NX_ETHERSCAN_URL=https://sepolia.etherscan.io -NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"} -NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf -NX_VEGA_CONSOLE_URL=https://console.fairground.wtf diff --git a/apps/liquidity-provision-dashboard/.env.capsule b/apps/liquidity-provision-dashboard/.env.capsule deleted file mode 100644 index 6bc5b34a1..000000000 --- a/apps/liquidity-provision-dashboard/.env.capsule +++ /dev/null @@ -1,3 +0,0 @@ -# App configuration variables -NX_VEGA_URL=http://localhost:3008/graphql -NX_VEGA_ENV=LOCAL diff --git a/apps/liquidity-provision-dashboard/.env.devnet b/apps/liquidity-provision-dashboard/.env.devnet deleted file mode 100644 index 112c12354..000000000 --- a/apps/liquidity-provision-dashboard/.env.devnet +++ /dev/null @@ -1,8 +0,0 @@ -# App configuration variables -NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml -NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql -NX_VEGA_ENV=DEVNET -NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"} -NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 -NX_ETHERSCAN_URL=https://sepolia.etherscan.io -NX_VEGA_EXPLORER_URL=# diff --git a/apps/liquidity-provision-dashboard/.env.mainnet b/apps/liquidity-provision-dashboard/.env.mainnet deleted file mode 100644 index f49f68cbd..000000000 --- a/apps/liquidity-provision-dashboard/.env.mainnet +++ /dev/null @@ -1,9 +0,0 @@ -# App configuration variables -NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml -NX_VEGA_URL=https://api.vega.community/graphql -NX_VEGA_ENV=MAINNET -NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"} -NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 -NX_ETHERSCAN_URL=https://etherscan.io -NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz -NX_VEGA_CONSOLE_URL=https://console.vega.xyz diff --git a/apps/liquidity-provision-dashboard/.env.stagnet1 b/apps/liquidity-provision-dashboard/.env.stagnet1 deleted file mode 100644 index 035c634de..000000000 --- a/apps/liquidity-provision-dashboard/.env.stagnet1 +++ /dev/null @@ -1,9 +0,0 @@ -# App configuration variables -NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml -NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql -NX_VEGA_ENV=STAGNET1 -NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 -NX_ETHERSCAN_URL=https://sepolia.etherscan.io -NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks -NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"} - diff --git a/apps/liquidity-provision-dashboard/.env.testnet b/apps/liquidity-provision-dashboard/.env.testnet deleted file mode 100644 index 8b73dcbca..000000000 --- a/apps/liquidity-provision-dashboard/.env.testnet +++ /dev/null @@ -1,9 +0,0 @@ -# App configuration variables -NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml -NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql -NX_VEGA_ENV=TESTNET -NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"} -NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 -NX_ETHERSCAN_URL=https://sepolia.etherscan.io -NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf -NX_VEGA_CONSOLE_URL=https://console.fairground.wtf diff --git a/apps/liquidity-provision-dashboard/.eslintrc.json b/apps/liquidity-provision-dashboard/.eslintrc.json deleted file mode 100644 index f3153d3b4..000000000 --- a/apps/liquidity-provision-dashboard/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["plugin:@nx/react", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*", "__generated__"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/apps/liquidity-provision-dashboard/jest.config.ts b/apps/liquidity-provision-dashboard/jest.config.ts deleted file mode 100644 index 03d03da6c..000000000 --- a/apps/liquidity-provision-dashboard/jest.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'liquidity-provision-dashboard', - preset: '../../jest.preset.js', - transform: { - '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', - '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/apps/liquidity-provision-dashboard', -}; diff --git a/apps/liquidity-provision-dashboard/postcss.config.js b/apps/liquidity-provision-dashboard/postcss.config.js deleted file mode 100644 index cbdd9c22c..000000000 --- a/apps/liquidity-provision-dashboard/postcss.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const { join } = require('path'); - -module.exports = { - plugins: { - tailwindcss: { - config: join(__dirname, 'tailwind.config.js'), - }, - autoprefixer: {}, - }, -}; diff --git a/apps/liquidity-provision-dashboard/project.json b/apps/liquidity-provision-dashboard/project.json deleted file mode 100644 index c8193aeee..000000000 --- a/apps/liquidity-provision-dashboard/project.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "name": "liquidity-provision-dashboard", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/liquidity-provision-dashboard/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nx/webpack:webpack", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { - "compiler": "babel", - "outputPath": "dist/apps/liquidity-provision-dashboard", - "index": "apps/liquidity-provision-dashboard/src/index.html", - "baseHref": "/", - "main": "apps/liquidity-provision-dashboard/src/main.tsx", - "polyfills": "apps/liquidity-provision-dashboard/src/polyfills.ts", - "tsConfig": "apps/liquidity-provision-dashboard/tsconfig.app.json", - "assets": [ - "apps/liquidity-provision-dashboard/src/favicon.ico", - "apps/liquidity-provision-dashboard/src/assets" - ], - "styles": ["apps/liquidity-provision-dashboard/src/styles.scss"], - "scripts": [], - "webpackConfig": "@nx/react/plugins/webpack" - }, - "configurations": { - "development": { - "extractLicenses": false, - "optimization": false, - "sourceMap": true, - "vendorChunk": true - }, - "production": { - "fileReplacements": [ - { - "replace": "apps/liquidity-provision-dashboard/src/environments/environment.ts", - "with": "apps/liquidity-provision-dashboard/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false - } - } - }, - "serve": { - "executor": "@nx/webpack:dev-server", - "options": { - "buildTarget": "liquidity-provision-dashboard:build", - "hmr": true, - "port": 4201 - }, - "configurations": { - "development": { - "buildTarget": "liquidity-provision-dashboard:build:development" - }, - "production": { - "buildTarget": "liquidity-provision-dashboard:build:production", - "hmr": false - } - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": [ - "apps/liquidity-provision-dashboard/**/*.{ts,tsx,js,jsx}" - ] - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/apps/liquidity-provision-dashboard" - ], - "options": { - "jestConfig": "apps/liquidity-provision-dashboard/jest.config.ts" - } - }, - "build-spec": { - "executor": "nx:run-commands", - "outputs": [], - "options": { - "command": "yarn tsc --project ./apps/liquidity-provision-dashboard/tsconfig.spec.json" - } - } - }, - "tags": [] -} diff --git a/apps/liquidity-provision-dashboard/src/app/app.tsx b/apps/liquidity-provision-dashboard/src/app/app.tsx deleted file mode 100644 index 357d05186..000000000 --- a/apps/liquidity-provision-dashboard/src/app/app.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import type { InMemoryCacheConfig } from '@apollo/client'; -import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment'; -import { useRoutes } from 'react-router-dom'; - -import '../styles.scss'; -import { Navbar } from './components/navbar'; - -import { routerConfig } from './routes/router-config'; - -const cache: InMemoryCacheConfig = { - typePolicies: { - Market: { - merge: true, - }, - Party: { - merge: true, - }, - Query: {}, - Account: { - keyFields: false, - fields: { - balanceFormatted: {}, - }, - }, - Node: { - keyFields: false, - }, - Instrument: { - keyFields: false, - }, - }, -}; -const AppRouter = () => useRoutes(routerConfig); - -export function App() { - useInitializeEnv(); - return ( - -
- - -
-
- ); -} - -export default App; diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/dashboard.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/dashboard.tsx deleted file mode 100644 index 58a4bf70f..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/dashboard.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { t } from '@vegaprotocol/i18n'; - -import { Intro } from './intro'; -import { MarketList } from './market-list'; - -export function Dashboard() { - return ( - <> -
-
-

- {t('Top liquidity opportunities')} -

- - -
-
-
-
- -
-
- - ); -} diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/index.tsx deleted file mode 100644 index b58b6c922..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './dashboard'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/index.tsx deleted file mode 100644 index b2a6383e2..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './intro'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/intro.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/intro.tsx deleted file mode 100644 index 013c54191..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/intro/intro.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { t } from '@vegaprotocol/i18n'; -import { ExternalLink } from '@vegaprotocol/ui-toolkit'; - -// TODO: add mainnet links once docs have been updated -const LINKS = { - testnet: [ - { - label: 'Learn about liquidity fees', - url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#resources', - }, - { - label: 'Provide liquidity', - url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#overview', - }, - { - label: 'View your liquidity provisions', - url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#viewing-existing-liquidity-provisions', - }, - { - label: 'Amend or remove liquidity', - url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#amending-a-liquidity-commitment', - }, - ], - mainnet: [], -}; - -// TODO: update this when network switcher is added -type Network = 'testnet' | 'mainnet'; - -export const Intro = ({ network = 'testnet' }: { network?: Network }) => { - return ( -
-

- {t( - 'Become a liquidity provider and earn a cut of the fees paid during trading.' - )} -

-
- -
-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/index.tsx deleted file mode 100644 index 9c45ed531..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './market-list'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/market-list.tsx b/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/market-list.tsx deleted file mode 100644 index 0ad2c2446..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/dashboard/market-list/market-list.tsx +++ /dev/null @@ -1,296 +0,0 @@ -import { DApp, useLinks } from '@vegaprotocol/environment'; -import { type Market } from '@vegaprotocol/liquidity'; -import { - displayChange, - formatWithAsset, - useMarketsLiquidity, -} from '@vegaprotocol/liquidity'; -import { - addDecimalsFormatNumber, - formatNumberPercentage, - getExpiryDate, - toBigNum, -} from '@vegaprotocol/utils'; -import { t } from '@vegaprotocol/i18n'; -import { type VegaValueFormatterParams } from '@vegaprotocol/datagrid'; -import { PriceChangeCell } from '@vegaprotocol/datagrid'; -import type * as Schema from '@vegaprotocol/types'; -import { - AsyncRenderer, - Icon, - HealthBar, - TooltipCellComponent, -} from '@vegaprotocol/ui-toolkit'; -import { - type GetRowIdParams, - type RowClickedEvent, - type ColDef, -} from 'ag-grid-community'; -import 'ag-grid-community/styles/ag-grid.css'; -import 'ag-grid-community/styles/ag-theme-alpine.css'; -import { useCallback, useState, useMemo } from 'react'; - -import { Grid } from '../../grid'; -import { HealthDialog } from '../../health-dialog'; -import { Status } from '../../status'; -import { intentForStatus } from '../../../lib/utils'; -import { formatDistanceToNow } from 'date-fns'; -import { getAsset } from '@vegaprotocol/markets'; - -export const MarketList = () => { - const { data, error, loading } = useMarketsLiquidity(); - const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false); - const consoleLink = useLinks(DApp.Console); - - const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []); - const columnDefs = useMemo( - () => [ - { - headerName: t('Market (futures)'), - field: 'tradableInstrument.instrument.name', - cellRenderer: ({ value, data }: { value: string; data: Market }) => { - return ( - <> - {value} - {getAsset(data).symbol} - - ); - }, - minWidth: 100, - flex: 1, - headerTooltip: t('The market name and settlement asset'), - }, - - { - headerName: t('Market Code'), - headerTooltip: t( - 'The market code is a unique identifier for this market' - ), - field: 'tradableInstrument.instrument.code', - }, - - { - headerName: t('Type'), - headerTooltip: t('Type'), - field: 'tradableInstrument.instrument.product.__typename', - }, - - { - headerName: t('Last Price'), - headerTooltip: t('Latest price for this market'), - field: 'data.markPrice', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => - value && data ? formatWithAsset(value, getAsset(data)) : '-', - }, - - { - headerName: t('Change (24h)'), - headerTooltip: t('Change in price over the last 24h'), - cellRenderer: ({ - data, - }: VegaValueFormatterParams) => { - if (data && data.candles) { - const prices = data.candles.map((candle) => candle.close); - return ( - - ); - } else return
{t('-')}
; - }, - }, - - { - headerName: t('Volume (24h)'), - field: 'dayVolume', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => - value && data - ? `${addDecimalsFormatNumber( - value, - getAsset(data).decimals || 0 - )} (${displayChange(data.volumeChange)})` - : '-', - headerTooltip: t('The trade volume over the last 24h'), - }, - - { - headerName: t('Total staked by LPs'), - field: 'liquidityCommitted', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => - data && value - ? formatWithAsset(value.toString(), getAsset(data)) - : '-', - headerTooltip: t('The amount of funds allocated to provide liquidity'), - }, - - { - headerName: t('Target stake'), - field: 'target', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => - data && value ? formatWithAsset(value, getAsset(data)) : '-', - headerTooltip: t( - 'The ideal committed liquidity to operate the market. If total commitment currently below this level then LPs can set the fee level with new commitment.' - ), - }, - - { - headerName: t('% Target stake met'), - valueFormatter: ({ data }: VegaValueFormatterParams) => { - if (data) { - const roundedPercentage = - parseInt( - (data.liquidityCommitted / parseFloat(data.target)).toFixed(0) - ) * 100; - const display = Number.isNaN(roundedPercentage) - ? 'N/A' - : formatNumberPercentage(toBigNum(roundedPercentage, 0), 0); - return display; - } else return '-'; - }, - headerTooltip: t('% Target stake met'), - }, - - { - headerName: t('Fee levels'), - field: 'fees', - valueFormatter: ({ value }: VegaValueFormatterParams) => - value ? `${value.factors.liquidityFee}%` : '-', - headerTooltip: t('Fee level for this market'), - }, - - { - headerName: t('Status'), - field: 'tradingMode', - cellRenderer: ({ - value, - data, - }: { - value: Schema.MarketTradingMode; - data: Market; - }) => { - return ; - }, - headerTooltip: t( - 'The current market status - those below the target stake mark are most in need of liquidity' - ), - }, - - { - headerComponent: () => { - return ( -
- {t('Health')}{' '} - -
- ); - }, - field: 'tradingMode', - cellRenderer: ({ - value, - data, - }: { - value: Schema.MarketTradingMode; - data: Market; - }) => ( - - ), - sortable: false, - cellStyle: { overflow: 'unset' }, - }, - { - headerName: t('Age'), - field: 'marketTimestamps.open', - headerTooltip: t('Age of the market'), - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => { - return value ? formatDistanceToNow(new Date(value)) : '-'; - }, - }, - { - headerName: t('Closing Time'), - field: 'tradableInstrument.instrument.metadata.tags', - headerTooltip: t('Closing time of the market'), - valueFormatter: ({ data }: VegaValueFormatterParams) => { - let expiry; - if (data?.tradableInstrument.instrument.metadata.tags) { - expiry = getExpiryDate( - data?.tradableInstrument.instrument.metadata.tags, - data?.marketTimestamps.close, - data?.state - ); - } - return expiry ? expiry : '-'; - }, - }, - ], - [] - ); - - return ( - -
- { - window.open( - liquidityDetailsConsoleLink(data.id, consoleLink), - '_blank', - 'noopener,noreferrer' - ); - }, - }} - rowData={data} - defaultColDef={{ - resizable: true, - sortable: true, - unSortIcon: true, - cellClass: ['flex', 'flex-col', 'justify-center'], - tooltipComponent: TooltipCellComponent, - }} - columnDefs={columnDefs} - getRowId={getRowId} - isRowClickable - tooltipShowDelay={500} - /> - { - setIsHealthDialogOpen(!isHealthDialogOpen); - }} - /> -
-
- ); -}; - -const liquidityDetailsConsoleLink = ( - marketId: string, - consoleLink: (url: string | undefined) => string -) => consoleLink(`/#/liquidity/${marketId}`); diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/detail.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/detail.tsx deleted file mode 100644 index 846ccfaf6..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/detail.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { useParams } from 'react-router-dom'; -import { makeDerivedDataProvider } from '@vegaprotocol/data-provider'; -import { t } from '@vegaprotocol/i18n'; -import { useDataProvider } from '@vegaprotocol/data-provider'; -import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; - -import { - getFeeLevels, - sumLiquidityCommitted, - lpAggregatedDataProvider, -} from '@vegaprotocol/liquidity'; -import { getAsset, marketWithDataProvider } from '@vegaprotocol/markets'; -import type { MarketWithData } from '@vegaprotocol/markets'; - -import { Market } from './market'; -import { Header } from './header'; -import { LPProvidersGrid } from './providers'; - -const formatMarket = (market: MarketWithData) => { - return { - name: market?.tradableInstrument.instrument.name, - symbol: getAsset(market).symbol, - settlementAsset: getAsset(market), - targetStake: market?.data?.targetStake, - tradingMode: market?.data?.marketTradingMode, - trigger: market?.data?.trigger, - }; -}; - -export const lpDataProvider = makeDerivedDataProvider( - [marketWithDataProvider, lpAggregatedDataProvider], - ([market, lpAggregatedData]) => ({ - market: { ...formatMarket(market) }, - liquidityProviders: lpAggregatedData || [], - }) -); - -const useMarketDetails = (marketId: string | undefined) => { - const { data, loading, error } = useDataProvider({ - dataProvider: lpDataProvider, - skipUpdates: true, - variables: { marketId: marketId || '' }, - }); - - const liquidityProviders = data?.liquidityProviders || []; - - return { - data: { - name: data?.market?.name, - symbol: data?.market?.symbol, - liquidityProviders: liquidityProviders, - feeLevels: getFeeLevels(liquidityProviders), - comittedLiquidity: sumLiquidityCommitted(liquidityProviders) || 0, - settlementAsset: data?.market?.settlementAsset || {}, - targetStake: data?.market?.targetStake || '0', - tradingMode: data?.market.tradingMode, - }, - error, - loading: loading, - }; -}; - -type Params = { marketId: string }; - -export const Detail = () => { - const { marketId } = useParams(); - const { data, loading, error } = useMarketDetails(marketId); - - return ( - -
-
-
-
-
-
-
-
- {marketId && ( - - )} -
-
-

- {t('Current Liquidity Provision')} -

- -
-
-
-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/header/header.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/header/header.tsx deleted file mode 100644 index abf8efc7c..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/header/header.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { t } from '@vegaprotocol/i18n'; -import { Link } from 'react-router-dom'; -import { Icon } from '@vegaprotocol/ui-toolkit'; - -export const Header = ({ - name, - symbol, -}: { - name?: string; - symbol?: string; -}) => { - return ( -
-
- - - - {t('Liquidity opportunities')} - - -
-

{name}

-

{symbol}

-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/header/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/header/index.tsx deleted file mode 100644 index 677ca79d4..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/header/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './header'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/index.tsx deleted file mode 100644 index 15e42dcdb..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './detail'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/index.tsx deleted file mode 100644 index 14d12f818..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './last-24h-volume'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx deleted file mode 100644 index 5a572a3ff..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { useState, useMemo, useRef, useCallback } from 'react'; -import throttle from 'lodash/throttle'; -import { addDecimalsFormatNumber } from '@vegaprotocol/utils'; -import { useYesterday } from '@vegaprotocol/react-helpers'; -import { useDataProvider } from '@vegaprotocol/data-provider'; -import * as Schema from '@vegaprotocol/types'; -import { - calcDayVolume, - getChange, - displayChange, -} from '@vegaprotocol/liquidity'; - -import type { Candle } from '@vegaprotocol/markets'; -import { marketCandlesProvider } from '@vegaprotocol/markets'; - -const THROTTLE_UPDATE_TIME = 500; - -export const Last24hVolume = ({ - marketId, - decimals, -}: { - marketId: string; - decimals: number; -}) => { - const [candleVolume, setCandleVolume] = useState(); - const [volumeChange, setVolumeChange] = useState(' - '); - - const yesterday = useYesterday(); - - const yTimestamp = useMemo(() => { - return new Date(yesterday).toISOString(); - }, [yesterday]); - - const variables = useMemo( - () => ({ - marketId: marketId, - interval: Schema.Interval.INTERVAL_I1H, - since: yTimestamp, - }), - [marketId, yTimestamp] - ); - - const variables24hAgo = { - marketId: marketId, - interval: Schema.Interval.INTERVAL_I1D, - since: yTimestamp, - }; - - const throttledSetCandles = useRef( - throttle((data: Candle[]) => { - setCandleVolume(calcDayVolume(data)); - }, THROTTLE_UPDATE_TIME) - ).current; - - const update = useCallback( - ({ data }: { data: Candle[] | null }) => { - if (data) { - throttledSetCandles(data); - } - return true; - }, - [throttledSetCandles] - ); - - const { data, error } = useDataProvider({ - dataProvider: marketCandlesProvider, - variables: variables, - update, - skip: !marketId, - }); - - const throttledSetVolumeChange = useRef( - throttle((candles: Candle[]) => { - const candle24hAgo = candles?.[0]; - setVolumeChange(getChange(data || [], candle24hAgo?.close)); - }, THROTTLE_UPDATE_TIME) - ).current; - - const updateCandle24hAgo = useCallback( - ({ data }: { data: Candle[] | null }) => { - if (data) { - throttledSetVolumeChange(data); - } - return true; - }, - [throttledSetVolumeChange] - ); - - useDataProvider({ - dataProvider: marketCandlesProvider, - update: updateCandle24hAgo, - variables: variables24hAgo, - skip: !marketId || !data, - }); - - return ( -
- - {!error && candleVolume - ? addDecimalsFormatNumber(candleVolume, decimals) - : '0'}{' '} - - - ({displayChange(volumeChange)}) - -
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/market/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/market/index.tsx deleted file mode 100644 index 9fc9e360b..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/market/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './market'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/market/market.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/market/market.tsx deleted file mode 100644 index 9a371165a..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/market/market.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { useState } from 'react'; -import { t } from '@vegaprotocol/i18n'; -import { Icon, HealthBar } from '@vegaprotocol/ui-toolkit'; -import { formatWithAsset } from '@vegaprotocol/liquidity'; - -import type * as Schema from '@vegaprotocol/types'; -import { HealthDialog } from '../../health-dialog'; -import { Last24hVolume } from '../last-24h-volume'; -import { Status } from '../../status'; -import { intentForStatus } from '../../../lib/utils'; - -interface Levels { - fee: string; - commitmentAmount: number; -} - -interface settlementAsset { - symbol?: string; - decimals?: number; -} - -export const Market = ({ - marketId, - feeLevels, - comittedLiquidity, - settlementAsset, - targetStake, - tradingMode, - trigger, -}: { - marketId: string; - feeLevels: Levels[]; - comittedLiquidity: number; - targetStake: string; - settlementAsset?: settlementAsset; - tradingMode?: Schema.MarketTradingMode; - trigger?: Schema.AuctionTrigger; -}) => { - const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false); - - return ( -
-
- - - - - - - - - - - - - - - - - - - -
{t('Volume (24h)')}{t('Commited Liquidity')}{t('Status')} - {t('Health')}{' '} - - {t('Est. APY')}
-
- {marketId && settlementAsset?.decimals && ( - - )} -
-
- - {comittedLiquidity && settlementAsset - ? formatWithAsset(`${comittedLiquidity}`, settlementAsset) - : '0'} - - - - - {tradingMode && settlementAsset?.decimals && feeLevels && ( - - )} - - -
-
- - { - setIsHealthDialogOpen(!isHealthDialogOpen); - }} - /> -
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/providers/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/providers/index.tsx deleted file mode 100644 index 254ec8d9f..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/providers/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './providers'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/providers/providers.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/providers/providers.tsx deleted file mode 100644 index 1c9915deb..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/providers/providers.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import { useCallback, useMemo } from 'react'; - -import { type GetRowIdParams, type ColDef } from 'ag-grid-community'; -import { t } from '@vegaprotocol/i18n'; - -import { - type LiquidityProviderFeeShareFieldsFragment, - type LiquidityProvisionFieldsFragment, -} from '@vegaprotocol/liquidity'; -import { formatWithAsset } from '@vegaprotocol/liquidity'; - -import { Grid } from '../../grid'; -import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit'; - -const formatToHours = ({ value }: { value?: string | null }) => { - if (!value) { - return '-'; - } - - const MS_IN_HOUR = 1000 * 60 * 60; - const created = new Date(value).getTime(); - const now = new Date().getTime(); - return `${Math.round(Math.abs(now - created) / MS_IN_HOUR)}h`; -}; - -export const LPProvidersGrid = ({ - liquidityProviders, - settlementAsset, -}: { - liquidityProviders: LiquidityProvisionFieldsFragment & - LiquidityProviderFeeShareFieldsFragment[]; - settlementAsset: { - decimals?: number; - symbol?: string; - }; -}) => { - const getRowId = useCallback(({ data }: GetRowIdParams) => data.party.id, []); - const columnDefs = useMemo( - () => [ - { - headerName: t('LPs'), - field: 'party.id', - flex: 1, - minWidth: 100, - headerTooltip: t('Liquidity providers'), - }, - { - headerName: t('Duration'), - valueFormatter: formatToHours, - field: 'createdAt', - headerTooltip: t('Time in market'), - }, - { - headerName: t('Equity-like share'), - field: 'equityLikeShare', - valueFormatter: ({ value }: { value?: string | null }) => { - return value - ? `${parseFloat(parseFloat(value).toFixed(2)) * 100}%` - : ''; - }, - headerTooltip: t( - 'The share of the markets liquidity held - the earlier you commit liquidity the greater % fees you earn' - ), - minWidth: 140, - }, - { - headerName: t('committed bond'), - field: 'commitmentAmount', - valueFormatter: ({ value }: { value?: string | null }) => - value ? formatWithAsset(value, settlementAsset) : '0', - headerTooltip: t('The amount of funds allocated to provide liquidity'), - minWidth: 140, - }, - { - headerName: t('Margin Req.'), - field: 'margin', - headerTooltip: t( - 'Margin required for arising positions based on liquidity commitment' - ), - }, - { - headerName: t('24h Fees'), - field: 'fees', - headerTooltip: t( - 'Total fees earned by the liquidity provider in the last 24 hours' - ), - }, - { - headerName: t('Fee level'), - valueFormatter: ({ value }: { value?: string | null }) => `${value}%`, - field: 'fee', - headerTooltip: t( - "The market's liquidity fee, or the percentage of a trade's value which is collected from the price taker for every trade" - ), - }, - - { - headerName: t('APY'), - field: 'apy', - headerTooltip: t( - 'An annualised estimate based on the total liquidity provision fees and maker fees collected by liquidity providers, the maximum margin needed and maximum commitment (bond) over the course of 7 epochs' - ), - }, - ], - [settlementAsset] - ); - - return ( - - ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/grid/grid.scss b/apps/liquidity-provision-dashboard/src/app/components/grid/grid.scss deleted file mode 100644 index 2b1ac6601..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/grid/grid.scss +++ /dev/null @@ -1,50 +0,0 @@ -.ag-theme-alpine { - --ag-line-height: 24px; - --ag-row-hover-color: transparent; - --ag-header-background-color: transparent; - --ag-odd-row-background-color: transparent; - --ag-header-foreground-color: #626262; - --ag-secondary-foreground-color: #626262; - --ag-font-size: 16px; - --ag-background-color: transparent; - --ag-range-selection-border-color: transparent; - - font-family: AlphaLyrae, Helvetica Neue, -apple-system, BlinkMacSystemFont, - Segoe UI, Roboto, Arial, Noto Sans, sans-serif, Apple Color Emoji, - Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; - font-feature-settings: 'liga' off, 'calt' off; -} - -.ag-theme-alpine .ag-cell { - display: flex; -} - -.ag-theme-alpine .ag-header { - border-bottom: 1px solid #a7a7a7; - font-size: 15px; - line-height: 1em; - text-transform: uppercase; -} - -.ag-theme-alpine .ag-root-wrapper { - border: none; -} - -.ag-theme-alpine .ag-header-row { - font-weight: 500; -} - -.ag-theme-alpine .ag-row { - border: none; - border-bottom: 1px solid #bfccd6; - font-size: 12px; -} - -.ag-theme-alpine .ag-root-wrapper-body.ag-layout-normal { - height: auto; -} - -.ag-theme-alpine.row-hover .ag-row:hover { - background: #f0f0f0; - cursor: pointer; -} diff --git a/apps/liquidity-provision-dashboard/src/app/components/grid/grid.tsx b/apps/liquidity-provision-dashboard/src/app/components/grid/grid.tsx deleted file mode 100644 index 8483b97af..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/grid/grid.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { useRef, useCallback, useEffect } from 'react'; -import { AgGridReact } from 'ag-grid-react'; -import { - type AgGridReactProps, - type AgReactUiProps, - type AgGridReact as AgGridReactType, -} from 'ag-grid-react'; -import classNames from 'classnames'; -import 'ag-grid-community/styles/ag-grid.css'; -import 'ag-grid-community/styles/ag-theme-alpine.css'; - -import './grid.scss'; - -type Props = (AgGridReactProps | AgReactUiProps) & { - isRowClickable?: boolean; - style?: React.CSSProperties; -}; - -export const Grid = ({ isRowClickable, ...props }: Props) => { - const gridRef = useRef(null); - - const resizeGrid = useCallback(() => { - gridRef.current?.api?.sizeColumnsToFit(); - }, [gridRef]); - - const handleOnGridReady = useCallback(() => { - resizeGrid(); - }, [resizeGrid]); - - useEffect(() => { - window.addEventListener('resize', resizeGrid); - return () => window.removeEventListener('resize', resizeGrid); - }, [resizeGrid]); - - return ( - - ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/grid/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/grid/index.tsx deleted file mode 100644 index d24d1bdc0..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/grid/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './grid'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/health-dialog/health-dialog.tsx b/apps/liquidity-provision-dashboard/src/app/components/health-dialog/health-dialog.tsx deleted file mode 100644 index 54154316f..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/health-dialog/health-dialog.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { t } from '@vegaprotocol/i18n'; -import { Dialog, HealthBar } from '@vegaprotocol/ui-toolkit'; -import * as Schema from '@vegaprotocol/types'; -import classNames from 'classnames'; -import { intentForStatus } from '../../lib/utils'; - -interface HealthDialogProps { - isOpen: boolean; - onChange: (isOpen: boolean) => void; -} - -const ROWS = [ - { - key: '1', - title: 'Continuous', - copy: 'Markets that have committed liquidity equal or greater than the target stake are trading continuously.', - data: { - status: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - target: '171320', - decimals: 5, - levels: [ - { fee: '0.6', commitmentAmount: 150000 }, - { fee: '1', commitmentAmount: 150000 }, - { fee: '2', commitmentAmount: 30000 }, - ], - }, - }, - { - key: '2', - title: 'Monitoring auction (liquidity)', - copy: 'Markets below the target stake will see trading suspended and go into liquidity auction.', - data: { - status: Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, - target: '171320', - decimals: 5, - levels: [ - { fee: '0.6', commitmentAmount: 110000 }, - { fee: '1', commitmentAmount: 50000 }, - ], - }, - }, - { - key: '3', - title: 'Opening auction', - copy: 'A newly created market looking for a target liquidity amount to start trading.', - data: { - status: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION, - target: '171320', - decimals: 3, - levels: [ - { fee: '0.6', commitmentAmount: 110000 }, - { fee: '1', commitmentAmount: 50000 }, - ], - }, - }, -]; - -export const HealthDialog = ({ onChange, isOpen }: HealthDialogProps) => { - return ( - -

- {t('Health')} -

-

- {t( - 'Market health is a representation of market and liquidity status and how close that market is to moving from one fee level to another.' - )} -

- - - - - - - - {ROWS.map((r, index) => { - const isFirstRow = index === 0; - return ( - - - - - ); - })} - -
- {t('Market status')} - - {t('Liquidity status')} -
-

- {t(r.title)} -

-

{t(r.copy)}

-
- -
-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/health-dialog/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/health-dialog/index.tsx deleted file mode 100644 index 935474263..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/health-dialog/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './health-dialog'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/indicator/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/indicator/index.tsx deleted file mode 100644 index ef086afd6..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/indicator/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './indicator'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/indicator/indicator.tsx b/apps/liquidity-provision-dashboard/src/app/components/indicator/indicator.tsx deleted file mode 100644 index 290b2d9f4..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/indicator/indicator.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import type * as Schema from '@vegaprotocol/types'; - -import { getColorForStatus } from '../../lib/utils'; - -export const Indicator = ({ - status, - opacity, -}: { - status?: Schema.MarketTradingMode; - opacity?: number; -}) => { - const backgroundColor = status ? getColorForStatus(status) : undefined; - return ( -
-
-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/market-list/market-list.scss b/apps/liquidity-provision-dashboard/src/app/components/market-list/market-list.scss deleted file mode 100644 index 609fe7b6c..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/market-list/market-list.scss +++ /dev/null @@ -1,35 +0,0 @@ -.ag-theme-alpine { - --ag-line-height: 24px; - --ag-row-hover-color: transparent; - --ag-header-background-color: #f5f5f5; - --ag-odd-row-background-color: transparent; - --ag-header-foreground-color: #000; - --ag-secondary-foreground-color: #fff; - --ag-font-family: 'Helvetica Neue'; - --ag-font-size: 12px; - - font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', - Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; -} - -.ag-theme-alpine .ag-cell { - display: flex; -} - -.ag-theme-alpine .ag-header { - border: 1px solid #bfccd6; -} - -.ag-theme-alpine .ag-root-wrapper { - border: none; -} - -.ag-theme-alpine .ag-row { - border: none; - border-bottom: 1px solid #bfccd6; - font-size: 12px; -} - -.ag-theme-alpine .ag-root-wrapper-body.ag-layout-normal { - height: auto; -} diff --git a/apps/liquidity-provision-dashboard/src/app/components/navbar/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/navbar/index.tsx deleted file mode 100644 index f5899d036..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/navbar/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './navbar'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/navbar/navbar.tsx b/apps/liquidity-provision-dashboard/src/app/components/navbar/navbar.tsx deleted file mode 100644 index ed1856f14..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/navbar/navbar.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Link } from 'react-router-dom'; -import { VegaLogo } from '@vegaprotocol/ui-toolkit'; - -export const Navbar = () => { - return ( -
-
- - - -
-
-
- ); -}; diff --git a/apps/liquidity-provision-dashboard/src/app/components/status/index.tsx b/apps/liquidity-provision-dashboard/src/app/components/status/index.tsx deleted file mode 100644 index 420cc02aa..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/status/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './status'; diff --git a/apps/liquidity-provision-dashboard/src/app/components/status/status.tsx b/apps/liquidity-provision-dashboard/src/app/components/status/status.tsx deleted file mode 100644 index 382ea4ef3..000000000 --- a/apps/liquidity-provision-dashboard/src/app/components/status/status.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Lozenge, Tooltip } from '@vegaprotocol/ui-toolkit'; -import classNames from 'classnames'; - -import * as Schema from '@vegaprotocol/types'; -import { t } from '@vegaprotocol/i18n'; - -import { Indicator } from '../indicator'; -import type { AuctionTrigger } from '@vegaprotocol/types'; - -export const Status = ({ - tradingMode, - trigger, - size = 'small', -}: { - tradingMode?: Schema.MarketTradingMode; - trigger?: Schema.AuctionTrigger; - size?: 'small' | 'large'; -}) => { - const getStatus = () => { - if (!tradingMode) return ''; - if ( - tradingMode === Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION - ) { - if ( - trigger && - trigger !== Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED - ) { - return `${Schema.MarketTradingModeMapping[tradingMode]} - ${Schema.AuctionTriggerMapping[trigger]}`; - } - } - return Schema.MarketTradingModeMapping[tradingMode]; - }; - - const status = getStatus(); - const tooltipDescription = - tradingMode && getTooltipDescription(tradingMode, trigger); - - return ( -
- -
- - - {status} - -
-
-
- ); -}; - -const getTooltipDescription = ( - status: Schema.MarketTradingMode, - trigger?: Schema.AuctionTrigger -) => { - switch (status) { - case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: - return t( - 'This is the standard trading mode where trades are executed whenever orders are received' - ); - case Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION: - return getMonitoringDescriptionTooltip(trigger); - case Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION: - return t( - 'This is a new market in an opening auction to determine a fair mid-price before starting continuous trading.' - ); - default: - return ''; - } -}; - -const getMonitoringDescriptionTooltip = (trigger?: AuctionTrigger) => { - switch (trigger) { - case Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET: - return t( - `This market is in auction until it reaches sufficient liquidity.` - ); - case Schema.AuctionTrigger.AUCTION_TRIGGER_UNABLE_TO_DEPLOY_LP_ORDERS: - return t( - `This market may have sufficient liquidity but there are not enough priced limit orders in the order book, which are required to deploy liquidity commitment pegged orders.` - ); - case Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE: - return t(`This market is in auction due to high price volatility.`); - case Schema.AuctionTrigger.AUCTION_TRIGGER_OPENING: - return t( - `This is a new market in an opening auction to determine a fair mid-price before starting continuous trading` - ); - default: - return ''; - } -}; diff --git a/apps/liquidity-provision-dashboard/src/app/lib/utils.tsx b/apps/liquidity-provision-dashboard/src/app/lib/utils.tsx deleted file mode 100644 index f83683be6..000000000 --- a/apps/liquidity-provision-dashboard/src/app/lib/utils.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as Schema from '@vegaprotocol/types'; -import { Intent } from '@vegaprotocol/ui-toolkit'; - -const marketTradingModeStyle = { - [Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS]: '#00D46E', - [Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: '#CF0064', - [Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: '#0046CD', - [Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: '#CF0064', - [Schema.MarketTradingMode.TRADING_MODE_NO_TRADING]: '#CF0064', - [Schema.MarketTradingMode.TRADING_MODE_SUSPENDED_VIA_GOVERNANCE]: '#CF0064', -}; - -export const getColorForStatus = (status: Schema.MarketTradingMode) => - marketTradingModeStyle[status]; - -const marketTradingModeIntent = { - [Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS]: Intent.Success, - [Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: Intent.Danger, - [Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: Intent.Primary, - [Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: Intent.Danger, - [Schema.MarketTradingMode.TRADING_MODE_NO_TRADING]: Intent.Danger, - [Schema.MarketTradingMode.TRADING_MODE_SUSPENDED_VIA_GOVERNANCE]: - Intent.Danger, -}; - -export const intentForStatus = (status: Schema.MarketTradingMode) => { - return marketTradingModeIntent[status]; -}; diff --git a/apps/liquidity-provision-dashboard/src/app/routes/index.ts b/apps/liquidity-provision-dashboard/src/app/routes/index.ts deleted file mode 100644 index b41a85505..000000000 --- a/apps/liquidity-provision-dashboard/src/app/routes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './router-config'; diff --git a/apps/liquidity-provision-dashboard/src/app/routes/router-config.tsx b/apps/liquidity-provision-dashboard/src/app/routes/router-config.tsx deleted file mode 100644 index 1568b43b8..000000000 --- a/apps/liquidity-provision-dashboard/src/app/routes/router-config.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { t } from '@vegaprotocol/i18n'; - -import { Dashboard } from '../components/dashboard'; -import { Detail } from '../components/detail'; - -export const ROUTES = { - MARKETS: 'markets', -}; - -export const routerConfig = [ - { path: '/', element: , icon: '' }, - { - path: ROUTES.MARKETS, - name: 'Markets', - text: t('Markets'), - children: [ - { - path: ':marketId', - element: , - }, - ], - icon: 'trade', - isNavItem: true, - }, -]; diff --git a/apps/liquidity-provision-dashboard/src/assets/.gitkeep b/apps/liquidity-provision-dashboard/src/assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/liquidity-provision-dashboard/src/environments/environment.prod.ts b/apps/liquidity-provision-dashboard/src/environments/environment.prod.ts deleted file mode 100644 index c9669790b..000000000 --- a/apps/liquidity-provision-dashboard/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true, -}; diff --git a/apps/liquidity-provision-dashboard/src/environments/environment.ts b/apps/liquidity-provision-dashboard/src/environments/environment.ts deleted file mode 100644 index 7ed83767f..000000000 --- a/apps/liquidity-provision-dashboard/src/environments/environment.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// When building for production, this file is replaced with `environment.prod.ts`. - -export const environment = { - production: false, -}; diff --git a/apps/liquidity-provision-dashboard/src/favicon.ico b/apps/liquidity-provision-dashboard/src/favicon.ico deleted file mode 100644 index 317ebcb23..000000000 Binary files a/apps/liquidity-provision-dashboard/src/favicon.ico and /dev/null differ diff --git a/apps/liquidity-provision-dashboard/src/index.html b/apps/liquidity-provision-dashboard/src/index.html deleted file mode 100644 index 0d91f9033..000000000 --- a/apps/liquidity-provision-dashboard/src/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Liquidity Provision Dashboard - - - - - - - - - -
- - diff --git a/apps/liquidity-provision-dashboard/src/main.tsx b/apps/liquidity-provision-dashboard/src/main.tsx deleted file mode 100644 index 7615e405e..000000000 --- a/apps/liquidity-provision-dashboard/src/main.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { StrictMode } from 'react'; -import { createRoot } from 'react-dom/client'; -import { BrowserRouter } from 'react-router-dom'; - -import App from './app/app'; - -const rootElement = document.getElementById('root'); -const root = rootElement && createRoot(rootElement); -root?.render( - - - - - -); diff --git a/apps/liquidity-provision-dashboard/src/polyfills.ts b/apps/liquidity-provision-dashboard/src/polyfills.ts deleted file mode 100644 index 2adf3d05b..000000000 --- a/apps/liquidity-provision-dashboard/src/polyfills.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Polyfill stable language features. These imports will be optimized by `@babel/preset-env`. - * - * See: https://github.com/zloirock/core-js#babel - */ -import 'core-js/stable'; -import 'regenerator-runtime/runtime'; diff --git a/apps/liquidity-provision-dashboard/src/styles.scss b/apps/liquidity-provision-dashboard/src/styles.scss deleted file mode 100644 index 670fe053c..000000000 --- a/apps/liquidity-provision-dashboard/src/styles.scss +++ /dev/null @@ -1,10 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -html, -body { - @apply h-full; - - font-family: 'Helvetica Neue', Helvetica, sans-serif; -} diff --git a/apps/liquidity-provision-dashboard/tailwind.config.js b/apps/liquidity-provision-dashboard/tailwind.config.js deleted file mode 100644 index 9a8169a76..000000000 --- a/apps/liquidity-provision-dashboard/tailwind.config.js +++ /dev/null @@ -1,29 +0,0 @@ -const { join } = require('path'); -const { createGlobPatternsForDependencies } = require('@nx/react/tailwind'); -const theme = require('../../libs/tailwindcss-config/src/theme-lite'); -const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes'); -const vegaCustomClassesLite = require('../../libs/tailwindcss-config/src/vega-custom-classes-lite'); - -module.exports = { - content: [ - join(__dirname, 'src/**/*.{js,ts,jsx,tsx}'), - 'libs/ui-toolkit/src/utils/shared.ts', - ...createGlobPatternsForDependencies(__dirname), - ], - darkMode: 'class', - theme: { - ...theme, - colors: { - ...theme.colors, - greys: { - light: { - 100: '#F0F0F0', - 200: '#D2D2D2', - 300: '#A7A7A7', - 400: '#626262', - }, - }, - }, - }, - plugins: [vegaCustomClasses, vegaCustomClassesLite], -}; diff --git a/apps/liquidity-provision-dashboard/tsconfig.app.json b/apps/liquidity-provision-dashboard/tsconfig.app.json deleted file mode 100644 index b278fbb45..000000000 --- a/apps/liquidity-provision-dashboard/tsconfig.app.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": [ - "node", - "@nx/react/typings/cssmodule.d.ts", - "@nx/react/typings/image.d.ts" - ] - }, - "files": [ - "../../node_modules/@nx/react/typings/cssmodule.d.ts", - "../../node_modules/@nx/react/typings/image.d.ts" - ], - "exclude": [ - "jest.config.ts", - "**/*.spec.ts", - "**/*.test.ts", - "**/*.spec.tsx", - "**/*.test.tsx", - "**/*.spec.js", - "**/*.test.js", - "**/*.spec.jsx", - "**/*.test.jsx" - ], - "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] -} diff --git a/apps/liquidity-provision-dashboard/tsconfig.json b/apps/liquidity-provision-dashboard/tsconfig.json deleted file mode 100644 index 842a5c68a..000000000 --- a/apps/liquidity-provision-dashboard/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "jsx": "react-jsx", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": false, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] -} diff --git a/apps/liquidity-provision-dashboard/tsconfig.spec.json b/apps/liquidity-provision-dashboard/tsconfig.spec.json deleted file mode 100644 index 1e42db7ff..000000000 --- a/apps/liquidity-provision-dashboard/tsconfig.spec.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "extends": "./tsconfig.json", - "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" - ], - "jsx": "react", - "allowSyntheticDefaultImports": true, - "esModuleInterop": true - }, - "include": [ - "jest.config.ts", - "**/*.test.ts", - "**/*.spec.ts", - "**/*.test.tsx", - "**/*.spec.tsx", - "**/*.test.js", - "**/*.spec.js", - "**/*.test.jsx", - "**/*.spec.jsx", - "**/*.d.ts" - ], - "files": [ - "../../node_modules/@nx/react/typings/cssmodule.d.ts", - "../../node_modules/@nx/react/typings/image.d.ts" - ] -} diff --git a/apps/multisig-signer/tailwind.config.js b/apps/multisig-signer/tailwind.config.js index beac189d1..51a2045f1 100644 --- a/apps/multisig-signer/tailwind.config.js +++ b/apps/multisig-signer/tailwind.config.js @@ -1,7 +1,9 @@ const { join } = require('path'); const { createGlobPatternsForDependencies } = require('@nx/react/tailwind'); -const theme = require('../../libs/tailwindcss-config/src/theme'); -const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes'); +const { theme } = require('../../libs/tailwindcss-config/src/theme'); +const { + vegaCustomClasses, +} = require('../../libs/tailwindcss-config/src/vega-custom-classes'); module.exports = { content: [ diff --git a/apps/trading/assets/apple-touch-icon.png b/apps/trading/assets/apple-touch-icon.png deleted file mode 100644 index 50cdf7782..000000000 Binary files a/apps/trading/assets/apple-touch-icon.png and /dev/null differ diff --git a/apps/trading/assets/logo.png b/apps/trading/assets/logo.png deleted file mode 100644 index 0245ca6ca..000000000 Binary files a/apps/trading/assets/logo.png and /dev/null differ diff --git a/apps/trading/assets/logo192.png b/apps/trading/assets/logo192.png deleted file mode 100644 index a229d08ba..000000000 Binary files a/apps/trading/assets/logo192.png and /dev/null differ diff --git a/apps/trading/assets/manifest.json b/apps/trading/assets/manifest.json deleted file mode 100644 index 37981d3d3..000000000 --- a/apps/trading/assets/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "Vega Protocol - Trading", - "short_name": "Console", - "description": "Vega Protocol - Trading dApp", - "start_url": "/", - "display": "standalone", - "orientation": "portrait", - "theme_color": "#000000", - "background_color": "#ffffff", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - } - ] -} diff --git a/apps/trading/components/bootstrapper/bootstrapper.tsx b/apps/trading/components/bootstrapper/bootstrapper.tsx index 422dbbbbd..1b56604bf 100644 --- a/apps/trading/components/bootstrapper/bootstrapper.tsx +++ b/apps/trading/components/bootstrapper/bootstrapper.tsx @@ -1,63 +1,126 @@ import type { InMemoryCacheConfig } from '@apollo/client'; import { - AppFailure, AppLoader, NetworkLoader, - NodeFailure, - NodeGuard, useEnvironment, + useNodeSwitcherStore, } from '@vegaprotocol/environment'; -import { type ReactNode } from 'react'; +import { useEffect, type ReactNode, useState } from 'react'; import { Web3Provider } from './web3-provider'; import { useT } from '../../lib/use-t'; import { DataLoader } from './data-loader'; import { WalletProvider } from '@vegaprotocol/wallet-react'; import { useVegaWalletConfig } from '../../lib/hooks/use-vega-wallet-config'; +import { Trans } from 'react-i18next'; +import { Button, Loader, Splash, VLogo } from '@vegaprotocol/ui-toolkit'; + +const Failure = ({ reason }: { reason?: ReactNode }) => { + const t = useT(); + const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen); + return ( + +
+
+ + {t('Failed to initialize the app')} +
+
+

{reason}

+
+ +
+
+
+
+ ); +}; + +const Loading = () => { + const [showSlowNotification, setShowSlowNotification] = useState(false); + const t = useT(); + const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen); + useEffect(() => { + const to = setTimeout(() => { + if (!showSlowNotification) setShowSlowNotification(true); + }, 5000); + return () => { + clearTimeout(to); + }; + }, [showSlowNotification]); + return ( + +
+
+ + {showSlowNotification && ( + <> +

+ {t( + "It looks like you're connection is slow, try switching to another node." + )} +

+
+ +
+ + )} +
+
+
+ ); +}; export const Bootstrapper = ({ children }: { children: ReactNode }) => { const t = useT(); - const { error, VEGA_URL } = useEnvironment(); + + const { error, VEGA_URL } = useEnvironment((state) => ({ + error: state.error, + VEGA_URL: state.VEGA_URL, + })); const config = useVegaWalletConfig(); if (!config) { return ; } + const ERR_DATA_LOADER = ( + + {VEGA_URL} + , + ]} + values={{ + VEGA_URL, + }} + /> + ); + return ( } - failure={ - - } + skeleton={} + failure={} > - } - failure={ - - } + } + failure={} > - } - failure={ - - } + } + failure={} > - } - failure={ - - } - > - {children} - - - + {children} + + ); }; @@ -107,6 +170,9 @@ const cacheConfig: InMemoryCacheConfig = { Fees: { keyFields: false, }, + PartyProfile: { + keyFields: ['partyId'], + }, // The folling types are cached by the data provider and not by apollo PositionUpdate: { keyFields: false, diff --git a/apps/trading/components/chart-container/chart-container.tsx b/apps/trading/components/chart-container/chart-container.tsx index ed3ddec00..d6eaa8659 100644 --- a/apps/trading/components/chart-container/chart-container.tsx +++ b/apps/trading/components/chart-container/chart-container.tsx @@ -30,8 +30,6 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => { setStudies, setStudySizes, setOverlays, - state, - setState, } = useChartSettings(); const pennantChart = ( @@ -68,10 +66,6 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => { onIntervalChange={(newInterval) => { setInterval(fromTradingViewResolution(newInterval)); }} - onAutoSaveNeeded={(data) => { - setState(data); - }} - state={state} /> ); } diff --git a/apps/trading/components/chart-container/constants.ts b/apps/trading/components/chart-container/constants.ts index 0ec1458b8..1540dba74 100644 --- a/apps/trading/components/chart-container/constants.ts +++ b/apps/trading/components/chart-container/constants.ts @@ -6,7 +6,12 @@ export const SUPPORTED_INTERVALS = [ Interval.INTERVAL_I1M, Interval.INTERVAL_I5M, Interval.INTERVAL_I15M, + Interval.INTERVAL_I30M, Interval.INTERVAL_I1H, + Interval.INTERVAL_I4H, Interval.INTERVAL_I6H, + Interval.INTERVAL_I8H, + Interval.INTERVAL_I12H, Interval.INTERVAL_I1D, + Interval.INTERVAL_I7D, ] as const; diff --git a/apps/trading/components/chart-container/use-chart-settings.ts b/apps/trading/components/chart-container/use-chart-settings.ts index 1f827b5a2..f2819679f 100644 --- a/apps/trading/components/chart-container/use-chart-settings.ts +++ b/apps/trading/components/chart-container/use-chart-settings.ts @@ -9,7 +9,6 @@ type StudySizes = { [S in Study]?: number }; export type Chartlib = 'pennant' | 'tradingview'; interface StoredSettings { - state: object | undefined; // Don't see a better type provided from TradingView type definitions chartlib: Chartlib; // For interval we use the enum from @vegaprotocol/types, this is to make mapping between different // chart types easier and more consistent @@ -30,7 +29,6 @@ const STUDY_ORDER: Study[] = [ ]; export const DEFAULT_CHART_SETTINGS = { - state: undefined, chartlib: 'pennant' as const, interval: Interval.INTERVAL_I15M, type: ChartType.CANDLE, @@ -47,7 +45,6 @@ export const useChartSettingsStore = create< setStudies: (studies?: Study[]) => void; setStudySizes: (sizes: number[]) => void; setChartlib: (lib: Chartlib) => void; - setState: (state: object) => void; } >()( persist( @@ -95,9 +92,6 @@ export const useChartSettingsStore = create< state.chartlib = lib; }); }, - setState: (state) => { - set({ state }); - }, })), { name: 'vega_candles_chart_store', @@ -151,7 +145,5 @@ export const useChartSettings = () => { setOverlays: settings.setOverlays, setStudySizes: settings.setStudySizes, setChartlib: settings.setChartlib, - state: settings.state, - setState: settings.setState, }; }; diff --git a/apps/trading/components/navbar/navbar.spec.tsx b/apps/trading/components/navbar/navbar.spec.tsx index 57c1127cb..c273ece55 100644 --- a/apps/trading/components/navbar/navbar.spec.tsx +++ b/apps/trading/components/navbar/navbar.spec.tsx @@ -8,6 +8,12 @@ import { mockConfig, MockedWalletProvider, } from '@vegaprotocol/wallet-react/testing'; +import { MockedProvider, type MockedResponse } from '@apollo/react-testing'; +import { + PartyProfilesDocument, + type PartyProfilesQuery, + type PartyProfilesQueryVariables, +} from '../vega-wallet-connect-button/__generated__/PartyProfiles'; jest.mock('@vegaprotocol/proposals', () => ({ ProtocolUpgradeCountdown: () => null, @@ -24,15 +30,45 @@ describe('Navbar', () => { publicKey: '2'.repeat(64), }, ]; + const key1Alias = 'key 1 alias'; const marketId = 'abc'; const navbarContent = 'navbar-menu-content'; + const partyProfilesMock: MockedResponse< + PartyProfilesQuery, + PartyProfilesQueryVariables + > = { + request: { + query: PartyProfilesDocument, + variables: { + partyIds: mockKeys.map((k) => k.publicKey), + }, + }, + result: { + data: { + partiesProfilesConnection: { + edges: [ + { + node: { + partyId: mockKeys[0].publicKey, + alias: key1Alias, + metadata: [], + }, + }, + ], + }, + }, + }, + }; + const renderComponent = (initialEntries?: string[]) => { return render( - - - + + + + + ); }; @@ -140,6 +176,7 @@ describe('Navbar', () => { const activeKey = within(menu.getByTestId(/key-1+-mobile/)); expect(activeKey.getByText(mockKeys[0].name)).toBeInTheDocument(); expect(activeKey.getByTestId('icon-tick')).toBeInTheDocument(); + expect(screen.getByText(key1Alias)).toBeInTheDocument(); const inactiveKey = within(menu.getByTestId(/key-2+-mobile/)); await userEvent.click(inactiveKey.getByText(mockKeys[1].name)); diff --git a/apps/trading/components/profile-dialog/index.ts b/apps/trading/components/profile-dialog/index.ts new file mode 100644 index 000000000..209d23d12 --- /dev/null +++ b/apps/trading/components/profile-dialog/index.ts @@ -0,0 +1 @@ +export { ProfileDialog } from './profile-dialog'; diff --git a/apps/trading/components/profile-dialog/profile-dialog.tsx b/apps/trading/components/profile-dialog/profile-dialog.tsx new file mode 100644 index 000000000..3778d9c88 --- /dev/null +++ b/apps/trading/components/profile-dialog/profile-dialog.tsx @@ -0,0 +1,166 @@ +import { + Dialog, + FormGroup, + Input, + InputError, + Intent, + TradingButton, +} from '@vegaprotocol/ui-toolkit'; +import { useProfileDialogStore } from '../../stores/profile-dialog-store'; +import { useForm } from 'react-hook-form'; +import { useT } from '../../lib/use-t'; +import { useRequired } from '@vegaprotocol/utils'; +import { + useSimpleTransaction, + type Status, + useVegaWallet, +} from '@vegaprotocol/wallet-react'; +import { + usePartyProfilesQuery, + type PartyProfilesQuery, +} from '../vega-wallet-connect-button/__generated__/PartyProfiles'; + +export const ProfileDialog = () => { + const t = useT(); + const { pubKeys } = useVegaWallet(); + const { data, refetch } = usePartyProfilesQuery({ + variables: { partyIds: pubKeys.map((pk) => pk.publicKey) }, + skip: pubKeys.length <= 0, + }); + const open = useProfileDialogStore((store) => store.open); + const pubKey = useProfileDialogStore((store) => store.pubKey); + const setOpen = useProfileDialogStore((store) => store.setOpen); + + const profileEdge = data?.partiesProfilesConnection?.edges.find( + (e) => e.node.partyId === pubKey + ); + + return ( + { + setOpen(undefined); + }} + title={t('Edit profile')} + > + { + refetch(); + + setTimeout(() => { + setOpen(undefined); + }, 1000); + }} + /> + + ); +}; + +interface FormFields { + alias: string; +} + +type Profile = NonNullable< + PartyProfilesQuery['partiesProfilesConnection'] +>['edges'][number]['node']; + +const ProfileFormContainer = ({ + profile, + onSuccess, +}: { + profile: Profile | undefined; + onSuccess: () => void; +}) => { + const { send, status, error } = useSimpleTransaction({ onSuccess }); + const sendTx = (field: FormFields) => { + send({ + updatePartyProfile: { + alias: field.alias, + metadata: [], + }, + }); + }; + return ( + + ); +}; + +const ProfileForm = ({ + profile, + onSubmit, + status, + error, +}: { + profile: Profile | undefined; + onSubmit: (fields: FormFields) => void; + status: Status; + error: string | undefined; +}) => { + const t = useT(); + const required = useRequired(); + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + defaultValues: { + alias: profile?.alias, + }, + }); + + const renderButtonText = () => { + if (status === 'requested') { + return t('Confirm in wallet...'); + } + + if (status === 'pending') { + return t('Confirming transaction...'); + } + + return t('Submit'); + }; + + const errorMessage = errors.alias?.message || error; + + if (status === 'confirmed') { + return ( +

+ {t('Profile updated')} +

+ ); + } + + return ( +
+ + + {errorMessage && ( + +

+ {errorMessage} +

+
+ )} +
+ + {renderButtonText()} + +
+ ); +}; diff --git a/apps/trading/components/vega-wallet-connect-button/PartyProfiles.graphql b/apps/trading/components/vega-wallet-connect-button/PartyProfiles.graphql new file mode 100644 index 000000000..6bfa72001 --- /dev/null +++ b/apps/trading/components/vega-wallet-connect-button/PartyProfiles.graphql @@ -0,0 +1,14 @@ +query PartyProfiles($partyIds: [ID!]) { + partiesProfilesConnection(ids: $partyIds) { + edges { + node { + partyId + alias + metadata { + key + value + } + } + } + } +} diff --git a/apps/trading/components/vega-wallet-connect-button/__generated__/PartyProfiles.ts b/apps/trading/components/vega-wallet-connect-button/__generated__/PartyProfiles.ts new file mode 100644 index 000000000..ef039cb93 --- /dev/null +++ b/apps/trading/components/vega-wallet-connect-button/__generated__/PartyProfiles.ts @@ -0,0 +1,57 @@ +import * as Types from '@vegaprotocol/types'; + +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +const defaultOptions = {} as const; +export type PartyProfilesQueryVariables = Types.Exact<{ + partyIds?: Types.InputMaybe | Types.Scalars['ID']>; +}>; + + +export type PartyProfilesQuery = { __typename?: 'Query', partiesProfilesConnection?: { __typename?: 'PartiesProfilesConnection', edges: Array<{ __typename?: 'PartyProfileEdge', node: { __typename?: 'PartyProfile', partyId: string, alias: string, metadata: Array<{ __typename?: 'Metadata', key: string, value: string }> } }> } | null }; + + +export const PartyProfilesDocument = gql` + query PartyProfiles($partyIds: [ID!]) { + partiesProfilesConnection(ids: $partyIds) { + edges { + node { + partyId + alias + metadata { + key + value + } + } + } + } +} + `; + +/** + * __usePartyProfilesQuery__ + * + * To run a query within a React component, call `usePartyProfilesQuery` and pass it any options that fit your needs. + * When your component renders, `usePartyProfilesQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = usePartyProfilesQuery({ + * variables: { + * partyIds: // value for 'partyIds' + * }, + * }); + */ +export function usePartyProfilesQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(PartyProfilesDocument, options); + } +export function usePartyProfilesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(PartyProfilesDocument, options); + } +export type PartyProfilesQueryHookResult = ReturnType; +export type PartyProfilesLazyQueryHookResult = ReturnType; +export type PartyProfilesQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx index 876c34091..a3e235b87 100644 --- a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx +++ b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx @@ -1,21 +1,57 @@ -import { act, fireEvent, render, screen } from '@testing-library/react'; +import { act, fireEvent, render, screen, within } from '@testing-library/react'; import { VegaWalletConnectButton } from './vega-wallet-connect-button'; -import { truncateByChars } from '@vegaprotocol/utils'; import userEvent from '@testing-library/user-event'; import { mockConfig, MockedWalletProvider, } from '@vegaprotocol/wallet-react/testing'; +import { MockedProvider, type MockedResponse } from '@apollo/react-testing'; +import { + PartyProfilesDocument, + type PartyProfilesQuery, +} from './__generated__/PartyProfiles'; jest.mock('../../lib/hooks/use-get-current-route-id', () => ({ useGetCurrentRouteId: jest.fn().mockReturnValue('current-route-id'), })); +const key = { publicKey: '123456__123456', name: 'test' }; +const key2 = { publicKey: 'abcdef__abcdef', name: 'test2' }; +const keys = [key, key2]; +const keyProfile = { + __typename: 'PartyProfile' as const, + partyId: key.publicKey, + alias: `${key.name} alias`, + metadata: [], +}; + const renderComponent = (mockOnClick = jest.fn()) => { + const partyProfilesMock: MockedResponse = { + request: { + query: PartyProfilesDocument, + variables: { partyIds: keys.map((k) => k.publicKey) }, + }, + result: { + data: { + partiesProfilesConnection: { + __typename: 'PartiesProfilesConnection', + edges: [ + { + __typename: 'PartyProfileEdge', + node: keyProfile, + }, + ], + }, + }, + }, + }; + return ( - - - + + + + + ); }; @@ -43,10 +79,6 @@ describe('VegaWalletConnectButton', () => { }); it('should open dropdown and refresh keys when connected', async () => { - const key = { publicKey: '123456__123456', name: 'test' }; - const key2 = { publicKey: 'abcdef__abcdef', name: 'test2' }; - const keys = [key, key2]; - mockConfig.store.setState({ status: 'connected', keys, @@ -61,14 +93,22 @@ describe('VegaWalletConnectButton', () => { expect(screen.queryByTestId('connect-vega-wallet')).not.toBeInTheDocument(); const button = screen.getByTestId('manage-vega-wallet'); - expect(button).toHaveTextContent(truncateByChars(key.publicKey)); + expect(button).toHaveTextContent(key.name); fireEvent.click(button); expect(await screen.findByRole('menu')).toBeInTheDocument(); - expect(await screen.findAllByRole('menuitemradio')).toHaveLength( - keys.length + const menuItems = await screen.findAllByRole('menuitemradio'); + expect(menuItems).toHaveLength(keys.length); + + expect(within(menuItems[0]).getByTestId('alias')).toHaveTextContent( + keyProfile.alias ); + + expect(within(menuItems[1]).getByTestId('alias')).toHaveTextContent( + 'No alias' + ); + expect(refreshKeys).toHaveBeenCalled(); fireEvent.click(screen.getByTestId(`key-${key2.publicKey}`)); diff --git a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx index 1f610a784..259dd42b4 100644 --- a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx +++ b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx @@ -14,6 +14,7 @@ import { TradingDropdownItem, TradingDropdownRadioItem, TradingDropdownItemIndicator, + Tooltip, } from '@vegaprotocol/ui-toolkit'; import { isBrowserWalletInstalled, type Key } from '@vegaprotocol/wallet'; import { useDialogStore, useVegaWallet } from '@vegaprotocol/wallet-react'; @@ -22,6 +23,8 @@ import classNames from 'classnames'; import { ViewType, useSidebar } from '../sidebar'; import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id'; import { useT } from '../../lib/use-t'; +import { usePartyProfilesQuery } from './__generated__/PartyProfiles'; +import { useProfileDialogStore } from '../../stores/profile-dialog-store'; export const VegaWalletConnectButton = ({ intent = Intent.None, @@ -68,10 +71,10 @@ export const VegaWalletConnectButton = ({ {activeKey ? ( <> {activeKey && ( - {activeKey.name} + + {activeKey.name ? activeKey.name : t('Unnamed key')} + )} - {' | '} - {truncateByChars(activeKey.publicKey)} ) : ( <>{'Select key'} @@ -88,20 +91,12 @@ export const VegaWalletConnectButton = ({ onEscapeKeyDown={() => setDropdownOpen(false)} >
- { - selectPubKey(value); - }} - > - {pubKeys.map((pk) => ( - - ))} - + {!isReadOnly && ( { +const KeypairRadioGroup = ({ + pubKey, + pubKeys, + activeKey, + onSelect, +}: { + pubKey: string | undefined; + pubKeys: Key[]; + activeKey: string | undefined; + onSelect: (pubKey: string) => void; +}) => { + const { data } = usePartyProfilesQuery({ + variables: { partyIds: pubKeys.map((pk) => pk.publicKey) }, + skip: pubKeys.length <= 0, + fetchPolicy: 'cache-and-network', + }); + + return ( + + {pubKeys.map((pk) => { + const profile = data?.partiesProfilesConnection?.edges.find( + (e) => e.node.partyId === pk.publicKey + ); + return ( + + ); + })} + + ); +}; + +const KeypairItem = ({ + pk, + isActive, + alias, +}: { + pk: Key; + alias: string | undefined; + isActive: boolean; +}) => { const t = useT(); const [copied, setCopied] = useCopyTimeout(); + const setOpen = useProfileDialogStore((store) => store.setOpen); return ( -
- - {pk.name} +
+
+ {pk.name ? pk.name : t('Unnamed key')} {' | '} - {truncateByChars(pk.publicKey)} - - + + {truncateByChars(pk.publicKey, 3, 3)} + setCopied(true)}> {copied && {t('Copied')}} - +
+
+ + + +
diff --git a/apps/trading/components/vega-wallet/vega-wallet-menu.tsx b/apps/trading/components/vega-wallet/vega-wallet-menu.tsx index 02a341980..cd418acff 100644 --- a/apps/trading/components/vega-wallet/vega-wallet-menu.tsx +++ b/apps/trading/components/vega-wallet/vega-wallet-menu.tsx @@ -12,6 +12,8 @@ import CopyToClipboard from 'react-copy-to-clipboard'; import { ViewType, useSidebar } from '../sidebar'; import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id'; import { useT } from '../../lib/use-t'; +import { usePartyProfilesQuery } from '../vega-wallet-connect-button/__generated__/PartyProfiles'; +import { useProfileDialogStore } from '../../stores/profile-dialog-store'; export const VegaWalletMenu = ({ setMenu, @@ -23,6 +25,12 @@ export const VegaWalletMenu = ({ const currentRouteId = useGetCurrentRouteId(); const setViews = useSidebar((store) => store.setViews); + const { data } = usePartyProfilesQuery({ + variables: { partyIds: pubKeys.map((pk) => pk.publicKey) }, + skip: pubKeys.length <= 0, + fetchPolicy: 'cache-and-network', + }); + const activeKey = useMemo(() => { return pubKeys?.find((pk) => pk.publicKey === pubKey); }, [pubKey, pubKeys]); @@ -37,14 +45,21 @@ export const VegaWalletMenu = ({ return (
- {(pubKeys || []).map((pk) => ( - - ))} + {(pubKeys || []).map((pk) => { + const profile = data?.partiesProfilesConnection?.edges.find( + (e) => e.node.partyId === pk.publicKey + ); + return ( + + ); + })}
@@ -72,18 +87,23 @@ export const VegaWalletMenu = ({ const KeypairListItem = ({ pk, isActive, + alias, onSelectItem, + setMenu, }: { pk: Key; isActive: boolean; + alias: string | undefined; onSelectItem: (pk: string) => void; + setMenu: (open: 'nav' | 'wallet' | null) => void; }) => { const t = useT(); const [copied, setCopied] = useCopyTimeout(); + const setOpen = useProfileDialogStore((store) => store.setOpen); return (
@@ -106,6 +126,24 @@ const KeypairListItem = ({ {copied && {t('Copied')}} + + {alias ? alias : t('No alias')} + {isActive && ( + + )} +
); }; diff --git a/apps/trading/e2e/actions/utils.py b/apps/trading/e2e/actions/utils.py index 947fd220d..04412fede 100644 --- a/apps/trading/e2e/actions/utils.py +++ b/apps/trading/e2e/actions/utils.py @@ -50,8 +50,6 @@ def truncate_middle(market_id, start=6, end=4): def change_keys(page: Page, vega: VegaServiceNull, key_name): page.get_by_test_id("manage-vega-wallet").click() page.get_by_test_id("key-" + vega.wallet.public_key(key_name)).click() - page.click( - f'data-testid=key-{vega.wallet.public_key(key_name)} >> .inline-flex') page.reload() diff --git a/apps/trading/e2e/conftest.py b/apps/trading/e2e/conftest.py index 520d5d484..47a12b188 100644 --- a/apps/trading/e2e/conftest.py +++ b/apps/trading/e2e/conftest.py @@ -339,4 +339,3 @@ def retry_on_http_error(request): print(f"Retrying due to HTTPError (attempt {i+1}/{retry_count})") else: raise - diff --git a/apps/trading/e2e/tests/deal_ticket/test_basic.py b/apps/trading/e2e/tests/deal_ticket/test_basic.py index 0a97dff71..aec2ffb9c 100644 --- a/apps/trading/e2e/tests/deal_ticket/test_basic.py +++ b/apps/trading/e2e/tests/deal_ticket/test_basic.py @@ -18,7 +18,7 @@ expire = "expire" @pytest.fixture(scope="module") def vega(request): with init_vega(request) as vega_instance: - request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + request.addfinalizer(lambda: cleanup_container(vega_instance)) yield vega_instance diff --git a/apps/trading/e2e/tests/deal_ticket/test_stop_order.py b/apps/trading/e2e/tests/deal_ticket/test_stop_order.py index 6ae055806..ec79464bd 100644 --- a/apps/trading/e2e/tests/deal_ticket/test_stop_order.py +++ b/apps/trading/e2e/tests/deal_ticket/test_stop_order.py @@ -261,7 +261,7 @@ class TestStopOcoValidation: @pytest.fixture(scope="class") def vega(request): with init_vega(request) as vega_instance: - request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + request.addfinalizer(lambda: cleanup_container(vega_instance)) yield vega_instance @pytest.fixture(scope="class") diff --git a/apps/trading/e2e/tests/fees/test_fees_combo_tier_2.py b/apps/trading/e2e/tests/fees/test_fees_combo_tier_2.py index dd7f3e1a2..6dfd60d29 100644 --- a/apps/trading/e2e/tests/fees/test_fees_combo_tier_2.py +++ b/apps/trading/e2e/tests/fees/test_fees_combo_tier_2.py @@ -1,6 +1,7 @@ import pytest +from typing import Tuple, Generator from fees_test_ids import * -from playwright.sync_api import Page, expect +from playwright.sync_api import expect, Page from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order from wallet_config import MM_WALLET @@ -16,77 +17,70 @@ from fixtures.market import setup_continuous_market @pytest.fixture(scope="module") -def vega(request): +def setup_environment( + request, browser +) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]: with init_vega(request) as vega_instance: - request.addfinalizer( - lambda: cleanup_container(vega_instance) + request.addfinalizer(lambda: cleanup_container(vega_instance)) + market = setup_continuous_market(vega_instance, custom_quantum=100000) + vega_instance.update_volume_discount_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "volume_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "volume_discount_factor": 0.2, + }, + ], + window_length=7, ) - yield vega_instance + next_epoch(vega_instance) + + vega_instance.update_referral_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "minimum_epochs": 1, + "referral_reward_factor": 0.1, + "referral_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "minimum_epochs": 2, + "referral_reward_factor": 0.2, + "referral_discount_factor": 0.2, + }, + ], + staking_tiers=[ + {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, + {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, + ], + window_length=1, + ) + vega_instance.create_referral_set(key_name=MM_WALLET.name) + next_epoch(vega_instance) + referral_set_id = list(vega_instance.list_referral_sets().keys())[0] + vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id) + next_epoch(vega_instance) + + for _ in range(2): + submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 2, 110) + forward_time(vega_instance, True if _ < 2 - 1 else False) + + with init_page(vega_instance, browser, request) as page_instance: + risk_accepted_setup(page_instance) + auth_setup(vega_instance, page_instance) + yield vega_instance, market, page_instance -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - yield page - - -@pytest.fixture(scope="module", autouse=True) -def setup_combined_market(vega: VegaServiceNull): - market = setup_continuous_market(vega, custom_quantum=100000) - vega.update_volume_discount_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "volume_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "volume_discount_factor": 0.2, - }, - ], - window_length=7, - ) - next_epoch(vega=vega) - - vega.update_referral_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "minimum_epochs": 1, - "referral_reward_factor": 0.1, - "referral_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "minimum_epochs": 2, - "referral_reward_factor": 0.2, - "referral_discount_factor": 0.2, - }, - ], - staking_tiers=[ - {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, - {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, - ], - window_length=1, - ) - vega.create_referral_set(key_name=MM_WALLET.name) - next_epoch(vega=vega) - referral_set_id = list(vega.list_referral_sets().keys())[0] - vega.apply_referral_code(key_name="Key 1", id=referral_set_id) - next_epoch(vega=vega) - - for _ in range(2): - submit_order(vega, "Key 1", market, "SIDE_BUY", 2, 110) - forward_time(vega, True if _ < 2 - 1 else False) - return market - - -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") -def test_fees_page_discount_program_my_trading_fees(page: Page): +def test_fees_page_discount_program_my_trading_fees( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("6.432%-6.432%") expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text( @@ -97,10 +91,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page): expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%") -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") def test_fees_page_discount_program_total_discount( - page: Page, -): + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("36%") expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount20%") @@ -113,8 +107,10 @@ def test_fees_page_discount_program_total_discount( ) -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") -def test_fees_page_discount_program_fees_by_market(page: Page): +def test_fees_page_discount_program_fees_by_market( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") pinned = page.locator(PINNED_ROW_LOCATOR) row = page.locator(ROW_LOCATOR) @@ -126,12 +122,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page): expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%") -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") def test_deal_ticket_discount_program( - page: Page, - setup_combined_market, -): - page.goto(f"/#/markets/{setup_combined_market}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(ORDER_SIZE).fill("1") page.get_by_test_id(ORDER_PRICE).fill("1") expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-36%") @@ -150,12 +145,9 @@ def test_deal_ticket_discount_program( expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.06432 tDAI") -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") -def test_fills_taker_discount_program( - page: Page, - setup_combined_market, -): - page.goto(f"/#/markets/{setup_combined_market}") +def test_fills_taker_discount_program(setup_environment): + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first expect(row.locator(COL_SIZE)).to_have_text("+2") @@ -166,13 +158,11 @@ def test_fills_taker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("7.48926 tDAI") -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") def test_fills_maker_discount_program( - vega: VegaServiceNull, - page: Page, - setup_combined_market, -): - page.goto(f"/#/markets/{setup_combined_market}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -184,11 +174,11 @@ def test_fills_maker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("7.452 tDAI") -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") def test_fills_maker_fee_tooltip_discount_program( - vega: VegaServiceNull, page: Page, setup_combined_market -): - page.goto(f"/#/markets/{setup_combined_market}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -200,12 +190,11 @@ def test_fills_maker_fee_tooltip_discount_program( ) -@pytest.mark.xdist_group(name="test_fees_combo_tier_2") def test_fills_taker_fee_tooltip_discount_program( - page: Page, - setup_combined_market, -): - page.goto(f"/#/markets/{setup_combined_market}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first # tbd - tooltip is not visible without this wait diff --git a/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_1.py b/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_1.py index 877672ba6..065b95c5e 100644 --- a/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_1.py +++ b/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_1.py @@ -1,4 +1,5 @@ import pytest +from typing import Tuple, Generator from fees_test_ids import * from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull @@ -14,63 +15,58 @@ from conftest import ( from actions.utils import next_epoch, change_keys, forward_time from fixtures.market import setup_continuous_market + @pytest.fixture(scope="module") -def vega(request): +def setup_environment( + request, browser +) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]: with init_vega(request) as vega_instance: - request.addfinalizer( - lambda: cleanup_container(vega_instance) + request.addfinalizer(lambda: cleanup_container(vega_instance)) + + # Setup the market with the referral discount program + market = setup_continuous_market(vega_instance, custom_quantum=100000) + vega_instance.update_referral_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "minimum_epochs": 1, + "referral_reward_factor": 0.1, + "referral_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "minimum_epochs": 2, + "referral_reward_factor": 0.2, + "referral_discount_factor": 0.2, + }, + ], + staking_tiers=[ + {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, + {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, + ], + window_length=1, ) - yield vega_instance + vega_instance.create_referral_set(key_name=MM_WALLET.name) + next_epoch(vega_instance) + referral_set_id = list(vega_instance.list_referral_sets().keys())[0] + vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id) + next_epoch(vega_instance) + + for _ in range(2): + submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110) + forward_time(vega_instance, True if _ < 2 - 1 else False) + + with init_page(vega_instance, browser, request) as page_instance: + risk_accepted_setup(page_instance) + auth_setup(vega_instance, page_instance) + yield vega_instance, market, page_instance -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - yield page - - -@pytest.fixture(scope="module", autouse=True) -def setup_market_with_referral_discount_program(vega: VegaServiceNull): - market = setup_continuous_market(vega, custom_quantum=100000) - vega.update_referral_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "minimum_epochs": 1, - "referral_reward_factor": 0.1, - "referral_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "minimum_epochs": 2, - "referral_reward_factor": 0.2, - "referral_discount_factor": 0.2, - }, - ], - staking_tiers=[ - {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, - {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, - ], - window_length=1, - ) - vega.create_referral_set(key_name=MM_WALLET.name) - next_epoch(vega=vega) - referral_set_id = list(vega.list_referral_sets().keys())[0] - vega.apply_referral_code(key_name="Key 1", id=referral_set_id) - next_epoch(vega=vega) - - for _ in range(2): - submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110) - forward_time(vega, True if _ < 2 - 1 else False) - - return market - - -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") -def test_fees_page_discount_program_my_trading_fees(page: Page): +def test_fees_page_discount_program_my_trading_fees( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("9.045%-9.045%") expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text( @@ -81,8 +77,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page): expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") -def test_fees_page_discount_program_total_discount(page: Page): +def test_fees_page_discount_program_total_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("10%") expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount0%") @@ -95,15 +93,19 @@ def test_fees_page_discount_program_total_discount(page: Page): ) -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") -def test_fees_page_referral_discount_program_referral_benefits(page: Page): +def test_fees_page_referral_discount_program_referral_benefits( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(RUNNING_NOTIONAL_TAKER_VOLUME)).to_have_text("103") expect(page.get_by_test_id(EPOCHS_IN_REFERRAL_SET)).to_have_text("1") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") -def test_fees_page_discount_program_discount(page: Page): +def test_fees_page_discount_program_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1") expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2") @@ -119,8 +121,10 @@ def test_fees_page_discount_program_discount(page: Page): expect(page.get_by_test_id("your-referral-tier-0").nth(1)).to_have_text("Your tier") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") -def test_fees_page_discount_program_fees_by_market(page: Page): +def test_fees_page_discount_program_fees_by_market( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") pinned = page.locator(PINNED_ROW_LOCATOR) row = page.locator(ROW_LOCATOR) @@ -132,11 +136,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page): expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") def test_deal_ticket_discount_program( - page: Page, setup_market_with_referral_discount_program -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(ORDER_SIZE).fill("1") page.get_by_test_id(ORDER_PRICE).fill("1") expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-10%") @@ -155,12 +159,11 @@ def test_deal_ticket_discount_program( expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.09045 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") def test_fills_taker_discount_program( - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first expect(row.locator(COL_SIZE)).to_have_text("+1") @@ -171,13 +174,11 @@ def test_fills_taker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.04017 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") def test_fills_maker_discount_program( - vega: VegaServiceNull, - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -189,11 +190,11 @@ def test_fills_maker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.035 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") def test_fills_maker_fee_tooltip_discount_program( - vega: VegaServiceNull, page: Page, setup_market_with_referral_discount_program -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -205,12 +206,11 @@ def test_fills_maker_fee_tooltip_discount_program( ) -@pytest.mark.xdist_group(name="test_fees_referral_tier_1") def test_fills_taker_fee_tooltip_discount_program( - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first # tbd - tooltip is not visible without this wait diff --git a/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_2.py b/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_2.py index b6c860549..70535c665 100644 --- a/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_2.py +++ b/apps/trading/e2e/tests/fees/test_fees_referral_discount_tier_2.py @@ -1,5 +1,6 @@ import pytest from fees_test_ids import * +from typing import Tuple, Generator from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order @@ -16,62 +17,56 @@ from fixtures.market import setup_continuous_market @pytest.fixture(scope="module") -def vega(request): +def setup_environment( + request, browser +) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]: with init_vega(request) as vega_instance: - request.addfinalizer( - lambda: cleanup_container(vega_instance) + request.addfinalizer(lambda: cleanup_container(vega_instance)) + + # Setup market with referral discount program + market = setup_continuous_market(vega_instance, custom_quantum=100000) + vega_instance.update_referral_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "minimum_epochs": 1, + "referral_reward_factor": 0.1, + "referral_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "minimum_epochs": 2, + "referral_reward_factor": 0.2, + "referral_discount_factor": 0.2, + }, + ], + staking_tiers=[ + {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, + {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, + ], + window_length=1, ) - yield vega_instance + vega_instance.create_referral_set(key_name=MM_WALLET.name) + next_epoch(vega_instance) + referral_set_id = list(vega_instance.list_referral_sets().keys())[0] + vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id) + next_epoch(vega_instance) + + for _ in range(2): + submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 2, 110) + forward_time(vega_instance, True if _ < 2 - 1 else False) + + with init_page(vega_instance, browser, request) as page_instance: + risk_accepted_setup(page_instance) + auth_setup(vega_instance, page_instance) + yield vega_instance, market, page_instance -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - yield page - - -@pytest.fixture(scope="module", autouse=True) -def setup_market_with_referral_discount_program(vega: VegaServiceNull): - market = setup_continuous_market(vega, custom_quantum=100000) - vega.update_referral_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "minimum_epochs": 1, - "referral_reward_factor": 0.1, - "referral_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "minimum_epochs": 2, - "referral_reward_factor": 0.2, - "referral_discount_factor": 0.2, - }, - ], - staking_tiers=[ - {"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1}, - {"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2}, - ], - window_length=1, - ) - vega.create_referral_set(key_name=MM_WALLET.name) - next_epoch(vega=vega) - referral_set_id = list(vega.list_referral_sets().keys())[0] - vega.apply_referral_code(key_name="Key 1", id=referral_set_id) - next_epoch(vega=vega) - - for _ in range(2): - submit_order(vega, "Key 1", market, "SIDE_BUY", 2, 110) - forward_time(vega, True if _ < 2 - 1 else False) - - return market - - -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") -def test_fees_page_discount_program_my_trading_fees(page: Page): +def test_fees_page_discount_program_my_trading_fees( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("8.04%-8.04%") expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text( @@ -82,8 +77,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page): expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") -def test_fees_page_discount_program_total_discount(page: Page): +def test_fees_page_discount_program_total_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("20%") expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount0%") @@ -96,15 +93,19 @@ def test_fees_page_discount_program_total_discount(page: Page): ) -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") -def test_fees_page_referral_discount_program_referral_benefits(page: Page): +def test_fees_page_referral_discount_program_referral_benefits( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(RUNNING_NOTIONAL_TAKER_VOLUME)).to_have_text("207") expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).not_to_be_visible() -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") -def test_fees_page_discount_program_discount(page: Page): +def test_fees_page_discount_program_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1") expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2") @@ -120,8 +121,10 @@ def test_fees_page_discount_program_discount(page: Page): expect(page.get_by_test_id("your-referral-tier-1").nth(1)).to_have_text("Your tier") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") -def test_fees_page_discount_program_fees_by_market(page: Page): +def test_fees_page_discount_program_fees_by_market( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") pinned = page.locator(PINNED_ROW_LOCATOR) row = page.locator(ROW_LOCATOR) @@ -133,11 +136,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page): expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") def test_deal_ticket_discount_program( - page: Page, setup_market_with_referral_discount_program -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(ORDER_SIZE).fill("1") page.get_by_test_id(ORDER_PRICE).fill("1") expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-20%") @@ -156,12 +159,11 @@ def test_deal_ticket_discount_program( expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.0804 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") def test_fills_taker_discount_program( - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first expect(row.locator(COL_SIZE)).to_have_text("+2") @@ -172,13 +174,11 @@ def test_fills_taker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("4.1607 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") def test_fills_maker_discount_program( - vega: VegaServiceNull, - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -190,11 +190,11 @@ def test_fills_maker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("4.14 tDAI") -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") def test_fills_maker_fee_tooltip_discount_program( - vega: VegaServiceNull, page: Page, setup_market_with_referral_discount_program -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -206,12 +206,11 @@ def test_fills_maker_fee_tooltip_discount_program( ) -@pytest.mark.xdist_group(name="test_fees_referral_tier_2") def test_fills_taker_fee_tooltip_discount_program( - page: Page, - setup_market_with_referral_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_referral_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first # tbd - tooltip is not visible without this wait diff --git a/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_1.py b/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_1.py index 3f037ecba..0c4a0cdc5 100644 --- a/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_1.py +++ b/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_1.py @@ -1,5 +1,6 @@ import pytest from fees_test_ids import * +from typing import Tuple, Generator from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order @@ -16,49 +17,45 @@ from fixtures.market import setup_continuous_market @pytest.fixture(scope="module") -def vega(request): +def setup_environment( + request, browser +) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]: with init_vega(request) as vega_instance: - request.addfinalizer( - lambda: cleanup_container(vega_instance) + request.addfinalizer(lambda: cleanup_container(vega_instance)) + + # Setup the market with volume discount program + market = setup_continuous_market(vega_instance, custom_quantum=100000) + vega_instance.update_volume_discount_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "volume_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "volume_discount_factor": 0.2, + }, + ], + window_length=7, ) - yield vega_instance + next_epoch(vega=vega_instance) + + for _ in range(2): + submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110) + forward_time(vega_instance, True if _ < 2 - 1 else False) + + # Initialize and setup page + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + yield vega_instance, market, page -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - yield page - - -@pytest.fixture(scope="module", autouse=True) -def setup_market_with_volume_discount_program(vega: VegaServiceNull): - market = setup_continuous_market(vega, custom_quantum=100000) - vega.update_volume_discount_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "volume_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "volume_discount_factor": 0.2, - }, - ], - window_length=7, - ) - next_epoch(vega=vega) - - for _ in range(2): - submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110) - forward_time(vega, True if _ < 2 - 1 else False) - return market - - -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") -def test_fees_page_discount_program_my_trading_fees(page: Page): +def test_fees_page_discount_program_my_trading_fees( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("9.045%-9.045%") expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text( @@ -69,10 +66,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page): expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%") -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fees_page_discount_program_total_discount( - page: Page, -): + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("10%") expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount10%") @@ -85,20 +82,20 @@ def test_fees_page_discount_program_total_discount( ) -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fees_page_volume_discount_program_my_current_volume( - page: Page, -): + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(PAST_EPOCHS_VOLUME)).to_have_text("103") expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).to_have_text("97") -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fees_page_discount_program_discount( - page: Page, -): + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1") expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2") @@ -111,8 +108,10 @@ def test_fees_page_discount_program_discount( expect(page.get_by_test_id("your-volume-tier-0").nth(1)).to_have_text("Your tier") -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") -def test_fees_page_discount_program_fees_by_market(page: Page): +def test_fees_page_discount_program_fees_by_market( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") pinned = page.locator(PINNED_ROW_LOCATOR) row = page.locator(ROW_LOCATOR) @@ -124,11 +123,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page): expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%") -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_deal_ticket_discount_program_testing( - page: Page, setup_market_with_volume_discount_program -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(ORDER_SIZE).fill("1") page.get_by_test_id(ORDER_PRICE).fill("1") expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-10%") @@ -149,9 +148,10 @@ def test_deal_ticket_discount_program_testing( @pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fills_taker_discount_program( - page: Page, setup_market_with_volume_discount_program -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first expect(row.locator(COL_SIZE)).to_have_text("+1") @@ -164,9 +164,10 @@ def test_fills_taker_discount_program( @pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fills_maker_discount_program( - page: Page, setup_market_with_volume_discount_program, vega: VegaServiceNull -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -178,11 +179,11 @@ def test_fills_maker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.035 tDAI") -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fills_maker_fee_tooltip_discount_program( - vega: VegaServiceNull, page: Page, setup_market_with_volume_discount_program -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -194,12 +195,11 @@ def test_fills_maker_fee_tooltip_discount_program( ) -@pytest.mark.xdist_group(name="test_fees_volume_tier_1") def test_fills_taker_fee_tooltip_discount_program( - page: Page, - setup_market_with_volume_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first # tbd - tooltip is not visible without this wait diff --git a/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_2.py b/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_2.py index 71590c20d..517da4010 100644 --- a/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_2.py +++ b/apps/trading/e2e/tests/fees/test_fees_volume_discount_tier_2.py @@ -1,5 +1,6 @@ import pytest from fees_test_ids import * +from typing import Tuple, Generator from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order @@ -14,51 +15,47 @@ from conftest import ( from actions.utils import next_epoch, change_keys, forward_time from fixtures.market import setup_continuous_market + @pytest.fixture(scope="module") -def vega(request): +def setup_environment( + request, browser +) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]: with init_vega(request) as vega_instance: - request.addfinalizer( - lambda: cleanup_container(vega_instance) + request.addfinalizer(lambda: cleanup_container(vega_instance)) + + # Setup the market with volume discount program + market = setup_continuous_market(vega_instance, custom_quantum=100000) + vega_instance.update_volume_discount_program( + proposal_key=MM_WALLET.name, + benefit_tiers=[ + { + "minimum_running_notional_taker_volume": 100, + "volume_discount_factor": 0.1, + }, + { + "minimum_running_notional_taker_volume": 200, + "volume_discount_factor": 0.2, + }, + ], + window_length=7, ) - yield vega_instance + next_epoch(vega=vega_instance) + + for _ in range(3): + submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110) + forward_time(vega_instance, True if _ < 3 - 1 else False) + + # Initialize page and apply setups + with init_page(vega_instance, browser, request) as page_instance: + risk_accepted_setup(page_instance) + auth_setup(vega_instance, page_instance) + yield vega_instance, market, page_instance -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - yield page - - -@pytest.fixture(scope="module", autouse=True) -def setup_market_with_volume_discount_program(vega: VegaServiceNull): - market = setup_continuous_market(vega, custom_quantum=100000) - vega.update_volume_discount_program( - proposal_key=MM_WALLET.name, - benefit_tiers=[ - { - "minimum_running_notional_taker_volume": 100, - "volume_discount_factor": 0.1, - }, - { - "minimum_running_notional_taker_volume": 200, - "volume_discount_factor": 0.2, - }, - ], - window_length=7, - ) - next_epoch(vega=vega) - - for _ in range(3): - submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110) - forward_time(vega, True if _ < 3 - 1 else False) - - return market - - -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") -def test_fees_page_discount_program_my_trading_fees(page: Page): +def test_fees_page_discount_program_my_trading_fees( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("8.04%-8.04%") expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text( @@ -69,8 +66,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page): expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") -def test_fees_page_discount_program_total_discount(page: Page): +def test_fees_page_discount_program_total_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("20%") expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount20%") @@ -83,15 +82,19 @@ def test_fees_page_discount_program_total_discount(page: Page): ) -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") -def test_fees_page_volume_discount_program_my_current_volume(page: Page): +def test_fees_page_volume_discount_program_my_current_volume( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(PAST_EPOCHS_VOLUME)).to_have_text("206") expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).not_to_be_visible() -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") -def test_fees_page_discount_program_discount(page: Page): +def test_fees_page_discount_program_discount( + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment page.goto("/#/fees") expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1") expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2") @@ -104,8 +107,8 @@ def test_fees_page_discount_program_discount(page: Page): expect(page.get_by_test_id("your-volume-tier-1").nth(1)).to_have_text("Your tier") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") -def test_fees_page_discount_program_fees_by_market(page: Page): +def test_fees_page_discount_program_fees_by_market(setup_environment): + vega, market, page = setup_environment page.goto("/#/fees") pinned = page.locator(PINNED_ROW_LOCATOR) row = page.locator(ROW_LOCATOR) @@ -117,12 +120,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page): expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") def test_deal_ticket_discount_program( - page: Page, - setup_market_with_volume_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(ORDER_SIZE).fill("1") page.get_by_test_id(ORDER_PRICE).fill("1") expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-20%") @@ -141,12 +143,11 @@ def test_deal_ticket_discount_program( expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.0804 tDAI") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") def test_fills_taker_discount_program( - page: Page, - setup_market_with_volume_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first expect(row.locator(COL_SIZE)).to_have_text("+1") @@ -159,13 +160,11 @@ def test_fills_taker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("2.08035 tDAI") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") def test_fills_maker_discount_program( - vega: VegaServiceNull, - page: Page, - setup_market_with_volume_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -177,11 +176,11 @@ def test_fills_maker_discount_program( expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("2.07 tDAI") -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") def test_fills_maker_fee_tooltip_discount_program( - vega, page: Page, setup_market_with_volume_discount_program -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") change_keys(page, vega, MM_WALLET.name) page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first @@ -193,12 +192,11 @@ def test_fills_maker_fee_tooltip_discount_program( ) -@pytest.mark.xdist_group(name="test_fees_volume_tier_2") def test_fills_taker_fee_tooltip_discount_program( - page: Page, - setup_market_with_volume_discount_program, -): - page.goto(f"/#/markets/{setup_market_with_volume_discount_program}") + setup_environment: Tuple[VegaServiceNull, str, Page], +) -> None: + vega, market, page = setup_environment + page.goto(f"/#/markets/{market}") page.get_by_test_id(FILLS).click() row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first # tbd - tooltip is not visible without this wait diff --git a/apps/trading/e2e/tests/market/test_market_info.py b/apps/trading/e2e/tests/market/test_market_info.py index c5223a0ee..db5705d5a 100644 --- a/apps/trading/e2e/tests/market/test_market_info.py +++ b/apps/trading/e2e/tests/market/test_market_info.py @@ -37,19 +37,16 @@ def validate_info_section(page: Page, fields: [[str, str]]): for rowNumber, field in enumerate(fields): name, value = field expect( - page.get_by_test_id( - "key-value-table-row").nth(rowNumber).locator("dt") + page.get_by_test_id("key-value-table-row").nth(rowNumber).locator("dt") ).to_contain_text(name) expect( - page.get_by_test_id( - "key-value-table-row").nth(rowNumber).locator("dd") + page.get_by_test_id("key-value-table-row").nth(rowNumber).locator("dd") ).to_contain_text(value) def test_market_info_current_fees(page: Page): # 6002-MDET-101 - page.get_by_test_id(market_title_test_id).get_by_text( - "Current fees").click() + page.get_by_test_id(market_title_test_id).get_by_text("Current fees").click() fields = [ ["Maker Fee", "10%"], ["Infrastructure Fee", "0.05%"], @@ -61,8 +58,7 @@ def test_market_info_current_fees(page: Page): def test_market_info_market_price(page: Page): # 6002-MDET-102 - page.get_by_test_id(market_title_test_id).get_by_text( - "Market price").click() + page.get_by_test_id(market_title_test_id).get_by_text("Market price").click() fields = [ ["Mark Price", "107.50"], ["Best Bid Price", "101.50"], @@ -71,11 +67,10 @@ def test_market_info_market_price(page: Page): ] validate_info_section(page, fields) - -def test_market_info_market_volume(page: Page): +#TODO: remove skip once volume is fixed +""" def test_market_info_market_volume(page: Page): # 6002-MDET-103 - page.get_by_test_id(market_title_test_id).get_by_text( - "Market volume").click() + page.get_by_test_id(market_title_test_id).get_by_text("Market volume").click() fields = [ ["24 Hour Volume", "0 (0 )"], ["Open Interest", "1"], @@ -84,12 +79,13 @@ def test_market_info_market_volume(page: Page): ["Best Static Bid Volume", "1"], ["Best Static Offer Volume", "1"], ] - validate_info_section(page, fields) + validate_info_section(page, fields) """ def test_market_info_liquidation_strategy(page: Page): page.get_by_test_id(market_title_test_id).get_by_text( - "Liquidation strategy").click() + "Liquidation strategy" + ).click() fields = [ ["Disposal Fraction", "1"], ["Disposal Time Step", "1"], @@ -101,16 +97,14 @@ def test_market_info_liquidation_strategy(page: Page): def test_market_info_liquidation(page: Page): # 6002-MDET-104 - page.get_by_test_id(market_title_test_id).get_by_text( - "Liquidations").click() + page.get_by_test_id(market_title_test_id).get_by_text("Liquidations").click() fields = [["Insurance Pool Balance", "0.00 tDAI"]] validate_info_section(page, fields) def test_market_info_key_details(page: Page, vega: VegaServiceNull): # 6002-MDET-201 - page.get_by_test_id(market_title_test_id).get_by_text( - "Key details").click() + page.get_by_test_id(market_title_test_id).get_by_text("Key details").click() market_id = vega.find_market_id("BTC:DAI_2023") short_market_id = market_id[:6] + "…" + market_id[-4:] fields = [ @@ -156,8 +150,7 @@ def test_market_info_oracle(page: Page): def test_market_info_settlement_asset(page: Page, vega: VegaServiceNull): # 6002-MDET-206 - page.get_by_test_id(market_title_test_id).get_by_text( - "Settlement asset").click() + page.get_by_test_id(market_title_test_id).get_by_text("Settlement asset").click() tdai_id = vega.find_asset_id("tDAI") tdai_id_short = tdai_id[:6] + "…" + tdai_id[-4:] fields = [ @@ -211,8 +204,7 @@ def test_market_info_margin_scaling_factors(page: Page): def test_market_info_risk_factors(page: Page): # 6002-MDET-210 - page.get_by_test_id(market_title_test_id).get_by_text( - "Risk factors").click() + page.get_by_test_id(market_title_test_id).get_by_text("Risk factors").click() fields = [ ["Long", "0.05153"], ["Short", "0.05422"], @@ -232,8 +224,7 @@ def test_market_info_price_monitoring_bounds(page: Page): expect(page.locator("p.col-span-1").nth(0)).to_contain_text( "99.9999% probability price bounds" ) - expect(page.locator("p.col-span-1").nth(1) - ).to_contain_text("Within 86,400 seconds") + expect(page.locator("p.col-span-1").nth(1)).to_contain_text("Within 86,400 seconds") fields = [ ["Highest Price", "138.66685 BTC"], ["Lowest Price", "83.11038 BTC"], @@ -254,7 +245,7 @@ def test_market_info_liquidity_monitoring_parameters(page: Page): # Liquidity resolves to 3 results -def test_market_info_liquidit(page: Page): +def test_market_info_liquidity(page: Page): # 6002-MDET-213 page.get_by_test_id(market_title_test_id).get_by_text( "Liquidity", exact=True @@ -283,17 +274,14 @@ def test_market_info_proposal(page: Page, vega: VegaServiceNull): # 6002-MDET-301 page.get_by_test_id(market_title_test_id).get_by_text("Proposal").click() first_link = ( - page.get_by_test_id( - "accordion-content").get_by_test_id("external-link").first + page.get_by_test_id("accordion-content").get_by_test_id("external-link").first ) second_link = ( - page.get_by_test_id( - "accordion-content").get_by_test_id("external-link").nth(1) + page.get_by_test_id("accordion-content").get_by_test_id("external-link").nth(1) ) expect(first_link).to_have_text("View governance proposal") expect(first_link).to_have_attribute( - "href", re.compile( - rf'(\/proposals\/{vega.find_market_id("BTC:DAI_2023")})') + "href", re.compile(rf'(\/proposals\/{vega.find_market_id("BTC:DAI_2023")})') ) expect(second_link).to_have_text("Propose a change to market") @@ -304,12 +292,10 @@ def test_market_info_proposal(page: Page, vega: VegaServiceNull): def test_market_info_succession_line(page: Page, vega: VegaServiceNull): - page.get_by_test_id(market_title_test_id).get_by_text( - "Succession line").click() + page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click() market_id = vega.find_market_id("BTC:DAI_2023") succession_line = page.get_by_test_id("succession-line-item") - expect(succession_line.get_by_test_id( - "external-link")).to_have_text("BTC:DAI_2023") + expect(succession_line.get_by_test_id("external-link")).to_have_text("BTC:DAI_2023") expect(succession_line.get_by_test_id("external-link")).to_have_attribute( "href", re.compile(rf"(\/proposals\/{market_id})") ) diff --git a/apps/trading/e2e/tests/order/test_order_status.py b/apps/trading/e2e/tests/order/test_order_status.py index 69be71638..62739c13c 100644 --- a/apps/trading/e2e/tests/order/test_order_status.py +++ b/apps/trading/e2e/tests/order/test_order_status.py @@ -10,228 +10,218 @@ order_tab = "tab-orders" @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser): + # Initialize Vega with cleanup with init_vega(request) as vega_instance: - request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function - yield vega_instance + request.addfinalizer(lambda: cleanup_container(vega_instance)) + # Setup multiple markets + markets = { + "market_1": setup_continuous_market(vega_instance, custom_market_name="market-1"), + "market_2": setup_continuous_market(vega_instance, custom_market_name="market-2"), + "market_3": setup_continuous_market(vega_instance, custom_market_name="market-3"), + "market_4": setup_continuous_market(vega_instance, custom_market_name="market-4"), + "market_5": setup_simple_market(vega_instance, custom_market_name="market-5"), + } -@pytest.fixture(scope="module", autouse=True) -def markets(vega: VegaServiceNull): - market_1 = setup_continuous_market( - vega, - custom_market_name="market-1", - ) - market_2 = setup_continuous_market( - vega, - custom_market_name="market-2", - ) - market_3 = setup_continuous_market( - vega, - custom_market_name="market-3", - ) - market_4 = setup_continuous_market( - vega, - custom_market_name="market-4", - ) - market_5 = setup_simple_market( - vega, - custom_market_name="market-5", - ) + # Execute a series of orders across different markets + # Example for market_1 orders, adjust as necessary for your test scenario + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_1"], + time_in_force="TIME_IN_FORCE_IOC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=100, + price=130, + ) + + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_1, - time_in_force="TIME_IN_FORCE_IOC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=100, - price=130, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_1"], + time_in_force="TIME_IN_FORCE_GTC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=100, + price=88, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_1, - time_in_force="TIME_IN_FORCE_GTC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=100, - price=88, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_1"], + time_in_force="TIME_IN_FORCE_IOC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=100, + price=88, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_1, - time_in_force="TIME_IN_FORCE_IOC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=100, - price=88, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_1"], + time_in_force="TIME_IN_FORCE_GTC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=1e10, + price=130, + wait=False, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_1, - time_in_force="TIME_IN_FORCE_GTC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=1e10, - price=130, - wait=False, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_2"], + time_in_force="TIME_IN_FORCE_IOC", + order_type="TYPE_LIMIT", + side="SIDE_BUY", + volume=100, + price=104, + ) + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_3"], + time_in_force="TIME_IN_FORCE_GTT", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=10, + price=120, + expires_at=vega_instance.get_blockchain_time() + 5 * 1e9, + ) - vega.submit_order( - trading_key="Key 1", - market_id=market_2, - time_in_force="TIME_IN_FORCE_IOC", - order_type="TYPE_LIMIT", - side="SIDE_BUY", - volume=100, - price=104, - ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_3, - time_in_force="TIME_IN_FORCE_GTT", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=10, - price=120, - expires_at=vega.get_blockchain_time() + 5 * 1e9, - ) + vega_instance.submit_order( + market_id=markets["market_4"], + trading_key="Key 1", + side="SIDE_BUY", + order_type="TYPE_LIMIT", + pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=5), + time_in_force="TIME_IN_FORCE_GTC", + volume=20, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - market_id=market_4, - trading_key="Key 1", - side="SIDE_BUY", - order_type="TYPE_LIMIT", - pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=5), - time_in_force="TIME_IN_FORCE_GTC", - volume=20, - ) + vega_instance.submit_order( + market_id=markets["market_4"], + trading_key="Key 1", + side="SIDE_BUY", + order_type="TYPE_LIMIT", + pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_BID", offset=10), + time_in_force="TIME_IN_FORCE_GTC", + volume=40, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - market_id=market_4, - trading_key="Key 1", - side="SIDE_BUY", - order_type="TYPE_LIMIT", - pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_BID", offset=10), - time_in_force="TIME_IN_FORCE_GTC", - volume=40, - ) + vega_instance.submit_order( + market_id=markets["market_4"], + trading_key="Key 1", + side="SIDE_SELL", + order_type="TYPE_LIMIT", + pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15), + time_in_force="TIME_IN_FORCE_GTC", + volume=60, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - market_id=market_4, - trading_key="Key 1", - side="SIDE_SELL", - order_type="TYPE_LIMIT", - pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15), - time_in_force="TIME_IN_FORCE_GTC", - volume=60, - ) + vega_instance.submit_order( + market_id=markets["market_5"], + trading_key="Key 1", + side="SIDE_SELL", + order_type="TYPE_LIMIT", + pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15), + wait=False, + time_in_force="TIME_IN_FORCE_GTC", + volume=60, + ) - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.forward("2s") + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - market_id=market_5, - trading_key="Key 1", - side="SIDE_SELL", - order_type="TYPE_LIMIT", - pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15), - wait=False, - time_in_force="TIME_IN_FORCE_GTC", - volume=60, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_2"], + time_in_force="TIME_IN_FORCE_GTC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=10, + price=150, + ) + + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.forward("2s") - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_2"], + time_in_force="TIME_IN_FORCE_GTC", + order_type="TYPE_LIMIT", + side="SIDE_SELL", + volume=10, + price=160, + ) - vega.submit_order( - trading_key="Key 1", - market_id=market_2, - time_in_force="TIME_IN_FORCE_GTC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=10, - price=150, - ) - - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() - vega.submit_order( - trading_key="Key 1", - market_id=market_2, - time_in_force="TIME_IN_FORCE_GTC", - order_type="TYPE_LIMIT", - side="SIDE_SELL", - volume=10, - price=160, - ) + vega_instance.submit_order( + trading_key="Key 1", + market_id=markets["market_3"], + time_in_force="TIME_IN_FORCE_GTC", + order_type="TYPE_LIMIT", + side="SIDE_BUY", + volume=10, + price=60, + ) - vega.wait_fn(1) - vega.wait_for_total_catchup() - - vega.submit_order( - trading_key="Key 1", - market_id=market_3, - time_in_force="TIME_IN_FORCE_GTC", - order_type="TYPE_LIMIT", - side="SIDE_BUY", - volume=10, - price=60, - ) - - vega.wait_fn(1) - vega.wait_for_total_catchup() + vega_instance.wait_fn(1) + vega_instance.wait_for_total_catchup() + # Initialize page and setup + + yield vega_instance, markets @pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: +def page(setup_environment, browser, request): + vega_instance, markets = setup_environment + with init_page(vega_instance, browser, request) as page: risk_accepted_setup(page) - auth_setup(vega, page) + auth_setup(vega_instance, page) page.goto("/") page.get_by_test_id("All").click() yield page -# close toast that is still opened after test @pytest.fixture(autouse=True) def after_each(page: Page): yield @@ -381,7 +371,8 @@ def test_order_status_pegged_mid(page: Page): ) -def test_order_amend_order(vega: VegaServiceNull, page: Page): +def test_order_amend_order(setup_environment, page:Page): + vega, markets = setup_environment # 7002-SORD-053 # 7003-MORD-012 # 7003-MORD-014 @@ -402,13 +393,13 @@ def test_order_amend_order(vega: VegaServiceNull, page: Page): ) -def test_order_cancel_single_order(vega: VegaServiceNull, page: Page): +def test_order_cancel_single_order(setup_environment, page:Page): + vega, markets = setup_environment # 7003-MORD-009 # 7003-MORD-010 # 7003-MORD-011 # 7002-SORD-043 page.get_by_test_id("cancel").first.click() - wait_for_toast_confirmation(page, timeout=5000) vega.wait_fn(1) vega.wait_for_total_catchup() @@ -420,7 +411,8 @@ def test_order_cancel_single_order(vega: VegaServiceNull, page: Page): ) -def test_order_cancel_all_orders(vega: VegaServiceNull, page: Page): +def test_order_cancel_all_orders(setup_environment, page:Page): + vega, markets = setup_environment # 7003-MORD-009 # 7003-MORD-010 # 7003-MORD-011 diff --git a/apps/trading/e2e/tests/rewards/test_hoarder_tier_0.py b/apps/trading/e2e/tests/rewards/test_hoarder_tier_0.py index d608069f0..999132590 100644 --- a/apps/trading/e2e/tests/rewards/test_hoarder_tier_0.py +++ b/apps/trading/e2e/tests/rewards/test_hoarder_tier_0.py @@ -1,8 +1,15 @@ import pytest import vega_sim.proto.vega as vega_protos +from typing import Tuple, Generator from rewards_test_ids import * from playwright.sync_api import Page, expect -from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container +from conftest import ( + init_vega, + init_page, + auth_setup, + risk_accepted_setup, + cleanup_container, +) from fixtures.market import setup_continuous_market from actions.utils import next_epoch, change_keys from wallet_config import MM_WALLET @@ -10,22 +17,20 @@ from vega_sim.null_service import VegaServiceNull @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]: with init_vega(request) as vega_instance: request.addfinalizer(lambda: cleanup_container(vega_instance)) - yield vega_instance -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - page.goto(REWARDS_URL) - change_keys(page, vega, PARTY_B) - yield page + tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance) + + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + page.goto(REWARDS_URL) + change_keys(page, vega_instance, PARTY_B) + yield page, tDAI_market, tDAI_asset_id -@pytest.fixture(scope="module", autouse=True) def setup_market_with_reward_program(vega: VegaServiceNull): tDAI_market = setup_continuous_market(vega) PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) @@ -83,39 +88,39 @@ def setup_market_with_reward_program(vega: VegaServiceNull): return tDAI_market, tDAI_asset_id -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0") def test_network_reward_pot( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("50.00 tDAI") -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0") def test_reward_multiplier( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("1x") expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0") def test_hoarder_bonus( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(HOARDER_BONUS_TOTAL_HOARDED)).to_contain_text( "5,000,000" ) -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0") def test_reward_history( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment page.locator('[name="fromEpoch"]').fill("1") expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text( "100.00100.00%" ) expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("100.00") page.get_by_test_id(EARNED_BY_ME_BUTTON).click() - expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("50.00") \ No newline at end of file + expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("50.00") diff --git a/apps/trading/e2e/tests/rewards/test_hoarder_tier_1.py b/apps/trading/e2e/tests/rewards/test_hoarder_tier_1.py index ecb1c2765..90c3942d4 100644 --- a/apps/trading/e2e/tests/rewards/test_hoarder_tier_1.py +++ b/apps/trading/e2e/tests/rewards/test_hoarder_tier_1.py @@ -1,8 +1,15 @@ import pytest from rewards_test_ids import * +from typing import Tuple, Generator import vega_sim.proto.vega as vega_protos from playwright.sync_api import Page, expect -from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container +from conftest import ( + init_vega, + init_page, + auth_setup, + risk_accepted_setup, + cleanup_container, +) from fixtures.market import setup_continuous_market from actions.utils import next_epoch, change_keys from wallet_config import MM_WALLET @@ -10,23 +17,21 @@ from vega_sim.null_service import VegaServiceNull @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]: + with init_vega(request) as vega_instance: - request.addfinalizer(lambda: cleanup_container(vega_instance)) - yield vega_instance + request.addfinalizer(lambda: cleanup_container(vega_instance)) + + tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance) + + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + page.goto(REWARDS_URL) + change_keys(page, vega_instance, PARTY_B) + yield page, tDAI_market, tDAI_asset_id -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - page.goto(REWARDS_URL) - change_keys(page, vega, PARTY_B) - yield page - - -@pytest.fixture(scope="module", autouse=True) def setup_market_with_reward_program(vega: VegaServiceNull): tDAI_market = setup_continuous_market(vega) PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) @@ -135,31 +140,35 @@ def setup_market_with_reward_program(vega: VegaServiceNull): return tDAI_market, tDAI_asset_id -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1") def test_network_reward_pot( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("166.66666 tDAI") -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1") def test_reward_multiplier( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("2x") expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("2x") -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1") -def test_hoarder_bonus(page: Page): +def test_hoarder_bonus( + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(HOARDER_BONUS_TOTAL_HOARDED)).to_contain_text( "16,666,666" ) -@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1") -def test_reward_history(page: Page): +def test_reward_history( + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment page.locator('[name="fromEpoch"]').fill("1") expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text( "299.99999100.00%" @@ -170,4 +179,4 @@ def test_reward_history(page: Page): page.get_by_test_id(EARNED_BY_ME_BUTTON).click() expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text( "166.66666" - ) \ No newline at end of file + ) diff --git a/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py index 667244e25..3d4114edd 100644 --- a/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py +++ b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py @@ -1,5 +1,6 @@ import pytest from rewards_test_ids import * +from typing import Tuple, Generator import vega_sim.proto.vega as vega_protos from playwright.sync_api import Page, expect from conftest import ( @@ -16,23 +17,23 @@ from vega_sim.null_service import VegaServiceNull @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]: + with init_vega(request) as vega_instance: request.addfinalizer(lambda: cleanup_container(vega_instance)) - yield vega_instance + + tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance) + + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + page.goto(REWARDS_URL) + change_keys(page, vega_instance, PARTY_B) + yield page, tDAI_market, tDAI_asset_id -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - page.goto(REWARDS_URL) - change_keys(page, vega, PARTY_B) - yield page -@pytest.fixture(scope="module", autouse=True) def setup_market_with_reward_program(vega: VegaServiceNull): tDAI_market = setup_continuous_market(vega) PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) @@ -90,25 +91,23 @@ def setup_market_with_reward_program(vega: VegaServiceNull): return tDAI_market, tDAI_asset_id -@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") def test_network_reward_pot( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("50.00 tDAI") - page.pause() -@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") def test_reward_multiplier( - page: Page, -): - page.pause() + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("1x") expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") -""" @pytest.mark.xdist_group(name="test_rewards_activity_tier_0") +""" def test_activity_streak( page: Page, ): @@ -117,7 +116,6 @@ def test_activity_streak( ) -@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") def test_reward_history( page: Page, ): diff --git a/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_1.py b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_1.py index 80467326e..97baa5406 100644 --- a/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_1.py +++ b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_1.py @@ -1,8 +1,15 @@ import pytest from rewards_test_ids import * +from typing import Tuple, Generator import vega_sim.proto.vega as vega_protos from playwright.sync_api import Page, expect -from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container +from conftest import ( + init_vega, + init_page, + auth_setup, + risk_accepted_setup, + cleanup_container, +) from fixtures.market import setup_continuous_market from actions.utils import next_epoch, change_keys from wallet_config import MM_WALLET @@ -10,22 +17,21 @@ from vega_sim.null_service import VegaServiceNull @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]: + with init_vega(request) as vega_instance: request.addfinalizer(lambda: cleanup_container(vega_instance)) - yield vega_instance + + tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance) + + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + page.goto(REWARDS_URL) + change_keys(page, vega_instance, PARTY_B) + yield page, tDAI_market, tDAI_asset_id -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - page.goto(REWARDS_URL) - change_keys(page, vega, PARTY_B) - yield page - -@pytest.fixture(scope="module", autouse=True) def setup_market_with_reward_program(vega: VegaServiceNull): tDAI_market = setup_continuous_market(vega) PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) @@ -128,34 +134,35 @@ def setup_market_with_reward_program(vega: VegaServiceNull): return tDAI_market, tDAI_asset_id -@pytest.mark.xdist_group(name="test_rewards_activity_tier_1") -def test_network_reward_pot(page: Page): - +def test_network_reward_pot( + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("116.66666 tDAI") -@pytest.mark.xdist_group(name="test_rewards_activity_tier_1") def test_reward_multiplier( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("2x") expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("2x") expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") -@pytest.mark.xdist_group(name="test_rewards_activity_tier_1") def test_activity_streak( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(EPOCH_STREAK)).to_have_text( "Active trader: 7 epochs so far (Tier 1 as of last epoch)" ) -@pytest.mark.xdist_group(name="test_rewards_activity_tier_1") def test_reward_history( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment page.locator('[name="fromEpoch"]').fill("1") expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text( "300.00100.00%" @@ -167,10 +174,10 @@ def test_reward_history( ) -@pytest.mark.xdist_group(name="test_rewards_activity_tier_1") def test_redeem( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment page.get_by_test_id("redeem-rewards-button").click() available_to_withdraw = page.get_by_test_id( "available-to-withdraw-value" @@ -184,4 +191,4 @@ def test_redeem( ) page.get_by_test_id("use-max-button").first.click() - expect(page.get_by_test_id(TRANSFER_AMOUNT)).to_have_text(available_to_withdraw) \ No newline at end of file + expect(page.get_by_test_id(TRANSFER_AMOUNT)).to_have_text(available_to_withdraw) diff --git a/apps/trading/e2e/tests/rewards/test_rewards_combo_tier_1.py b/apps/trading/e2e/tests/rewards/test_rewards_combo_tier_1.py index a2263dcc9..3a533c687 100644 --- a/apps/trading/e2e/tests/rewards/test_rewards_combo_tier_1.py +++ b/apps/trading/e2e/tests/rewards/test_rewards_combo_tier_1.py @@ -1,5 +1,6 @@ import pytest from rewards_test_ids import * +from typing import Tuple, Generator import vega_sim.proto.vega as vega_protos from playwright.sync_api import Page, expect from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container @@ -8,25 +9,23 @@ from actions.utils import next_epoch, change_keys from wallet_config import MM_WALLET from vega_sim.null_service import VegaServiceNull + @pytest.fixture(scope="module") -def vega(request): +def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]: with init_vega(request) as vega_instance: request.addfinalizer(lambda: cleanup_container(vega_instance)) - yield vega_instance + + tDAI_market, tDAI_asset_id = setup_market_with_reward_program( + vega_instance) + + with init_page(vega_instance, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega_instance, page) + page.goto(REWARDS_URL) + change_keys(page, vega_instance, PARTY_B) + yield page, tDAI_market, tDAI_asset_id - -@pytest.fixture(scope="module") -def page(vega, browser, request): - with init_page(vega, browser, request) as page: - risk_accepted_setup(page) - auth_setup(vega, page) - page.goto(REWARDS_URL) - change_keys(page, vega, PARTY_B) - yield page - - -@pytest.fixture(scope="module", autouse=True) def setup_market_with_reward_program(vega: VegaServiceNull): tDAI_market = setup_continuous_market(vega) PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) @@ -57,6 +56,16 @@ def setup_market_with_reward_program(vega: VegaServiceNull): ) next_epoch(vega=vega) + vega.recurring_transfer( + from_key_name=PARTY_A.name, + from_account_type=vega_protos.vega.ACCOUNT_TYPE_GENERAL, + to_account_type=vega_protos.vega.ACCOUNT_TYPE_GLOBAL_REWARD, + asset=tDAI_asset_id, + amount=100, + factor=1.0, + ) + vega.wait_fn(1) + vega.wait_for_total_catchup() vega.recurring_transfer( from_key_name=PARTY_A.name, from_account_type=vega_protos.vega.ACCOUNT_TYPE_GENERAL, @@ -140,16 +149,16 @@ def setup_market_with_reward_program(vega: VegaServiceNull): return tDAI_market, tDAI_asset_id -@pytest.mark.xdist_group(name="test_rewards_combo_tier_1") -def test_network_reward_pot( page: Page -): +def test_network_reward_pot(setup_environment: Tuple[Page, str, str], + ) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("183.33333 tDAI") -@pytest.mark.xdist_group(name="test_rewards_combo_tier_1") def test_reward_multiplier( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("4x") expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text( "2x" @@ -159,16 +168,45 @@ def test_reward_multiplier( ) -@pytest.mark.xdist_group(name="test_rewards_combo_tier_1") def test_reward_history( - page: Page, -): + setup_environment: Tuple[Page, str, str], +) -> None: + page, tDAI_market, tDAI_asset_id = setup_environment page.locator('[name="fromEpoch"]').fill("1") expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text( "299.99999100.00%" ) - expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("299.99999") + expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth( + 1)).to_have_text("299.99999") page.get_by_test_id(EARNED_BY_ME_BUTTON).click() expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text( "183.33333" - ) \ No newline at end of file + ) + + +def test_staking_reward( + setup_environment: Tuple[Page, str, str], +): + page, tDAI_market, tDAI_asset_id = setup_environment + expect(page.get_by_test_id("active-rewards-card")).to_have_count(2) + staking_reward_card = page.get_by_test_id("active-rewards-card").nth(1) + expect(staking_reward_card).to_be_visible() + expect(staking_reward_card.get_by_test_id( + "entity-scope")).to_have_text("Individual") + expect(staking_reward_card.get_by_test_id( + "locked-for")).to_have_text("0 epochs") + expect(staking_reward_card.get_by_test_id( + "reward-value")).to_have_text("100.00") + expect(staking_reward_card.get_by_test_id( + "distribution-strategy")).to_have_text("Pro rata") + expect(staking_reward_card.get_by_test_id("dispatch-metric-info")).to_have_text( + "Staking rewards" + ) + expect(staking_reward_card.get_by_test_id( + "assessed-over")).to_have_text("1 epoch") + expect(staking_reward_card.get_by_test_id( + "scope")).to_have_text("Individual") + expect(staking_reward_card.get_by_test_id( + "staking-requirement")).to_have_text("1.00") + expect(staking_reward_card.get_by_test_id( + "average-position")).to_have_text("0.00") diff --git a/apps/trading/e2e/tests/successor_market/test_succession_line.py b/apps/trading/e2e/tests/successor_market/test_succession_line.py index bd45edc53..15d96d61b 100644 --- a/apps/trading/e2e/tests/successor_market/test_succession_line.py +++ b/apps/trading/e2e/tests/successor_market/test_succession_line.py @@ -97,10 +97,13 @@ def test_banners(vega: VegaServiceNull, page: Page): settlement_price=100, market_id=parent_market_id, ) - + vega.wait_fn(1) + vega.wait_for_total_catchup() successor_name = "successor market name" propose_successor(vega, parent_market_id, tdai_id, successor_name) - + vega.wait_fn(1) + vega.wait_for_total_catchup() + page.reload() # Check that the banners notifying about the successor proposal and market has been settled are shown banner = page.get_by_test_id(market_banner) expect(banner).to_be_attached() diff --git a/apps/trading/e2e/tests/teams/test_teams.py b/apps/trading/e2e/tests/teams/test_teams.py index 15ad474ed..a7180c77e 100644 --- a/apps/trading/e2e/tests/teams/test_teams.py +++ b/apps/trading/e2e/tests/teams/test_teams.py @@ -299,10 +299,10 @@ def test_leaderboard(competitions_page: Page, setup_teams_and_games): def test_game_card(competitions_page: Page): - expect(competitions_page.get_by_test_id("active-rewards-card")).to_have_count(2) + expect(competitions_page.get_by_test_id("active-rewards-card")).to_have_count(1) game_1 = competitions_page.get_by_test_id("active-rewards-card").first expect(game_1).to_be_visible() - expect(game_1.get_by_test_id("entity-scope")).to_have_text("Individual") + expect(game_1.get_by_test_id("entity-scope")).to_have_text("Team") expect(game_1.get_by_test_id("locked-for")).to_have_text("1 epoch") expect(game_1.get_by_test_id("reward-value")).to_have_text("100.00") expect(game_1.get_by_test_id("reward-asset")).to_have_text("VEGA") @@ -311,7 +311,7 @@ def test_game_card(competitions_page: Page): "Price maker fees paid • tDAI" ) expect(game_1.get_by_test_id("assessed-over")).to_have_text("15 epochs") - expect(game_1.get_by_test_id("scope")).to_have_text("In team") + expect(game_1.get_by_test_id("scope")).to_have_text("All teams") expect(game_1.get_by_test_id("staking-requirement")).to_have_text("0.00") expect(game_1.get_by_test_id("average-position")).to_have_text("0.00") diff --git a/apps/trading/lib/hooks/Games.graphql b/apps/trading/lib/hooks/Games.graphql index 5a5b2a1ed..4962e08e7 100644 --- a/apps/trading/lib/hooks/Games.graphql +++ b/apps/trading/lib/hooks/Games.graphql @@ -25,8 +25,12 @@ fragment GameFields on Game { } } -query Games($epochFrom: Int) { - games(epochFrom: $epochFrom, entityScope: ENTITY_SCOPE_TEAMS) { +query Games($epochFrom: Int, $teamId: ID) { + games( + epochFrom: $epochFrom + teamId: $teamId + entityScope: ENTITY_SCOPE_TEAMS + ) { edges { node { ...GameFields diff --git a/apps/trading/lib/hooks/__generated__/Games.ts b/apps/trading/lib/hooks/__generated__/Games.ts index 3306b8ed7..21ba546d5 100644 --- a/apps/trading/lib/hooks/__generated__/Games.ts +++ b/apps/trading/lib/hooks/__generated__/Games.ts @@ -9,6 +9,7 @@ export type GameFieldsFragment = { __typename?: 'Game', id: string, epoch: numbe export type GamesQueryVariables = Types.Exact<{ epochFrom?: Types.InputMaybe; + teamId?: Types.InputMaybe; }>; @@ -44,8 +45,8 @@ export const GameFieldsFragmentDoc = gql` } ${TeamEntityFragmentDoc}`; export const GamesDocument = gql` - query Games($epochFrom: Int) { - games(epochFrom: $epochFrom, entityScope: ENTITY_SCOPE_TEAMS) { + query Games($epochFrom: Int, $teamId: ID) { + games(epochFrom: $epochFrom, teamId: $teamId, entityScope: ENTITY_SCOPE_TEAMS) { edges { node { ...GameFields @@ -68,6 +69,7 @@ export const GamesDocument = gql` * const { data, loading, error } = useGamesQuery({ * variables: { * epochFrom: // value for 'epochFrom' + * teamId: // value for 'teamId' * }, * }); */ diff --git a/apps/trading/lib/hooks/use-games.ts b/apps/trading/lib/hooks/use-games.ts index 5e30adebf..293766862 100644 --- a/apps/trading/lib/hooks/use-games.ts +++ b/apps/trading/lib/hooks/use-games.ts @@ -51,6 +51,7 @@ export const useGames = (teamId?: string, epochFrom?: number): GamesData => { const { data, loading, error } = useGamesQuery({ variables: { epochFrom: from, + teamId: teamId, }, skip: !from, fetchPolicy: 'cache-and-network', diff --git a/apps/trading/lib/hooks/use-rewards.spec.ts b/apps/trading/lib/hooks/use-rewards.spec.ts index 92ed9febd..0a48f6997 100644 --- a/apps/trading/lib/hooks/use-rewards.spec.ts +++ b/apps/trading/lib/hooks/use-rewards.spec.ts @@ -194,11 +194,11 @@ describe('isScopedToTeams', () => { undefined, makeDispatchStrategy( EntityScope.ENTITY_SCOPE_INDIVIDUALS, - IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM // individual in teams + IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM // individual in teams but not a team game ), 'RecurringTransfer' ), - true, + false, ], [ makeReward( diff --git a/apps/trading/lib/hooks/use-rewards.ts b/apps/trading/lib/hooks/use-rewards.ts index 59cb6045d..20295def4 100644 --- a/apps/trading/lib/hooks/use-rewards.ts +++ b/apps/trading/lib/hooks/use-rewards.ts @@ -14,7 +14,6 @@ import { TransferStatus, type DispatchStrategy, EntityScope, - IndividualScope, MarketState, AccountType, } from '@vegaprotocol/types'; @@ -75,20 +74,11 @@ export const isActiveReward = (node: RewardTransfer, currentEpoch: number) => { /** * Checks if given reward (transfer) is scoped to teams. - * - * A reward is scoped to teams if it's entity scope is set to teams or - * if the scope is set to individuals but the individuals are in a team. */ export const isScopedToTeams = (node: EnrichedRewardTransfer) => // scoped to teams node.transfer.kind.dispatchStrategy?.entityScope === - EntityScope.ENTITY_SCOPE_TEAMS || - // or to individuals - (node.transfer.kind.dispatchStrategy?.entityScope === - EntityScope.ENTITY_SCOPE_INDIVIDUALS && - // but they have to be in a team - node.transfer.kind.dispatchStrategy?.individualScope === - IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM); + EntityScope.ENTITY_SCOPE_TEAMS; /** Retrieves rewards (transfers) */ export const useRewards = ({ diff --git a/apps/trading/pages/_document.page.tsx b/apps/trading/pages/_document.page.tsx index 4ddd0fa58..335678d49 100644 --- a/apps/trading/pages/_document.page.tsx +++ b/apps/trading/pages/_document.page.tsx @@ -4,11 +4,10 @@ export default function Document() { return ( <> - {/* - meta tags - - next advised against using _document for this, so they exist in our - - single page index.page.tsx - */} + {/* preload fonts */} + + {/* icons */} - + + + {/* scripts */}