Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
789e5faf76 | ||
|
|
43ec3921da | ||
|
|
dc25fe53e3 |
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Feature Epic
|
||||
about: A template to capture and scope user requirements, high level process, and basic mockups for an upcoming feature as part of the initial core spec review process.
|
||||
title: 'FEATURE EPIC: '
|
||||
title: 'Epic: '
|
||||
labels: feature-epic
|
||||
---
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
secrets: inherit
|
||||
with:
|
||||
projects: ${{ needs.lint-test-build.outputs.projects-e2e }}
|
||||
tags: '@smoke'
|
||||
tags: '@smoke @regression'
|
||||
|
||||
publish-dist:
|
||||
needs: lint-test-build
|
||||
|
||||
@@ -10,8 +10,8 @@ on:
|
||||
jobs:
|
||||
run-tests:
|
||||
name: run-tests
|
||||
runs-on: 8-cores
|
||||
timeout-minutes: 20
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
#----------------------------------------------
|
||||
# check-out frontend-monorepo
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
#----------------------------------------------
|
||||
- name: Run tests
|
||||
working-directory: ./console-test
|
||||
run: poetry run pytest -s --numprocesses auto
|
||||
run: poetry run pytest --numprocesses auto
|
||||
- name: Check files
|
||||
run: |
|
||||
ls -al .
|
||||
|
||||
@@ -23,7 +23,6 @@ module.exports = defineConfig({
|
||||
viewportWidth: 1440,
|
||||
viewportHeight: 900,
|
||||
testIsolation: false,
|
||||
experimentalMemoryManagement: true,
|
||||
},
|
||||
env: {
|
||||
environment: 'CUSTOM',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createSuccessorMarketProposal } from '../support/governance.functions';
|
||||
|
||||
context('Market page', { tags: '@regression' }, function () {
|
||||
describe('Verify elements on page', function () {
|
||||
const marketHeaders = 'markets-heading';
|
||||
const createdMarketId =
|
||||
'2eab0e66545a789047561bc5a2e5cbc3b19eb708da41104e3cac2474ee36c4d4';
|
||||
|
||||
before('Create market', function () {
|
||||
cy.visit('/');
|
||||
@@ -11,7 +11,7 @@ context('Market page', { tags: '@regression' }, function () {
|
||||
|
||||
beforeEach('Get market id', function () {
|
||||
cy.navigate_to('markets');
|
||||
cy.get('[col-id="id"]').last().invoke('text').as('createdMarketId');
|
||||
cy.get('[col-id="id"]').eq(1).invoke('text').as('createdMarketId');
|
||||
});
|
||||
|
||||
it('Market displayed on market page', function () {
|
||||
@@ -106,7 +106,6 @@ context('Market page', { tags: '@regression' }, function () {
|
||||
// Able to view Json
|
||||
cy.contains('View JSON').click();
|
||||
cy.get('.language-json').should('exist');
|
||||
cy.getByTestId('icon-cross').click();
|
||||
});
|
||||
|
||||
// Skipping due to resize observer loop limit error
|
||||
@@ -114,60 +113,17 @@ context('Market page', { tags: '@regression' }, function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.navigate_to('markets', true);
|
||||
cy.getByTestId(marketHeaders).should('be.visible');
|
||||
cy.get(`[row-id="${this.createdMarketId}"]`)
|
||||
cy.get(`[row-id="${createdMarketId}"]`)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get_element_by_col_id('code').should('have.text', 'TEST.24h');
|
||||
cy.get_element_by_col_id('name').should('have.text', 'Test market 1');
|
||||
cy.get_element_by_col_id('state').should('have.text', 'Pending');
|
||||
cy.get_element_by_col_id('asset').should('have.text', 'fUSDC');
|
||||
cy.get_element_by_col_id('id').should(
|
||||
'have.text',
|
||||
this.createdMarketId
|
||||
);
|
||||
cy.get_element_by_col_id('id').should('have.text', createdMarketId);
|
||||
cy.get_element_by_col_id('actions')
|
||||
.find('a')
|
||||
.should('have.attr', 'href', `/markets/${this.createdMarketId}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to go to market details page for successor market', function () {
|
||||
const successionLineItem = 'succession-line-item';
|
||||
const successionLineMarketId = 'succession-line-item-market-id';
|
||||
|
||||
createSuccessorMarketProposal(this.createdMarketId);
|
||||
cy.navigate_to('markets');
|
||||
cy.reload();
|
||||
cy.contains('Token test market', { timeout: 8000 }).should('be.visible');
|
||||
cy.get('[row-index="0"]')
|
||||
.invoke('attr', 'row-id')
|
||||
.as('successorMarketId');
|
||||
cy.contains('Token test market').click();
|
||||
cy.getByTestId(marketHeaders).should('have.text', 'Token test market');
|
||||
cy.validate_proposal_change_type('Triggering Ratio', 'Added');
|
||||
cy.validate_element_from_table('Triggering Ratio', '0.7');
|
||||
cy.validate_proposal_change_type('Time Window', 'Added');
|
||||
cy.validate_element_from_table('Time Window', '3,600');
|
||||
cy.validate_proposal_change_type('Scaling Factor', 'Added');
|
||||
cy.validate_element_from_table('Scaling Factor', '10');
|
||||
|
||||
cy.getByTestId(successionLineItem)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.contains('Test market 1');
|
||||
cy.getByTestId(successionLineMarketId).should(
|
||||
'have.text',
|
||||
this.createdMarketId
|
||||
);
|
||||
});
|
||||
cy.getByTestId(successionLineItem)
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.contains('Token test market');
|
||||
cy.getByTestId(successionLineMarketId).should(
|
||||
'have.text',
|
||||
this.successorMarketId
|
||||
);
|
||||
.should('have.attr', 'href', `/markets/${createdMarketId}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,31 +13,28 @@ context('Proposal page', { tags: '@smoke' }, function () {
|
||||
it('Able to view proposal', function () {
|
||||
cy.navigate_to('governanceProposals');
|
||||
cy.getByTestId(proposalHeading).should('be.visible');
|
||||
cy.contains(proposalTitle)
|
||||
.parent()
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
|
||||
cy.get_element_by_col_id('type').should('have.text', 'NewMarket');
|
||||
cy.get_element_by_col_id('state').should('have.text', 'Enacted');
|
||||
cy.getByTestId('vote-progress').should('be.visible');
|
||||
cy.get('[col-id="cDate"]')
|
||||
.invoke('text')
|
||||
.should('match', dateTimeRegex);
|
||||
cy.get('[col-id="eDate"]')
|
||||
.invoke('text')
|
||||
.should('match', dateTimeRegex);
|
||||
cy.getByTestId('external-link')
|
||||
.should('have.attr', 'href')
|
||||
.and('contains', 'https://governance.fairground.wtf/proposals/');
|
||||
cy.contains('View terms').should('exist').click();
|
||||
});
|
||||
// get first proposal in list
|
||||
cy.get('[row-index="0"]').within(() => {
|
||||
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
|
||||
cy.get_element_by_col_id('type').should('have.text', 'NewMarket');
|
||||
cy.get_element_by_col_id('state').should('have.text', 'Enacted');
|
||||
cy.getByTestId('vote-progress').should('be.visible');
|
||||
cy.get('[col-id="cDate"]')
|
||||
.invoke('text')
|
||||
.should('match', dateTimeRegex);
|
||||
cy.get('[col-id="eDate"]')
|
||||
.invoke('text')
|
||||
.should('match', dateTimeRegex);
|
||||
cy.getByTestId('external-link')
|
||||
.should('have.attr', 'href')
|
||||
.and('contains', 'https://governance.fairground.wtf/proposals/');
|
||||
cy.contains('View terms').should('exist').click();
|
||||
});
|
||||
cy.getByTestId('dialog-title').should('have.text', proposalTitle);
|
||||
cy.get('.language-json').should('exist');
|
||||
});
|
||||
|
||||
it.skip('Proposal page displayed on mobile', function () {
|
||||
it('Proposal page displayed on mobile', function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.navigate_to('governanceProposals', true);
|
||||
cy.getByTestId(proposalHeading).should('be.visible');
|
||||
|
||||
@@ -127,10 +127,3 @@ Cypress.Commands.add(
|
||||
.should('have.text', tableRowValue);
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'validate_proposal_change_type',
|
||||
(tableRowName, changeType) => {
|
||||
cy.contains(tableRowName).siblings().should('have.text', changeType);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
export function createSuccessorMarketProposal(parentMarketId) {
|
||||
cy.VegaWalletSubmitProposal(getSuccessorTxBody(parentMarketId));
|
||||
}
|
||||
|
||||
function getSuccessorTxBody(parentMarketId) {
|
||||
return {
|
||||
proposalSubmission: {
|
||||
rationale: {
|
||||
title: 'Test successor market proposal details',
|
||||
description: 'E2E test for successor market',
|
||||
},
|
||||
terms: {
|
||||
newMarket: {
|
||||
changes: {
|
||||
decimalPlaces: '5',
|
||||
positionDecimalPlaces: '5',
|
||||
linearSlippageFactor: '0.001',
|
||||
quadraticSlippageFactor: '0',
|
||||
lpPriceRange: '10',
|
||||
instrument: {
|
||||
name: 'Token test market',
|
||||
code: 'TEST.24h',
|
||||
future: {
|
||||
settlementAsset:
|
||||
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc',
|
||||
quoteName: 'fUSDC',
|
||||
dataSourceSpecForSettlementData: {
|
||||
external: {
|
||||
oracle: {
|
||||
signers: [
|
||||
{
|
||||
pubKey: {
|
||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
||||
},
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
key: {
|
||||
name: 'prices.BTC.value',
|
||||
type: 'TYPE_INTEGER',
|
||||
numberDecimalPlaces: '0',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
operator: 'OPERATOR_GREATER_THAN',
|
||||
value: '0',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
external: {
|
||||
oracle: {
|
||||
signers: [
|
||||
{
|
||||
pubKey: {
|
||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
||||
},
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
key: {
|
||||
name: 'trading.terminated.ETH5',
|
||||
type: 'TYPE_BOOLEAN',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
operator: 'OPERATOR_EQUALS',
|
||||
value: 'true',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecBinding: {
|
||||
settlementDataProperty: 'prices.BTC.value',
|
||||
tradingTerminationProperty: 'trading.terminated.ETH5',
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: [
|
||||
'sector:food',
|
||||
'sector:materials',
|
||||
'source:docs.vega.xyz',
|
||||
],
|
||||
priceMonitoringParameters: {
|
||||
triggers: [
|
||||
{
|
||||
horizon: '43200',
|
||||
probability: '0.9999999',
|
||||
auctionExtension: '600',
|
||||
},
|
||||
],
|
||||
},
|
||||
liquidityMonitoringParameters: {
|
||||
targetStakeParameters: {
|
||||
timeWindow: '3600',
|
||||
scalingFactor: 10,
|
||||
},
|
||||
triggeringRatio: '0.7',
|
||||
auctionExtension: '1',
|
||||
},
|
||||
logNormal: {
|
||||
tau: 0.0001140771161,
|
||||
riskAversionParameter: 0.01,
|
||||
params: {
|
||||
mu: 0,
|
||||
r: 0.016,
|
||||
sigma: 0.5,
|
||||
},
|
||||
},
|
||||
successor: {
|
||||
parentMarketId: parentMarketId,
|
||||
insurancePoolFraction: '0.75',
|
||||
},
|
||||
},
|
||||
},
|
||||
closingTimestamp: 1695666618,
|
||||
enactmentTimestamp: 1695666618,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export const Footer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<footer className="grid grid-cols-[1fr_auto] items-center text-xs md:text-md lg:flex md:col-span-2 px-4 pt-2 pb-3 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<footer className="grid grid-rows-2 lg:grid-cols-[1fr_auto] text-xs md:text-md lg:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<div className="flex justify-between gap-2 align-middle">
|
||||
{GIT_COMMIT_HASH && (
|
||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
@@ -43,12 +43,9 @@ export const Footer = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="content-center flex pr-4 md:border-r border-neutral-700 dark:border-neutral-300">
|
||||
<span className="pr-2">{VEGA_URL && <NodeUrl url={VEGA_URL} />}</span>
|
||||
<Link
|
||||
className="ml-2 underline-offset-4"
|
||||
onClick={() => setNodeSwitcherOpen(true)}
|
||||
>
|
||||
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
|
||||
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
|
||||
{t('Change')}
|
||||
</Link>
|
||||
</div>
|
||||
@@ -62,10 +59,7 @@ export const Footer = () => {
|
||||
) : null}
|
||||
</div>
|
||||
<div className="pl-2 align-center lg:align-right lg:flex lg:justify-end gap-2 align-middle lg:max-w-xs lg:ml-auto">
|
||||
<RouteLink
|
||||
to={`/${Routes.DISCLAIMER}`}
|
||||
className="underline underline-offset-4"
|
||||
>
|
||||
<RouteLink to={`/${Routes.DISCLAIMER}`} className="underline">
|
||||
Disclaimer
|
||||
</RouteLink>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
||||
import {
|
||||
PriceMonitoringBoundsInfoPanel,
|
||||
SuccessionLineInfoPanel,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { PriceMonitoringBoundsInfoPanel } from '@vegaprotocol/markets';
|
||||
import {
|
||||
LiquidityInfoPanel,
|
||||
LiquidityMonitoringParametersInfoPanel,
|
||||
@@ -106,8 +103,6 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||
<OracleInfoPanel market={market} type="settlementData" />
|
||||
</>
|
||||
)}
|
||||
<h2 className={`${headerClassName} mb-4`}>{t('Succession line')}</h2>
|
||||
<SuccessionLineInfoPanel market={market} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,8 +10,6 @@ import Hash from '../../links/hash';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { ProposalSignatureBundleNewAsset } from './proposal/signature-bundle-new';
|
||||
import { ProposalSignatureBundleUpdateAsset } from './proposal/signature-bundle-update';
|
||||
import { MarketLink } from '../../links';
|
||||
import { formatNumber } from '@vegaprotocol/utils';
|
||||
|
||||
export type Proposal = components['schemas']['v1ProposalSubmission'];
|
||||
export type ProposalTerms = components['schemas']['vegaProposalTerms'];
|
||||
@@ -55,11 +53,7 @@ export function proposalTypeLabel(terms?: ProposalTerms): string {
|
||||
} else if (has(terms, 'updateAsset')) {
|
||||
return t('Update asset proposal');
|
||||
} else if (has(terms, 'newMarket')) {
|
||||
if (terms?.newMarket?.changes?.successor) {
|
||||
return t('Successor market proposal');
|
||||
} else {
|
||||
return t('New market proposal');
|
||||
}
|
||||
return t('New market proposal');
|
||||
} else if (has(terms, 'updateMarket')) {
|
||||
return t('Update market proposal');
|
||||
} else if (has(terms, 'updateNetworkParameter')) {
|
||||
@@ -91,13 +85,6 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
|
||||
}
|
||||
|
||||
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
|
||||
const isSuccessorMarketProposal =
|
||||
proposal?.terms?.newMarket?.changes?.successor;
|
||||
const parentMarketId =
|
||||
isSuccessorMarketProposal &&
|
||||
proposal?.terms.newMarket?.changes?.successor?.parentMarketId;
|
||||
const insurancePoolFraction =
|
||||
proposal?.terms?.newMarket?.changes?.successor?.insurancePoolFraction;
|
||||
|
||||
// This component is not rendered if no bundle is required
|
||||
const SignatureBundleComponent = proposal.terms?.newAsset
|
||||
@@ -124,30 +111,6 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
|
||||
<Hash text={deterministicId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{isSuccessorMarketProposal ? (
|
||||
<>
|
||||
{parentMarketId ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Previous market')}</TableCell>
|
||||
<TableCell>
|
||||
<MarketLink
|
||||
id={
|
||||
proposal.terms?.newMarket.changes.successor.parentMarketId
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
{insurancePoolFraction ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Insurance pool fraction')}</TableCell>
|
||||
<TableCell>
|
||||
{formatNumber(Number(insurancePoolFraction) * 100, 0)}%
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</TableWithTbody>
|
||||
<ProposalSummary
|
||||
id={deterministicId}
|
||||
|
||||
@@ -78,11 +78,7 @@ export function getLabelForProposal(
|
||||
} else if (proposal.terms?.updateAsset) {
|
||||
return t('Proposal: Update asset');
|
||||
} else if (proposal.terms?.newMarket) {
|
||||
if (proposal.terms?.newMarket.changes?.successor) {
|
||||
return t('Proposal: Successor market');
|
||||
} else {
|
||||
return t('Proposal: New market');
|
||||
}
|
||||
return t('Proposal: New market');
|
||||
} else if (proposal.terms?.updateMarket) {
|
||||
return t('Proposal: Update market');
|
||||
} else if (proposal.terms?.updateNetworkParameter) {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 547 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"short_name": "Mainnet Stats",
|
||||
"name": "Vega Mainnet statistics",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -1,39 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charset="utf-8" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Explorer" />
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:url" content="https://explorer.vega.xyz/" />
|
||||
<meta name="og:title" content="Vega Protocol - Explorer" />
|
||||
<meta name="og:site_name" content="Vega Protocol - Explorer" />
|
||||
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
|
||||
<meta name="twitter:card" content="https://static.vega.xyz/favicon.ico" />
|
||||
<meta name="twitter:title" content="Vega Protocol - Explorer" />
|
||||
<meta name="twitter:description" content="Vega Protocol - Explorer" />
|
||||
<meta name="twitter:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
<meta name="twitter:image:alt" content="VEGA logo" />
|
||||
<meta name="twitter:site" content="@vegaprotocol" />
|
||||
|
||||
<meta name="description" content="Vega Protocol - Explorer" />
|
||||
<link rel="apple-touch-icon" href="assets/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="assets/manifest.json" />
|
||||
<title>Explorer</title>
|
||||
<base href="/" />
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<title>VEGA Explorer</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
<script src="./assets/env-config.js"></script>
|
||||
</head>
|
||||
<body class="dark:bg-black h-full w-full">
|
||||
|
||||
@@ -18,7 +18,6 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
|
||||
@@ -28,7 +28,6 @@ module.exports = defineConfig({
|
||||
numTestsKeptInMemory: 5,
|
||||
downloadsFolder: 'cypress/downloads',
|
||||
testIsolation: false,
|
||||
experimentalMemoryManagement: true,
|
||||
},
|
||||
env: {
|
||||
ethProviderUrl: 'http://localhost:8545/',
|
||||
|
||||
@@ -11,9 +11,7 @@ import {
|
||||
getDateFormatForSpecifiedDays,
|
||||
getProposalFromTitle,
|
||||
getProposalInformationFromTable,
|
||||
proposalChangeType,
|
||||
submitUniqueRawProposal,
|
||||
validateProposalDetailsDiff,
|
||||
voteForProposal,
|
||||
} from '../../../../governance-e2e/src/support/governance.functions';
|
||||
import {
|
||||
@@ -28,9 +26,7 @@ import {
|
||||
} from '../../support/wallet-functions';
|
||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
||||
import { createSuccessorMarketProposalTxBody } from '../../support/proposal.functions';
|
||||
|
||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||
const proposalVoteProgressForPercentage =
|
||||
'vote-progress-indicator-percentage-for';
|
||||
const proposalVoteProgressAgainstPercentage =
|
||||
@@ -46,7 +42,6 @@ const viewProposalButton = 'view-proposal-btn';
|
||||
const proposalDescriptionToggle = 'proposal-description-toggle';
|
||||
const voteBreakdownToggle = 'vote-breakdown-toggle';
|
||||
const proposalTermsToggle = 'proposal-json-toggle';
|
||||
const marketDataToggle = 'proposal-market-data-toggle';
|
||||
|
||||
describe(
|
||||
'Governance flow for proposal details',
|
||||
@@ -55,12 +50,12 @@ describe(
|
||||
before('connect wallets and set approval limit', function () {
|
||||
cy.visit('/');
|
||||
ethereumWalletConnect();
|
||||
// cy.associateTokensToVegaWallet('1');
|
||||
});
|
||||
|
||||
beforeEach('visit proposals tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -359,98 +354,5 @@ describe(
|
||||
switchVegaWalletPubKey();
|
||||
stakingPageDisassociateAllTokens();
|
||||
});
|
||||
|
||||
it('Able to see successor market details with new and updated values', function () {
|
||||
cy.createMarket();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.getByTestId('closed-proposals').within(() => {
|
||||
cy.contains('Add Lorem Ipsum market')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId(viewProposalButton).click();
|
||||
});
|
||||
});
|
||||
getProposalInformationFromTable('ID')
|
||||
.invoke('text')
|
||||
.as('parentMarketId')
|
||||
.then(() => {
|
||||
cy.VegaWalletSubmitProposal(
|
||||
createSuccessorMarketProposalTxBody(this.parentMarketId)
|
||||
);
|
||||
});
|
||||
navigateTo(navigation.proposals);
|
||||
cy.reload();
|
||||
getProposalFromTitle('Test successor market proposal details').within(
|
||||
() => cy.getByTestId(viewProposalButton).click()
|
||||
);
|
||||
// #3003-PMAN-010
|
||||
cy.getByTestId(proposalTermsToggle).click();
|
||||
cy.get('.language-json').within(() => {
|
||||
cy.get('.hljs-attr').should('contain.text', 'parentMarketId');
|
||||
cy.get('.hljs-string').should('contain.text', this.parentMarketId);
|
||||
cy.get('.hljs-attr').should('contain.text', 'insurancePoolFraction');
|
||||
cy.get('.hljs-string').should('contain.text', '0.75');
|
||||
});
|
||||
// 3003-PMAN-011 3003-PMAN-012
|
||||
cy.getByTestId(marketDataToggle).click();
|
||||
cy.getByTestId('proposal-market-data').within(() => {
|
||||
cy.contains('Key details').click();
|
||||
validateProposalDetailsDiff(
|
||||
'Name',
|
||||
proposalChangeType.UPDATED,
|
||||
'Token test market',
|
||||
'Test market 1'
|
||||
);
|
||||
validateProposalDetailsDiff(
|
||||
'Parent Market ID',
|
||||
proposalChangeType.ADDED,
|
||||
this.parentMarketId
|
||||
);
|
||||
validateProposalDetailsDiff(
|
||||
'Insurance Pool Fraction',
|
||||
proposalChangeType.ADDED,
|
||||
'0.75'
|
||||
);
|
||||
validateProposalDetailsDiff(
|
||||
'Trading Mode',
|
||||
proposalChangeType.UPDATED,
|
||||
'No trading',
|
||||
'Opening auction'
|
||||
);
|
||||
|
||||
cy.contains('Instrument').click();
|
||||
validateProposalDetailsDiff(
|
||||
'Market Name',
|
||||
proposalChangeType.UPDATED,
|
||||
'Token test market',
|
||||
'Test market 1'
|
||||
);
|
||||
|
||||
cy.contains('Metadata').click();
|
||||
validateProposalDetailsDiff(
|
||||
'Sector',
|
||||
proposalChangeType.UPDATED,
|
||||
'materials',
|
||||
'tech'
|
||||
);
|
||||
});
|
||||
|
||||
// 3003-PMAN-011
|
||||
cy.get('.underline').contains('Parent Market ID').realHover();
|
||||
cy.getByTestId('tooltip-content', { timeout: 8000 }).should(
|
||||
'contain.text',
|
||||
'The ID of the market this market succeeds.'
|
||||
);
|
||||
cy.get('.underline')
|
||||
.contains('Insurance Pool Fraction')
|
||||
.realMouseUp()
|
||||
.realHover();
|
||||
cy.getByTestId('tooltip-content', { timeout: 8000 }).should(
|
||||
'contain.text',
|
||||
'The fraction of the insurance pool balance that is carried over from the parent market to the successor.'
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -42,7 +42,6 @@ context(
|
||||
beforeEach('visit proposals', function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
|
||||
@@ -82,7 +82,6 @@ context(
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.reload();
|
||||
cy.mockChainId();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
ethereumWalletConnect();
|
||||
|
||||
@@ -74,7 +74,6 @@ context(
|
||||
beforeEach('visit governance tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -655,7 +654,44 @@ context(
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', this.parentMarketId);
|
||||
cy.getByTestId('view-proposal-btn').click();
|
||||
});
|
||||
// #3003-PMAN-010
|
||||
cy.getByTestId(proposalJsonToggle).click();
|
||||
cy.get('.language-json').within(() => {
|
||||
cy.get('.hljs-attr').should('contain.text', 'parentMarketId');
|
||||
cy.get('.hljs-string').should('contain.text', this.parentMarketId);
|
||||
cy.get('.hljs-attr').should('contain.text', 'insurancePoolFraction');
|
||||
cy.get('.hljs-string').should('contain.text', '0.75');
|
||||
});
|
||||
cy.getByTestId('proposal-market-data').within(() => {
|
||||
cy.getByTestId('proposal-market-data-toggle').click();
|
||||
cy.contains('Key details').click();
|
||||
// 3003-PMAN-009
|
||||
getMarketProposalDetailsFromTable('Parent Market ID').should(
|
||||
'have.text',
|
||||
this.parentMarketId
|
||||
);
|
||||
getMarketProposalDetailsFromTable('Insurance Pool Fraction').should(
|
||||
'have.text',
|
||||
'0.75'
|
||||
);
|
||||
getMarketProposalDetailsFromTable('Trading Mode').should(
|
||||
'have.text',
|
||||
'No trading'
|
||||
);
|
||||
});
|
||||
// 3003-PMAN-011
|
||||
cy.contains('Parent Market ID').realHover();
|
||||
cy.getByTestId('tooltip-content').should(
|
||||
'contain.text',
|
||||
'The ID of the market this market succeeds.'
|
||||
);
|
||||
cy.contains('Insurance Pool Fraction').realHover();
|
||||
cy.getByTestId('tooltip-content').should(
|
||||
'contain.text',
|
||||
'The fraction of the insurance pool balance that is carried over from the parent market to the successor.'
|
||||
);
|
||||
});
|
||||
|
||||
after('Disassociate from second wallet key if present', function () {
|
||||
@@ -694,7 +730,6 @@ context(
|
||||
.getByTestId('key-value-table-row')
|
||||
.contains(heading)
|
||||
.parent()
|
||||
.parent()
|
||||
.siblings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.reload();
|
||||
cy.mockChainId();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
ethereumWalletConnect();
|
||||
|
||||
@@ -26,7 +26,6 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
||||
before('set up environment to allow rewards', function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.visit('/');
|
||||
waitForSpinner();
|
||||
ethereumWalletConnect();
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
vegaWalletSetSpecifiedApprovalAmount,
|
||||
vegaWalletTeardown,
|
||||
} from '../../support/wallet-functions';
|
||||
|
||||
const stakeValidatorListTotalStake = 'total-stake';
|
||||
const stakeValidatorListTotalShare = 'total-stake-share';
|
||||
const stakeValidatorListStakePercentage = 'stake-percentage';
|
||||
@@ -68,7 +67,6 @@ context(
|
||||
function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
// Go to homepage to allow wallet teardown without epoch timer refreshing page
|
||||
navigateTo(navigation.home);
|
||||
vegaWalletTeardown();
|
||||
|
||||
@@ -56,7 +56,6 @@ context(
|
||||
function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
|
||||
@@ -50,7 +50,6 @@ context(
|
||||
beforeEach('Navigate to withdrawal page', function () {
|
||||
cy.clearLocalStorage();
|
||||
turnTelemetryOff();
|
||||
cy.mockChainId();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
navigateTo(navigation.withdraw);
|
||||
@@ -97,8 +96,7 @@ context(
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line
|
||||
it.skip(
|
||||
it(
|
||||
'Able to withdraw asset: -eth wallet connected -withdraw funds button',
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
|
||||
@@ -231,7 +231,7 @@ context(
|
||||
});
|
||||
|
||||
// 3009-NTWU-001 3009-NTWU-002 3009-NTWU-006 3009-NTWU-009
|
||||
it.skip('should display network upgrade banner with estimate', function () {
|
||||
it('should display network upgrade banner with estimate', function () {
|
||||
mockNetworkUpgradeProposal();
|
||||
cy.visit('/');
|
||||
cy.getByTestId('banners').within(() => {
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
waitForBeginningOfEpoch,
|
||||
} from '../../support/staking.functions';
|
||||
import { previousEpochData } from '../../fixtures/mocks/previous-epoch';
|
||||
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
||||
|
||||
const guideLink = 'staking-guide-link';
|
||||
const validatorTitle = 'validator-node-title';
|
||||
@@ -34,22 +33,11 @@ const overstakedPenaltyToolTip = 'overstaked-penalty-tooltip';
|
||||
const multisigPenaltyToolTip = 'multisig-error-tooltip';
|
||||
const epochCountDown = 'epoch-countdown';
|
||||
const stakeNumberRegex = /^\d{1,3}(,\d{3})*(\.\d+)?$/;
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
context('Validators Page - verify elements on page', function () {
|
||||
before('navigate to validators page', () => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
before('navigate to validators page', function () {
|
||||
cy.visit('/validators');
|
||||
});
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
});
|
||||
|
||||
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
||||
it('Should have validators tab highlighted', function () {
|
||||
@@ -189,11 +177,6 @@ context('Validators Page - verify elements on page', function () {
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
before('connect wallets and click on validator', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.visit('/validators');
|
||||
cy.connectVegaWallet();
|
||||
clickOnValidatorFromList(0);
|
||||
});
|
||||
@@ -280,7 +263,7 @@ context('Validators Page - verify elements on page', function () {
|
||||
|
||||
cy.getByTestId(epochCountDown).within(() => {
|
||||
cy.get(epochTitle).should('not.be.empty');
|
||||
cy.get(nextEpochInfo, txTimeout).should('contain.text', 'Next epoch');
|
||||
cy.get(nextEpochInfo).should('contain.text', 'Next epoch');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import {
|
||||
vegaWalletFaucetAssetsWithoutCheck,
|
||||
vegaWalletTeardown,
|
||||
} from '../../support/wallet-functions';
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
||||
|
||||
const walletContainer = 'aside [data-testid="vega-wallet"]';
|
||||
const walletHeader = '[data-testid="wallet-header"] h1';
|
||||
@@ -16,6 +14,10 @@ const dialogHeader = 'dialog-title';
|
||||
const walletDialogHeader = 'wallet-dialog-title';
|
||||
const connectorsList = 'connectors-list';
|
||||
const dialogCloseBtn = 'dialog-close';
|
||||
const restConnectorForm = 'rest-connector-form';
|
||||
const restWallet = '#wallet';
|
||||
const restPassphrase = '#passphrase';
|
||||
const restConnectBtn = '[type="submit"]';
|
||||
const accountNo = 'vega-account-truncated';
|
||||
const currencyTitle = 'currency-title';
|
||||
const currencyValue = 'currency-value';
|
||||
@@ -67,7 +69,7 @@ context(
|
||||
cy.get(dialog).within(() => {
|
||||
cy.getByTestId(walletDialogHeader)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Get a Vega wallet');
|
||||
.and('have.text', 'Connect');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,7 +77,10 @@ context(
|
||||
cy.getByTestId(connectorsList).within(() => {
|
||||
cy.getByTestId('connector-jsonRpc')
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Use the Desktop App/CLI');
|
||||
.and('have.text', 'Connect Vega wallet');
|
||||
cy.getByTestId('connector-rest')
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Hosted Fairground wallet');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,14 +91,48 @@ context(
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rest connector form opened', function () {
|
||||
before('click hosted wallet app button', function () {
|
||||
cy.getByTestId(connectorsList).within(() => {
|
||||
cy.getByTestId('connector-rest').click();
|
||||
});
|
||||
});
|
||||
|
||||
// 0002-WCON-002
|
||||
it('should have wallet field visible', function () {
|
||||
cy.getByTestId(restConnectorForm).within(() => {
|
||||
cy.get(restWallet).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have password field visible', function () {
|
||||
cy.getByTestId(restConnectorForm).within(() => {
|
||||
cy.get(restPassphrase).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have connect button visible', function () {
|
||||
cy.getByTestId(restConnectorForm).within(() => {
|
||||
cy.get(restConnectBtn)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have close button visible', function () {
|
||||
cy.get(dialog).within(() => {
|
||||
cy.getByTestId(dialogCloseBtn).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
after('close dialog', function () {
|
||||
cy.getByTestId(dialogCloseBtn).click().should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when vega wallet connected', function () {
|
||||
before('connect vega wallet', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@ChainId');
|
||||
cy.connectVegaWallet();
|
||||
vegaWalletTeardown();
|
||||
});
|
||||
@@ -276,10 +315,6 @@ context(
|
||||
];
|
||||
|
||||
before('faucet assets to connected vega wallet', function () {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
});
|
||||
for (const { id, amount } of assets) {
|
||||
vegaWalletFaucetAssetsWithoutCheck(id, amount, vegaWalletPublicKey);
|
||||
}
|
||||
|
||||
@@ -232,23 +232,6 @@ export function getDownloadedProposalJsonPath(proposalType: string) {
|
||||
return filepath;
|
||||
}
|
||||
|
||||
export function validateProposalDetailsDiff(
|
||||
RowName: string,
|
||||
changeType: proposalChangeType,
|
||||
newValue: string,
|
||||
oldValue?: string
|
||||
) {
|
||||
cy.contains(RowName)
|
||||
.parentsUntil(proposalInformationTableRows)
|
||||
.parent()
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.contains(changeType).should('be.visible');
|
||||
cy.contains(newValue).should('be.visible');
|
||||
if (oldValue) cy.contains(oldValue).should('have.class', 'line-through');
|
||||
});
|
||||
}
|
||||
|
||||
function getFormattedTime() {
|
||||
const now = new Date();
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
@@ -269,8 +252,3 @@ export enum governanceProposalType {
|
||||
FREEFORM = 'Freeform',
|
||||
RAW = 'raw proposal',
|
||||
}
|
||||
|
||||
export enum proposalChangeType {
|
||||
UPDATED = 'Updated',
|
||||
ADDED = 'Added',
|
||||
}
|
||||
|
||||
@@ -211,143 +211,6 @@ export function createNewMarketProposalTxBody(): ProposalSubmissionBody {
|
||||
};
|
||||
}
|
||||
|
||||
// Requires cy.createMarket() to be run to set up parent market
|
||||
export function createSuccessorMarketProposalTxBody(
|
||||
parentMarketId: string
|
||||
): ProposalSubmissionBody {
|
||||
const MIN_CLOSE_SEC = 10000;
|
||||
const MIN_ENACT_SEC = 10000;
|
||||
|
||||
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
|
||||
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
|
||||
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
|
||||
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
|
||||
return {
|
||||
proposalSubmission: {
|
||||
rationale: {
|
||||
title: 'Test successor market proposal details',
|
||||
description: 'E2E test for successor market',
|
||||
},
|
||||
terms: {
|
||||
newMarket: {
|
||||
changes: {
|
||||
decimalPlaces: '5',
|
||||
positionDecimalPlaces: '5',
|
||||
linearSlippageFactor: '0.001',
|
||||
quadraticSlippageFactor: '0',
|
||||
lpPriceRange: '10',
|
||||
instrument: {
|
||||
name: 'Token test market',
|
||||
code: 'TEST.24h',
|
||||
future: {
|
||||
settlementAsset:
|
||||
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc',
|
||||
quoteName: 'fUSDC',
|
||||
dataSourceSpecForSettlementData: {
|
||||
external: {
|
||||
oracle: {
|
||||
signers: [
|
||||
{
|
||||
pubKey: {
|
||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
||||
},
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
key: {
|
||||
name: 'prices.BTC.value',
|
||||
type: 'TYPE_INTEGER' as const,
|
||||
numberDecimalPlaces: '0',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
operator: 'OPERATOR_GREATER_THAN' as const,
|
||||
value: '0',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
external: {
|
||||
oracle: {
|
||||
signers: [
|
||||
{
|
||||
pubKey: {
|
||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
||||
},
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
key: {
|
||||
name: 'trading.terminated.ETH5',
|
||||
type: 'TYPE_BOOLEAN' as const,
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
operator: 'OPERATOR_EQUALS' as const,
|
||||
value: 'true',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecBinding: {
|
||||
settlementDataProperty: 'prices.BTC.value',
|
||||
tradingTerminationProperty: 'trading.terminated.ETH5',
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: [
|
||||
'sector:food',
|
||||
'sector:materials',
|
||||
'source:docs.vega.xyz',
|
||||
],
|
||||
priceMonitoringParameters: {
|
||||
triggers: [
|
||||
{
|
||||
horizon: '43200',
|
||||
probability: '0.9999999',
|
||||
auctionExtension: '600',
|
||||
},
|
||||
],
|
||||
},
|
||||
liquidityMonitoringParameters: {
|
||||
targetStakeParameters: {
|
||||
timeWindow: '3600',
|
||||
scalingFactor: 10,
|
||||
},
|
||||
triggeringRatio: '0.7',
|
||||
auctionExtension: '1',
|
||||
},
|
||||
logNormal: {
|
||||
tau: 0.0001140771161,
|
||||
riskAversionParameter: 0.01,
|
||||
params: {
|
||||
mu: 0,
|
||||
r: 0.016,
|
||||
sigma: 0.5,
|
||||
},
|
||||
},
|
||||
successor: {
|
||||
parentMarketId: parentMarketId,
|
||||
insurancePoolFraction: '0.75',
|
||||
},
|
||||
},
|
||||
},
|
||||
closingTimestamp,
|
||||
enactmentTimestamp,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function mockNetworkUpgradeProposal() {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'Nodes', nodeData);
|
||||
|
||||
@@ -9,7 +9,6 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https:
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
@@ -22,12 +21,9 @@ NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
LC_ALL="en_US.UTF-8"
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
VegaConnectDialog,
|
||||
VegaManageDialog,
|
||||
ViewAsDialog,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { VegaConnectDialog, VegaManageDialog } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@@ -29,8 +25,6 @@ export const VegaWalletDialogs = () => {
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
<ViewAsDialog connector={Connectors.view} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ExternalLinks } from '@vegaprotocol/environment';
|
||||
|
||||
export const DownloadWalletPrompt = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<h3 className="mt-4 mb-2">{t('getWallet')}</h3>
|
||||
<p>
|
||||
<Link className="text-neutral-500" href={ExternalLinks.VEGA_WALLET_URL}>
|
||||
{t('getWalletLink')}
|
||||
</Link>
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ExternalLinks } from '@vegaprotocol/environment';
|
||||
import { useViewAsDialog } from '@vegaprotocol/wallet';
|
||||
|
||||
export const VegaWalletPrompt = () => {
|
||||
const { t } = useTranslation();
|
||||
const setViewAsDialog = useViewAsDialog((state) => state.setOpen);
|
||||
return (
|
||||
<>
|
||||
<h3 className="mt-4 mb-2">{t('getWallet')}</h3>
|
||||
<div className="flex flex-row gap-4">
|
||||
<Link className="text-neutral-500" href={ExternalLinks.VEGA_WALLET_URL}>
|
||||
{t('getWalletLink')}
|
||||
</Link>
|
||||
<ButtonLink
|
||||
className="text-neutral-500"
|
||||
data-testid="view-as-user"
|
||||
onClick={() => setViewAsDialog(true)}
|
||||
>
|
||||
{t('viewAsParty')}
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
WalletCardHeader,
|
||||
WalletCardRow,
|
||||
} from '../wallet-card';
|
||||
import { VegaWalletPrompt } from './vega-wallet-prompt';
|
||||
import { DownloadWalletPrompt } from './download-wallet-prompt';
|
||||
import { usePollForDelegations } from './hooks';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
@@ -85,7 +85,7 @@ const VegaWalletNotConnected = () => {
|
||||
>
|
||||
{t('connectVegaWalletToUseAssociated')}
|
||||
</Button>
|
||||
<VegaWalletPrompt />
|
||||
<DownloadWalletPrompt />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -855,6 +855,5 @@
|
||||
"Estimated time to upgrade": "Estimated time to upgrade",
|
||||
"Upgraded at": "Upgraded at",
|
||||
"dataIsIdentical": "Data is identical",
|
||||
"updatesToMarket": "Updates to market",
|
||||
"viewAsParty": "View as party"
|
||||
"updatesToMarket": "Updates to market"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark bg-black w-full h-full">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="//static.vega.xyz/fonts.css" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
@@ -10,42 +10,35 @@
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Governance" />
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:url" content="https://governance.vega.xyz/" />
|
||||
<meta name="og:title" content="Vega Protocol - Governance" />
|
||||
<meta name="og:site_name" content="Vega Protocol - Governance" />
|
||||
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
|
||||
<meta name="twitter:card" content="https://static.vega.xyz/favicon.ico" />
|
||||
<meta name="twitter:title" content="Vega Protocol - Governance" />
|
||||
<meta name="twitter:description" content="Vega Protocol - Governance" />
|
||||
<meta name="twitter:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
<meta name="twitter:image:alt" content="VEGA logo" />
|
||||
<meta name="twitter:site" content="@vegaprotocol" />
|
||||
|
||||
<meta name="description" content="Vega Protocol - Governance" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Token Vesting" />
|
||||
<link rel="apple-touch-icon" href="assets/apple-touch-icon.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="assets/manifest.json" />
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<title>VEGA Governance</title>
|
||||
<title>Vega Governance dApp</title>
|
||||
<script src="./assets/env-config.js"></script>
|
||||
</head>
|
||||
<body class="h-full">
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="h-full"></div>
|
||||
<!-- This HTML file is a template.
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`. -->
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
RestConnector,
|
||||
JsonRpcConnector,
|
||||
ViewConnector,
|
||||
InjectedConnector,
|
||||
@@ -7,11 +8,13 @@ import {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
export const injected = new InjectedConnector();
|
||||
export const rest = new RestConnector();
|
||||
export const jsonRpc = new JsonRpcConnector();
|
||||
export const view = new ViewConnector(urlParams.get('address'));
|
||||
|
||||
export const Connectors = {
|
||||
injected,
|
||||
rest,
|
||||
jsonRpc,
|
||||
view,
|
||||
};
|
||||
|
||||
+11
-85
@@ -25,7 +25,7 @@ import {
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { SubHeading } from '../../../../components/heading';
|
||||
import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
|
||||
import type { MarketInfo } from '@vegaprotocol/markets';
|
||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
||||
import type { DataSourceDefinition } from '@vegaprotocol/types';
|
||||
import { create } from 'zustand';
|
||||
|
||||
@@ -45,10 +45,8 @@ export const useMarketDataDialogStore = create<MarketDataDialogState>(
|
||||
|
||||
export const ProposalMarketData = ({
|
||||
marketData,
|
||||
parentMarketData,
|
||||
}: {
|
||||
marketData: MarketInfo;
|
||||
parentMarketData?: MarketInfo;
|
||||
marketData: MarketInfoWithData;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, open, close } = useMarketDataDialogStore();
|
||||
@@ -60,21 +58,8 @@ export const ProposalMarketData = ({
|
||||
|
||||
const settlementData = marketData.tradableInstrument.instrument.product
|
||||
.dataSourceSpecForSettlementData.data as DataSourceDefinition;
|
||||
const parentSettlementData =
|
||||
parentMarketData?.tradableInstrument.instrument?.product
|
||||
?.dataSourceSpecForSettlementData?.data;
|
||||
const terminationData = marketData.tradableInstrument.instrument.product
|
||||
.dataSourceSpecForTradingTermination.data as DataSourceDefinition;
|
||||
const parentTerminationData =
|
||||
parentMarketData?.tradableInstrument.instrument?.product
|
||||
?.dataSourceSpecForTradingTermination?.data;
|
||||
|
||||
const isParentSettlementDataEqual =
|
||||
parentSettlementData !== undefined &&
|
||||
isEqual(settlementData, parentSettlementData);
|
||||
const isParentTerminationDataEqual =
|
||||
parentTerminationData !== undefined &&
|
||||
isEqual(terminationData, parentTerminationData);
|
||||
|
||||
const getSigners = (data: DataSourceDefinition) => {
|
||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
||||
@@ -112,22 +97,12 @@ export const ProposalMarketData = ({
|
||||
<AccordionItem
|
||||
itemId="key-details"
|
||||
title={t('Key details')}
|
||||
content={
|
||||
<KeyDetailsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<KeyDetailsInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="instrument"
|
||||
title={t('Instrument')}
|
||||
content={
|
||||
<InstrumentInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<InstrumentInfoPanel market={marketData} />}
|
||||
/>
|
||||
{isEqual(
|
||||
getSigners(settlementData),
|
||||
@@ -140,11 +115,6 @@ export const ProposalMarketData = ({
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="settlementData"
|
||||
parentMarket={
|
||||
isParentSettlementDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -157,11 +127,6 @@ export const ProposalMarketData = ({
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="settlementData"
|
||||
parentMarket={
|
||||
isParentSettlementDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -170,21 +135,11 @@ export const ProposalMarketData = ({
|
||||
itemId="termination-oracle"
|
||||
title={t('Termination Oracle')}
|
||||
content={
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="termination"
|
||||
parentMarket={
|
||||
isParentTerminationDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
<OracleInfoPanel market={marketData} type="termination" />
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{/*Note: successor markets will not differ in their settlement*/}
|
||||
{/*assets, so no need to pass in parent market data for comparison.*/}
|
||||
<AccordionItem
|
||||
itemId="settlement-asset"
|
||||
title={t('Settlement asset')}
|
||||
@@ -193,42 +148,22 @@ export const ProposalMarketData = ({
|
||||
<AccordionItem
|
||||
itemId="metadata"
|
||||
title={t('Metadata')}
|
||||
content={
|
||||
<MetadataInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<MetadataInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-model"
|
||||
title={t('Risk model')}
|
||||
content={
|
||||
<RiskModelInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskModelInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-parameters"
|
||||
title={t('Risk parameters')}
|
||||
content={
|
||||
<RiskParametersInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskParametersInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-factors"
|
||||
title={t('Risk factors')}
|
||||
content={
|
||||
<RiskFactorsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskFactorsInfoPanel market={marketData} />}
|
||||
/>
|
||||
{(
|
||||
marketData.priceMonitoringSettings?.parameters?.triggers || []
|
||||
@@ -239,7 +174,6 @@ export const ProposalMarketData = ({
|
||||
content={
|
||||
<PriceMonitoringBoundsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
triggerIndex={triggerIndex}
|
||||
/>
|
||||
}
|
||||
@@ -249,21 +183,13 @@ export const ProposalMarketData = ({
|
||||
itemId="liqudity-monitoring-parameters"
|
||||
title={t('Liquidity monitoring parameters')}
|
||||
content={
|
||||
<LiquidityMonitoringParametersInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
<LiquidityMonitoringParametersInfoPanel market={marketData} />
|
||||
}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="liquidity-price-range"
|
||||
title={t('Liquidity price range')}
|
||||
content={
|
||||
<LiquidityPriceRangeInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<LiquidityPriceRangeInfoPanel market={marketData} />}
|
||||
/>
|
||||
</Accordion>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ import Routes from '../../../routes';
|
||||
import { ProposalMarketData } from '../proposal-market-data';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import type { MarketInfo } from '@vegaprotocol/markets';
|
||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
||||
import type { AssetQuery } from '@vegaprotocol/assets';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
@@ -31,8 +31,7 @@ export enum ProposalType {
|
||||
export interface ProposalProps {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
networkParams: Partial<NetworkParamsResult>;
|
||||
newMarketData?: MarketInfo | null;
|
||||
parentMarketData?: MarketInfo | null;
|
||||
newMarketData?: MarketInfoWithData | null;
|
||||
assetData?: AssetQuery | null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
restData: any;
|
||||
@@ -47,7 +46,6 @@ export const Proposal = ({
|
||||
networkParams,
|
||||
restData,
|
||||
newMarketData,
|
||||
parentMarketData,
|
||||
assetData,
|
||||
originalMarketProposalRestData,
|
||||
mostRecentlyEnactedAssociatedMarketProposal,
|
||||
@@ -159,10 +157,7 @@ export const Proposal = ({
|
||||
|
||||
{newMarketData && (
|
||||
<div className="mb-4">
|
||||
<ProposalMarketData
|
||||
marketData={newMarketData}
|
||||
parentMarketData={parentMarketData ? parentMarketData : undefined}
|
||||
/>
|
||||
<ProposalMarketData marketData={newMarketData} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -8,15 +8,12 @@ import { useProposalQuery } from './__generated__/Proposal';
|
||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||
import { ENV } from '../../../config';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { marketInfoProvider } from '@vegaprotocol/markets';
|
||||
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
|
||||
import { useAssetQuery } from '@vegaprotocol/assets';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { useParentMarketIdQuery } from '@vegaprotocol/markets';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
|
||||
|
||||
export const ProposalContainer = () => {
|
||||
const [
|
||||
@@ -57,10 +54,6 @@ export const ProposalContainer = () => {
|
||||
skip: !params.proposalId,
|
||||
});
|
||||
|
||||
const successor = useSuccessorMarketProposalDetails(params.proposalId);
|
||||
|
||||
const isSuccessor = !!successor?.parentMarketId || !!successor.code;
|
||||
|
||||
const {
|
||||
state: {
|
||||
data: originalMarketProposalRestData,
|
||||
@@ -95,7 +88,7 @@ export const ProposalContainer = () => {
|
||||
loading: newMarketLoading,
|
||||
error: newMarketError,
|
||||
} = useDataProvider({
|
||||
dataProvider: marketInfoProvider,
|
||||
dataProvider: marketInfoWithDataProvider,
|
||||
skipUpdates: true,
|
||||
variables: {
|
||||
marketId: data?.proposal?.id || '',
|
||||
@@ -103,33 +96,6 @@ export const ProposalContainer = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: parentMarketId,
|
||||
loading: parentMarketIdLoading,
|
||||
error: parentMarketIdError,
|
||||
} = useParentMarketIdQuery({
|
||||
variables: {
|
||||
marketId: newMarketData?.id || '',
|
||||
},
|
||||
skip: !FLAGS.SUCCESSOR_MARKETS || !isSuccessor || !newMarketData?.id,
|
||||
});
|
||||
|
||||
const {
|
||||
data: parentMarketData,
|
||||
loading: parentMarketLoading,
|
||||
error: parentMarketError,
|
||||
} = useDataProvider({
|
||||
dataProvider: marketInfoProvider,
|
||||
skipUpdates: true,
|
||||
variables: {
|
||||
marketId: parentMarketId?.market?.parentMarketID || '',
|
||||
skip:
|
||||
!FLAGS.SUCCESSOR_MARKETS ||
|
||||
!isSuccessor ||
|
||||
!parentMarketId?.market?.parentMarketID,
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: assetData,
|
||||
loading: assetLoading,
|
||||
@@ -194,8 +160,6 @@ export const ProposalContainer = () => {
|
||||
newMarketLoading ||
|
||||
assetLoading ||
|
||||
networkParamsLoading ||
|
||||
parentMarketIdLoading ||
|
||||
parentMarketLoading ||
|
||||
(restLoading ? (restLoading as boolean) : false) ||
|
||||
(originalMarketProposalRestLoading
|
||||
? (originalMarketProposalRestLoading as boolean)
|
||||
@@ -208,18 +172,15 @@ export const ProposalContainer = () => {
|
||||
error ||
|
||||
newMarketError ||
|
||||
assetError ||
|
||||
networkParamsError ||
|
||||
parentMarketIdError ||
|
||||
parentMarketError ||
|
||||
restError ||
|
||||
originalMarketProposalRestError ||
|
||||
previouslyEnactedMarketProposalsRestError
|
||||
previouslyEnactedMarketProposalsRestError ||
|
||||
networkParamsError
|
||||
}
|
||||
data={{
|
||||
...data,
|
||||
...networkParams,
|
||||
...(newMarketData ? { newMarketData } : {}),
|
||||
...(parentMarketData ? { parentMarketData } : {}),
|
||||
...(assetData ? { assetData } : {}),
|
||||
...(restData ? { restData } : {}),
|
||||
...(originalMarketProposalRestData
|
||||
@@ -236,7 +197,6 @@ export const ProposalContainer = () => {
|
||||
networkParams={networkParams}
|
||||
restData={restData}
|
||||
newMarketData={newMarketData}
|
||||
parentMarketData={parentMarketData}
|
||||
assetData={assetData}
|
||||
originalMarketProposalRestData={originalMarketProposalRestData}
|
||||
mostRecentlyEnactedAssociatedMarketProposal={
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// #region consts
|
||||
const assetColId = '[col-id="asset.symbol"]';
|
||||
const assetDetailsDialog = 'dialog-content';
|
||||
const assetRow = 'key-value-table-row';
|
||||
const contractAddress = '7_value';
|
||||
const dialogCloseBtn = 'close-asset-details-dialog';
|
||||
const dialogCloseX = 'dialog-close';
|
||||
const dialogTitle = 'dialog-title';
|
||||
|
||||
const indicesWithLabelTooltips = [4, 5, 6, 7, 8, 9, 11, 12, 13, 14];
|
||||
const indicesWithValueTooltips = [1, 6];
|
||||
|
||||
const labelValueToolTipPairs = [
|
||||
{
|
||||
label: 'ID',
|
||||
value: 'asset-id',
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
value: 'ERC20',
|
||||
valueToolTip: 'An asset originated from an Ethereum ERC20 Token',
|
||||
},
|
||||
{
|
||||
label: 'Name',
|
||||
value: 'Euro',
|
||||
},
|
||||
{
|
||||
label: 'Symbol',
|
||||
value: 'tEURO',
|
||||
},
|
||||
{
|
||||
label: 'Decimals',
|
||||
value: '5',
|
||||
labelTooltip: 'Number of decimal / precision handled by this asset',
|
||||
},
|
||||
{
|
||||
label: 'Quantum',
|
||||
value: '0.00001',
|
||||
labelTooltip: 'The minimum economically meaningful amount of the asset',
|
||||
},
|
||||
{
|
||||
label: 'Status',
|
||||
value: 'Enabled',
|
||||
labelTooltip: 'The status of the asset in the Vega network',
|
||||
valueToolTip: 'Asset can be used on the Vega network',
|
||||
},
|
||||
{
|
||||
label: 'Contract address',
|
||||
value: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4 ',
|
||||
labelTooltip:
|
||||
'The address of the contract for the token, on the ethereum network',
|
||||
},
|
||||
{
|
||||
label: 'Withdrawal threshold',
|
||||
value: '0.0005',
|
||||
labelTooltip:
|
||||
"The maximum you can withdraw instantly. There's no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them",
|
||||
},
|
||||
{
|
||||
label: 'Lifetime limit',
|
||||
value: '1,230.00',
|
||||
labelTooltip:
|
||||
'The lifetime deposit limit per address. Note: this is a temporary measure that can be changed or removed through governance',
|
||||
},
|
||||
{ label: '', value: '' },
|
||||
{
|
||||
label: 'Infrastructure fee account balance',
|
||||
value: '0.00001',
|
||||
labelTooltip: 'The infrastructure fee account in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Global reward pool account balance',
|
||||
value: '0.00002',
|
||||
labelTooltip: 'The global rewards acquired in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Maker paid fees account balance',
|
||||
value: '0.00003',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the fees paid to makers in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Maker received fees account balance',
|
||||
value: '0.00004',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on fees received for being a maker on trades',
|
||||
},
|
||||
{
|
||||
label: 'Liquidity provision fee reward account balance',
|
||||
value: '0.00005',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the liquidity provision fees in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Market proposer reward account balance',
|
||||
value: '0.00006',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the market proposer reward in this asset',
|
||||
},
|
||||
];
|
||||
//endregion
|
||||
|
||||
beforeEach(() => {
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setVegaWallet();
|
||||
});
|
||||
|
||||
const visitPortfolioAndClickAsset = (assetName: string) => {
|
||||
cy.visit('/#/portfolio');
|
||||
cy.get(assetColId).contains(assetName).click();
|
||||
};
|
||||
|
||||
const testTooltip = (index: number, testId: string, tooltip: string) => {
|
||||
cy.getByTestId(`${index}_${testId}`).realHover();
|
||||
cy.get('[role="tooltip"]').find('div').should('have.text', tooltip);
|
||||
cy.getByTestId(dialogTitle).click();
|
||||
};
|
||||
|
||||
describe('assets', { tags: '@smoke', testIsolation: true }, () => {
|
||||
it('asset details', () => {
|
||||
visitPortfolioAndClickAsset('tBTC');
|
||||
|
||||
cy.getByTestId(assetRow).each((element, index) => {
|
||||
if (index === 10) {
|
||||
return;
|
||||
}
|
||||
const { label, value, labelTooltip, valueToolTip } =
|
||||
labelValueToolTipPairs[index];
|
||||
// 6501-ASSE-001
|
||||
// 6501-ASSE-002
|
||||
// 6501-ASSE-003
|
||||
// 6501-ASSE-004
|
||||
// 6501-ASSE-005
|
||||
// 6501-ASSE-006
|
||||
// 6501-ASSE-007
|
||||
// 6501-ASSE-008
|
||||
// 6501-ASSE-009
|
||||
// 6501-ASSE-010
|
||||
// 6501-ASSE-011
|
||||
cy.getByTestId(`${index}_label`).should('have.text', label);
|
||||
cy.getByTestId(`${index}_value`).should('have.text', value);
|
||||
|
||||
// 6501-ASSE-012
|
||||
if (indicesWithLabelTooltips.includes(index)) {
|
||||
if (labelTooltip) {
|
||||
testTooltip(index, 'label', labelTooltip);
|
||||
}
|
||||
}
|
||||
if (indicesWithValueTooltips.includes(index)) {
|
||||
if (valueToolTip) {
|
||||
testTooltip(index, 'value', valueToolTip);
|
||||
}
|
||||
}
|
||||
});
|
||||
// 6501-ASSE-013
|
||||
cy.getByTestId(dialogCloseX).click();
|
||||
cy.document().then((doc) => {
|
||||
expect(doc.querySelector(assetDetailsDialog)).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
it('ERC20 Contract address', () => {
|
||||
visitPortfolioAndClickAsset('tBTC');
|
||||
cy.getByTestId(contractAddress).within(() => {
|
||||
// 6501-ASSE-014
|
||||
cy.getByTestId('external-link')
|
||||
.should('have.attr', 'target', '_blank')
|
||||
.should('have.text', '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4');
|
||||
});
|
||||
// 6501-ASSE-013
|
||||
cy.getByTestId(dialogCloseBtn).click();
|
||||
cy.document().then((doc) => {
|
||||
expect(doc.querySelector(assetDetailsDialog)).to.not.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -104,11 +104,11 @@ describe('deposit actions', { tags: '@smoke' }, () => {
|
||||
cy.visit('/#/markets/market-1');
|
||||
});
|
||||
|
||||
it('Deposit to trade is visible', () => {
|
||||
it('Deposit to trade is visble', () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
cy.get('[row-id="asset-id"]').contains('tEURO').should('be.visible');
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit').should('be.visible');
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit').click();
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.getByTestId('deposit-submit').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const dialogContent = 'welcome-dialog';
|
||||
|
||||
const generateProposal = (code: string): ProposalListFieldsFragment => ({
|
||||
__typename: 'Proposal',
|
||||
reference: '',
|
||||
state: Schema.ProposalState.STATE_OPEN,
|
||||
datetime: '',
|
||||
votes: {
|
||||
__typename: undefined,
|
||||
yes: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
no: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
},
|
||||
requiredMajority: '',
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: '',
|
||||
},
|
||||
rationale: {
|
||||
__typename: 'ProposalRationale',
|
||||
description: '',
|
||||
title: '',
|
||||
},
|
||||
requiredParticipation: '',
|
||||
errorDetails: '',
|
||||
rejectionReason: null,
|
||||
requiredLpMajority: '',
|
||||
requiredLpParticipation: '',
|
||||
terms: {
|
||||
__typename: 'ProposalTerms',
|
||||
closingDatetime: '',
|
||||
enactmentDatetime: undefined,
|
||||
change: {
|
||||
__typename: 'NewMarket',
|
||||
decimalPlaces: 1,
|
||||
lpPriceRange: '',
|
||||
riskParameters: {
|
||||
__typename: 'SimpleRiskModel',
|
||||
params: {
|
||||
__typename: 'SimpleRiskModelParams',
|
||||
factorLong: 0,
|
||||
factorShort: 1,
|
||||
},
|
||||
},
|
||||
metadata: [],
|
||||
instrument: {
|
||||
__typename: 'InstrumentConfiguration',
|
||||
code: code,
|
||||
name: code,
|
||||
futureProduct: {
|
||||
__typename: 'FutureProduct',
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'A',
|
||||
name: 'A',
|
||||
symbol: 'A',
|
||||
decimals: 1,
|
||||
quantum: '',
|
||||
},
|
||||
quoteName: '',
|
||||
dataSourceSpecBinding: {
|
||||
__typename: 'DataSourceSpecToFutureBinding',
|
||||
settlementDataProperty: '',
|
||||
tradingTerminationProperty: '',
|
||||
},
|
||||
dataSourceSpecForSettlementData: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionInternal',
|
||||
},
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionInternal',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe('home', { tags: '@regression' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
});
|
||||
|
||||
describe('default market found', () => {
|
||||
it('redirects to a default market with the landing dialog open', () => {
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
|
||||
cy.get('[data-testid^="pathname-/markets/"]');
|
||||
|
||||
// the choose market overlay is no longer showing
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('no markets found', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
const data = {
|
||||
marketsConnection: {
|
||||
__typename: 'MarketConnection',
|
||||
edges: [],
|
||||
},
|
||||
};
|
||||
const proposalA: ProposalListFieldsFragment =
|
||||
generateProposal('AAAZZZ');
|
||||
|
||||
aliasGQLQuery(req, 'Markets', data);
|
||||
aliasGQLQuery(req, 'MarketsData', data);
|
||||
aliasGQLQuery(req, 'ProposalsList', {
|
||||
proposalsConnection: {
|
||||
__typename: 'ProposalsConnection',
|
||||
edges: [{ __typename: 'ProposalEdge', node: proposalA }],
|
||||
},
|
||||
});
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
});
|
||||
|
||||
it('close welcome dialog should redirect to market/all', () => {
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
cy.getByTestId('welcome-dialog').should('be.visible');
|
||||
cy.getByTestId('welcome-title').should('contain.text', 'Console CUSTOM');
|
||||
cy.getByTestId('browse-markets-button').should('not.be.disabled');
|
||||
cy.getByTestId('get-started-banner').should('be.visible');
|
||||
cy.getByTestId('get-started-button').should('not.be.disabled');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
cy.window().then((window) => {
|
||||
expect(window.localStorage.getItem('vega_onboarding_viewed')).to.equal(
|
||||
'true'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('click browse markets button should redirect to market/all', () => {
|
||||
cy.getByTestId('welcome-dialog').should('be.visible');
|
||||
cy.getByTestId('browse-markets-button').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
cy.window().then((window) => {
|
||||
expect(window.localStorage.getItem('vega_onboarding_viewed')).to.equal(
|
||||
'true'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('click get started button should open connect dialog', () => {
|
||||
cy.getByTestId('welcome-dialog').should('be.visible');
|
||||
cy.getByTestId('get-started-button').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
cy.window().then((window) => {
|
||||
expect(window.localStorage.getItem('vega_onboarding_viewed')).to.equal(
|
||||
'true'
|
||||
);
|
||||
});
|
||||
cy.getByTestId('wallet-dialog-title').should('contain.text', 'Connect');
|
||||
});
|
||||
});
|
||||
|
||||
describe('redirect should take last visited market into consideration', () => {
|
||||
it('marketId comes from existing market', () => {
|
||||
cy.window().then((window) => {
|
||||
window.localStorage.setItem('marketId', 'market-1');
|
||||
cy.visit('/');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.location('hash').should('equal', '#/markets/market-1');
|
||||
cy.getByTestId(dialogContent).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('marketId comes from not-existing market', () => {
|
||||
cy.window().then((window) => {
|
||||
window.localStorage.setItem('marketId', 'market-not-existing');
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'Market', null);
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.location('hash').should('equal', '#/markets/market-not-existing');
|
||||
cy.getByTestId(dialogContent).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import { marketsQuery } from '@vegaprotocol/mock';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
|
||||
describe('markets table', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage().then(() => {
|
||||
cy.mockTradingPage(
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
|
||||
);
|
||||
cy.mockSubscription();
|
||||
cy.setOnBoardingViewed();
|
||||
cy.visit('/#/markets/all');
|
||||
});
|
||||
});
|
||||
|
||||
it('opening auction subsets should be properly displayed', () => {
|
||||
cy.mockTradingPage(
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
||||
);
|
||||
cy.mockGQL((req) => {
|
||||
const override = {
|
||||
marketsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
name: `opening auction MARKET`,
|
||||
},
|
||||
},
|
||||
state: Schema.MarketState.STATE_ACTIVE,
|
||||
tradingMode:
|
||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
// @ts-ignore partial deep check failing
|
||||
const market = marketsQuery(override);
|
||||
aliasGQLQuery(req, 'Market', market);
|
||||
aliasGQLQuery(req, 'ProposalOfMarket', {
|
||||
proposal: { terms: { enactmentDatetime: '2023-01-31 12:00:01' } },
|
||||
});
|
||||
});
|
||||
cy.visit('#/markets/market-0');
|
||||
cy.url().should('contain', 'market-0');
|
||||
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||
cy.getByTestId('opening-auction-sub-status').should(
|
||||
'contain.text',
|
||||
'Opening auction: Not enough liquidity to open'
|
||||
);
|
||||
|
||||
const now = new Date(Date.parse('2023-01-30 12:00:01')).getTime();
|
||||
cy.clock(now, ['Date']); // Set "now" to BEFORE reservation
|
||||
cy.reload();
|
||||
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||
cy.getByTestId('opening-auction-sub-status').should(
|
||||
'contain.text',
|
||||
`Opening auction: Closing on ${getDateTimeFormat().format(
|
||||
new Date('2023-01-31 12:00:01')
|
||||
)}`
|
||||
);
|
||||
cy.clock().then((clock) => {
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -63,7 +63,6 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTC');
|
||||
cy.getByTestId(orderSizeField).clear().type('1');
|
||||
cy.getByTestId(orderPriceField).clear().type('1.123456');
|
||||
cy.getByTestId(placeOrderBtn).click();
|
||||
cy.getByTestId('deal-ticket-error-message-price-limit').should(
|
||||
'have.text',
|
||||
'Price accepts up to 5 decimal places'
|
||||
@@ -74,7 +73,6 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
|
||||
describe('market order', () => {
|
||||
before(() => {
|
||||
cy.getByTestId(toggleMarket).click();
|
||||
cy.getByTestId(placeOrderBtn).click();
|
||||
});
|
||||
|
||||
it('must not see the price unit', function () {
|
||||
|
||||
@@ -48,7 +48,6 @@ describe('suspended market validation', { tags: '@regression' }, () => {
|
||||
cy.getByTestId(orderPriceField).clear().type('0.1');
|
||||
cy.getByTestId(orderSizeField).clear().type('1');
|
||||
cy.getByTestId(placeOrderBtn).should('be.enabled');
|
||||
cy.getByTestId(placeOrderBtn).click();
|
||||
cy.getByTestId('deal-ticket-warning-auction').should(
|
||||
'have.text',
|
||||
'Any orders placed now will not trade until the auction ends'
|
||||
@@ -61,7 +60,6 @@ describe('suspended market validation', { tags: '@regression' }, () => {
|
||||
TIFlist.filter((item) => item.code === 'FOK')[0].value
|
||||
);
|
||||
cy.getByTestId(placeOrderBtn).should('be.enabled');
|
||||
cy.getByTestId(placeOrderBtn).click();
|
||||
cy.getByTestId('deal-ticket-error-message-tif').should(
|
||||
'have.text',
|
||||
'This market is in auction until it reaches sufficient liquidity. Until the auction ends, you can only place GFA, GTT, or GTC limit orders'
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('fills', { tags: '@regression' }, () => {
|
||||
cy.getByTestId(tabFills).contains('Market');
|
||||
cy.getByTestId(tabFills)
|
||||
.get(
|
||||
'[role="gridcell"][col-id="market.tradableInstrument.instrument.code"]'
|
||||
'[role="gridcell"][col-id="market.tradableInstrument.instrument.name"]'
|
||||
)
|
||||
.each(($marketSymbol) => {
|
||||
cy.wrap($marketSymbol).invoke('text').should('not.be.empty');
|
||||
|
||||
@@ -27,8 +27,7 @@ describe('positions', { tags: '@smoke', testIsolation: true }, () => {
|
||||
validatePositionsDisplayed();
|
||||
});
|
||||
|
||||
// TODO: move this to sim, its flakey
|
||||
it.skip('renders positions on portfolio page', () => {
|
||||
it('renders positions on portfolio page', () => {
|
||||
cy.mockGQL((req) => {
|
||||
const positions = positionsQuery();
|
||||
if (positions.positions?.edges) {
|
||||
@@ -143,22 +142,22 @@ describe('positions', { tags: '@regression', testIsolation: true }, () => {
|
||||
it('sorting by Market', () => {
|
||||
visitAndClickPositions();
|
||||
const marketsSortedDefault = [
|
||||
'AAPL.MF21',
|
||||
'BTCUSD.MF21',
|
||||
'ETHBTC.QM21',
|
||||
'SOLUSD',
|
||||
'ACTIVE MARKET',
|
||||
'Apple Monthly (30 Jun 2022)',
|
||||
'ETHBTC Quarterly (30 Jun 2022)',
|
||||
'SUSPENDED MARKET',
|
||||
];
|
||||
const marketsSortedAsc = [
|
||||
'AAPL.MF21',
|
||||
'BTCUSD.MF21',
|
||||
'ETHBTC.QM21',
|
||||
'SOLUSD',
|
||||
'ACTIVE MARKET',
|
||||
'Apple Monthly (30 Jun 2022)',
|
||||
'ETHBTC Quarterly (30 Jun 2022)',
|
||||
'SUSPENDED MARKET',
|
||||
];
|
||||
const marketsSortedDesc = [
|
||||
'SOLUSD',
|
||||
'ETHBTC.QM21',
|
||||
'BTCUSD.MF21',
|
||||
'AAPL.MF21',
|
||||
'SUSPENDED MARKET',
|
||||
'ETHBTC Quarterly (30 Jun 2022)',
|
||||
'Apple Monthly (30 Jun 2022)',
|
||||
'ACTIVE MARKET',
|
||||
];
|
||||
cy.getByTestId(positions).click();
|
||||
// 7004-POSI-003
|
||||
@@ -231,7 +230,7 @@ describe('positions', { tags: '@regression', testIsolation: true }, () => {
|
||||
deltaX: 500,
|
||||
});
|
||||
// 7004-POSI-004
|
||||
cy.get('[col-id="unrealisedPNL"]').should('be.visible');
|
||||
cy.get('[col-id="updatedAt"]').should('be.visible');
|
||||
});
|
||||
|
||||
it('Drag and drop columns', () => {
|
||||
@@ -292,11 +291,9 @@ describe('positions', { tags: '@regression', testIsolation: true }, () => {
|
||||
|
||||
it('View settlement asset', () => {
|
||||
visitAndClickPositions();
|
||||
cy.get('[col-id="asset"]')
|
||||
.eq(3)
|
||||
.within(() => {
|
||||
cy.get('button[type="button"]').click();
|
||||
});
|
||||
cy.get('[col-id="asset"]').within(() => {
|
||||
cy.get('button[type="button"]').first().click();
|
||||
});
|
||||
// 7004-POSI-008
|
||||
cy.getByTestId(dialogContent).should('be.visible');
|
||||
cy.getByTestId(dialogCloseX).click();
|
||||
@@ -311,7 +308,7 @@ function validatePositionsDisplayed(multiKey = false) {
|
||||
cy.getByTestId('tab-positions').should('be.visible');
|
||||
cy.getByTestId('tab-positions')
|
||||
.get('.ag-center-cols-container .ag-row')
|
||||
.eq(multiKey ? 3 : 1)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get('[col-id="marketName"]')
|
||||
.should('be.visible')
|
||||
|
||||
@@ -59,7 +59,8 @@ describe('trades', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(tradesTable) // order table shares identical col id
|
||||
.find(`${colIdCreatedAt} ${colHeader}`)
|
||||
.should('have.text', 'Created at');
|
||||
const dateTimeRegex = /(\d{1,2}):(\d{1,2}):(\d{1,2})/gm;
|
||||
const dateTimeRegex =
|
||||
/(\d{1,2})\/(\d{1,2})\/(\d{4}), (\d{1,2}):(\d{1,2}):(\d{1,2})/gm;
|
||||
cy.getByTestId(tradesTable)
|
||||
.get(`.ag-center-cols-container ${colIdCreatedAt}`)
|
||||
.each(($tradeDateTime) => {
|
||||
@@ -86,7 +87,6 @@ describe('trades', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('copy price to deal ticket form', () => {
|
||||
cy.getByTestId('Order').click();
|
||||
// 6005-THIS-007
|
||||
cy.get(colIdPrice).last().should('be.visible').click();
|
||||
cy.getByTestId('order-price').should('have.value', '171.16898');
|
||||
|
||||
@@ -5,8 +5,118 @@ import {
|
||||
|
||||
const connectVegaBtn = 'connect-vega-wallet';
|
||||
const manageVegaBtn = 'manage-vega-wallet';
|
||||
const form = 'rest-connector-form';
|
||||
const dialogContent = 'dialog-content';
|
||||
|
||||
describe(
|
||||
'connect hosted wallet',
|
||||
{ tags: '@smoke', testIsolation: true },
|
||||
() => {
|
||||
beforeEach(() => {
|
||||
// Using portfolio page as it requires vega wallet connection
|
||||
cy.visit('/#/portfolio');
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setOnBoardingViewed();
|
||||
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
||||
});
|
||||
|
||||
it('can connect', () => {
|
||||
// 0002-WCON-002
|
||||
// 0002-WCON-003
|
||||
// 0002-WCON-039
|
||||
// 0002-WCON-017
|
||||
// 0002-WCON-018
|
||||
// 0002-WCON-019
|
||||
|
||||
// Mock authentication
|
||||
cy.intercept(
|
||||
'POST',
|
||||
'https://wallet.testnet.vega.xyz/api/v1/auth/token',
|
||||
{
|
||||
body: {
|
||||
token: 'test-token',
|
||||
},
|
||||
}
|
||||
);
|
||||
// Mock getting keys from wallet
|
||||
cy.intercept('GET', 'https://wallet.testnet.vega.xyz/api/v1/keys', {
|
||||
body: {
|
||||
keys: [
|
||||
{
|
||||
algorithm: {
|
||||
name: 'algo',
|
||||
version: 1,
|
||||
},
|
||||
index: 0,
|
||||
meta: [],
|
||||
pub: 'HOSTED_PUBKEY',
|
||||
tainted: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
cy.getByTestId(connectVegaBtn).click();
|
||||
cy.contains(
|
||||
'Choose wallet app to connect, or to change port or server URL enter a custom wallet location first'
|
||||
);
|
||||
cy.contains('Connect Vega wallet');
|
||||
cy.contains('Hosted Fairground wallet');
|
||||
|
||||
cy.getByTestId('connectors-list')
|
||||
.find('[data-testid="connector-rest"]')
|
||||
.click();
|
||||
cy.getByTestId(form).find('#wallet').click().type('user');
|
||||
cy.getByTestId(form).find('#passphrase').click().type('pass');
|
||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
||||
cy.getByTestId(manageVegaBtn).should('exist');
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('keypair-list').should('exist');
|
||||
});
|
||||
|
||||
it('doesnt connect with invalid credentials', () => {
|
||||
// 0002-WCON-020
|
||||
|
||||
// Mock incorrect username/password
|
||||
cy.intercept(
|
||||
'POST',
|
||||
'https://wallet.testnet.vega.xyz/api/v1/auth/token',
|
||||
{
|
||||
body: {
|
||||
error: 'No wallet',
|
||||
},
|
||||
statusCode: 403, // 403 forbidden invalid crednetials
|
||||
}
|
||||
);
|
||||
cy.getByTestId(connectVegaBtn).click();
|
||||
cy.getByTestId('connectors-list')
|
||||
.find('[data-testid="connector-rest"]')
|
||||
.click();
|
||||
cy.getByTestId(form).find('#wallet').click().type('invalid name');
|
||||
cy.getByTestId(form).find('#passphrase').click().type('invalid password');
|
||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
||||
cy.getByTestId('form-error').should('have.text', 'Invalid credentials');
|
||||
});
|
||||
|
||||
it('doesnt connect with empty fields', () => {
|
||||
cy.getByTestId(connectVegaBtn).click();
|
||||
cy.getByTestId('connectors-list')
|
||||
.find('[data-testid="connector-rest"]')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
||||
cy.getByTestId(form)
|
||||
.find('#wallet')
|
||||
.next('[data-testid="input-error-text"]')
|
||||
.should('have.text', 'Required');
|
||||
cy.getByTestId(form)
|
||||
.find('#passphrase')
|
||||
.next('[data-testid="input-error-text"]')
|
||||
.should('have.text', 'Required');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe('connect vega wallet', { tags: '@smoke', testIsolation: true }, () => {
|
||||
beforeEach(() => {
|
||||
// Using portfolio page as it requires vega wallet connection
|
||||
@@ -86,6 +196,8 @@ describe('connect vega wallet', { tags: '@smoke', testIsolation: true }, () => {
|
||||
cy.getByTestId('connect-vega-wallet').should('exist');
|
||||
cy.getByTestId('manage-vega-wallet').should('not.exist');
|
||||
cy.getByTestId('connect-vega-wallet').click();
|
||||
cy.contains('Enter a custom wallet location');
|
||||
cy.contains(
|
||||
'Choose wallet app to connect, or to change port or server URL enter a custom wallet location first'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,108 +12,100 @@ const walletTransfer = 'wallet-transfer';
|
||||
|
||||
const ASSET_SEPOLIA_TBTC = 2;
|
||||
|
||||
describe.skip(
|
||||
'transfer fees',
|
||||
{ tags: '@regression', testIsolation: true },
|
||||
() => {
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setVegaWallet();
|
||||
describe('transfer fees', { tags: '@regression', testIsolation: true }, () => {
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setVegaWallet();
|
||||
|
||||
cy.visit('/');
|
||||
cy.getByTestId(manageVegaWallet).click();
|
||||
cy.getByTestId(walletTransfer).click();
|
||||
cy.visit('/');
|
||||
cy.getByTestId(manageVegaWallet).click();
|
||||
cy.getByTestId(walletTransfer).click();
|
||||
|
||||
cy.wait('@Assets');
|
||||
cy.wait('@Accounts');
|
||||
cy.wait('@Assets');
|
||||
cy.wait('@Accounts');
|
||||
|
||||
cy.mockVegaWalletTransaction();
|
||||
});
|
||||
cy.mockVegaWalletTransaction();
|
||||
});
|
||||
|
||||
it('transfer fees tooltips', () => {
|
||||
// 1003-TRAN-015
|
||||
// 1003-TRAN-016
|
||||
// 1003-TRAN-017
|
||||
// 1003-TRAN-018
|
||||
// 1003-TRAN-019
|
||||
cy.getByTestId(transferForm);
|
||||
cy.contains('Enter manually').click();
|
||||
cy.getByTestId(transferForm)
|
||||
.find(toAddressField)
|
||||
.type(
|
||||
'7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535'
|
||||
);
|
||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||
cy.getByTestId(transferForm)
|
||||
.find(amountField)
|
||||
.type('1', { delay: 100, force: true });
|
||||
it('transfer fees tooltips', () => {
|
||||
// 1003-TRAN-015
|
||||
// 1003-TRAN-016
|
||||
// 1003-TRAN-017
|
||||
// 1003-TRAN-018
|
||||
// 1003-TRAN-019
|
||||
cy.getByTestId(transferForm);
|
||||
cy.contains('Enter manually').click();
|
||||
cy.getByTestId(transferForm)
|
||||
.find(toAddressField)
|
||||
.type('7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535');
|
||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||
cy.getByTestId(transferForm)
|
||||
.find(amountField)
|
||||
.type('1', { delay: 100, force: true });
|
||||
|
||||
/// Check Include Transfer Fee tooltip
|
||||
cy.get('label[for="include-transfer-fee"] div').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
/// Check Include Transfer Fee tooltip
|
||||
cy.get('label[for="include-transfer-fee"] div').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
|
||||
//Check Transfer Fee tooltip
|
||||
cy.contains('div', 'Transfer fee').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
//Check Transfer Fee tooltip
|
||||
cy.contains('div', 'Transfer fee').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
|
||||
//Check Amount to be transferred tooltip
|
||||
cy.contains('div', 'Amount to be transferred').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
//Check Amount to be transferred tooltip
|
||||
cy.contains('div', 'Amount to be transferred').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
|
||||
//Check Total amount (with fee) tooltip
|
||||
cy.contains('div', 'Total amount (with fee)').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
//Check Total amount (with fee) tooltip
|
||||
cy.contains('div', 'Total amount (with fee)').realHover();
|
||||
cy.get('[data-side="bottom"] div')
|
||||
.should('be.visible')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
|
||||
it('transfer fees', () => {
|
||||
// 1003-TRAN-020
|
||||
// 1003-TRAN-021
|
||||
// 1003-TRAN-022
|
||||
// 1003-TRAN-023
|
||||
cy.getByTestId(transferForm);
|
||||
cy.contains('Enter manually').click();
|
||||
it('transfer fees', () => {
|
||||
// 1003-TRAN-020
|
||||
// 1003-TRAN-021
|
||||
// 1003-TRAN-022
|
||||
// 1003-TRAN-023
|
||||
cy.getByTestId(transferForm);
|
||||
cy.contains('Enter manually').click();
|
||||
|
||||
cy.getByTestId(transferForm)
|
||||
.find(toAddressField)
|
||||
.type(
|
||||
'7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535'
|
||||
);
|
||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||
cy.getByTestId(includeTransferFeeRadioBtn).should('be.disabled');
|
||||
cy.getByTestId(transferForm)
|
||||
.find(toAddressField)
|
||||
.type('7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535');
|
||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||
cy.getByTestId(includeTransferFeeRadioBtn).should('be.disabled');
|
||||
|
||||
cy.getByTestId(transferForm)
|
||||
.find(amountField)
|
||||
.type('1', { delay: 100, force: true });
|
||||
cy.getByTestId(transferForm)
|
||||
.find(amountField)
|
||||
.type('1', { delay: 100, force: true });
|
||||
|
||||
cy.getByTestId(transferFee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.01');
|
||||
cy.getByTestId(transferAmount)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.00');
|
||||
cy.getByTestId(totalTransferfee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.01');
|
||||
cy.getByTestId(includeTransferFeeRadioBtn).click();
|
||||
cy.getByTestId(transferFee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.01');
|
||||
cy.getByTestId(transferAmount)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.99');
|
||||
cy.getByTestId(totalTransferfee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.00');
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.getByTestId(transferFee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.01');
|
||||
cy.getByTestId(transferAmount)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.00');
|
||||
cy.getByTestId(totalTransferfee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.01');
|
||||
cy.getByTestId(includeTransferFeeRadioBtn).click();
|
||||
cy.getByTestId(transferFee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.01');
|
||||
cy.getByTestId(transferAmount)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '0.99');
|
||||
cy.getByTestId(totalTransferfee)
|
||||
.should('be.visible')
|
||||
.should('contain.text', '1.00');
|
||||
});
|
||||
});
|
||||
|
||||
+2
-3
@@ -1,3 +1,4 @@
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
@@ -12,11 +13,9 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_STOP_ORDERS=true
|
||||
# NX_ICEBERG_ORDERS
|
||||
# NX_PRODUCT_PERPETUALS
|
||||
# NX_PRODUCT_PERPETUALS
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1 +0,0 @@
|
||||
window._env_ = {};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 547 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"short_name": "Mainnet Stats",
|
||||
"name": "Vega Mainnet statistics",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -10,6 +10,7 @@ import { TradeGrid } from './trade-grid';
|
||||
import { TradePanels } from './trade-panels';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||
|
||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||
@@ -64,6 +65,8 @@ export const MarketPage = () => {
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const lastMarketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
const onSelect = useMarketClickHandler();
|
||||
|
||||
const { data, error, loading } = useMarket(marketId);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -84,6 +87,7 @@ export const MarketPage = () => {
|
||||
return (
|
||||
<TradeGrid
|
||||
market={data}
|
||||
onSelect={onSelect}
|
||||
pinnedAsset={
|
||||
data?.tradableInstrument.instrument.product.settlementAsset
|
||||
}
|
||||
@@ -93,12 +97,11 @@ export const MarketPage = () => {
|
||||
return (
|
||||
<TradePanels
|
||||
market={data}
|
||||
pinnedAsset={
|
||||
data?.tradableInstrument.instrument.product.settlementAsset
|
||||
}
|
||||
onSelect={onSelect}
|
||||
onClickCollateral={() => navigate('/portfolio')}
|
||||
/>
|
||||
);
|
||||
}, [largeScreen, data]);
|
||||
}, [largeScreen, data, onSelect, navigate]);
|
||||
|
||||
if (!data && marketId) {
|
||||
return (
|
||||
|
||||
@@ -9,6 +9,7 @@ import { OracleBanner } from '@vegaprotocol/markets';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import { Filter } from '@vegaprotocol/orders';
|
||||
import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
import {
|
||||
ResizableGrid,
|
||||
ResizableGridPanel,
|
||||
@@ -23,6 +24,7 @@ import { FLAGS } from '@vegaprotocol/environment';
|
||||
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
@@ -38,19 +40,20 @@ const MainGrid = memo(
|
||||
const [sizesMiddle, handleOnMiddleLayoutChange] = usePaneLayout({
|
||||
id: 'middle-1',
|
||||
});
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
|
||||
return (
|
||||
<ResizableGrid vertical onChange={handleOnLayoutChange}>
|
||||
<ResizableGridPanel
|
||||
preferredSize={sizes[0]}
|
||||
priority={LayoutPriority.High}
|
||||
minSize={200}
|
||||
>
|
||||
<ResizableGrid onChange={handleOnMiddleLayoutChange}>
|
||||
<ResizableGridPanel minSize={75} priority={LayoutPriority.High}>
|
||||
<ResizableGrid
|
||||
proportionalLayout={false}
|
||||
minSize={200}
|
||||
onChange={handleOnMiddleLayoutChange}
|
||||
>
|
||||
<ResizableGridPanel
|
||||
priority={LayoutPriority.High}
|
||||
minSize={200}
|
||||
preferredSize={sizesMiddle[0] || '75%'}
|
||||
preferredSize={sizesMiddle[1] || '50%'}
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-main-left">
|
||||
@@ -71,8 +74,8 @@ const MainGrid = memo(
|
||||
</TradeGridChild>
|
||||
</ResizableGridPanel>
|
||||
<ResizableGridPanel
|
||||
preferredSize={sizesMiddle[2] || 300}
|
||||
minSize={200}
|
||||
preferredSize={sizesMiddle[1] || 300}
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-main-right">
|
||||
@@ -88,34 +91,37 @@ const MainGrid = memo(
|
||||
</ResizableGrid>
|
||||
</ResizableGridPanel>
|
||||
<ResizableGridPanel
|
||||
priority={LayoutPriority.Low}
|
||||
preferredSize={sizes[1] || '25%'}
|
||||
minSize={50}
|
||||
priority={LayoutPriority.Low}
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-bottom">
|
||||
<Tab id="positions" name={t('Positions')}>
|
||||
<TradingViews.positions.component />
|
||||
<TradingViews.positions.component
|
||||
onMarketClick={onMarketClick}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="open-orders"
|
||||
name={t('Open')}
|
||||
menu={<TradingViews.activeOrders.menu marketId={marketId} />}
|
||||
>
|
||||
<TradingViews.orders.component filter={Filter.Open} />
|
||||
<Tab id="open-orders" name={t('Open')}>
|
||||
<TradingViews.orders.component
|
||||
marketId={marketId}
|
||||
filter={Filter.Open}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab id="closed-orders" name={t('Closed')}>
|
||||
<TradingViews.orders.component filter={Filter.Closed} />
|
||||
<TradingViews.orders.component
|
||||
marketId={marketId}
|
||||
filter={Filter.Closed}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab id="rejected-orders" name={t('Rejected')}>
|
||||
<TradingViews.orders.component filter={Filter.Rejected} />
|
||||
<TradingViews.orders.component
|
||||
marketId={marketId}
|
||||
filter={Filter.Rejected}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="orders"
|
||||
name={t('All')}
|
||||
menu={<TradingViews.orders.menu marketId={marketId} />}
|
||||
>
|
||||
<TradingViews.orders.component />
|
||||
<Tab id="orders" name={t('All')}>
|
||||
<TradingViews.orders.component marketId={marketId} />
|
||||
</Tab>
|
||||
{FLAGS.STOP_ORDERS ? (
|
||||
<Tab id="stop-orders" name={t('Stop orders')}>
|
||||
@@ -123,14 +129,17 @@ const MainGrid = memo(
|
||||
</Tab>
|
||||
) : null}
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
<TradingViews.fills.component marketId={marketId} />
|
||||
<TradingViews.fills.component
|
||||
marketId={marketId}
|
||||
onMarketClick={onMarketClick}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="accounts"
|
||||
name={t('Collateral')}
|
||||
menu={<TradingViews.collateral.menu />}
|
||||
>
|
||||
<TradingViews.collateral.component pinnedAsset={pinnedAsset} />
|
||||
<Tab id="accounts" name={t('Collateral')}>
|
||||
<TradingViews.collateral.component
|
||||
pinnedAsset={pinnedAsset}
|
||||
onMarketClick={onMarketClick}
|
||||
hideButtons
|
||||
/>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import type { PinnedAsset } from '@vegaprotocol/accounts';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import { OracleBanner } from '@vegaprotocol/markets';
|
||||
import {
|
||||
useMarketClickHandler,
|
||||
useMarketLiquidityClickHandler,
|
||||
} from '../../lib/hooks/use-market-click-handler';
|
||||
import type { TradingView } from './trade-views';
|
||||
import { TradingViews } from './trade-views';
|
||||
import { useState } from 'react';
|
||||
import { memo, useState } from 'react';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { NO_MARKET } from './constants';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
@@ -16,14 +20,33 @@ import { FLAGS } from '@vegaprotocol/environment';
|
||||
|
||||
interface TradePanelsProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onOrderTypeClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
export const TradePanels = ({
|
||||
market,
|
||||
onSelect,
|
||||
onClickCollateral,
|
||||
pinnedAsset,
|
||||
}: TradePanelsProps) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||
|
||||
const [view, setView] = useState<TradingView>('candles');
|
||||
|
||||
const renderView = () => {
|
||||
const Component = TradingViews[view].component;
|
||||
const Component = memo<{
|
||||
marketId: string;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onOrderTypeClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}>(TradingViews[view].component);
|
||||
|
||||
if (!Component) {
|
||||
throw new Error(`No component for view: ${view}`);
|
||||
@@ -31,7 +54,16 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
|
||||
if (!market) return <Splash>{NO_MARKET}</Splash>;
|
||||
|
||||
return <Component marketId={market?.id} pinnedAsset={pinnedAsset} />;
|
||||
return (
|
||||
<Component
|
||||
marketId={market?.id}
|
||||
onSelect={onSelect}
|
||||
onClickCollateral={onClickCollateral}
|
||||
pinnedAsset={pinnedAsset}
|
||||
onMarketClick={onMarketClick}
|
||||
onOrderTypeClick={onOrderTypeClick}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const renderMenu = () => {
|
||||
@@ -39,10 +71,9 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
|
||||
if ('menu' in viewCfg) {
|
||||
const Menu = viewCfg.menu;
|
||||
|
||||
return (
|
||||
<div className="flex gap-1 p-1 bg-vega-clight-800 dark:bg-vega-cdark-800 border-b border-default">
|
||||
<Menu marketId={market?.id || ''} />
|
||||
<Menu />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { TradesContainer } from '@vegaprotocol/trades';
|
||||
import { DepthChartContainer } from '@vegaprotocol/market-depth';
|
||||
import {
|
||||
CandlesChartContainer,
|
||||
CandlesMenu,
|
||||
} from '@vegaprotocol/candles-chart';
|
||||
import { Filter, OpenOrdersMenu } from '@vegaprotocol/orders';
|
||||
import { Filter } from '@vegaprotocol/orders';
|
||||
import { NO_MARKET } from './constants';
|
||||
import { TradesContainer } from '../../components/trades-container';
|
||||
import { OrderbookContainer } from '../../components/orderbook-container';
|
||||
import { FillsContainer } from '../../components/fills-container';
|
||||
import { PositionsContainer } from '../../components/positions-container';
|
||||
@@ -16,7 +16,6 @@ import { LiquidityContainer } from '../../components/liquidity-container';
|
||||
import type { OrderContainerProps } from '../../components/orders-container';
|
||||
import { OrdersContainer } from '../../components/orders-container';
|
||||
import { StopOrdersContainer } from '../../components/stop-orders-container';
|
||||
import { AccountsMenu } from '../../components/accounts-menu';
|
||||
|
||||
type MarketDependantView =
|
||||
| typeof CandlesChartContainer
|
||||
@@ -63,7 +62,6 @@ export const TradingViews = {
|
||||
component: (props: OrderContainerProps) => (
|
||||
<OrdersContainer {...props} filter={Filter.Open} />
|
||||
),
|
||||
menu: OpenOrdersMenu,
|
||||
},
|
||||
closedOrders: {
|
||||
label: 'Closed',
|
||||
@@ -80,16 +78,11 @@ export const TradingViews = {
|
||||
orders: {
|
||||
label: 'All',
|
||||
component: OrdersContainer,
|
||||
menu: OpenOrdersMenu,
|
||||
},
|
||||
stopOrders: {
|
||||
label: 'Stop',
|
||||
component: StopOrdersContainer,
|
||||
},
|
||||
collateral: {
|
||||
label: 'Collateral',
|
||||
component: AccountsContainer,
|
||||
menu: AccountsMenu,
|
||||
},
|
||||
collateral: { label: 'Collateral', component: AccountsContainer },
|
||||
fills: { label: 'Fills', component: FillsContainer },
|
||||
};
|
||||
|
||||
@@ -411,26 +411,24 @@ describe('Closed', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
await act(() => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<MockedProvider
|
||||
mocks={[
|
||||
mixedMarketsMock,
|
||||
marketsDataMock,
|
||||
oracleDataMock,
|
||||
successorMarketsMock,
|
||||
]}
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<MockedProvider
|
||||
mocks={[
|
||||
mixedMarketsMock,
|
||||
marketsDataMock,
|
||||
oracleDataMock,
|
||||
successorMarketsMock,
|
||||
]}
|
||||
>
|
||||
<VegaWalletContext.Provider
|
||||
value={{ pubKey } as VegaWalletContextShape}
|
||||
>
|
||||
<VegaWalletContext.Provider
|
||||
value={{ pubKey } as VegaWalletContextShape}
|
||||
>
|
||||
<Closed />
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
<Closed />
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
|
||||
@@ -276,9 +276,15 @@ const ClosedMarketsDataGrid = ({
|
||||
|
||||
return (
|
||||
<AgGrid
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
rowData={rowData}
|
||||
columnDefs={colDefs}
|
||||
getRowId={({ data }) => data.id}
|
||||
defaultColDef={{
|
||||
resizable: true,
|
||||
minWidth: 100,
|
||||
flex: 1,
|
||||
}}
|
||||
components={{ SuccessorMarketRenderer }}
|
||||
overlayNoRowsTemplate={error ? error.message : t('No markets')}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { DepositsTable } from '@vegaprotocol/deposits';
|
||||
import { depositsProvider } from '@vegaprotocol/deposits';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useSidebar, ViewType } from '../../components/sidebar';
|
||||
|
||||
export const DepositsContainer = () => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: depositsProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
}
|
||||
return (
|
||||
<div className="h-full">
|
||||
<DepositsTable
|
||||
rowData={data}
|
||||
overlayNoRowsTemplate={error ? error.message : t('No deposits')}
|
||||
/>
|
||||
{!isReadOnly && (
|
||||
<div className="h-auto flex justify-end p-2 bottom-0 right-0 absolute dark:bg-black/75 bg-white/75 rounded">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => setView({ type: ViewType.Deposit })}
|
||||
data-testid="deposit-button"
|
||||
>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -6,11 +6,12 @@ import { t } from '@vegaprotocol/i18n';
|
||||
import { useIncompleteWithdrawals } from '@vegaprotocol/withdraws';
|
||||
import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit';
|
||||
import { usePageTitleStore } from '../../stores';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
import { AccountsContainer } from '../../components/accounts-container';
|
||||
import { DepositsContainer } from '../../components/deposits-container';
|
||||
import { DepositsContainer } from './deposits-container';
|
||||
import { FillsContainer } from '../../components/fills-container';
|
||||
import { PositionsContainer } from '../../components/positions-container';
|
||||
import { WithdrawalsContainer } from '../../components/withdrawals-container';
|
||||
import { WithdrawalsContainer } from './withdrawals-container';
|
||||
import { OrdersContainer } from '../../components/orders-container';
|
||||
import { LedgerContainer } from '../../components/ledger-container';
|
||||
import { AccountHistoryContainer } from './account-history-container';
|
||||
@@ -20,9 +21,6 @@ import {
|
||||
usePaneLayout,
|
||||
} from '../../components/resizable-grid';
|
||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||
import { AccountsMenu } from '../../components/accounts-menu';
|
||||
import { DepositsMenu } from '../../components/deposits-menu';
|
||||
import { WithdrawalsMenu } from '../../components/withdrawals-menu';
|
||||
|
||||
const WithdrawalsIndicator = () => {
|
||||
const { ready } = useIncompleteWithdrawals();
|
||||
@@ -53,6 +51,7 @@ export const Portfolio = () => {
|
||||
}
|
||||
}, [init, view, setView]);
|
||||
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'portfolio' });
|
||||
const wrapperClasses = 'p-0.5 h-full max-h-full flex flex-col';
|
||||
return (
|
||||
@@ -65,13 +64,13 @@ export const Portfolio = () => {
|
||||
<AccountHistoryContainer />
|
||||
</Tab>
|
||||
<Tab id="positions" name={t('Positions')}>
|
||||
<PositionsContainer allKeys />
|
||||
<PositionsContainer onMarketClick={onMarketClick} allKeys />
|
||||
</Tab>
|
||||
<Tab id="orders" name={t('Orders')}>
|
||||
<OrdersContainer />
|
||||
</Tab>
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
<FillsContainer />
|
||||
<FillsContainer onMarketClick={onMarketClick} />
|
||||
</Tab>
|
||||
<Tab id="ledger-entries" name={t('Ledger entries')}>
|
||||
<LedgerContainer />
|
||||
@@ -86,21 +85,16 @@ export const Portfolio = () => {
|
||||
>
|
||||
<PortfolioGridChild>
|
||||
<Tabs storageKey="console-portfolio-bottom">
|
||||
<Tab
|
||||
id="collateral"
|
||||
name={t('Collateral')}
|
||||
menu={<AccountsMenu />}
|
||||
>
|
||||
<Tab id="collateral" name={t('Collateral')}>
|
||||
<AccountsContainer />
|
||||
</Tab>
|
||||
<Tab id="deposits" name={t('Deposits')} menu={<DepositsMenu />}>
|
||||
<Tab id="deposits" name={t('Deposits')}>
|
||||
<DepositsContainer />
|
||||
</Tab>
|
||||
<Tab
|
||||
id="withdrawals"
|
||||
name={t('Withdrawals')}
|
||||
indicator={<WithdrawalsIndicator />}
|
||||
menu={<WithdrawalsMenu />}
|
||||
>
|
||||
<WithdrawalsContainer />
|
||||
</Tab>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
withdrawalProvider,
|
||||
WithdrawalsTable,
|
||||
useIncompleteWithdrawals,
|
||||
} from '@vegaprotocol/withdraws';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||
|
||||
export const WithdrawalsContainer = () => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: withdrawalProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
const { ready, delayed } = useIncompleteWithdrawals();
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="h-full relative">
|
||||
<WithdrawalsTable
|
||||
data-testid="withdrawals-history"
|
||||
rowData={data}
|
||||
overlayNoRowsTemplate={error ? error.message : t('No withdrawals')}
|
||||
ready={ready}
|
||||
delayed={delayed}
|
||||
/>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
<div className="h-auto flex justify-end p-2 bottom-0 right-0 absolute dark:bg-black/75 bg-white/75 rounded">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => setView({ type: ViewType.Withdraw })}
|
||||
data-testid="withdraw-dialog-button"
|
||||
>
|
||||
{t('Make withdrawal')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback } from 'react';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
@@ -11,14 +12,16 @@ import { useDataGridEvents } from '@vegaprotocol/datagrid';
|
||||
import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const AccountsContainer = ({
|
||||
pinnedAsset,
|
||||
hideButtons,
|
||||
onMarketClick,
|
||||
}: {
|
||||
pinnedAsset?: PinnedAsset;
|
||||
hideButtons?: boolean;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
}) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
@@ -45,23 +48,44 @@ export const AccountsContainer = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountManager
|
||||
partyId={pubKey}
|
||||
onClickAsset={onClickAsset}
|
||||
onClickWithdraw={(assetId) => {
|
||||
setView({ type: ViewType.Withdraw, assetId });
|
||||
}}
|
||||
onClickDeposit={(assetId) => {
|
||||
setView({ type: ViewType.Deposit, assetId });
|
||||
}}
|
||||
onClickTransfer={(assetId) => {
|
||||
setView({ type: ViewType.Transfer, assetId });
|
||||
}}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
pinnedAsset={pinnedAsset}
|
||||
gridProps={gridStoreCallbacks}
|
||||
/>
|
||||
<div className="h-full relative">
|
||||
<AccountManager
|
||||
partyId={pubKey}
|
||||
onClickAsset={onClickAsset}
|
||||
onClickWithdraw={(assetId) => {
|
||||
setView({ type: ViewType.Withdraw, assetId });
|
||||
}}
|
||||
onClickDeposit={(assetId) => {
|
||||
setView({ type: ViewType.Deposit, assetId });
|
||||
}}
|
||||
onClickTransfer={(assetId) => {
|
||||
setView({ type: ViewType.Transfer, assetId });
|
||||
}}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
pinnedAsset={pinnedAsset}
|
||||
gridProps={gridStoreCallbacks}
|
||||
/>
|
||||
{!isReadOnly && !hideButtons && (
|
||||
<div className="flex gap-2 justify-end p-2 absolute bottom-0 right-0 dark:bg-black/75 bg-white/75 rounded">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
data-testid="open-transfer"
|
||||
onClick={() => setView({ type: ViewType.Transfer })}
|
||||
>
|
||||
{t('Transfer')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => setView({ type: ViewType.Deposit })}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
|
||||
export const AccountsMenu = () => {
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
size="extra-small"
|
||||
data-testid="open-transfer"
|
||||
onClick={() => setView({ type: ViewType.Transfer })}
|
||||
>
|
||||
{t('Transfer')}
|
||||
</TradingButton>
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
size="extra-small"
|
||||
onClick={() => setView({ type: ViewType.Deposit })}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</TradingButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './accounts-menu';
|
||||
@@ -1,24 +0,0 @@
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { DepositsTable } from '@vegaprotocol/deposits';
|
||||
import { depositsProvider } from '@vegaprotocol/deposits';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export const DepositsContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: depositsProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
}
|
||||
return (
|
||||
<DepositsTable
|
||||
rowData={data}
|
||||
overlayNoRowsTemplate={error ? error.message : t('No deposits')}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './deposits-container';
|
||||
@@ -1,18 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
|
||||
export const DepositsMenu = () => {
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
|
||||
return (
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
size="extra-small"
|
||||
onClick={() => setView({ type: ViewType.Deposit })}
|
||||
data-testid="deposit-button"
|
||||
>
|
||||
{t('Deposit')}
|
||||
</TradingButton>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './deposits-menu';
|
||||
@@ -7,10 +7,14 @@ import { t } from '@vegaprotocol/i18n';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const FillsContainer = ({ marketId }: { marketId?: string }) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
export const FillsContainer = ({
|
||||
marketId,
|
||||
onMarketClick,
|
||||
}: {
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
}) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const gridStore = useFillsStore((store) => store.gridStore);
|
||||
|
||||
@@ -134,20 +134,6 @@ describe('MarketSelector', () => {
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
it('Button "All" should be selected by default', () => {
|
||||
const buttons = ['All', 'Futures', 'Spot', 'Perpetuals'];
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<MarketSelector currentMarketId="market-0" onSelect={jest.fn()} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
screen
|
||||
.getAllByTestId(/^product-(All|Future|Spot|Perpetual)$/)
|
||||
.forEach((elem, i) => {
|
||||
expect(elem.textContent).toEqual(buttons[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders only active markets', () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
@@ -183,12 +169,6 @@ describe('MarketSelector', () => {
|
||||
activeMarkets.length
|
||||
);
|
||||
expect(screen.queryByTestId('no-items')).not.toBeInTheDocument();
|
||||
|
||||
await userEvent.click(screen.getByTestId('product-All'));
|
||||
expect(screen.queryAllByTestId(/market-\d/)).toHaveLength(
|
||||
activeMarkets.length
|
||||
);
|
||||
expect(screen.queryByTestId('no-items')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('filters by search term', async () => {
|
||||
|
||||
@@ -39,7 +39,7 @@ export const MarketSelector = ({
|
||||
}) => {
|
||||
const [filter, setFilter] = useState<Filter>({
|
||||
searchTerm: '',
|
||||
product: Product.All,
|
||||
product: Product.Future,
|
||||
sort: Sort.None,
|
||||
assets: [],
|
||||
});
|
||||
|
||||
@@ -6,7 +6,6 @@ import { VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
// Make sure these match the available __typename properties on product
|
||||
export const Product = {
|
||||
All: 'All',
|
||||
Future: 'Future',
|
||||
Spot: 'Spot',
|
||||
Perpetual: 'Perpetual',
|
||||
@@ -17,7 +16,6 @@ export type ProductType = keyof typeof Product;
|
||||
const ProductTypeMapping: {
|
||||
[key in ProductType]: string;
|
||||
} = {
|
||||
[Product.All]: 'All',
|
||||
[Product.Future]: 'Futures',
|
||||
[Product.Spot]: 'Spot',
|
||||
[Product.Perpetual]: 'Perpetuals',
|
||||
@@ -51,12 +49,8 @@ export const ProductSelector = ({
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
<Link
|
||||
to={Routes.MARKETS}
|
||||
className="flex items-center gap-2 ml-auto"
|
||||
title={t('See all markets')}
|
||||
>
|
||||
<span className="underline underline-offset-4">{t('Browse')}</span>
|
||||
<Link to={Routes.MARKETS} className="flex items-center gap-2 ml-auto">
|
||||
<span className="underline underline-offset-4">{t('All markets')}</span>
|
||||
<VegaIcon name={VegaIconNames.ARROW_RIGHT} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -120,13 +120,6 @@ describe('useMarketSelectorList', () => {
|
||||
assets: [],
|
||||
});
|
||||
expect(result.current.markets).toEqual([markets[2]]);
|
||||
rerender({
|
||||
searchTerm: '',
|
||||
product: Product.All,
|
||||
sort: Sort.None,
|
||||
assets: [],
|
||||
});
|
||||
expect(result.current.markets).toEqual(markets);
|
||||
});
|
||||
|
||||
it('filters by asset', () => {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { calcCandleVolume, useMarketList } from '@vegaprotocol/markets';
|
||||
import { priceChangePercentage } from '@vegaprotocol/utils';
|
||||
import type { Filter } from '../../components/market-selector/market-selector';
|
||||
import { Sort } from './sort-dropdown';
|
||||
import { Product } from './product-selector';
|
||||
|
||||
// Used for sort order and filter
|
||||
const MARKET_TEMPLATE = [
|
||||
@@ -29,10 +28,7 @@ export const useMarketSelectorList = ({
|
||||
.filter((m) => isMarketActive(m.state))
|
||||
// only selected product type
|
||||
.filter((m) => {
|
||||
if (
|
||||
product === Product.All ||
|
||||
m.tradableInstrument.instrument.product.__typename === product
|
||||
) {
|
||||
if (m.tradableInstrument.instrument.product.__typename === product) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { OrderbookManager } from '@vegaprotocol/market-depth';
|
||||
import { useCreateOrderStore } from '@vegaprotocol/orders';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
import { useDealTicketFormValues } from '@vegaprotocol/deal-ticket';
|
||||
import { useStopOrderFormValues } from '@vegaprotocol/deal-ticket';
|
||||
|
||||
export const OrderbookContainer = ({ marketId }: { marketId: string }) => {
|
||||
const update = useDealTicketFormValues((state) => state.updateAll);
|
||||
const useOrderStoreRef = useCreateOrderStore();
|
||||
const updateOrder = useOrderStoreRef((store) => store.update);
|
||||
const updateStoredFormValues = useStopOrderFormValues(
|
||||
(state) => state.update
|
||||
);
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
return (
|
||||
<OrderbookManager
|
||||
marketId={marketId}
|
||||
onClick={(values) => {
|
||||
update(marketId, values);
|
||||
onClick={({ price, size }) => {
|
||||
if (price) {
|
||||
updateOrder(marketId, { price });
|
||||
updateStoredFormValues(marketId, { price });
|
||||
}
|
||||
if (size) {
|
||||
updateOrder(marketId, { size });
|
||||
updateStoredFormValues(marketId, { size });
|
||||
}
|
||||
setView({ type: ViewType.Order });
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -25,10 +25,11 @@ export const FilterStatusValue = {
|
||||
};
|
||||
|
||||
export interface OrderContainerProps {
|
||||
marketId?: string;
|
||||
filter?: Filter;
|
||||
}
|
||||
|
||||
export const OrdersContainer = ({ filter }: OrderContainerProps) => {
|
||||
export const OrdersContainer = ({ marketId, filter }: OrderContainerProps) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||
@@ -44,6 +45,7 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
|
||||
return (
|
||||
<OrderListManager
|
||||
partyId={pubKey}
|
||||
marketId={marketId}
|
||||
filter={filter}
|
||||
onMarketClick={onMarketClick}
|
||||
onOrderTypeClick={onOrderTypeClick}
|
||||
|
||||
@@ -7,15 +7,21 @@ import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const PositionsContainer = ({ allKeys }: { allKeys?: boolean }) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
export const PositionsContainer = ({
|
||||
onMarketClick,
|
||||
allKeys,
|
||||
}: {
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
allKeys?: boolean;
|
||||
}) => {
|
||||
const { pubKey, pubKeys, isReadOnly } = useVegaWallet();
|
||||
|
||||
const gridStore = usePositionsStore((store) => store.gridStore);
|
||||
const updateGridStore = usePositionsStore((store) => store.updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridStore, updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridStore, (colState) => {
|
||||
updateGridStore(colState);
|
||||
});
|
||||
|
||||
if (!pubKey) {
|
||||
return (
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './trades-container';
|
||||
@@ -1,24 +0,0 @@
|
||||
import { TradesManager } from '@vegaprotocol/trades';
|
||||
import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { useDataGridEvents } from '@vegaprotocol/datagrid';
|
||||
|
||||
interface TradesContainerProps {
|
||||
marketId: string;
|
||||
}
|
||||
|
||||
export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||
const gridStore = useTradesStore((store) => store.gridStore);
|
||||
const updateGridStore = useTradesStore((store) => store.updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridStore, updateGridStore);
|
||||
|
||||
return <TradesManager marketId={marketId} gridProps={gridStoreCallbacks} />;
|
||||
};
|
||||
|
||||
const useTradesStore = create<DataGridSlice>()(
|
||||
persist(createDataGridSlice, {
|
||||
name: 'vega_trades_store',
|
||||
})
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||
import { GetStarted } from './get-started';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
describe('GetStarted', () => {
|
||||
const renderComponent = (context: Partial<VegaWalletContextShape> = {}) => {
|
||||
return render(
|
||||
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
|
||||
<GetStarted />
|
||||
</VegaWalletContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
it('renders full get started content if not connected and no browser wallet detected', () => {
|
||||
renderComponent();
|
||||
expect(screen.getByTestId('get-started-banner')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders connect prompt if no pubKey but wallet installed', () => {
|
||||
globalThis.window.vega = {} as Vega;
|
||||
renderComponent();
|
||||
expect(screen.getByTestId('order-connect-wallet')).toBeInTheDocument();
|
||||
globalThis.window.vega = undefined as unknown as Vega;
|
||||
});
|
||||
|
||||
it('renders nothing if connected', () => {
|
||||
const { container } = renderComponent({ pubKey: 'my-pubkey' });
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
@@ -16,6 +16,7 @@ interface Props {
|
||||
|
||||
export const GetStarted = ({ lead }: Props) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const { VEGA_ENV, VEGA_NETWORKS } = useEnvironment();
|
||||
const CANONICAL_URL = VEGA_NETWORKS[VEGA_ENV] || 'https://console.vega.xyz';
|
||||
|
||||
@@ -39,7 +40,7 @@ export const GetStarted = ({ lead }: Props) => {
|
||||
{ 'mt-8': !lead }
|
||||
);
|
||||
|
||||
if (!pubKey && !isBrowserWalletInstalled()) {
|
||||
if (!isBrowserWalletInstalled()) {
|
||||
return (
|
||||
<div className={wrapperClasses} data-testid="get-started-banner">
|
||||
{lead && <h2>{lead}</h2>}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './withdrawals-container';
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
withdrawalProvider,
|
||||
WithdrawalsTable,
|
||||
useIncompleteWithdrawals,
|
||||
} from '@vegaprotocol/withdraws';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
|
||||
export const WithdrawalsContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: withdrawalProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const { ready, delayed } = useIncompleteWithdrawals();
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
}
|
||||
return (
|
||||
<WithdrawalsTable
|
||||
data-testid="withdrawals-history"
|
||||
rowData={data}
|
||||
overlayNoRowsTemplate={error ? error.message : t('No withdrawals')}
|
||||
ready={ready}
|
||||
delayed={delayed}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './withdrawals-menu';
|
||||
@@ -1,18 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
|
||||
export const WithdrawalsMenu = () => {
|
||||
const setView = useSidebar((store) => store.setView);
|
||||
|
||||
return (
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
size="extra-small"
|
||||
onClick={() => setView({ type: ViewType.Withdraw })}
|
||||
data-testid="withdraw-dialog-button"
|
||||
>
|
||||
{t('Make withdrawal')}
|
||||
</TradingButton>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,11 @@
|
||||
import {
|
||||
RestConnector,
|
||||
JsonRpcConnector,
|
||||
ViewConnector,
|
||||
InjectedConnector,
|
||||
} from '@vegaprotocol/wallet';
|
||||
|
||||
export const rest = new RestConnector();
|
||||
export const jsonRpc = new JsonRpcConnector();
|
||||
export const injected = new InjectedConnector();
|
||||
|
||||
@@ -17,6 +19,7 @@ if (typeof window !== 'undefined') {
|
||||
|
||||
export const Connectors = {
|
||||
injected,
|
||||
rest,
|
||||
jsonRpc,
|
||||
view,
|
||||
};
|
||||
|
||||
@@ -5,45 +5,12 @@ export default function Document() {
|
||||
<Html>
|
||||
<Head>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charSet="utf-8" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Console" />
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:url" content="https://console.vega.xyz/" />
|
||||
<meta name="og:title" content="Vega Protocol - Console" />
|
||||
<meta name="og:site_name" content="Vega Protocol - Console" />
|
||||
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
|
||||
<meta
|
||||
name="twitter:card"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:title" content="Vega Protocol - Console" />
|
||||
<meta name="twitter:description" content="Vega Protocol - Console" />
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:image:alt" content="VEGA logo" />
|
||||
<meta name="twitter:site" content="@vegaprotocol" />
|
||||
|
||||
<meta name="description" content="Vega Protocol - Console" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
<link rel="stylesheet" href="/preloader.css" media="all" />
|
||||
|
||||
@@ -142,19 +142,12 @@ html [data-theme='dark'] {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.vega-ag-grid .ag-cell .ag-cell-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.vega-ag-grid .ag-header-row {
|
||||
@apply font-alpha font-normal;
|
||||
}
|
||||
|
||||
/* Light variables */
|
||||
.ag-theme-balham {
|
||||
--ag-grid-size: 2px; /* Used for compactness */
|
||||
--ag-row-height: 36px;
|
||||
--ag-header-height: 36px;
|
||||
--ag-background-color: theme(colors.white);
|
||||
--ag-border-color: theme(colors.vega.clight.600);
|
||||
--ag-header-background-color: theme(colors.vega.clight.700);
|
||||
@@ -167,9 +160,6 @@ html [data-theme='dark'] {
|
||||
|
||||
/* Dark variables */
|
||||
.ag-theme-balham-dark {
|
||||
--ag-grid-size: 2px; /* Used for compactness */
|
||||
--ag-row-height: 36px;
|
||||
--ag-header-height: 36px;
|
||||
--ag-background-color: theme(colors.vega.cdark.900);
|
||||
--ag-border-color: theme(colors.vega.cdark.600);
|
||||
--ag-header-background-color: theme(colors.vega.cdark.700);
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = {
|
||||
'scope-enum': async (ctx) => [
|
||||
2,
|
||||
'always',
|
||||
['ci', 'docs', 'specs', ...(await utils.getProjects(ctx))],
|
||||
['ci', 'docs', ...(await utils.getProjects(ctx))],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user