Compare commits
134
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fc719dd4d | ||
|
|
f7a33c47ca | ||
|
|
15d2aed343 | ||
|
|
0284eaf9a2 | ||
|
|
c9c240cb29 | ||
|
|
64aa39fe4b | ||
|
|
485c609791 | ||
|
|
61457bc24d | ||
|
|
2217925285 | ||
|
|
28fe7458ca | ||
|
|
2cb88624f3 | ||
|
|
d2ae780996 | ||
|
|
bd129f1229 | ||
|
|
f3cd2db1ce | ||
|
|
418ea41e22 | ||
|
|
bcc1c8a474 | ||
|
|
496fdee10e | ||
|
|
c8fc91a3bd | ||
|
|
48cccc2678 | ||
|
|
9d66eeae51 | ||
|
|
7ab20d07f9 | ||
|
|
b0aa1b8a3e | ||
|
|
13ffe8a8d0 | ||
|
|
01420c56ff | ||
|
|
15bb7b94ad | ||
|
|
d65ef297a9 | ||
|
|
4062c493cb | ||
|
|
786ab51bd1 | ||
|
|
6cb2e3a3cf | ||
|
|
cf0e0ce4b2 | ||
|
|
9c21a4481a | ||
|
|
7a6c69d773 | ||
|
|
4f10a75386 | ||
|
|
9c26f4d01b | ||
|
|
b3bbe260c6 | ||
|
|
69a4ecdbde | ||
|
|
dbba734672 | ||
|
|
1c57ec4df1 | ||
|
|
f4fa0bd25a | ||
|
|
c2595b533d | ||
|
|
65316075fa | ||
|
|
46955dd933 | ||
|
|
024ed575fc | ||
|
|
871d7068da | ||
|
|
efbb75ec01 | ||
|
|
57c9ea9471 | ||
|
|
448f8f4ba5 | ||
|
|
5a5cd1daeb | ||
|
|
d7365c4b66 | ||
|
|
b6c448b630 | ||
|
|
87e1f9998e | ||
|
|
bdff40b4bc | ||
|
|
0b4f918208 | ||
|
|
df609d442c | ||
|
|
5730e39b32 | ||
|
|
83e9bc8ff6 | ||
|
|
a830e4729f | ||
|
|
e3ff090915 | ||
|
|
c5b6032184 | ||
|
|
cb80c6d417 | ||
|
|
b9ff2388db | ||
|
|
07b766e4d2 | ||
|
|
d19ef2607d | ||
|
|
af0b7391c9 | ||
|
|
9ea980c603 | ||
|
|
2741551c18 | ||
|
|
b06003990c | ||
|
|
377d219220 | ||
|
|
0f20f79a5e | ||
|
|
f658ae4d64 | ||
|
|
4e7192264c | ||
|
|
69ecf00999 | ||
|
|
cbb7189328 | ||
|
|
a05ff9c41a | ||
|
|
62b80a6438 | ||
|
|
4f76724e3e | ||
|
|
e20061d921 | ||
|
|
f133200c7f | ||
|
|
98d01d7933 | ||
|
|
0a3509faad | ||
|
|
070f2a2045 | ||
|
|
7a56e1695d | ||
|
|
bbfef16889 | ||
|
|
ba0211698f | ||
|
|
9f9d44e87d | ||
|
|
349eba7053 | ||
|
|
b28d671975 | ||
|
|
7d5cc9b080 | ||
|
|
dce802d153 | ||
|
|
6d646e3baf | ||
|
|
05b07c2bfe | ||
|
|
e653ad328f | ||
|
|
6b7a04176b | ||
|
|
ac44f4c553 | ||
|
|
b52386622c | ||
|
|
b47caa7667 | ||
|
|
071a9ab34b | ||
|
|
e49ad9da6a | ||
|
|
b508d7b252 | ||
|
|
817521bb08 | ||
|
|
f60e8a2910 | ||
|
|
a557678513 | ||
|
|
9ff68ecba3 | ||
|
|
48e0cf0808 | ||
|
|
c14e57cfd5 | ||
|
|
01addaea7c | ||
|
|
9002e63961 | ||
|
|
098bdb5e3a | ||
|
|
2514a2342b | ||
|
|
4600d6e4ca | ||
|
|
c217741924 | ||
|
|
1180a5ff97 | ||
|
|
71399105ee | ||
|
|
3bca206e45 | ||
|
|
044e9639e9 | ||
|
|
2cde42971e | ||
|
|
c6c320a2ff | ||
|
|
757cbd0f49 | ||
|
|
d70ff8d3d6 | ||
|
|
7ba2acefda | ||
|
|
03a1d10fe4 | ||
|
|
39f55cee5d | ||
|
|
5227d118fc | ||
|
|
16e095104f | ||
|
|
e6531daa41 | ||
|
|
7bf753e6c2 | ||
|
|
22610c2d0a | ||
|
|
4b86b981b3 | ||
|
|
615748548b | ||
|
|
13c9dffc3d | ||
|
|
fa8868d42a | ||
|
|
d382887b95 | ||
|
|
74265b25d7 | ||
|
|
2211abbd72 |
@@ -8,21 +8,17 @@ outputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Create passphrase
|
||||
shell: bash
|
||||
run: echo "${{ inputs.passphrase }}" > ./passphrase
|
||||
|
||||
- name: Initialize wallet
|
||||
shell: bash
|
||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import wallet
|
||||
shell: bash
|
||||
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Generate second public key
|
||||
shell: bash
|
||||
run: vega wallet key generate -w capsule_wallet -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
run: vega wallet key generate -w capsule_wallet -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import network
|
||||
shell: bash
|
||||
@@ -30,13 +26,13 @@ runs:
|
||||
|
||||
- name: Init api-token
|
||||
shell: bash
|
||||
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file passphrase
|
||||
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file ./frontend-monorepo/vegacapsule/passphrase
|
||||
|
||||
- name: Generate api-token
|
||||
id: generate-api-token
|
||||
shell: bash
|
||||
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file passphrase --wallet-passphrase-file passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --wallet-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Start service using capsule network
|
||||
shell: bash
|
||||
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
@@ -19,6 +19,9 @@ jobs:
|
||||
if: ${{ inputs.trigger == 'true' }}
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
@@ -24,6 +24,12 @@ jobs:
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
- name: Vegacapsule version
|
||||
run: vegacapsule version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
@@ -85,10 +91,16 @@ jobs:
|
||||
## Upload logs
|
||||
######
|
||||
|
||||
- name: Logs
|
||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
||||
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
|
||||
- name: Rename files to allow archive
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
while read -r file; do
|
||||
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs
|
||||
path: ./vega-capsule-logs.txt
|
||||
path: /home/runner/.vegacapsule/testnet/logs
|
||||
|
||||
@@ -20,6 +20,12 @@ jobs:
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
- name: Vegacapsule version
|
||||
run: vegacapsule version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
@@ -80,10 +86,16 @@ jobs:
|
||||
## Upload logs
|
||||
######
|
||||
|
||||
- name: Logs
|
||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
||||
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
|
||||
- name: Rename files to allow archive
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
while read -r file; do
|
||||
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs
|
||||
path: ./vega-capsule-logs.txt
|
||||
path: /home/runner/.vegacapsule/testnet/logs
|
||||
|
||||
@@ -20,6 +20,9 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
* @vegaprotocol/frontend
|
||||
*.graphql @vegaprotocol/core
|
||||
|
||||
@@ -156,6 +156,23 @@ In order to run the bootstrap command to generate and start a new network, we mu
|
||||
vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl
|
||||
```
|
||||
|
||||
In order to setup and run vegawallet for e2e capsule tests, in a separate terminal window:
|
||||
|
||||
1. cd into `./vegacapsule`
|
||||
2. run:
|
||||
|
||||
```bash
|
||||
bash setup-vegawallet.sh
|
||||
```
|
||||
|
||||
3. copy generated `api-token` and paste the token into `CYPRESS_VEGA_WALLET_API_TOKEN` environment variable in either `apps/token-e2e/.env` or `apps/explorer-e2e/.env` depending on which project needs testing.
|
||||
|
||||
Note: The script is only needed if capsule was built for first time or fresh. To run existing wallet service for capsule:
|
||||
|
||||
```bash
|
||||
vega wallet service run -n DV --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet
|
||||
```
|
||||
|
||||
# 📑 License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import {
|
||||
generateSimpleMarkets,
|
||||
generateMarketsCandles,
|
||||
} from '../support/mocks/generate-markets';
|
||||
|
||||
describe('simple trading app', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
});
|
||||
cy.mockConsole();
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import type { MarketsQuery } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
generateLongListMarkets,
|
||||
generateSimpleMarkets,
|
||||
generateMarketsCandles,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { marketCandlesQuery, marketsQuery } from '@vegaprotocol/mock';
|
||||
|
||||
describe('market list', { tags: '@smoke' }, () => {
|
||||
describe('simple url', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
});
|
||||
cy.mockConsole();
|
||||
cy.visit('/markets');
|
||||
});
|
||||
|
||||
@@ -64,10 +57,7 @@ describe('market list', { tags: '@smoke' }, () => {
|
||||
|
||||
describe('url params should select filters', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
});
|
||||
cy.mockConsole();
|
||||
});
|
||||
|
||||
it('suspended status', () => {
|
||||
@@ -100,14 +90,26 @@ describe('market list', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
describe('long list of results should be handled properly', () => {
|
||||
it('handles 1000 markets', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockConsole();
|
||||
cy.viewport(1440, 900);
|
||||
const market = marketsQuery().marketsConnection?.edges[0];
|
||||
const edges = new Array(1000)
|
||||
.fill('')
|
||||
.map(() => Object.assign({}, market));
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Markets', generateLongListMarkets(1000));
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
'Markets',
|
||||
marketsQuery({ marketsConnection: { edges } })
|
||||
);
|
||||
aliasGQLQuery(req, 'MarketsCandles', marketCandlesQuery());
|
||||
});
|
||||
performance.mark('start-1k');
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets');
|
||||
});
|
||||
it('handles 1000 markets', () => {
|
||||
cy.get('.ag-center-cols-container', { timeout: 50000 }).then(() => {
|
||||
performance.mark('end-1k');
|
||||
performance.measure('load-1k', 'start-1k', 'end-1k');
|
||||
|
||||
@@ -1,155 +1,84 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import {
|
||||
generateMarket,
|
||||
generateMarketData,
|
||||
generateMarketsCandles,
|
||||
generateMarketsData,
|
||||
generateSimpleMarkets,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
||||
import { generateMarketNames } from '../support/mocks/generate-market-names';
|
||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
|
||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
||||
const marketId = 'market-0';
|
||||
const marketName = 'ACTIVE MARKET';
|
||||
|
||||
describe('market selector', { tags: '@smoke' }, () => {
|
||||
let markets: Market[];
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
});
|
||||
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets').then((response) => {
|
||||
const data: MarketsQuery | undefined = response?.response?.body?.data;
|
||||
if (data?.marketsConnection?.edges.length) {
|
||||
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
|
||||
}
|
||||
});
|
||||
cy.mockConsole();
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.wait('@Markets');
|
||||
});
|
||||
|
||||
it('should be properly rendered', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
markets[0].tradableInstrument.instrument.name
|
||||
);
|
||||
cy.getByTestId('arrow-button').click();
|
||||
cy.getByTestId('market-pane').should('be.visible');
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.first()
|
||||
.should('contain.text', markets[0].tradableInstrument.instrument.name);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.first()
|
||||
.click();
|
||||
cy.getByTestId('market-pane').should('not.be.visible');
|
||||
}
|
||||
cy.get('input[placeholder="Search"]').should('have.value', marketName);
|
||||
cy.getByTestId('arrow-button').click();
|
||||
cy.getByTestId('market-pane').should('be.visible');
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.first()
|
||||
.should('contain.text', marketName);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.first()
|
||||
.click();
|
||||
cy.getByTestId('market-pane').should('not.be.visible');
|
||||
});
|
||||
|
||||
it('typing should change list', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length.at.least', 1);
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.get('input[placeholder="Search"]').type('aa');
|
||||
const filtered = markets.filter(
|
||||
(market) =>
|
||||
market.state === 'STATE_ACTIVE' &&
|
||||
market.tradableInstrument.instrument.name.match(/aa/i)
|
||||
);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length', filtered.length);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.last()
|
||||
.click();
|
||||
cy.location('pathname').should(
|
||||
'eq',
|
||||
`/trading/${filtered[filtered.length - 1].id}`
|
||||
);
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
filtered[filtered.length - 1].tradableInstrument.instrument.name
|
||||
);
|
||||
}
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length.at.least', 1);
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.get('input[placeholder="Search"]').type('ACTIVE');
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length', 1);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.last()
|
||||
.click();
|
||||
cy.location('pathname').should('eq', `/trading/${marketId}`);
|
||||
cy.get('input[placeholder="Search"]').should('have.value', marketName);
|
||||
});
|
||||
// constantly failing on ci
|
||||
it.skip('keyboard navigation should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.focused().realPress('ArrowDown');
|
||||
cy.focused().should('contain.text', 'AAVEDAI Monthly');
|
||||
cy.focused().realPress('ArrowDown');
|
||||
cy.focused().should('contain.text', 'ETHBTC').realPress('Enter');
|
||||
cy.location('pathname').should('eq', '/trading/ethbtc-quaterly');
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.focused().realPress('ArrowDown');
|
||||
cy.focused().should('contain.text', marketName);
|
||||
cy.focused().realPress('ArrowDown');
|
||||
cy.focused().should('contain.text', 'ETHBTC').realPress('Enter');
|
||||
cy.location('pathname').should('eq', '/trading/ethbtc-quaterly');
|
||||
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.getByTestId('market-pane').should('be.visible');
|
||||
cy.get('body').realPress('ArrowDown');
|
||||
cy.get('body').realPress('Tab');
|
||||
cy.getByTestId('market-pane').should('not.be.visible');
|
||||
}
|
||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.getByTestId('market-pane').should('be.visible');
|
||||
cy.get('body').realPress('ArrowDown');
|
||||
cy.get('body').realPress('Tab');
|
||||
cy.getByTestId('market-pane').should('not.be.visible');
|
||||
});
|
||||
|
||||
it('mobile view', () => {
|
||||
if (markets?.length) {
|
||||
cy.viewport('iphone-xr');
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('[role="dialog"]').should('not.exist');
|
||||
cy.getByTestId('arrow-button').click();
|
||||
cy.get('[role="dialog"]').should('be.visible');
|
||||
cy.get('input[placeholder="Search"]').then((search) => {
|
||||
cy.wrap(search).clear();
|
||||
});
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length', 9);
|
||||
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
markets[0].tradableInstrument.instrument.name
|
||||
);
|
||||
}
|
||||
cy.viewport('iphone-xr');
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.get('[role="dialog"]').should('not.exist');
|
||||
cy.getByTestId('arrow-button').click();
|
||||
cy.get('[role="dialog"]').should('be.visible');
|
||||
cy.get('input[placeholder="Search"]').then((search) => {
|
||||
cy.wrap(search).clear();
|
||||
});
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length', 3);
|
||||
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.get('input[placeholder="Search"]').should('have.value', marketName);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,53 +1,38 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import {
|
||||
generateSimpleMarkets,
|
||||
generateMarketsCandles,
|
||||
generateMarketsData,
|
||||
generateMarket,
|
||||
generateMarketData,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
|
||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import { marketQuery, marketsQuery } from '@vegaprotocol/mock';
|
||||
|
||||
describe('Market trade', { tags: '@smoke' }, () => {
|
||||
let markets: Market[];
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
});
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets').then((response) => {
|
||||
const data: MarketsQuery | undefined = response?.response?.body?.data;
|
||||
if (data?.marketsConnection?.edges.length) {
|
||||
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
|
||||
}
|
||||
});
|
||||
const marketId =
|
||||
marketsQuery().marketsConnection?.edges[1].node.id || 'market-1';
|
||||
const marketOverride = {
|
||||
market: {
|
||||
depth: {
|
||||
lastTrade: {
|
||||
price: '9893006',
|
||||
},
|
||||
},
|
||||
id: marketId,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
id: 'asset-id-2',
|
||||
name: 'DAI Name',
|
||||
symbol: 'tDAI',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe('Market trade with wallet disconnected', { tags: '@smoke' }, () => {
|
||||
before(() => {
|
||||
cy.mockConsole();
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.wait('@Market');
|
||||
console.log('marketId', marketId);
|
||||
});
|
||||
|
||||
it('should not display steps if wallet is disconnected', () => {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
it('should not display steps', () => {
|
||||
cy.getByTestId('trading-connect-wallet')
|
||||
.find('h3')
|
||||
.should('have.text', 'Please connect your Vega wallet to make a trade');
|
||||
@@ -58,273 +43,236 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
.find('a')
|
||||
.should('have.text', 'https://vega.xyz/wallet');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Market trade', { tags: '@regression' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.mockConsole();
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'Market', marketQuery(marketOverride));
|
||||
});
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.wait('@Market');
|
||||
});
|
||||
|
||||
it('side selector should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
||||
'have.text',
|
||||
'Long'
|
||||
);
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
||||
'have.text',
|
||||
'Short'
|
||||
);
|
||||
}
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
||||
'have.text',
|
||||
'Long'
|
||||
);
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
||||
'have.text',
|
||||
'Short'
|
||||
);
|
||||
});
|
||||
|
||||
it('side selector mobile view should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.viewport('iphone-xr');
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.getByTestId('next-button').scrollIntoView().click();
|
||||
cy.viewport('iphone-xr');
|
||||
cy.getByTestId('next-button').scrollIntoView().click();
|
||||
|
||||
cy.get('button[aria-label="Open long position"]').should(
|
||||
'have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.get('button[aria-label="Open short position"]').should(
|
||||
'not.have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.get('button[aria-label="Open long position"]').should(
|
||||
'have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.get('button[aria-label="Open short position"]').should(
|
||||
'not.have.class',
|
||||
'selected'
|
||||
);
|
||||
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('button[aria-label="Open long position"]').should(
|
||||
'not.have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.get('button[aria-label="Open short position"]').should(
|
||||
'have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.getByTestId('next-button').scrollIntoView().click();
|
||||
cy.get('#step-1-control').should(
|
||||
'contain.html',
|
||||
'aria-label="Selected value Short"'
|
||||
);
|
||||
}
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('button[aria-label="Open long position"]').should(
|
||||
'not.have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.get('button[aria-label="Open short position"]').should(
|
||||
'have.class',
|
||||
'selected'
|
||||
);
|
||||
cy.getByTestId('next-button').scrollIntoView().click();
|
||||
cy.get('#step-1-control').should(
|
||||
'contain.html',
|
||||
'aria-label="Selected value Short"'
|
||||
);
|
||||
});
|
||||
|
||||
it('size slider should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('[role="slider"]').type('{rightarrow}');
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('[role="slider"]').type('{rightarrow}');
|
||||
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '2');
|
||||
}
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '2');
|
||||
});
|
||||
|
||||
it('percentage selection should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
|
||||
cy.getByTestId('max-label').should('have.text', '21');
|
||||
cy.getByTestId('max-label').should('have.text', '10');
|
||||
|
||||
cy.getByTestId('percentage-selector')
|
||||
.find('button')
|
||||
.contains('Max')
|
||||
.click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '21');
|
||||
}
|
||||
cy.getByTestId('percentage-selector')
|
||||
.find('button')
|
||||
.contains('Max')
|
||||
.click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '10');
|
||||
});
|
||||
|
||||
it('size input should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('input')
|
||||
.type('{backspace}2');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '2');
|
||||
cy.get('button').contains('Max').click();
|
||||
}
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('input').type('{backspace}2');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '2');
|
||||
cy.get('button').contains('Max').click();
|
||||
});
|
||||
|
||||
it('slippage value should be displayed', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.02%');
|
||||
}
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.01%');
|
||||
});
|
||||
|
||||
it('allow slippage value to be adjusted', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.02%');
|
||||
cy.get('#step-2-panel').find('dl').eq(2).find('button').click();
|
||||
cy.get('#input-order-slippage')
|
||||
.focus()
|
||||
.type('{backspace}{backspace}{backspace}1');
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.01%');
|
||||
cy.get('#step-2-panel').find('dl').eq(2).find('button').click();
|
||||
cy.get('#input-order-slippage')
|
||||
.focus()
|
||||
.type('{backspace}{backspace}{backspace}1');
|
||||
|
||||
cy.getByTestId('slippage-dialog').find('button').click();
|
||||
cy.getByTestId('slippage-dialog').find('button').click();
|
||||
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '1%');
|
||||
}
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '1%');
|
||||
});
|
||||
|
||||
it('notional position size should be present', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('input')
|
||||
.type('{backspace}2');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(2)
|
||||
.should('have.text', 'Est. Position Size (tDAI)');
|
||||
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
|
||||
}
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('input').type('{backspace}2');
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(2)
|
||||
.should('have.text', 'Est. Position Size (tDAI)');
|
||||
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
|
||||
});
|
||||
|
||||
it('total fees should be displayed', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(3)
|
||||
.should('have.text', 'Est. Fees (tDAI)');
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
}
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(3)
|
||||
.should('have.text', 'Est. Fees (tDAI)');
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
});
|
||||
|
||||
it('order review should display proper calculations', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-3-control').click();
|
||||
cy.get('#step-3-control').click();
|
||||
|
||||
cy.getByTestId('review-trade')
|
||||
.get('#contracts_tooltip_trigger')
|
||||
.trigger('click')
|
||||
.realTouch();
|
||||
cy.getByTestId('review-trade')
|
||||
.get('#contracts_tooltip_trigger')
|
||||
.trigger('click')
|
||||
.realTouch();
|
||||
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The number of contracts determines'
|
||||
);
|
||||
cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1');
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The number of contracts determines'
|
||||
);
|
||||
cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1');
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
||||
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
||||
|
||||
cy.get('#step-3-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
cy.get('#step-3-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
||||
cy.get('#step-3-panel')
|
||||
.find('dd')
|
||||
.eq(4)
|
||||
.should('have.text', '45,126.90058');
|
||||
|
||||
cy.getByTestId('place-order').should('be.enabled').click();
|
||||
}
|
||||
cy.getByTestId('place-order').should('be.enabled').click();
|
||||
});
|
||||
|
||||
it('info tooltip on mobile view should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.viewport('iphone-xr');
|
||||
cy.visit(`/trading/${markets[0].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-3-control').click();
|
||||
cy.viewport('iphone-xr');
|
||||
cy.get('#step-3-control').click();
|
||||
|
||||
// Start from the bottom tooltip to ensure the tooltip above
|
||||
// can be interacted with
|
||||
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The notional size represents the position size'
|
||||
);
|
||||
// Start from the bottom tooltip to ensure the tooltip above
|
||||
// can be interacted with
|
||||
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The notional size represents the position size'
|
||||
);
|
||||
|
||||
cy.getByTestId('review-trade')
|
||||
.get('#contracts_tooltip_trigger')
|
||||
.realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The number of contracts determines'
|
||||
);
|
||||
}
|
||||
cy.getByTestId('review-trade')
|
||||
.get('#contracts_tooltip_trigger')
|
||||
.realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The number of contracts determines'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import {
|
||||
generatePositions,
|
||||
emptyPositions,
|
||||
generateMargins,
|
||||
} from '../support/mocks/generate-positions';
|
||||
import { generateAccounts } from '../support/mocks/generate-accounts';
|
||||
import { generateAssets } from '../support/mocks/generate-assets';
|
||||
import { generateOrders } from '../support/mocks/generate-orders';
|
||||
import { generateFills } from '../support/mocks/generate-fills';
|
||||
import {
|
||||
generateFillsMarkets,
|
||||
generateMarketsData,
|
||||
generatePositionsMarkets,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
||||
accountsQuery,
|
||||
assetsQuery,
|
||||
chainIdQuery,
|
||||
fillsQuery,
|
||||
marginsQuery,
|
||||
marketsDataQuery,
|
||||
marketsQuery,
|
||||
ordersQuery,
|
||||
positionsQuery,
|
||||
statisticsQuery,
|
||||
} from '@vegaprotocol/mock';
|
||||
|
||||
describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
|
||||
it('button for wallet connect should work', () => {
|
||||
@@ -29,14 +25,14 @@ describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
|
||||
describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
before(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Positions', generatePositions());
|
||||
aliasQuery(req, 'Margins', generateMargins());
|
||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'Accounts', generateAccounts());
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Positions', positionsQuery());
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
|
||||
aliasGQLQuery(req, 'Accounts', accountsQuery());
|
||||
aliasGQLQuery(req, 'Assets', assetsQuery());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,21 +59,21 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
describe('Assets view', () => {
|
||||
before(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Positions', generatePositions());
|
||||
aliasQuery(req, 'Margins', generateMargins());
|
||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'Accounts', generateAccounts());
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Positions', positionsQuery());
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
|
||||
aliasGQLQuery(req, 'Accounts', accountsQuery());
|
||||
aliasGQLQuery(req, 'Assets', assetsQuery());
|
||||
});
|
||||
cy.visit('/portfolio/assets');
|
||||
cy.connectVegaWallet();
|
||||
});
|
||||
|
||||
it('data should be properly rendered', () => {
|
||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 3);
|
||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 5);
|
||||
cy.get(
|
||||
'.ag-center-cols-container [row-id="ACCOUNT_TYPE_GENERAL-asset-id-null"]'
|
||||
)
|
||||
@@ -94,14 +90,14 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
describe('Positions view', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Positions', generatePositions());
|
||||
aliasQuery(req, 'Accounts', generateAccounts());
|
||||
aliasQuery(req, 'Margins', generateMargins());
|
||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Positions', positionsQuery());
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
|
||||
aliasGQLQuery(req, 'Accounts', accountsQuery());
|
||||
aliasGQLQuery(req, 'Assets', assetsQuery());
|
||||
});
|
||||
cy.visit('/portfolio/positions');
|
||||
cy.connectVegaWallet();
|
||||
@@ -115,10 +111,10 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
describe('Orders view', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Orders', generateOrders());
|
||||
aliasQuery(req, 'Markets', generateFillsMarkets());
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Orders', ordersQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
});
|
||||
cy.visit('/portfolio/orders');
|
||||
cy.connectVegaWallet();
|
||||
@@ -132,10 +128,11 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
describe('Fills view', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Fills', generateFills());
|
||||
aliasQuery(req, 'Markets', generateFillsMarkets());
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Orders', ordersQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
aliasGQLQuery(req, 'Fills', fillsQuery());
|
||||
});
|
||||
cy.visit('/portfolio/fills');
|
||||
cy.connectVegaWallet();
|
||||
@@ -149,20 +146,20 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
describe('Empty views', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', generateChainId());
|
||||
aliasQuery(req, 'Statistics', generateStatistics());
|
||||
aliasQuery(req, 'Positions', emptyPositions());
|
||||
aliasQuery(req, 'Accounts', { party: null });
|
||||
aliasQuery(req, 'Orders', { party: null });
|
||||
aliasQuery(req, 'Fills', { party: null });
|
||||
aliasQuery(req, 'Markets', {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Positions', { party: null });
|
||||
aliasGQLQuery(req, 'Accounts', { party: null });
|
||||
aliasGQLQuery(req, 'Orders', { party: null });
|
||||
aliasGQLQuery(req, 'Fills', { party: null });
|
||||
aliasGQLQuery(req, 'Markets', {
|
||||
marketsConnection: { edges: [], __typename: 'MarketConnection' },
|
||||
});
|
||||
aliasQuery(req, 'Assets', {
|
||||
aliasGQLQuery(req, 'Assets', {
|
||||
assetsConnection: { edges: null, __typename: 'AssetsConnection' },
|
||||
});
|
||||
aliasQuery(req, 'Margins', generateMargins());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
|
||||
});
|
||||
cy.visit('/portfolio');
|
||||
cy.connectVegaWallet();
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
@@ -0,0 +1,56 @@
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||
import {
|
||||
accountsQuery,
|
||||
assetsQuery,
|
||||
chainIdQuery,
|
||||
estimateOrderQuery,
|
||||
fillsQuery,
|
||||
marginsQuery,
|
||||
marketDataQuery,
|
||||
marketDepthQuery,
|
||||
marketQuery,
|
||||
marketsCandlesQuery,
|
||||
marketsDataQuery,
|
||||
marketsQuery,
|
||||
ordersQuery,
|
||||
positionsQuery,
|
||||
statisticsQuery,
|
||||
} from '@vegaprotocol/mock';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Cypress {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Chainable<Subject> {
|
||||
mockConsole(): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mockPage = (req: CyHttpMessages.IncomingHttpRequest) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
||||
aliasGQLQuery(req, 'MarketsCandles', marketsCandlesQuery());
|
||||
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
|
||||
aliasGQLQuery(req, 'MarketData', marketDataQuery());
|
||||
aliasGQLQuery(req, 'Market', marketQuery());
|
||||
aliasGQLQuery(req, 'MarketTags', {});
|
||||
aliasGQLQuery(req, 'EstimateOrder', estimateOrderQuery());
|
||||
aliasGQLQuery(req, 'MarketNames', {});
|
||||
aliasGQLQuery(req, 'MarketDepth', marketDepthQuery());
|
||||
aliasGQLQuery(req, 'Positions', positionsQuery());
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'Accounts', accountsQuery());
|
||||
aliasGQLQuery(req, 'Assets', assetsQuery());
|
||||
aliasGQLQuery(req, 'SimpleMarkets', marketsQuery());
|
||||
aliasGQLQuery(req, 'Orders', ordersQuery());
|
||||
aliasGQLQuery(req, 'Fills', fillsQuery());
|
||||
};
|
||||
|
||||
export const addMockConsole = () => {
|
||||
Cypress.Commands.add('mockConsole', () => {
|
||||
cy.mockGQL(mockPage);
|
||||
});
|
||||
};
|
||||
@@ -1,36 +1,7 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
import '@vegaprotocol/cypress';
|
||||
import 'cypress-real-events/support';
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
import registerCypressGrep from '@cypress/grep';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
registerCypressGrep();
|
||||
import { addMockConsole } from './console-mock';
|
||||
|
||||
before(() => {
|
||||
// Mock chainId fetch which happens on every page for wallet connection
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', {
|
||||
statistics: {
|
||||
__typename: 'Statistics',
|
||||
chainId:
|
||||
Cypress.env('VEGA_ENV').toLowerCase() ||
|
||||
'vega-fairground-202210041151',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
registerCypressGrep();
|
||||
addMockConsole();
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
||||
|
||||
export const protoCandles = [
|
||||
{ open: '9556163', close: '9587028', __typename: 'Candle' },
|
||||
{
|
||||
open: '9587028',
|
||||
close: '9769899',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9769899', close: '9586292', __typename: 'Candle' },
|
||||
{
|
||||
open: '9586292',
|
||||
close: '9261774',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9261773', close: '9236369', __typename: 'Candle' },
|
||||
{
|
||||
open: '9236369',
|
||||
close: '9226070',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9226077', close: '9233252', __typename: 'Candle' },
|
||||
{
|
||||
open: '9249854',
|
||||
close: '9333038',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9333038', close: '9410371', __typename: 'Candle' },
|
||||
{
|
||||
open: '9410371',
|
||||
close: '9626249',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9626247', close: '9493253', __typename: 'Candle' },
|
||||
{
|
||||
open: '9493253',
|
||||
close: '9309054',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9309054', close: '9378428', __typename: 'Candle' },
|
||||
{
|
||||
open: '9378428',
|
||||
close: '9352996',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9352996', close: '9451142', __typename: 'Candle' },
|
||||
{
|
||||
open: '9451142',
|
||||
close: '9691070',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9691071', close: '9622031', __typename: 'Candle' },
|
||||
{
|
||||
open: '9622034',
|
||||
close: '9519285',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9528904', close: '9671275', __typename: 'Candle' },
|
||||
{
|
||||
open: '9671275',
|
||||
close: '9988454',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9982457', close: '10085537', __typename: 'Candle' },
|
||||
{
|
||||
open: '10085537',
|
||||
close: '9967390',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
{ open: '9967390', close: '9974844', __typename: 'Candle' },
|
||||
{
|
||||
open: '9974844',
|
||||
close: '9940706',
|
||||
__typename: 'Candle',
|
||||
},
|
||||
];
|
||||
|
||||
export const protoMarket: Market = {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
state: Schema.MarketState.STATE_ACTIVE,
|
||||
decimalPlaces: 5,
|
||||
positionDecimalPlaces: 0,
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
close: '',
|
||||
open: '',
|
||||
},
|
||||
fees: {
|
||||
__typename: 'Fees',
|
||||
factors: {
|
||||
__typename: 'FeeFactors',
|
||||
makerFee: '',
|
||||
infrastructureFee: '',
|
||||
liquidityFee: '',
|
||||
},
|
||||
},
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
id: '',
|
||||
code: 'AAVEDAI.MF21',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:2839D9B2329C9E70',
|
||||
'base:AAVE',
|
||||
'quote:DAI',
|
||||
'class:fx/crypto',
|
||||
'monthly',
|
||||
'sector:defi',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: {
|
||||
__typename: 'Future',
|
||||
quoteName: 'DAI',
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
};
|
||||
|
||||
export const singleMarket: SingleMarketFieldsFragment = {
|
||||
...protoMarket,
|
||||
tradableInstrument: {
|
||||
...protoMarket.tradableInstrument,
|
||||
instrument: {
|
||||
...protoMarket.tradableInstrument.instrument,
|
||||
product: {
|
||||
...protoMarket.tradableInstrument.instrument.product,
|
||||
settlementAsset: {
|
||||
...protoMarket.tradableInstrument.instrument.product.settlementAsset,
|
||||
id: 'dai-id',
|
||||
name: 'DAI Name',
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
id: 'oid',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
depth: {
|
||||
__typename: 'MarketDepth',
|
||||
lastTrade: { price: '9893006', __typename: 'Trade' },
|
||||
},
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { AccountsQuery } from '@vegaprotocol/accounts';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateAccounts = (
|
||||
override?: PartialDeep<AccountsQuery>
|
||||
): AccountsQuery => {
|
||||
const defaultAccounts: AccountsQuery = {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: null,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: {
|
||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
||||
__typename: 'Market',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id-2',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '1000',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '1000',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id-2',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: null,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-0',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
return merge(defaultAccounts, override);
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { AssetsQuery } from '@vegaprotocol/assets';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
const defaultAssets: AssetsQuery = {
|
||||
assetsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
name: 'Euro',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id-2',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
name: 'DAI',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-0',
|
||||
symbol: 'AST0',
|
||||
decimals: 5,
|
||||
name: 'Asto',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
maxFaucetAmountMint: '3',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '0',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: null,
|
||||
takerFeeRewardAccount: null,
|
||||
makerFeeRewardAccount: null,
|
||||
lpFeeRewardAccount: null,
|
||||
marketProposerRewardAccount: null,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
return merge(defaultAssets, override);
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ChainIdQuery } from '@vegaprotocol/react-helpers';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateChainId = (
|
||||
override?: PartialDeep<ChainIdQuery>
|
||||
): ChainIdQuery => {
|
||||
const defaultResult = {
|
||||
statistics: {
|
||||
__typename: 'Statistics',
|
||||
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
export const generateEstimateOrder = () => {
|
||||
return {
|
||||
estimateOrder: {
|
||||
fee: {
|
||||
__typename: 'TradeFee',
|
||||
makerFee: '100000',
|
||||
liquidityFee: '100000',
|
||||
infrastructureFee: '100000',
|
||||
},
|
||||
marginLevels: {
|
||||
initialLevel: '2844054.80937741220203',
|
||||
__typename: 'MarginLevels',
|
||||
},
|
||||
__typename: 'OrderEstimate',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,111 +0,0 @@
|
||||
import type { FillsQuery, FillFieldsFragment } from '@vegaprotocol/fills';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateFills = (
|
||||
override?: PartialDeep<FillsQuery>
|
||||
): FillsQuery => {
|
||||
const fills: FillFieldsFragment[] = [
|
||||
generateFill({
|
||||
buyer: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
}),
|
||||
generateFill({
|
||||
id: '1',
|
||||
seller: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
buyerFee: {
|
||||
infrastructureFee: '5000',
|
||||
},
|
||||
market: {
|
||||
id: 'market-1',
|
||||
},
|
||||
}),
|
||||
generateFill({
|
||||
id: '2',
|
||||
seller: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_BUY,
|
||||
}),
|
||||
generateFill({
|
||||
id: '3',
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
market: {
|
||||
id: 'market-2',
|
||||
},
|
||||
buyer: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const defaultResult: FillsQuery = {
|
||||
party: {
|
||||
id: 'buyer-id',
|
||||
tradesConnection: {
|
||||
__typename: 'TradeConnection',
|
||||
edges: fills.map((f) => {
|
||||
return {
|
||||
__typename: 'TradeEdge',
|
||||
node: f,
|
||||
cursor: '3',
|
||||
};
|
||||
}),
|
||||
pageInfo: {
|
||||
__typename: 'PageInfo',
|
||||
startCursor: '1',
|
||||
endCursor: '2',
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
},
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const generateFill = (override?: PartialDeep<FillFieldsFragment>) => {
|
||||
const defaultFill: FillFieldsFragment = {
|
||||
__typename: 'Trade',
|
||||
id: '0',
|
||||
createdAt: new Date().toISOString(),
|
||||
price: '10000000',
|
||||
size: '50000',
|
||||
buyOrder: 'buy-order',
|
||||
sellOrder: 'sell-order',
|
||||
aggressor: Schema.Side.SIDE_BUY,
|
||||
buyer: {
|
||||
__typename: 'Party',
|
||||
id: 'buyer-id',
|
||||
},
|
||||
seller: {
|
||||
__typename: 'Party',
|
||||
id: 'seller-id',
|
||||
},
|
||||
buyerFee: {
|
||||
__typename: 'TradeFee',
|
||||
makerFee: '100',
|
||||
infrastructureFee: '100',
|
||||
liquidityFee: '100',
|
||||
},
|
||||
sellerFee: {
|
||||
__typename: 'TradeFee',
|
||||
makerFee: '200',
|
||||
infrastructureFee: '200',
|
||||
liquidityFee: '200',
|
||||
},
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-0',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultFill, override);
|
||||
};
|
||||
@@ -1,210 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import type { MarketDepthQuery } from '../../../../../libs/market-depth/src/lib/__generated___/MarketDepth';
|
||||
|
||||
export const generateMarketDepth = (
|
||||
override?: PartialDeep<MarketDepthQuery>
|
||||
): MarketDepthQuery => {
|
||||
const defaultResult: MarketDepthQuery = {
|
||||
market: {
|
||||
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
||||
depth: {
|
||||
sell: [
|
||||
{
|
||||
price: '9893007',
|
||||
volume: '3',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893010',
|
||||
volume: '4',
|
||||
numberOfOrders: '4',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893012',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893015',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893017',
|
||||
volume: '2',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893021',
|
||||
volume: '4',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893025',
|
||||
volume: '5',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893125',
|
||||
volume: '4',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893135',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893165',
|
||||
volume: '5',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893175',
|
||||
volume: '3',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893185',
|
||||
volume: '3',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9894185',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9894585',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9895585',
|
||||
volume: '4',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9896585',
|
||||
volume: '2',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
],
|
||||
buy: [
|
||||
{
|
||||
price: '9893005',
|
||||
volume: '4',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893003',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893001',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9892006',
|
||||
volume: '3',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9891006',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9891001',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890101',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890091',
|
||||
volume: '5',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890081',
|
||||
volume: '4',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890050',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890040',
|
||||
volume: '6',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890030',
|
||||
volume: '6',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890021',
|
||||
volume: '3',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890011',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890001',
|
||||
volume: '11',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
],
|
||||
sequenceNumber: '1661773865550746910',
|
||||
__typename: 'MarketDepth',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
};
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
export const generateMarketMarkPrice = () => {
|
||||
return {
|
||||
market: {
|
||||
decimalPlaces: 5,
|
||||
data: { markPrice: '692748', __typename: 'MarketData' },
|
||||
__typename: 'Market',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,136 +0,0 @@
|
||||
import { protoMarket } from './commons';
|
||||
|
||||
export const generateMarketNames = () => {
|
||||
return {
|
||||
markets: [
|
||||
{ ...protoMarket },
|
||||
{
|
||||
id: '1d7ddf67dac4924db03f5bf58571a7bcb1908d70c66580467717aabc5345b68a',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'AAPL.MF21',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:4899E01009F1A721',
|
||||
'quote:USD',
|
||||
'ticker:AAPL',
|
||||
'class:equities/single-stock-futures',
|
||||
'sector:tech',
|
||||
'listing_venue:NASDAQ',
|
||||
'country:US',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: { quoteName: 'USD', __typename: 'Future' },
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
id: '87ae87cd3244fc1fab4b0e2dad2437879864192bb969f3109b69293421644c8b',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'TSLA.QM21',
|
||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:5A86B190C384997F',
|
||||
'quote:EURO',
|
||||
'ticker:TSLA',
|
||||
'class:equities/single-stock-futures',
|
||||
'sector:tech',
|
||||
'listing_venue:NASDAQ',
|
||||
'country:US',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: { quoteName: 'EURO', __typename: 'Future' },
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
id: '69205712a854f1bbfb69fa3d11b60e01a1e249bafb5ece88115e7451e8ef07b3',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
'base:BTC',
|
||||
'quote:USD',
|
||||
'class:fx/crypto',
|
||||
'monthly',
|
||||
'sector:crypto',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: { quoteName: 'USD', __typename: 'Future' },
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
id: 'ethbtc-quaterly',
|
||||
state: 'STATE_ACTIVE',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'ETHBTC.QM21',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:1F0BB6EB5703B099',
|
||||
'base:ETH',
|
||||
'quote:BTC',
|
||||
'class:fx/crypto',
|
||||
'quarterly',
|
||||
'sector:crypto',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: { quoteName: 'BTC', __typename: 'Future' },
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
id: '3c62b2714c4332d1a689a5352bff090e6aabccfd6bd87ce018936b38372530c9',
|
||||
state: 'STATE_ACTIVE',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'UNIDAI.MF21',
|
||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:3C58ED2A4A6C5D7E',
|
||||
'base:UNI',
|
||||
'quote:DAI',
|
||||
'class:fx/crypto',
|
||||
'monthly',
|
||||
'sector:defi',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
product: { quoteName: 'DAI', __typename: 'Future' },
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import type { MarketPositionsQuery } from '@vegaprotocol/deal-ticket';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
|
||||
export const generateMarketPositions = (): MarketPositionsQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
balance: '400000000000000000000',
|
||||
market: {
|
||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
balance: '265329',
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
positionsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
openVolume: '3',
|
||||
market: {
|
||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
},
|
||||
__typename: 'PositionEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
openVolume: '12',
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
},
|
||||
__typename: 'PositionEdge',
|
||||
},
|
||||
],
|
||||
__typename: 'PositionConnection',
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
export const generateMarketTags = () => {
|
||||
return {
|
||||
market: {
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:2839D9B2329C9E70',
|
||||
'base:AAVE',
|
||||
'quote:DAI',
|
||||
'class:fx/crypto',
|
||||
'monthly',
|
||||
'sector:defi',
|
||||
'settlement:2022-08-01',
|
||||
],
|
||||
__typename: 'InstrumentMetadata',
|
||||
},
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
};
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { OrdersQuery, OrderFieldsFragment } from '@vegaprotocol/orders';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
|
||||
export const generateOrders = (
|
||||
override?: PartialDeep<OrdersQuery>
|
||||
): OrdersQuery => {
|
||||
const orders: OrderFieldsFragment[] = [
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-0',
|
||||
},
|
||||
size: '10',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '20000000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 30).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '48DB6767E4E4E0F649C5A13ABFADE39F8451C27DA828DAF14B7A1E8E5EBDAD99',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-1',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '100',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 29).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '4e93702990712c41f6995fcbbd94f60bb372ad12d64dfa7d96d205c49f790336',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-2',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '20000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 28).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-3',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_ACTIVE,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '100000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '94aead3ca92dc932efcb503631b03a410e2a5d4606cae6083e2406dc38e52f78',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'market-3',
|
||||
},
|
||||
size: '10',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
remaining: '3',
|
||||
price: '100000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
rejectionReason: null,
|
||||
},
|
||||
];
|
||||
|
||||
const defaultResult: OrdersQuery = {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
ordersConnection: {
|
||||
__typename: 'OrderConnection',
|
||||
edges: orders.map((f) => {
|
||||
return {
|
||||
__typename: 'OrderEdge',
|
||||
node: f,
|
||||
cursor: f.id,
|
||||
};
|
||||
}),
|
||||
pageInfo: {
|
||||
__typename: 'PageInfo',
|
||||
startCursor:
|
||||
'066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
|
||||
endCursor:
|
||||
'94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
},
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,81 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
export const generatePartyBalance = (
|
||||
override?: PartialDeep<PartyBalanceQuery>
|
||||
): PartyBalanceQuery => {
|
||||
const defaultResult: PartyBalanceQuery = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '88474051',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '100000000',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
|
||||
symbol: 'tEURO',
|
||||
name: 'tEURO TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '3412867',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '70007',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
import type { PartyMarketDataQuery } from '@vegaprotocol/deal-ticket';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
export const generatePartyMarketData = (): PartyMarketDataQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1200000',
|
||||
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
|
||||
market: null,
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '0.000000001',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
decimals: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
marginsConnection: { edges: null, __typename: 'MarginConnection' },
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,145 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment,
|
||||
MarginsQuery,
|
||||
} from '@vegaprotocol/positions';
|
||||
|
||||
export const generatePositions = (
|
||||
override?: PartialDeep<PositionsQuery>
|
||||
): PositionsQuery => {
|
||||
const nodes: PositionFieldsFragment[] = [
|
||||
{
|
||||
__typename: 'Position',
|
||||
realisedPNL: '0',
|
||||
openVolume: '6',
|
||||
unrealisedPNL: '895000',
|
||||
averageEntryPrice: '1129935',
|
||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
||||
market: {
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'Position',
|
||||
realisedPNL: '100',
|
||||
openVolume: '20',
|
||||
unrealisedPNL: '895000',
|
||||
averageEntryPrice: '8509338',
|
||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
||||
market: {
|
||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
{
|
||||
realisedPNL: '0',
|
||||
openVolume: '1',
|
||||
unrealisedPNL: '-22519',
|
||||
averageEntryPrice: '84400088',
|
||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
||||
market: {
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
},
|
||||
];
|
||||
|
||||
const defaultResult: PositionsQuery = {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
positionsConnection: {
|
||||
__typename: 'PositionConnection',
|
||||
edges: nodes.map((node) => {
|
||||
return {
|
||||
__typename: 'PositionEdge',
|
||||
node,
|
||||
};
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const emptyPositions = (): PositionsQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
positionsConnection: { edges: null, __typename: 'PositionConnection' },
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMargins = (): MarginsQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
marginsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
},
|
||||
__typename: 'MarginEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tEURO-id',
|
||||
},
|
||||
},
|
||||
__typename: 'MarginEdge',
|
||||
},
|
||||
],
|
||||
__typename: 'MarginConnection',
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { StatisticsQuery } from '@vegaprotocol/environment';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateStatistics = (
|
||||
override?: PartialDeep<StatisticsQuery>
|
||||
): StatisticsQuery => {
|
||||
const defaultResult = {
|
||||
statistics: {
|
||||
__typename: 'Statistics',
|
||||
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
|
||||
blockHeight: '11',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
@@ -1,7 +1,5 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
import {
|
||||
VegaConnectDialog,
|
||||
@@ -18,8 +16,7 @@ import useLocalValues from './hooks/use-local-values';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const localValues = useLocalValues(theme, toggleTheme);
|
||||
const localValues = useLocalValues();
|
||||
const {
|
||||
vegaWalletDialog,
|
||||
menu: { setMenuOpen },
|
||||
@@ -56,25 +53,23 @@ function App() {
|
||||
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</LocalContext.Provider>
|
||||
</VegaWalletProvider>
|
||||
</NetworkLoader>
|
||||
</ThemeContext.Provider>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</LocalContext.Provider>
|
||||
</VegaWalletProvider>
|
||||
</NetworkLoader>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import React, {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import React, { forwardRef, useCallback, useMemo, useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
||||
import { ThemeContext, useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useScreenDimensions,
|
||||
useThemeSwitcher,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
GridOptions,
|
||||
GetRowIdParams,
|
||||
@@ -43,7 +40,7 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
|
||||
) => {
|
||||
const { isMobile, screenSize } = useScreenDimensions();
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const theme = useContext(ThemeContext);
|
||||
const { theme } = useThemeSwitcher();
|
||||
const handleOnGridReady = useCallback(() => {
|
||||
(
|
||||
(ref as React.RefObject<AgGridReact>) || gridRef
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
-47
@@ -1,51 +1,54 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: MarketTags
|
||||
// ====================================================
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarketTagsQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
export interface MarketTags_market_tradableInstrument_instrument_metadata {
|
||||
__typename: "InstrumentMetadata";
|
||||
/**
|
||||
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
||||
*/
|
||||
tags: string[] | null;
|
||||
|
||||
export type MarketTagsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null } } } } | null };
|
||||
|
||||
|
||||
export const MarketTagsDocument = gql`
|
||||
query MarketTags($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export interface MarketTags_market_tradableInstrument_instrument {
|
||||
__typename: "Instrument";
|
||||
/**
|
||||
* Metadata for this instrument
|
||||
*/
|
||||
metadata: MarketTags_market_tradableInstrument_instrument_metadata;
|
||||
}
|
||||
|
||||
export interface MarketTags_market_tradableInstrument {
|
||||
__typename: "TradableInstrument";
|
||||
/**
|
||||
* An instance of, or reference to, a fully specified instrument.
|
||||
*/
|
||||
instrument: MarketTags_market_tradableInstrument_instrument;
|
||||
}
|
||||
|
||||
export interface MarketTags_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* An instance of, or reference to, a tradable instrument.
|
||||
*/
|
||||
tradableInstrument: MarketTags_market_tradableInstrument;
|
||||
}
|
||||
|
||||
export interface MarketTags {
|
||||
/**
|
||||
* An instrument that is trading on the Vega network
|
||||
*/
|
||||
market: MarketTags_market | null;
|
||||
}
|
||||
|
||||
export interface MarketTagsVariables {
|
||||
marketId: string;
|
||||
}
|
||||
/**
|
||||
* __useMarketTagsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarketTagsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarketTagsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useMarketTagsQuery({
|
||||
* variables: {
|
||||
* marketId: // value for 'marketId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarketTagsQuery(baseOptions: Apollo.QueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
||||
}
|
||||
export function useMarketTagsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
||||
}
|
||||
export type MarketTagsQueryHookResult = ReturnType<typeof useMarketTagsQuery>;
|
||||
export type MarketTagsLazyQueryHookResult = ReturnType<typeof useMarketTagsLazyQuery>;
|
||||
export type MarketTagsQueryResult = Apollo.QueryResult<MarketTagsQuery, MarketTagsQueryVariables>;
|
||||
@@ -1,54 +0,0 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarketTagsQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketTagsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null } } } } | null };
|
||||
|
||||
|
||||
export const MarketTagsDocument = gql`
|
||||
query MarketTags($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMarketTagsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarketTagsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarketTagsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useMarketTagsQuery({
|
||||
* variables: {
|
||||
* marketId: // value for 'marketId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarketTagsQuery(baseOptions: Apollo.QueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
||||
}
|
||||
export function useMarketTagsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
||||
}
|
||||
export type MarketTagsQueryHookResult = ReturnType<typeof useMarketTagsQuery>;
|
||||
export type MarketTagsLazyQueryHookResult = ReturnType<typeof useMarketTagsLazyQuery>;
|
||||
export type MarketTagsQueryResult = Apollo.QueryResult<MarketTagsQuery, MarketTagsQueryVariables>;
|
||||
@@ -1,61 +0,0 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type PartyBalanceQueryQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } | null> | null } | null } | null };
|
||||
|
||||
|
||||
export const PartyBalanceQueryDocument = gql`
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __usePartyBalanceQueryQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePartyBalanceQueryQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePartyBalanceQueryQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = usePartyBalanceQueryQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePartyBalanceQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
||||
}
|
||||
export function usePartyBalanceQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
||||
}
|
||||
export type PartyBalanceQueryQueryHookResult = ReturnType<typeof usePartyBalanceQueryQuery>;
|
||||
export type PartyBalanceQueryLazyQueryHookResult = ReturnType<typeof usePartyBalanceQueryLazyQuery>;
|
||||
export type PartyBalanceQueryQueryResult = Apollo.QueryResult<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>;
|
||||
@@ -1,9 +1,13 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
|
||||
const tDAI: MarketDealTicketAsset = {
|
||||
__typename: 'Asset',
|
||||
@@ -13,23 +17,20 @@ const tDAI: MarketDealTicketAsset = {
|
||||
decimals: 2,
|
||||
};
|
||||
|
||||
const accounts: AccountFragment[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1000000',
|
||||
asset: tDAI,
|
||||
},
|
||||
];
|
||||
let mockAccountBalance: {
|
||||
accountBalance: string;
|
||||
accountDecimals: number | null;
|
||||
} = { accountBalance: '1000000', accountDecimals: 2 };
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useAccountBalance: jest.fn(() => mockAccountBalance),
|
||||
}));
|
||||
|
||||
describe('DealTicketBalance', function () {
|
||||
it('should render the balance', () => {
|
||||
const { getByText, getByRole } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={accounts}
|
||||
isWalletConnected
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
|
||||
@@ -39,11 +40,8 @@ describe('DealTicketBalance', function () {
|
||||
|
||||
it('should prompt to connect wallet', () => {
|
||||
const { getByText } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={accounts}
|
||||
isWalletConnected={false}
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={false} />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -52,12 +50,10 @@ describe('DealTicketBalance', function () {
|
||||
});
|
||||
|
||||
it('should display zero balance', () => {
|
||||
mockAccountBalance = { accountBalance: '', accountDecimals: null };
|
||||
const { getByText } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={[]}
|
||||
isWalletConnected={true}
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={true} />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
|
||||
|
||||
@@ -1,41 +1,38 @@
|
||||
import classNames from 'classnames';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
t,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
accounts: AccountFragment[];
|
||||
isWalletConnected: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const DealTicketBalance = ({
|
||||
settlementAsset,
|
||||
accounts,
|
||||
isWalletConnected,
|
||||
className = '',
|
||||
}: DealTicketBalanceProps) => {
|
||||
const settlementAssetId = settlementAsset?.id;
|
||||
const settlementAssetSymbol = settlementAsset?.symbol;
|
||||
const settlementAccount = useSettlementAccount(
|
||||
settlementAssetId,
|
||||
accounts,
|
||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
||||
);
|
||||
|
||||
const { accountBalance, accountDecimals } =
|
||||
useAccountBalance(settlementAssetId) || {};
|
||||
const settlementBalance = toBigNum(accountBalance || 0, accountDecimals || 0);
|
||||
|
||||
const formattedNumber =
|
||||
settlementAccount?.balance &&
|
||||
settlementAccount.asset.decimals &&
|
||||
addDecimalsFormatNumber(
|
||||
settlementAccount.balance,
|
||||
settlementAccount.asset.decimals
|
||||
);
|
||||
accountBalance &&
|
||||
accountDecimals &&
|
||||
addDecimalsFormatNumber(accountBalance, accountDecimals);
|
||||
|
||||
const balance = (
|
||||
<p className="text-blue text-lg font-semibold">
|
||||
{settlementAccount
|
||||
{!settlementBalance.isZero()
|
||||
? t(`${formattedNumber}`)
|
||||
: `No ${settlementAssetSymbol} left to trade`}
|
||||
</p>
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import { useParams } from 'react-router-dom';
|
||||
import {
|
||||
DealTicketManager,
|
||||
usePartyBalanceQuery,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketManager } from '@vegaprotocol/deal-ticket';
|
||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
t,
|
||||
useDataProvider,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
@@ -29,11 +22,6 @@ export const DealTicketContainer = () => {
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const { data: partyData } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId || '',
|
||||
@@ -49,10 +37,6 @@ export const DealTicketContainer = () => {
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const accounts = removePaginationWrapper(
|
||||
partyData?.party?.accountsConnection?.edges
|
||||
);
|
||||
|
||||
const loader = <Loader />;
|
||||
if (marketId && data) {
|
||||
const balance = (
|
||||
@@ -61,7 +45,6 @@ export const DealTicketContainer = () => {
|
||||
settlementAsset={
|
||||
data.tradableInstrument.instrument.product?.settlementAsset
|
||||
}
|
||||
accounts={accounts || []}
|
||||
isWalletConnected={!!pubKey}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
getDefaultOrder,
|
||||
useOrderCloseOut,
|
||||
useOrderMargin,
|
||||
usePartyBalanceQuery,
|
||||
useMaximumPositionSize,
|
||||
useCalculateSlippage,
|
||||
validateAmount,
|
||||
@@ -24,7 +23,6 @@ import {
|
||||
addDecimalsFormatNumber,
|
||||
addDecimal,
|
||||
formatNumber,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useOrderSubmit,
|
||||
@@ -37,7 +35,7 @@ import { DealTicketSize } from './deal-ticket-size';
|
||||
import MarketNameRenderer from '../simple-market-list/simple-market-renderer';
|
||||
import SideSelector, { SIDE_NAMES } from './side-selector';
|
||||
import ReviewTrade from './review-trade';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
||||
import { useOrderValidation } from './use-order-validation';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
@@ -77,17 +75,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
});
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
|
||||
const { data: partyBalance } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const accounts = removePaginationWrapper(
|
||||
partyBalance?.party?.accountsConnection?.edges
|
||||
);
|
||||
const maxTrade = useMaximumPositionSize({
|
||||
partyId: pubKey || '',
|
||||
accounts: accounts,
|
||||
marketId: market.id,
|
||||
settlementAssetId:
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
@@ -98,7 +86,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const estCloseOut = useOrderCloseOut({
|
||||
order,
|
||||
market,
|
||||
partyData: partyBalance,
|
||||
});
|
||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||
const [slippageValue, setSlippageValue] = useState(
|
||||
|
||||
@@ -8,28 +8,10 @@ import classNames from 'classnames';
|
||||
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { SIDE_NAMES } from './side-selector';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
MarketTags,
|
||||
MarketTagsVariables,
|
||||
} from './__generated__/MarketTags';
|
||||
|
||||
export const MARKET_TAGS_QUERY = gql`
|
||||
query MarketTags($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
import { useMarketTagsQuery } from './__generated__/MarketTags';
|
||||
|
||||
interface Props {
|
||||
market: MarketDealTicket;
|
||||
@@ -57,12 +39,9 @@ export default ({
|
||||
notionalSize,
|
||||
slippage,
|
||||
}: Props) => {
|
||||
const { data: tagsData } = useQuery<MarketTags, MarketTagsVariables>(
|
||||
MARKET_TAGS_QUERY,
|
||||
{
|
||||
variables: { marketId: market.id },
|
||||
}
|
||||
);
|
||||
const { data: tagsData } = useMarketTagsQuery({
|
||||
variables: { marketId: market.id },
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="mb-8 text-black dark:text-white" data-testid="review-trade">
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
interface SideSelectorProps {
|
||||
value: Schema.Side;
|
||||
|
||||
@@ -3,11 +3,7 @@ import { renderHook } from '@testing-library/react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
MarketStateMapping,
|
||||
Schema as Types,
|
||||
Schema,
|
||||
} from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { ValidationProps } from './use-order-validation';
|
||||
import { marketTranslations, useOrderValidation } from './use-order-validation';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
@@ -78,7 +74,7 @@ const market: MarketDealTicket = {
|
||||
bestBidPrice: '1605489971',
|
||||
bestOfferPrice: '1606823730',
|
||||
markPrice: '1606823730',
|
||||
trigger: Types.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
staticMidPrice: '1606156850',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
@@ -245,7 +241,7 @@ describe('useOrderValidation', () => {
|
||||
});
|
||||
expect(result.current).toStrictEqual({
|
||||
isDisabled: false,
|
||||
message: `This market is ${MarketStateMapping[
|
||||
message: `This market is ${Schema.MarketStateMapping[
|
||||
state as Schema.MarketState
|
||||
].toLowerCase()} and only accepting liquidity commitment orders`,
|
||||
section: 'sec-summary',
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { FieldErrors } from 'react-hook-form';
|
||||
import { useMemo } from 'react';
|
||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
@@ -39,7 +39,7 @@ export const marketTranslations = (marketState: Schema.MarketState) => {
|
||||
case Schema.MarketState.STATE_TRADING_TERMINATED:
|
||||
return t('terminated');
|
||||
default:
|
||||
return t(MarketStateMapping[marketState]).toLowerCase();
|
||||
return t(Schema.MarketStateMapping[marketState]).toLowerCase();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ const Header = () => {
|
||||
}));
|
||||
const {
|
||||
vegaWalletDialog: { setManage },
|
||||
theme,
|
||||
toggleTheme,
|
||||
} = useContext(LocalContext);
|
||||
return (
|
||||
<div
|
||||
@@ -25,7 +23,7 @@ const Header = () => {
|
||||
setConnectDialog={updateVegaWalletDialog}
|
||||
setManageDialog={setManage}
|
||||
/>
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
||||
<ThemeSwitcher className="-my-4" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
|
||||
@@ -14,20 +14,14 @@ import {
|
||||
import type { OrderFieldsFragment, Order } from '@vegaprotocol/orders';
|
||||
import type { OrderCancellationBody } from '@vegaprotocol/wallet';
|
||||
import { isOrderActive } from '@vegaprotocol/orders';
|
||||
import {
|
||||
OrderRejectionReasonMapping,
|
||||
OrderStatusMapping,
|
||||
OrderTypeMapping,
|
||||
Schema,
|
||||
OrderTimeInForceMapping,
|
||||
} from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
type StatusKey = keyof typeof OrderStatusMapping;
|
||||
type RejectReasonKey = keyof typeof OrderRejectionReasonMapping;
|
||||
type OrderTimeKey = keyof typeof OrderTimeInForceMapping;
|
||||
type StatusKey = keyof typeof Schema.OrderStatusMapping;
|
||||
type RejectReasonKey = keyof typeof Schema.OrderRejectionReasonMapping;
|
||||
type OrderTimeKey = keyof typeof Schema.OrderTimeInForceMapping;
|
||||
interface Props {
|
||||
setEditOrder: (order: Order) => void;
|
||||
orderCancel: {
|
||||
@@ -81,7 +75,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['type'];
|
||||
}) => OrderTypeMapping[value as Schema.OrderType],
|
||||
}) => Schema.OrderTypeMapping[value as Schema.OrderType],
|
||||
},
|
||||
{
|
||||
colId: 'status',
|
||||
@@ -95,14 +89,14 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
}) => {
|
||||
if (value && data && data.market) {
|
||||
if (value === Schema.OrderStatus.STATUS_REJECTED) {
|
||||
return `${OrderStatusMapping[value as StatusKey]}: ${
|
||||
return `${Schema.OrderStatusMapping[value as StatusKey]}: ${
|
||||
data.rejectionReason &&
|
||||
OrderRejectionReasonMapping[
|
||||
Schema.OrderRejectionReasonMapping[
|
||||
data.rejectionReason as RejectReasonKey
|
||||
]
|
||||
}`;
|
||||
}
|
||||
return OrderStatusMapping[value as StatusKey] as string;
|
||||
return Schema.OrderStatusMapping[value as StatusKey] as string;
|
||||
}
|
||||
return '-';
|
||||
},
|
||||
@@ -176,11 +170,11 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
new Date(data.expiresAt)
|
||||
);
|
||||
return `${
|
||||
OrderTimeInForceMapping[value as OrderTimeKey]
|
||||
Schema.OrderTimeInForceMapping[value as OrderTimeKey]
|
||||
}: ${expiry}`;
|
||||
}
|
||||
|
||||
return OrderTimeInForceMapping[value as OrderTimeKey];
|
||||
return Schema.OrderTimeInForceMapping[value as OrderTimeKey];
|
||||
}
|
||||
return '-';
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ import type {
|
||||
GroupCellRendererParams,
|
||||
ColDef,
|
||||
} from 'ag-grid-community';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import { Intent, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import colors from 'tailwindcss/colors';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { IS_MARKET_TRADABLE } from '../../constants';
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import SimpleMarketList from './simple-market-list';
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import SimpleMarketToolbar from './simple-market-toolbar';
|
||||
import { IS_MARKET_TRADABLE } from '../../constants';
|
||||
import { ConsoleLiteGrid } from '../console-lite-grid';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { marketsWithCandlesProvider } from '@vegaprotocol/market-list';
|
||||
|
||||
export type MarketWithPercentChange = Market & {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import { InView } from 'react-intersection-observer';
|
||||
import { useDataProvider, useYesterday } from '@vegaprotocol/react-helpers';
|
||||
import type { Candle } from '@vegaprotocol/market-list';
|
||||
import { marketCandlesProvider } from '@vegaprotocol/market-list';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
interface Props {
|
||||
candles: (Candle | null)[] | null;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import MarketNameRenderer from './simple-market-renderer';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import {
|
||||
getAllByText,
|
||||
} from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/react-testing';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import SimpleMarketToolbar from './simple-market-toolbar';
|
||||
import { markets as filterData } from './mocks/market-filters.json';
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
DropdownMenuItemIndicator,
|
||||
Icon,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { HorizontalMenu } from '../horizontal-menu';
|
||||
import type { HorizontalMenuItem } from '../horizontal-menu';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMemo } from 'react';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { MarketWithCandles } from '@vegaprotocol/market-list';
|
||||
import type { RouterParams } from './simple-market-list';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ interface MenuState {
|
||||
export interface LocalValues {
|
||||
vegaWalletDialog: VegaWalletDialogState;
|
||||
menu: MenuState;
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const LocalContext = createContext<LocalValues>({} as LocalValues);
|
||||
|
||||
@@ -3,8 +3,7 @@ import useLocalValues from './use-local-values';
|
||||
|
||||
describe('local values hook', () => {
|
||||
it('state of wallet dialog should be properly handled', () => {
|
||||
const setTheme = jest.fn();
|
||||
const { result } = renderHook(() => useLocalValues('light', setTheme));
|
||||
const { result } = renderHook(() => useLocalValues());
|
||||
expect(result.current.vegaWalletDialog).toBeDefined();
|
||||
expect(result.current.vegaWalletDialog.manage).toBe(false);
|
||||
act(() => {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import type { LocalValues } from '../context/local-context';
|
||||
|
||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
const useLocalValues = () => {
|
||||
const [manage, setManage] = useState<boolean>(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
return useMemo<LocalValues>(
|
||||
() => ({
|
||||
vegaWalletDialog: { manage, setManage },
|
||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||
theme,
|
||||
toggleTheme,
|
||||
}),
|
||||
[manage, theme, toggleTheme, menuOpen]
|
||||
[manage, menuOpen]
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useState, useEffect } from 'react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { BrowserTracing } from '@sentry/tracing';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
EnvironmentProvider,
|
||||
NetworkLoader,
|
||||
@@ -19,7 +18,6 @@ import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
function App() {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
const location = useLocation();
|
||||
@@ -57,25 +55,18 @@ function App() {
|
||||
);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<div className={layoutClasses}>
|
||||
<Header
|
||||
theme={theme}
|
||||
toggleTheme={toggleTheme}
|
||||
menuOpen={menuOpen}
|
||||
setMenuOpen={setMenuOpen}
|
||||
/>
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</TendermintWebsocketProvider>
|
||||
</ThemeContext.Provider>
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<div className={layoutClasses}>
|
||||
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</TendermintWebsocketProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
query ExplorerGovernanceAsset {
|
||||
networkParameter(key: "reward.asset") {
|
||||
value
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerGovernanceAssetQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerGovernanceAssetQuery = { __typename?: 'Query', networkParameter?: { __typename?: 'NetworkParameter', value: string } | null };
|
||||
|
||||
|
||||
export const ExplorerGovernanceAssetDocument = gql`
|
||||
query ExplorerGovernanceAsset {
|
||||
networkParameter(key: "reward.asset") {
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useExplorerGovernanceAssetQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useExplorerGovernanceAssetQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useExplorerGovernanceAssetQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useExplorerGovernanceAssetQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useExplorerGovernanceAssetQuery(baseOptions?: Apollo.QueryHookOptions<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>(ExplorerGovernanceAssetDocument, options);
|
||||
}
|
||||
export function useExplorerGovernanceAssetLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>(ExplorerGovernanceAssetDocument, options);
|
||||
}
|
||||
export type ExplorerGovernanceAssetQueryHookResult = ReturnType<typeof useExplorerGovernanceAssetQuery>;
|
||||
export type ExplorerGovernanceAssetLazyQueryHookResult = ReturnType<typeof useExplorerGovernanceAssetLazyQuery>;
|
||||
export type ExplorerGovernanceAssetQueryResult = Apollo.QueryResult<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>;
|
||||
@@ -0,0 +1,40 @@
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { AssetLink } from '../links';
|
||||
import { useExplorerAssetQuery } from '../links/asset-link/__generated__/Asset';
|
||||
|
||||
export type AssetBalanceProps = {
|
||||
assetId: string;
|
||||
price: string;
|
||||
showAssetLink?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a market ID and a price it will fetch the market
|
||||
* and format the price in that market's decimal places.
|
||||
*/
|
||||
const AssetBalance = ({
|
||||
assetId,
|
||||
price,
|
||||
showAssetLink = true,
|
||||
}: AssetBalanceProps) => {
|
||||
const { data } = useExplorerAssetQuery({
|
||||
fetchPolicy: 'cache-first',
|
||||
variables: { id: assetId },
|
||||
});
|
||||
|
||||
const label =
|
||||
data && data.asset?.decimals
|
||||
? addDecimalsFormatNumber(price, data.asset.decimals)
|
||||
: price;
|
||||
|
||||
return (
|
||||
<div className="inline-block">
|
||||
<span>{label}</span>{' '}
|
||||
{showAssetLink && data?.asset?.id ? (
|
||||
<AssetLink id={data.asset.id} />
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetBalance;
|
||||
@@ -0,0 +1,30 @@
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { useExplorerGovernanceAssetQuery } from './__generated__/Governance-asset';
|
||||
import AssetBalance from './asset-balance';
|
||||
|
||||
export type GovernanceAssetBalanceProps = {
|
||||
price: string;
|
||||
};
|
||||
|
||||
const DEFAULT_DECIMALS = 18;
|
||||
|
||||
/**
|
||||
* Effectively a wrapper around AssetBalance that does an extra query to fetch
|
||||
* the governance asset first, which is set by a network parameter
|
||||
*/
|
||||
const GovernanceAssetBalance = ({ price }: GovernanceAssetBalanceProps) => {
|
||||
const { data } = useExplorerGovernanceAssetQuery();
|
||||
|
||||
if (data && data.networkParameter?.value) {
|
||||
const governanceAssetId = data.networkParameter.value;
|
||||
return <AssetBalance price={price} assetId={governanceAssetId} />;
|
||||
} else {
|
||||
return (
|
||||
<div className="inline-block">
|
||||
<span>{addDecimalsFormatNumber(price, DEFAULT_DECIMALS)}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default GovernanceAssetBalance;
|
||||
@@ -14,12 +14,7 @@ jest.mock('../search', () => ({
|
||||
|
||||
const renderComponent = () => (
|
||||
<MemoryRouter>
|
||||
<Header
|
||||
theme="dark"
|
||||
toggleTheme={jest.fn()}
|
||||
menuOpen={false}
|
||||
setMenuOpen={jest.fn()}
|
||||
/>
|
||||
<Header menuOpen={false} setMenuOpen={jest.fn()} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
|
||||
@@ -8,18 +8,11 @@ import type { Dispatch, SetStateAction } from 'react';
|
||||
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
||||
|
||||
interface ThemeToggleProps {
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
menuOpen: boolean;
|
||||
setMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const Header = ({
|
||||
theme,
|
||||
toggleTheme,
|
||||
menuOpen,
|
||||
setMenuOpen,
|
||||
}: ThemeToggleProps) => {
|
||||
export const Header = ({ menuOpen, setMenuOpen }: ThemeToggleProps) => {
|
||||
const headerClasses = classnames(
|
||||
'md:col-span-2',
|
||||
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
||||
@@ -48,7 +41,7 @@ export const Header = ({
|
||||
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
||||
</button>
|
||||
<Search />
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
||||
<ThemeSwitcher className="-my-4" />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -16,6 +16,7 @@ export type AssetLinkProps = Partial<ComponentProps<typeof Link>> & {
|
||||
*/
|
||||
const AssetLink = ({ id, ...props }: AssetLinkProps) => {
|
||||
const { data } = useExplorerAssetQuery({
|
||||
fetchPolicy: 'cache-first',
|
||||
variables: { id },
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export const EthExplorerLink = ({
|
||||
const link = `${DATA_SOURCES.ethExplorerUrl}/${type}/${id}`;
|
||||
return (
|
||||
<a
|
||||
className="underline external"
|
||||
className="underline external font-mono"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
{...props}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -88,7 +88,7 @@ describe('NestedDataList', () => {
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const item = getByTestId(`T${i}`);
|
||||
const expected = BORDER_COLOURS.dark[i % 5];
|
||||
const expected = BORDER_COLOURS.light[i % 5];
|
||||
expect(item.style.borderColor.toUpperCase()).toBe(expected);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import isObject from 'lodash/isObject';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import { VegaColours } from '@vegaprotocol/tailwindcss-config';
|
||||
@@ -65,7 +65,7 @@ const NestedDataListItem = ({
|
||||
);
|
||||
const hasChildren = isObject(value) && !!Object.keys(value).length;
|
||||
const title = useMemo(() => camelToTitle(label), [label]);
|
||||
const theme = useContext(ThemeContext);
|
||||
const { theme } = useThemeSwitcher();
|
||||
const currentLevelBorder = useMemo(
|
||||
() => getBorderColour(index, theme),
|
||||
[index, theme]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -5,7 +5,7 @@ import { MemoryRouter } from 'react-router-dom';
|
||||
import AmendOrderDetails from './amend-order-details';
|
||||
import { ExplorerDeterministicOrderDocument } from './__generated__/Order';
|
||||
import { render } from '@testing-library/react';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { ExplorerMarketDocument } from '../links/market-link/__generated__/Market';
|
||||
|
||||
type Amend = components['schemas']['v1OrderAmendment'];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { Schema } from '@vegaprotocol/types';
|
||||
import type * as Schema from '@vegaprotocol/types';
|
||||
|
||||
export interface DeterministicOrderDetailsProps {
|
||||
id: string;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
+5
@@ -13,6 +13,7 @@ export const successCodes = new Set([0]);
|
||||
interface ChainResponseCodeProps {
|
||||
code: number;
|
||||
hideLabel?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ interface ChainResponseCodeProps {
|
||||
export const ChainResponseCode = ({
|
||||
code,
|
||||
hideLabel = false,
|
||||
error,
|
||||
}: ChainResponseCodeProps) => {
|
||||
const isSuccess = successCodes.has(code);
|
||||
|
||||
@@ -39,6 +41,9 @@ export const ChainResponseCode = ({
|
||||
{icon}
|
||||
</span>
|
||||
{hideLabel ? null : <span>{label}</span>}
|
||||
{!hideLabel && !!error ? (
|
||||
<span className="ml-1">— {error}</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ export const TxDetailsShared = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Response code')}</TableCell>
|
||||
<TableCell>
|
||||
<ChainResponseCode code={txData.code} />
|
||||
<ChainResponseCode code={txData.code} error={txData.error} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import { NodeLink } from '../../links';
|
||||
import GovernanceAssetBalance from '../../asset-balance/governance-asset-balance';
|
||||
import type { components } from '../../../../types/explorer';
|
||||
|
||||
interface TxDetailsDelegateProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
pubKey: string | undefined;
|
||||
blockData: TendermintBlocksResponse | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* There aren't currently good APIs for exploring delegations or epochs so this
|
||||
* view is currently a little basic - but it gives the key details.
|
||||
*
|
||||
* Future improvements could be:
|
||||
* - Show if the delegation has taken effect or not, based on epoch
|
||||
*
|
||||
* The signature can be turned in to an id with txSignatureToDeterministicId but
|
||||
* for now there are no details to fetch.
|
||||
*/
|
||||
export const TxDetailsDelegate = ({
|
||||
txData,
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsDelegateProps) => {
|
||||
if (!txData || !txData.command.delegateSubmission) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
const d: components['schemas']['v1DelegateSubmission'] =
|
||||
txData.command.delegateSubmission;
|
||||
|
||||
return (
|
||||
<TableWithTbody className="mb-8">
|
||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||
{d.nodeId ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Node')}</TableCell>
|
||||
<TableCell>
|
||||
<NodeLink id={d.nodeId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
{d.amount ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>
|
||||
<GovernanceAssetBalance price={d.amount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
</TableWithTbody>
|
||||
);
|
||||
};
|
||||
@@ -14,6 +14,9 @@ import { TxDetailsNodeVote } from './tx-node-vote';
|
||||
import { TxDetailsOrderCancel } from './tx-order-cancel';
|
||||
import get from 'lodash/get';
|
||||
import { TxDetailsOrderAmend } from './tx-order-amend';
|
||||
import { TxDetailsWithdrawSubmission } from './tx-withdraw-submission';
|
||||
import { TxDetailsDelegate } from './tx-delegation';
|
||||
import { TxDetailsUndelegate } from './tx-undelegation';
|
||||
|
||||
interface TxDetailsWrapperProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -88,6 +91,12 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
|
||||
return TxDetailsChainEvent;
|
||||
case 'Node Vote':
|
||||
return TxDetailsNodeVote;
|
||||
case 'Withdraw':
|
||||
return TxDetailsWithdrawSubmission;
|
||||
case 'Delegate':
|
||||
return TxDetailsDelegate;
|
||||
case 'Undelegate':
|
||||
return TxDetailsUndelegate;
|
||||
default:
|
||||
return TxDetailsGeneric;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@ import type { BlockExplorerTransactionResult } from '../../../routes/types/block
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import type { ExplorerNodeVoteQueryResult } from './__generated___/node-vote';
|
||||
import { useExplorerNodeVoteQuery } from './__generated___/node-vote';
|
||||
import type { ExplorerNodeVoteQueryResult } from './__generated__/Node-vote';
|
||||
import { useExplorerNodeVoteQuery } from './__generated__/Node-vote';
|
||||
import { PartyLink } from '../../links';
|
||||
import { Time } from '../../time';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsNodeVoteProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -80,10 +84,10 @@ export function TxDetailsNodeVoteDeposit({
|
||||
<TableCell>
|
||||
<Time date={deposit?.deposit?.creditedTimestamp} />
|
||||
</TableCell>
|
||||
{deposit?.deposit?.txHash ? (
|
||||
<TxHash hash={deposit?.deposit?.txHash} />
|
||||
) : null}
|
||||
</TableRow>
|
||||
{deposit?.deposit?.txHash ? (
|
||||
<TxHash hash={deposit?.deposit?.txHash} />
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -119,10 +123,10 @@ export function TxDetailsNodeVoteWithdrawal({
|
||||
<TableCell>
|
||||
<Time date={withdrawal?.withdrawal?.withdrawnTimestamp} />
|
||||
</TableCell>
|
||||
{withdrawal?.withdrawal?.txHash ? (
|
||||
<TxHash hash={withdrawal?.withdrawal?.txHash} />
|
||||
) : null}
|
||||
</TableRow>
|
||||
{withdrawal?.withdrawal?.txHash ? (
|
||||
<TxHash hash={withdrawal?.withdrawal?.txHash} />
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -138,7 +142,9 @@ export function TxHash({ hash }: TxDetailsEthTxHashProps) {
|
||||
return (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>Ethereum TX:</TableCell>
|
||||
<TableCell>{hash}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink id={hash} type={EthExplorerLinkTypes.tx} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import { NodeLink } from '../../links';
|
||||
import GovernanceAssetBalance from '../../asset-balance/governance-asset-balance';
|
||||
import type { components } from '../../../../types/explorer';
|
||||
|
||||
export const methodText: Record<
|
||||
components['schemas']['UndelegateSubmissionMethod'],
|
||||
string
|
||||
> = {
|
||||
METHOD_NOW: 'Immediate',
|
||||
METHOD_UNSPECIFIED: 'Unspecified',
|
||||
METHOD_AT_END_OF_EPOCH: 'End of epoch',
|
||||
// This will be removed in a future release
|
||||
METHOD_IN_ANGER: 'Immediate',
|
||||
};
|
||||
|
||||
interface TxDetailsUndelegateProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
pubKey: string | undefined;
|
||||
blockData: TendermintBlocksResponse | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* There aren't currently good APIs for exploring delegations or epochs so this
|
||||
* view is currently a little basic - but it gives the key details.
|
||||
*
|
||||
* Future improvements could be:
|
||||
* - Show if the undelegation has taken effect or not, based on epoch
|
||||
* - Show the the total stake for the node after undelegation takes effect
|
||||
*
|
||||
* The signature can be turned in to an id with txSignatureToDeterministicId but
|
||||
* for now there are no details to fetch.
|
||||
*/
|
||||
export const TxDetailsUndelegate = ({
|
||||
txData,
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsUndelegateProps) => {
|
||||
if (!txData || !txData.command.undelegateSubmission) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const u: components['schemas']['v1UndelegateSubmission'] =
|
||||
txData.command.undelegateSubmission;
|
||||
|
||||
return (
|
||||
<TableWithTbody className="mb-8">
|
||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||
{u.nodeId ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Node')}</TableCell>
|
||||
<TableCell>
|
||||
<NodeLink id={u.nodeId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
{u.amount ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>
|
||||
<GovernanceAssetBalance price={u.amount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
{u.method ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('When')}</TableCell>
|
||||
<TableCell>{methodText[u.method]}</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
</TableWithTbody>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../links/eth-explorer-link/eth-explorer-link';
|
||||
import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
|
||||
import AssetBalance from '../../asset-balance/asset-balance';
|
||||
import { useScrollToLocation } from '../../../hooks/scroll-to-location';
|
||||
import { WithdrawalProgress } from '../../withdrawal/withdrawal-progress';
|
||||
|
||||
interface TxDetailsOrderCancelProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
pubKey: string | undefined;
|
||||
blockData: TendermintBlocksResponse | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The first part of a withdrawal. If the validators all approve this request (i.e. the user has the
|
||||
* required funds), they will produce a multisig bundle that can be submitted to the ERC20 bridge to
|
||||
* execute the withdrawal.
|
||||
*/
|
||||
export const TxDetailsWithdrawSubmission = ({
|
||||
txData,
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsOrderCancelProps) => {
|
||||
useScrollToLocation();
|
||||
|
||||
if (!txData || !txData.command.withdrawSubmission) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const w = txData.command.withdrawSubmission;
|
||||
const id = txData?.signature?.value
|
||||
? txSignatureToDeterministicId(txData.signature.value)
|
||||
: '-';
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableWithTbody className="mb-8">
|
||||
<TxDetailsShared
|
||||
txData={txData}
|
||||
pubKey={pubKey}
|
||||
blockData={blockData}
|
||||
/>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetBalance price={w.amount} assetId={w.asset} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={w.ext.erc20.receiverAddress}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableWithTbody>
|
||||
{id !== '-' ? (
|
||||
<WithdrawalProgress id={id} txStatus={txData.code} />
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -2,8 +2,8 @@ import { t } from '@vegaprotocol/react-helpers';
|
||||
import { useEffect } from 'react';
|
||||
import { InfoBlock } from '../../components/info-block';
|
||||
import { Panel } from '../../components/panel';
|
||||
import { useExplorerStatsQuery } from './__generated__/explorer-stats';
|
||||
import type { ExplorerStatsFieldsFragment } from './__generated__/explorer-stats';
|
||||
import { useExplorerStatsQuery } from './__generated__/Explorer-stats';
|
||||
import type { ExplorerStatsFieldsFragment } from './__generated__/Explorer-stats';
|
||||
|
||||
interface StatsMap {
|
||||
field: keyof ExplorerStatsFieldsFragment;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
fragment ExplorerWithdrawalProperties on Withdrawal {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
withdrawnTimestamp
|
||||
ref
|
||||
txHash
|
||||
details {
|
||||
... on Erc20WithdrawalDetails {
|
||||
receiverAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query ExplorerWithdrawal($id: ID!) {
|
||||
withdrawal(id: $id) {
|
||||
...ExplorerWithdrawalProperties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerWithdrawalPropertiesFragment = { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null };
|
||||
|
||||
export type ExplorerWithdrawalQueryVariables = Types.Exact<{
|
||||
id: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerWithdrawalQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null } | null };
|
||||
|
||||
export const ExplorerWithdrawalPropertiesFragmentDoc = gql`
|
||||
fragment ExplorerWithdrawalProperties on Withdrawal {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
withdrawnTimestamp
|
||||
ref
|
||||
txHash
|
||||
details {
|
||||
... on Erc20WithdrawalDetails {
|
||||
receiverAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const ExplorerWithdrawalDocument = gql`
|
||||
query ExplorerWithdrawal($id: ID!) {
|
||||
withdrawal(id: $id) {
|
||||
...ExplorerWithdrawalProperties
|
||||
}
|
||||
}
|
||||
${ExplorerWithdrawalPropertiesFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useExplorerWithdrawalQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useExplorerWithdrawalQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useExplorerWithdrawalQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useExplorerWithdrawalQuery({
|
||||
* variables: {
|
||||
* id: // value for 'id'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useExplorerWithdrawalQuery(baseOptions: Apollo.QueryHookOptions<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>(ExplorerWithdrawalDocument, options);
|
||||
}
|
||||
export function useExplorerWithdrawalLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>(ExplorerWithdrawalDocument, options);
|
||||
}
|
||||
export type ExplorerWithdrawalQueryHookResult = ReturnType<typeof useExplorerWithdrawalQuery>;
|
||||
export type ExplorerWithdrawalLazyQueryHookResult = ReturnType<typeof useExplorerWithdrawalLazyQuery>;
|
||||
export type ExplorerWithdrawalQueryResult = Apollo.QueryResult<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>;
|
||||
@@ -0,0 +1,125 @@
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { MockedResponse } from '@apollo/client/testing';
|
||||
import { render } from '@testing-library/react';
|
||||
import WithdrawalProgress from './withdrawal-progress';
|
||||
import { ExplorerWithdrawalDocument } from './__generated__/Withdrawal';
|
||||
import { ApolloError } from '@apollo/client';
|
||||
|
||||
function renderComponent(id: string, status: number, mock: MockedResponse[]) {
|
||||
return (
|
||||
<MockedProvider mocks={mock}>
|
||||
<WithdrawalProgress id={id} txStatus={status} />
|
||||
</MockedProvider>
|
||||
);
|
||||
}
|
||||
|
||||
describe('Withdrawal Progress component', () => {
|
||||
it('Renders success for the first indicator if txStatus is 0', () => {
|
||||
const res = render(renderComponent('123', 0, []));
|
||||
expect(res.getByText('Requested')).toBeInTheDocument();
|
||||
|
||||
// Steps 2 and three should not be complete also
|
||||
expect(res.getByText('Not prepared')).toBeInTheDocument();
|
||||
expect(res.getByText('Not complete')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders success for the first indicator if txStatus is anything except 0', () => {
|
||||
const res = render(renderComponent('123', 20, []));
|
||||
expect(res.getByText('Rejected')).toBeInTheDocument();
|
||||
|
||||
// Steps 2 and three should not be complete also
|
||||
expect(res.getByText('Not prepared')).toBeInTheDocument();
|
||||
expect(res.getByText('Not complete')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders success for the second indicator if a date can be fetched', async () => {
|
||||
const mock = {
|
||||
request: {
|
||||
query: ExplorerWithdrawalDocument,
|
||||
variables: {
|
||||
id: '123',
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
withdrawal: {
|
||||
__typename: 'Withdrawal',
|
||||
id: '123',
|
||||
status: 'STATUS_OPEN',
|
||||
createdTimestamp: '2022-03-24T11:03:40.026173466Z',
|
||||
withdrawnTimestamp: null,
|
||||
ref: 'irrelevant',
|
||||
txHash: '0x123456890',
|
||||
details: {
|
||||
__typename: 'Erc20WithdrawalDetails',
|
||||
receiverAddress: '0x5435345432342423',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = render(renderComponent('123', 0, [mock]));
|
||||
// Step 1 should be filled in
|
||||
expect(res.getByText('Requested')).toBeInTheDocument();
|
||||
|
||||
// Step 2
|
||||
expect(await res.findByText('Prepared')).toBeInTheDocument();
|
||||
|
||||
// Step 3
|
||||
expect(await res.findByText('Not complete')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders success for the third indicator if the withdrawal has been executed', async () => {
|
||||
const mock = {
|
||||
request: {
|
||||
query: ExplorerWithdrawalDocument,
|
||||
variables: {
|
||||
id: '123',
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
withdrawal: {
|
||||
__typename: 'Withdrawal',
|
||||
id: '123',
|
||||
status: 'STATUS_FINALIZED',
|
||||
createdTimestamp: '2022-03-24T11:03:40.026173466Z',
|
||||
withdrawnTimestamp: '2022-03-24T11:03:40.026173466Z',
|
||||
ref: 'irrelevant',
|
||||
txHash: '0x123456890',
|
||||
details: {
|
||||
__typename: 'Erc20WithdrawalDetails',
|
||||
receiverAddress: '0x5435345432342423',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = render(renderComponent('123', 0, [mock]));
|
||||
// Step 1 should be filled in
|
||||
expect(res.getByText('Requested')).toBeInTheDocument();
|
||||
|
||||
// Step 2
|
||||
expect(await res.findByText('Prepared')).toBeInTheDocument();
|
||||
|
||||
// Step 3
|
||||
expect(await res.findByText('Complete')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders an error under step 2 if the tx status code is ok but there is a graphql error', async () => {
|
||||
const mock = {
|
||||
request: {
|
||||
query: ExplorerWithdrawalDocument,
|
||||
variables: {
|
||||
id: '123',
|
||||
},
|
||||
},
|
||||
error: new ApolloError({ errorMessage: 'No such withdrawal' }),
|
||||
};
|
||||
|
||||
const res = render(renderComponent('123', 0, [mock]));
|
||||
expect(await res.findByText('No such withdrawal')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,149 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Time } from '../time';
|
||||
import { useExplorerWithdrawalQuery } from './__generated__/Withdrawal';
|
||||
|
||||
interface TxsStatsInfoProps {
|
||||
id: string;
|
||||
txStatus: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const OK = 0;
|
||||
|
||||
/**
|
||||
* Shows a user the *current* state of a proposal. Which sound easy, but.. strap in
|
||||
* 1. Step one is the submission and acceptance of the WithdrawalSubmission. If it is not rejected, it is accepted and we can mark it as complete
|
||||
* 2. Is complete when there is a multisig bundle available to the user. This means that their funds have been moved to an account locked for
|
||||
* withdrawal. To move out of this phase, the user (any user - but realistically the owner of the recipient address) needs to execute the withdrawal
|
||||
* bundle on Ethereum, then we progress to.
|
||||
* 3. The funds have left the ERC20 bridge and been sent to the user. This is complete.
|
||||
*
|
||||
* There could actually be some extra complexity:
|
||||
* - If a deposit is above { asset { withdrawalThreshold } } then the multisig bundle is still produced (step 2) but cannot be submitted for a period
|
||||
* of time. The period of time is defined on the ERC20 bridge. Attempts to submit the multisig bundle before that would be rejected.
|
||||
* - The bridge could be paused, which would cause attempts to complete step three to be rejected
|
||||
*
|
||||
* Also:
|
||||
* - 1 -> 2 is completed automatically by the system
|
||||
* - 2 -> 3 requires action from the user
|
||||
* - Any user with an Ethereum wallet can complete 2 -> 3 as above, but it will likely be the person who owns the vega public key of the source and
|
||||
* the ethereum public key of the recipient. Whoever is looking at this page may be none of those people.
|
||||
* - This renders fine if the useExplorerWithdrawalQuery fails or returns nothing. It will render an error under the rejection if it failed to fetch
|
||||
*/
|
||||
export const WithdrawalProgress = ({ id, txStatus }: TxsStatsInfoProps) => {
|
||||
const { data, error } = useExplorerWithdrawalQuery({ variables: { id } });
|
||||
|
||||
const step2Date = data?.withdrawal?.createdTimestamp || undefined;
|
||||
const step3Date = data?.withdrawal?.withdrawnTimestamp || undefined;
|
||||
|
||||
const isStep1Complete = txStatus === OK;
|
||||
const isStep2Complete = isStep1Complete && !!step2Date;
|
||||
const isStep3Complete = isStep2Complete && !!step3Date;
|
||||
const hasApiError = !!error?.message;
|
||||
return (
|
||||
<div className="p-5 mb-12 max-w-xl">
|
||||
<div className="mx-4 p-4">
|
||||
<div className="flex items-center">
|
||||
<WithdrawalProgressIndicator
|
||||
step={isStep1Complete ? 1 : '✕'}
|
||||
isComplete={isStep1Complete}
|
||||
statusDescription={isStep1Complete ? t('Requested') : t('Rejected')}
|
||||
/>
|
||||
<WithdrawalProgressSeparator isComplete={isStep1Complete} />
|
||||
<WithdrawalProgressIndicator
|
||||
step={2}
|
||||
isComplete={isStep2Complete}
|
||||
statusDescription={
|
||||
isStep2Complete ? t('Prepared') : t('Not prepared')
|
||||
}
|
||||
>
|
||||
{isStep2Complete ? (
|
||||
<Time date={step2Date} />
|
||||
) : hasApiError ? (
|
||||
<span>{error?.message}</span>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</WithdrawalProgressIndicator>
|
||||
<WithdrawalProgressSeparator isComplete={isStep3Complete} />
|
||||
<WithdrawalProgressIndicator
|
||||
step={3}
|
||||
isComplete={isStep3Complete}
|
||||
statusDescription={
|
||||
isStep3Complete ? t('Complete') : t('Not complete')
|
||||
}
|
||||
>
|
||||
{isStep3Complete ? <Time date={step3Date} /> : ''}
|
||||
</WithdrawalProgressIndicator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const classes = {
|
||||
indicatorFailed:
|
||||
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-red-600 bg-red-600 text-center text-white font-bold leading-5',
|
||||
textFailed:
|
||||
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-vega-red',
|
||||
indicatorComplete:
|
||||
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-vega-green-dark bg-vega-green-dark text-center text-white leading-5',
|
||||
textComplete:
|
||||
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-vega-green-dark',
|
||||
indicatorIncomplete:
|
||||
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-gray-300 text-center leading-5',
|
||||
textIncomplete:
|
||||
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-gray-500',
|
||||
};
|
||||
|
||||
interface WithdrawalProgressIndicatorProps {
|
||||
step: string | number;
|
||||
isComplete: boolean;
|
||||
statusDescription: string;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export function WithdrawalProgressIndicator({
|
||||
isComplete,
|
||||
statusDescription,
|
||||
step,
|
||||
children,
|
||||
}: WithdrawalProgressIndicatorProps) {
|
||||
return (
|
||||
<div className="flex items-center relative">
|
||||
<div
|
||||
className={
|
||||
isComplete ? classes.indicatorComplete : classes.indicatorIncomplete
|
||||
}
|
||||
>
|
||||
{step}
|
||||
</div>
|
||||
<div
|
||||
className={isComplete ? classes.textComplete : classes.textIncomplete}
|
||||
>
|
||||
{statusDescription}
|
||||
<br />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface WithdrawalProgressSeparatorProps {
|
||||
isComplete: boolean;
|
||||
}
|
||||
|
||||
export function WithdrawalProgressSeparator({
|
||||
isComplete,
|
||||
}: WithdrawalProgressSeparatorProps) {
|
||||
return (
|
||||
<div
|
||||
className={`flex-auto border-t-2 transition duration-500 ease-in-out ${
|
||||
isComplete ? 'border-vega-green-dark' : 'border-gray-300'
|
||||
}`}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
|
||||
export default WithdrawalProgress;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
// Source: https://scribe.rip/scrolling-to-an-anchor-in-react-when-your-elements-are-rendered-asynchronously-8c64f77b5f34
|
||||
export const useScrollToLocation = () => {
|
||||
const scrolledRef = React.useRef(false);
|
||||
const { hash } = useLocation();
|
||||
const hashRef = React.useRef(hash);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hash) {
|
||||
// We want to reset if the hash has changed
|
||||
if (hashRef.current !== hash) {
|
||||
hashRef.current = hash;
|
||||
scrolledRef.current = false;
|
||||
}
|
||||
|
||||
const id = hash.replace('#', '');
|
||||
const element = document.getElementById(id);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
|
||||
scrolledRef.current = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Set the document title
|
||||
* @param segments string array of segments. Will be reversed.
|
||||
*/
|
||||
export function useDocumentTitle(segments?: string[]) {
|
||||
const base = 'VEGA explorer';
|
||||
const split = ' | ';
|
||||
|
||||
React.useEffect(() => {
|
||||
const segmentsOrdered = segments?.reverse() || [];
|
||||
|
||||
if (segments && segments.length > 0) {
|
||||
document.title = `${segmentsOrdered.join(split)}${split}${base}`;
|
||||
} else {
|
||||
document.title = base;
|
||||
}
|
||||
}, [segments]);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user