feat(#1812): do not require Ethereum connection to display collateral (#2028)

* feat(#1812): don not require ethereum connection to display collateral

* feat(#1812): amend trading-account e2e tests

* feat(#1812): move Web3ConnectDialog to dialogs container, fix Web3Container childrenOnly option

* feat(#1812): fix withdraw e2e tests

* feat(#1812): reverse DialogsContainer changes, add Web3ConnectUncontrolledDialog

* feat(#1812): wrap WithdrawalDialog with  Web3Container

* feat(#1812): fix deposit dialog handling in ZeroBalanceError

* feat(#1812): fix deposit and withdraw dialog e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

Co-authored-by: maciek <maciek@vegaprotocol.io>
This commit is contained in:
Bartłomiej Głownia 2022-11-16 15:10:17 +01:00 committed by GitHub
parent 3b2750dd6d
commit d1b45a65a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 308 additions and 202 deletions

View File

@ -1,3 +1,4 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress'; import { aliasQuery } from '@vegaprotocol/cypress';
import { import {
generateMarketsCandles, generateMarketsCandles,
@ -14,11 +15,15 @@ import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-p
import { generateMarketNames } from '../support/mocks/generate-market-names'; import { generateMarketNames } from '../support/mocks/generate-market-names';
import { generateMarketDepth } from '../support/mocks/generate-market-depth'; import { generateMarketDepth } from '../support/mocks/generate-market-depth';
import type { Market, MarketsQuery } from '@vegaprotocol/market-list'; import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
describe('market selector', { tags: '@smoke' }, () => { describe('market selector', { tags: '@smoke' }, () => {
let markets: Market[]; let markets: Market[];
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Markets', generateSimpleMarkets()); aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles()); aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
aliasQuery(req, 'MarketsData', generateMarketsData()); aliasQuery(req, 'MarketsData', generateMarketsData());
@ -45,7 +50,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it('should be properly rendered', () => { it('should be properly rendered', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('input[placeholder="Search"]').should( cy.get('input[placeholder="Search"]').should(
'have.value', 'have.value',
markets[0].tradableInstrument.instrument.name markets[0].tradableInstrument.instrument.name
@ -69,7 +74,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it('typing should change list', () => { it('typing should change list', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}'); cy.get('input[placeholder="Search"]').type('{backspace}');
cy.getByTestId('market-pane') cy.getByTestId('market-pane')
.children() .children()
@ -105,7 +110,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it.skip('keyboard navigation should work well', () => { it.skip('keyboard navigation should work well', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}'); cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear(); cy.get('input[placeholder="Search"]').clear();
cy.focused().realPress('ArrowDown'); cy.focused().realPress('ArrowDown');
@ -127,11 +132,13 @@ describe('market selector', { tags: '@smoke' }, () => {
if (markets?.length) { if (markets?.length) {
cy.viewport('iphone-xr'); cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('[role="dialog"]').should('not.exist'); cy.get('[role="dialog"]').should('not.exist');
cy.getByTestId('arrow-button').click(); cy.getByTestId('arrow-button').click();
cy.get('[role="dialog"]').should('be.visible'); cy.get('[role="dialog"]').should('be.visible');
cy.get('input[placeholder="Search"]').clear(); cy.get('input[placeholder="Search"]').then((search) => {
cy.wrap(search).clear();
});
cy.getByTestId('market-pane') cy.getByTestId('market-pane')
.children() .children()
.find('[role="button"]') .find('[role="button"]')

View File

@ -1,3 +1,4 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress'; import { aliasQuery } from '@vegaprotocol/cypress';
import { import {
generateSimpleMarkets, generateSimpleMarkets,
@ -14,11 +15,15 @@ import { generatePartyMarketData } from '../support/mocks/generate-party-market-
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price'; import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
import { generateMarketDepth } from '../support/mocks/generate-market-depth'; import { generateMarketDepth } from '../support/mocks/generate-market-depth';
import type { MarketsQuery, Market } from '@vegaprotocol/market-list'; import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
describe('Market trade', { tags: '@smoke' }, () => { describe('Market trade', { tags: '@smoke' }, () => {
let markets: Market[]; let markets: Market[];
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Markets', generateSimpleMarkets()); aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles()); aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
aliasQuery(req, 'MarketsData', generateMarketsData()); aliasQuery(req, 'MarketsData', generateMarketsData());
@ -58,7 +63,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('side selector should work well', () => { it('side selector should work well', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').should( cy.get('#step-1-control [aria-label^="Selected value"]').should(
'have.text', 'have.text',
'Long' 'Long'
@ -77,7 +82,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
if (markets?.length) { if (markets?.length) {
cy.viewport('iphone-xr'); cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.getByTestId('next-button').scrollIntoView().click(); cy.getByTestId('next-button').scrollIntoView().click();
cy.get('button[aria-label="Open long position"]').should( cy.get('button[aria-label="Open long position"]').should(
@ -109,7 +114,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('size slider should work well', () => { it('size slider should work well', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -131,7 +136,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('percentage selection should work well', () => { it('percentage selection should work well', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -158,7 +163,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('size input should work well', () => { it('size input should work well', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -186,7 +191,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('slippage value should be displayed', () => { it('slippage value should be displayed', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -202,7 +207,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('allow slippage value to be adjusted', () => { it('allow slippage value to be adjusted', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -230,7 +235,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('notional position size should be present', () => { it('notional position size should be present', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -257,7 +262,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('total fees should be displayed', () => { it('total fees should be displayed', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`); cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click(); cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click(); cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click(); cy.get('#step-2-control').click();
@ -272,7 +277,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('order review should display proper calculations', () => { it('order review should display proper calculations', () => {
if (markets?.length) { if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-3-control').click(); cy.get('#step-3-control').click();
cy.getByTestId('review-trade') cy.getByTestId('review-trade')
@ -299,7 +304,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
if (markets?.length) { if (markets?.length) {
cy.viewport('iphone-xr'); cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`); cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet(); connectVegaWallet();
cy.get('#step-3-control').click(); cy.get('#step-3-control').click();
// Start from the bottom tooltip to ensure the tooltip above // Start from the bottom tooltip to ensure the tooltip above

View File

@ -1,3 +1,4 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress'; import { aliasQuery } from '@vegaprotocol/cypress';
import { import {
generatePositions, generatePositions,
@ -13,13 +14,15 @@ import {
generateMarketsData, generateMarketsData,
generatePositionsMarkets, generatePositionsMarkets,
} from '../support/mocks/generate-markets'; } from '../support/mocks/generate-markets';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
describe('Portfolio page - wallet', { tags: '@smoke' }, () => { describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
it('button for wallet connect should work', () => { it('button for wallet connect should work', () => {
cy.visit('/'); cy.visit('/');
cy.get('[href="/portfolio"]').eq(0).click(); cy.get('[href="/portfolio"]').eq(0).click();
cy.getByTestId('trading-connect-wallet').should('be.visible'); cy.getByTestId('trading-connect-wallet').should('be.visible');
cy.connectVegaWallet(); connectVegaWallet();
cy.getByTestId('trading-connect-wallet').should('not.exist'); cy.getByTestId('trading-connect-wallet').should('not.exist');
}); });
}); });
@ -27,6 +30,8 @@ describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
describe('Portfolio page tabs', { tags: '@smoke' }, () => { describe('Portfolio page tabs', { tags: '@smoke' }, () => {
before(() => { before(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions()); aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Margins', generateMargins()); aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'Markets', generatePositionsMarkets()); aliasQuery(req, 'Markets', generatePositionsMarkets());
@ -38,7 +43,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
it('certain tabs should exist', () => { it('certain tabs should exist', () => {
cy.visit('/portfolio'); cy.visit('/portfolio');
cy.connectVegaWallet(); connectVegaWallet();
cy.getByTestId('assets').click(); cy.getByTestId('assets').click();
cy.location('pathname').should('eq', '/portfolio/assets'); cy.location('pathname').should('eq', '/portfolio/assets');
@ -59,6 +64,8 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Assets view', () => { describe('Assets view', () => {
before(() => { before(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions()); aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Margins', generateMargins()); aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'Markets', generatePositionsMarkets()); aliasQuery(req, 'Markets', generatePositionsMarkets());
@ -67,7 +74,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', generateAssets()); aliasQuery(req, 'Assets', generateAssets());
}); });
cy.visit('/portfolio/assets'); cy.visit('/portfolio/assets');
cy.connectVegaWallet(); connectVegaWallet();
}); });
it('data should be properly rendered', () => { it('data should be properly rendered', () => {
@ -88,6 +95,8 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Positions view', () => { describe('Positions view', () => {
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions()); aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Accounts', generateAccounts()); aliasQuery(req, 'Accounts', generateAccounts());
aliasQuery(req, 'Margins', generateMargins()); aliasQuery(req, 'Margins', generateMargins());
@ -96,7 +105,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', generateAssets()); aliasQuery(req, 'Assets', generateAssets());
}); });
cy.visit('/portfolio/positions'); cy.visit('/portfolio/positions');
cy.connectVegaWallet(); connectVegaWallet();
}); });
it('data should be properly rendered', () => { it('data should be properly rendered', () => {
@ -107,11 +116,13 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Orders view', () => { describe('Orders view', () => {
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Orders', generateOrders()); aliasQuery(req, 'Orders', generateOrders());
aliasQuery(req, 'Markets', generateFillsMarkets()); aliasQuery(req, 'Markets', generateFillsMarkets());
}); });
cy.visit('/portfolio/orders'); cy.visit('/portfolio/orders');
cy.connectVegaWallet(); connectVegaWallet();
}); });
it('data should be properly rendered', () => { it('data should be properly rendered', () => {
@ -122,11 +133,13 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Fills view', () => { describe('Fills view', () => {
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Fills', generateFills()); aliasQuery(req, 'Fills', generateFills());
aliasQuery(req, 'Markets', generateFillsMarkets()); aliasQuery(req, 'Markets', generateFillsMarkets());
}); });
cy.visit('/portfolio/fills'); cy.visit('/portfolio/fills');
cy.connectVegaWallet(); connectVegaWallet();
}); });
it('data should be properly rendered', () => { it('data should be properly rendered', () => {
@ -137,6 +150,8 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Empty views', () => { describe('Empty views', () => {
beforeEach(() => { beforeEach(() => {
cy.mockGQL((req) => { cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', emptyPositions()); aliasQuery(req, 'Positions', emptyPositions());
aliasQuery(req, 'Accounts', { party: null }); aliasQuery(req, 'Accounts', { party: null });
aliasQuery(req, 'Orders', { party: null }); aliasQuery(req, 'Orders', { party: null });
@ -147,9 +162,11 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', { aliasQuery(req, 'Assets', {
assetsConnection: { edges: null, __typename: 'AssetsConnection' }, assetsConnection: { edges: null, __typename: 'AssetsConnection' },
}); });
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'MarketsData', generateMarketsData());
}); });
cy.visit('/portfolio'); cy.visit('/portfolio');
cy.connectVegaWallet(); connectVegaWallet();
}); });
it('"No data to display" should be always displayed', () => { it('"No data to display" should be always displayed', () => {

View File

@ -0,0 +1,16 @@
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: 'test-chain-id',
},
};
return merge(defaultResult, override);
};

View File

@ -0,0 +1,17 @@
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: 'test-chain-id',
blockHeight: '11',
},
};
return merge(defaultResult, override);
};

View File

@ -0,0 +1,12 @@
export const connectVegaWallet = () => {
const form = 'rest-connector-form';
const walletName = Cypress.env('TRADING_TEST_VEGA_WALLET_NAME');
const walletPassphrase = Cypress.env('TRADING_TEST_VEGA_WALLET_PASSPHRASE');
cy.getByTestId('connect-vega-wallet').click();
cy.getByTestId('connectors-list')
.find('[data-testid="connector-gui"]')
.click();
cy.getByTestId(form).find('#wallet').click().type(walletName);
cy.getByTestId(form).find('#passphrase').click().type(walletPassphrase);
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
};

View File

@ -1,20 +1,16 @@
import { useState } from 'react';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { Button } from '@vegaprotocol/ui-toolkit'; import { Button } from '@vegaprotocol/ui-toolkit';
import { DepositDialog } from '@vegaprotocol/deposits'; import { DepositDialog, useDepositDialog } from '@vegaprotocol/deposits';
/** /**
* Fetches data required for the Deposit page * Fetches data required for the Deposit page
*/ */
export const DepositContainer = () => { export const DepositContainer = () => {
const [depositDialog, setDepositDialog] = useState(false); const openDepositDialog = useDepositDialog((state) => state.open);
return ( return (
<div> <div>
<DepositDialog <DepositDialog />
depositDialog={depositDialog} <Button size="sm" onClick={() => openDepositDialog()}>
setDepositDialog={setDepositDialog}
/>
<Button size="sm" onClick={() => setDepositDialog(true)}>
{t('Make deposit')} {t('Make deposit')}
</Button> </Button>
</div> </div>

View File

@ -7,10 +7,9 @@ import { VegaWalletContainer } from '../../components/vega-wallet-container';
import { import {
PendingWithdrawalsTable, PendingWithdrawalsTable,
useWithdrawals, useWithdrawals,
WithdrawalDialogs, useWithdrawalDialog,
WithdrawalsTable, WithdrawalsTable,
} from '@vegaprotocol/withdraws'; } from '@vegaprotocol/withdraws';
import { useState } from 'react';
import { useDocumentTitle } from '../../hooks/use-document-title'; import { useDocumentTitle } from '../../hooks/use-document-title';
import type { RouteChildProps } from '../index'; import type { RouteChildProps } from '../index';
@ -29,7 +28,7 @@ const Withdrawals = ({ name }: RouteChildProps) => {
}; };
const WithdrawPendingContainer = () => { const WithdrawPendingContainer = () => {
const [withdrawDialog, setWithdrawDialog] = useState(false); const openWithdrawalDialog = useWithdrawalDialog((state) => state.open);
const { t } = useTranslation(); const { t } = useTranslation();
const { pending, completed, loading, error } = useWithdrawals(); const { pending, completed, loading, error } = useWithdrawals();
@ -54,7 +53,7 @@ const WithdrawPendingContainer = () => {
<> <>
<header className="flex items-start justify-between"> <header className="flex items-start justify-between">
<h2>{t('withdrawalsPreparedWarningHeading')}</h2> <h2>{t('withdrawalsPreparedWarningHeading')}</h2>
<Button data-testid="withdraw" onClick={() => setWithdrawDialog(true)}> <Button data-testid="withdraw" onClick={() => openWithdrawalDialog()}>
Withdraw Withdraw
</Button> </Button>
</header> </header>
@ -67,10 +66,6 @@ const WithdrawPendingContainer = () => {
<h4 className="pt-3 pb-1">{t('Withdrawal history')}</h4> <h4 className="pt-3 pb-1">{t('Withdrawal history')}</h4>
<WithdrawalsTable rowData={completed} /> <WithdrawalsTable rowData={completed} />
</div> </div>
<WithdrawalDialogs
withdrawDialog={withdrawDialog}
setWithdrawDialog={setWithdrawDialog}
/>
</> </>
); );
}; };

View File

@ -19,10 +19,6 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
connectVegaWallet(); connectVegaWallet();
// validateFillsDisplayed(); // validateFillsDisplayed();
cy.getByTestId('deposit-button').click(); cy.getByTestId('deposit-button').click();
// Deposit page requires connection Ethereum wallet first
cy.getByTestId(connectEthWalletBtn).click();
cy.getByTestId('web3-connector-MetaMask').click();
cy.wait('@Assets'); cy.wait('@Assets');
}); });

View File

@ -1,5 +1,4 @@
import { connectVegaWallet } from '../support/vega-wallet'; import { connectVegaWallet } from '../support/vega-wallet';
import { connectEthereumWallet } from '../support/ethereum-wallet';
beforeEach(() => { beforeEach(() => {
cy.mockTradingPage(); cy.mockTradingPage();
@ -12,10 +11,8 @@ describe('accounts', { tags: '@smoke' }, () => {
it('renders accounts', () => { it('renders accounts', () => {
const tradingAccountRowId = '[row-id="asset-0"]'; const tradingAccountRowId = '[row-id="asset-0"]';
cy.getByTestId('Collateral').click(); cy.getByTestId('Collateral').click();
cy.getByTestId('tab-accounts').contains('Please connect Vega wallet');
connectVegaWallet(); connectVegaWallet();
connectEthereumWallet();
cy.getByTestId('tab-accounts').should('be.visible'); cy.getByTestId('tab-accounts').should('be.visible');
cy.getByTestId('tab-accounts') cy.getByTestId('tab-accounts')

View File

@ -243,7 +243,7 @@ describe(
() => { () => {
before(() => { before(() => {
cy.mockTradingPage( cy.mockTradingPage(
Schema.MarketState.STATE_PENDING, Schema.MarketState.STATE_SUSPENDED,
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION, Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
); );
@ -302,7 +302,7 @@ describe(
() => { () => {
before(() => { before(() => {
cy.mockTradingPage( cy.mockTradingPage(
Schema.MarketState.STATE_PENDING, Schema.MarketState.STATE_SUSPENDED,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
); );
@ -361,7 +361,7 @@ describe(
() => { () => {
before(() => { before(() => {
cy.mockTradingPage( cy.mockTradingPage(
Schema.MarketState.STATE_PENDING, Schema.MarketState.STATE_SUSPENDED,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
); );
@ -512,7 +512,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
.should('have.text', 'Price (tBTC)'); .should('have.text', 'Price (tBTC)');
}); });
it('must see warning when placing an order with expiry date in past', function () { it('must see warning when placing an order with expiry date in past', () => {
const expiresAt = new Date(Date.now() - 24 * 60 * 60 * 1000); const expiresAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const expiresAtInputValue = expiresAt.toISOString().substring(0, 16); const expiresAtInputValue = expiresAt.toISOString().substring(0, 16);
cy.getByTestId(toggleLimit).click(); cy.getByTestId(toggleLimit).click();

View File

@ -1,12 +1,11 @@
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit'; import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
import { DepositDialog, DepositsTable } from '@vegaprotocol/deposits'; import { useDepositDialog, DepositsTable } from '@vegaprotocol/deposits';
import { useDeposits } from '@vegaprotocol/deposits'; import { useDeposits } from '@vegaprotocol/deposits';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { useState } from 'react';
export const DepositsContainer = () => { export const DepositsContainer = () => {
const { deposits, loading, error } = useDeposits(); const { deposits, loading, error } = useDeposits();
const [depositDialog, setDepositDialog] = useState(false); const openDepositDialog = useDepositDialog((state) => state.open);
return ( return (
<div className="h-full grid grid-rows-[1fr,min-content]"> <div className="h-full grid grid-rows-[1fr,min-content]">
@ -20,14 +19,10 @@ export const DepositsContainer = () => {
}} }}
/> />
</div> </div>
<DepositDialog
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
/>
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2"> <div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
<Button <Button
size="sm" size="sm"
onClick={() => setDepositDialog(true)} onClick={() => openDepositDialog()}
data-testid="deposit-button" data-testid="deposit-button"
> >
{t('Deposit')} {t('Deposit')}

View File

@ -2,17 +2,16 @@ import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
import { import {
PendingWithdrawalsTable, PendingWithdrawalsTable,
useWithdrawals, useWithdrawals,
WithdrawalDialogs, useWithdrawalDialog,
WithdrawalsTable, WithdrawalsTable,
} from '@vegaprotocol/withdraws'; } from '@vegaprotocol/withdraws';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { useState } from 'react';
import { VegaWalletContainer } from '../../components/vega-wallet-container'; import { VegaWalletContainer } from '../../components/vega-wallet-container';
import { Web3Container } from '@vegaprotocol/web3'; import { Web3Container } from '@vegaprotocol/web3';
export const WithdrawalsContainer = () => { export const WithdrawalsContainer = () => {
const { pending, completed, loading, error } = useWithdrawals(); const { pending, completed, loading, error } = useWithdrawals();
const [withdrawDialog, setWithdrawDialog] = useState(false); const openWithdrawDialog = useWithdrawalDialog((state) => state.open);
return ( return (
<Web3Container> <Web3Container>
@ -45,17 +44,13 @@ export const WithdrawalsContainer = () => {
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2"> <div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
<Button <Button
size="sm" size="sm"
onClick={() => setWithdrawDialog(true)} onClick={() => openWithdrawDialog()}
data-testid="withdraw-dialog-button" data-testid="withdraw-dialog-button"
> >
{t('Make withdrawal')} {t('Make withdrawal')}
</Button> </Button>
</div> </div>
</div> </div>
<WithdrawalDialogs
withdrawDialog={withdrawDialog}
setWithdrawDialog={setWithdrawDialog}
/>
</VegaWalletContainer> </VegaWalletContainer>
</Web3Container> </Web3Container>
); );

View File

@ -1,21 +1,19 @@
import { useCallback, useState } from 'react'; import { useCallback } from 'react';
import { Button } from '@vegaprotocol/ui-toolkit'; import { Button } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { WithdrawalDialogs } from '@vegaprotocol/withdraws'; import { useWithdrawalDialog } from '@vegaprotocol/withdraws';
import { Web3Container } from '@vegaprotocol/web3';
import type { AssetFieldsFragment } from '@vegaprotocol/assets'; import type { AssetFieldsFragment } from '@vegaprotocol/assets';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { Splash } from '@vegaprotocol/ui-toolkit'; import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet'; import { useVegaWallet } from '@vegaprotocol/wallet';
import { AccountManager } from '@vegaprotocol/accounts'; import { AccountManager } from '@vegaprotocol/accounts';
import { DepositDialog } from '@vegaprotocol/deposits'; import { useDepositDialog } from '@vegaprotocol/deposits';
export const AccountsContainer = () => { export const AccountsContainer = () => {
const { pubKey } = useVegaWallet(); const { pubKey } = useVegaWallet();
const [withdrawDialog, setWithdrawDialog] = useState(false);
const [depositDialog, setDepositDialog] = useState(false);
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
const [assetId, setAssetId] = useState<string>(); const openWithdrawalDialog = useWithdrawalDialog((store) => store.open);
const openDepositDialog = useDepositDialog((store) => store.open);
const onClickAsset = useCallback( const onClickAsset = useCallback(
(value?: string | AssetFieldsFragment) => { (value?: string | AssetFieldsFragment) => {
@ -24,16 +22,6 @@ export const AccountsContainer = () => {
[openAssetDetailsDialog] [openAssetDetailsDialog]
); );
const onClickWithdraw = useCallback((assetId?: string) => {
setWithdrawDialog(true);
setAssetId(assetId);
}, []);
const onClickDeposit = useCallback((assetId?: string) => {
setDepositDialog(true);
setAssetId(assetId);
}, []);
if (!pubKey) { if (!pubKey) {
return ( return (
<Splash> <Splash>
@ -43,38 +31,20 @@ export const AccountsContainer = () => {
} }
return ( return (
<Web3Container> <div className="h-full relative grid grid-rows-[1fr,min-content]">
<div className="h-full relative grid grid-rows-[1fr,min-content]"> <div>
<div> <AccountManager
<AccountManager partyId={pubKey}
partyId={pubKey} onClickAsset={onClickAsset}
onClickAsset={onClickAsset} onClickWithdraw={openWithdrawalDialog}
onClickWithdraw={onClickWithdraw} onClickDeposit={openDepositDialog}
onClickDeposit={onClickDeposit} />
/>
</div>
<div className="flex justify-end p-2 px-[11px]">
<Button
size="sm"
onClick={() => {
setAssetId(undefined);
setDepositDialog(true);
}}
>
{t('Deposit')}
</Button>
</div>
</div> </div>
<WithdrawalDialogs <div className="flex justify-end p-2 px-[11px]">
assetId={assetId} <Button size="sm" onClick={() => openDepositDialog()}>
withdrawDialog={withdrawDialog} {t('Deposit')}
setWithdrawDialog={setWithdrawDialog} </Button>
/> </div>
<DepositDialog </div>
assetId={assetId}
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
/>
</Web3Container>
); );
}; };

View File

@ -5,6 +5,10 @@ import {
import { VegaConnectDialog } from '@vegaprotocol/wallet'; import { VegaConnectDialog } from '@vegaprotocol/wallet';
import { Connectors } from '../lib/vega-connectors'; import { Connectors } from '../lib/vega-connectors';
import { RiskNoticeDialog } from '../components/risk-notice-dialog'; import { RiskNoticeDialog } from '../components/risk-notice-dialog';
import { WithdrawalDialog } from '@vegaprotocol/withdraws';
import { DepositDialog } from '@vegaprotocol/deposits';
import { Web3Container } from '@vegaprotocol/web3';
import { Web3ConnectUncontrolledDialog } from '@vegaprotocol/web3';
const DialogsContainer = () => { const DialogsContainer = () => {
const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore(); const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore();
@ -18,6 +22,11 @@ const DialogsContainer = () => {
onChange={setOpen} onChange={setOpen}
/> />
<RiskNoticeDialog /> <RiskNoticeDialog />
<DepositDialog />
<Web3ConnectUncontrolledDialog />
<Web3Container childrenOnly connectEagerly>
<WithdrawalDialog />
</Web3Container>
</> </>
); );
}; };

View File

@ -1,7 +1,6 @@
import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers'; import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers';
import { ButtonLink } from '@vegaprotocol/ui-toolkit'; import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { useState } from 'react'; import { DepositDialog, useDepositDialog } from '@vegaprotocol/deposits';
import { DepositDialog } from '@vegaprotocol/deposits';
interface Props { interface Props {
margin: string; margin: string;
@ -14,7 +13,7 @@ interface Props {
} }
export const MarginWarning = ({ margin, balance, asset }: Props) => { export const MarginWarning = ({ margin, balance, asset }: Props) => {
const [depositDialog, setDepositDialog] = useState(false); const openDepositDialog = useDepositDialog((state) => state.open);
return ( return (
<> <>
<div <div
@ -25,7 +24,7 @@ export const MarginWarning = ({ margin, balance, asset }: Props) => {
{t('You may not have enough margin available to open this position.')}{' '} {t('You may not have enough margin available to open this position.')}{' '}
<ButtonLink <ButtonLink
data-testid="deal-ticket-deposit-dialog-button" data-testid="deal-ticket-deposit-dialog-button"
onClick={() => setDepositDialog(true)} onClick={() => openDepositDialog(asset.id)}
> >
{t(`Deposit ${asset.symbol}`)} {t(`Deposit ${asset.symbol}`)}
</ButtonLink> </ButtonLink>
@ -39,11 +38,7 @@ export const MarginWarning = ({ margin, balance, asset }: Props) => {
)} ${asset.symbol} ${t('available')}`} )} ${asset.symbol} ${t('available')}`}
</p> </p>
</div> </div>
<DepositDialog <DepositDialog />
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
assetId={asset.id}
/>
</> </>
); );
}; };

View File

@ -1,8 +1,6 @@
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { ButtonLink, InputError } from '@vegaprotocol/ui-toolkit'; import { ButtonLink, InputError } from '@vegaprotocol/ui-toolkit';
import { useState } from 'react'; import { useDepositDialog } from '@vegaprotocol/deposits';
import { DepositDialog } from '@vegaprotocol/deposits';
interface ZeroBalanceErrorProps { interface ZeroBalanceErrorProps {
asset: { asset: {
id: string; id: string;
@ -11,25 +9,18 @@ interface ZeroBalanceErrorProps {
} }
export const ZeroBalanceError = ({ asset }: ZeroBalanceErrorProps) => { export const ZeroBalanceError = ({ asset }: ZeroBalanceErrorProps) => {
const [depositDialog, setDepositDialog] = useState(false); const openDepositDialog = useDepositDialog((state) => state.open);
return ( return (
<> <InputError data-testid="dealticket-error-message-zero-balance">
<InputError data-testid="dealticket-error-message-zero-balance"> <p className="mb-2">
<p className="mb-2"> {t('Insufficient balance. ')}
{t('Insufficient balance. ')} <ButtonLink
<ButtonLink data-testid="deal-ticket-deposit-dialog-button"
data-testid="deal-ticket-deposit-dialog-button" onClick={() => openDepositDialog(asset.id)}
onClick={() => setDepositDialog(true)} >
> {t(`Deposit ${asset.symbol}`)}
{t(`Deposit ${asset.symbol}`)} </ButtonLink>
</ButtonLink> </p>
</p> </InputError>
</InputError>
<DepositDialog
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
assetId={asset.id}
/>
</>
); );
}; };

View File

@ -27,7 +27,6 @@ export const DealTicketContainer = ({
) )
) : ( ) : (
<Splash> <Splash>
{JSON.stringify(data)}
<p>{t('Could not load market')}</p> <p>{t('Could not load market')}</p>
</Splash> </Splash>
)} )}

View File

@ -24,7 +24,7 @@ export const DepositContainer = ({
return ( return (
<AsyncRenderer data={data} loading={loading} error={error}> <AsyncRenderer data={data} loading={loading} error={error}>
{data && data.length ? ( {data && data.length ? (
<Web3Container> <Web3Container connectEagerly>
<DepositManager <DepositManager
assetId={assetId} assetId={assetId}
assets={data} assets={data}

View File

@ -1,20 +1,34 @@
import create from 'zustand';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import type { Intent } from '@vegaprotocol/ui-toolkit'; import type { Intent } from '@vegaprotocol/ui-toolkit';
import { Dialog } from '@vegaprotocol/ui-toolkit'; import { Dialog } from '@vegaprotocol/ui-toolkit';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { DepositContainer } from './deposit-container'; import { DepositContainer } from './deposit-container';
import { useWeb3ConnectDialog } from '@vegaprotocol/web3';
export interface DepositDialogProps { interface State {
isOpen: boolean;
assetId?: string; assetId?: string;
depositDialog: boolean;
setDepositDialog: (open: boolean) => void;
} }
interface Actions {
open: (assetId?: string) => void;
close: () => void;
}
export const useDepositDialog = create<State & Actions>((set) => ({
isOpen: false,
assetId: undefined,
open: (assetId) => set(() => ({ assetId, isOpen: true })),
close: () => set(() => ({ assetId: undefined, isOpen: false })),
}));
export type DepositDialogStyleProps = { export type DepositDialogStyleProps = {
title: string; title: string;
icon?: JSX.Element; icon?: JSX.Element;
intent?: Intent; intent?: Intent;
}; };
export type DepositDialogStylePropsSetter = ( export type DepositDialogStylePropsSetter = (
props?: DepositDialogStyleProps props?: DepositDialogStyleProps
) => void; ) => void;
@ -25,11 +39,11 @@ const DEFAULT_STYLE: DepositDialogStyleProps = {
icon: undefined, icon: undefined,
}; };
export const DepositDialog = ({ export const DepositDialog = () => {
assetId, const { assetId, isOpen, open, close } = useDepositDialog();
depositDialog, const connectWalletDialogIsOpen = useWeb3ConnectDialog(
setDepositDialog, (state) => state.isOpen
}: DepositDialogProps) => { );
const [dialogStyleProps, _setDialogStyleProps] = useState(DEFAULT_STYLE); const [dialogStyleProps, _setDialogStyleProps] = useState(DEFAULT_STYLE);
const setDialogStyleProps: DepositDialogStylePropsSetter = const setDialogStyleProps: DepositDialogStylePropsSetter =
useCallback<DepositDialogStylePropsSetter>( useCallback<DepositDialogStylePropsSetter>(
@ -41,8 +55,8 @@ export const DepositDialog = ({
); );
return ( return (
<Dialog <Dialog
open={depositDialog} open={isOpen && !connectWalletDialogIsOpen}
onChange={setDepositDialog} onChange={(isOpen) => (isOpen ? open() : close())}
{...dialogStyleProps} {...dialogStyleProps}
> >
<DepositContainer <DepositContainer

View File

@ -1,5 +1,11 @@
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { useEffect, useState, createContext, useContext } from 'react'; import {
useEffect,
useState,
createContext,
useContext,
useCallback,
} from 'react';
import { NodeSwitcherDialog } from '../components/node-switcher-dialog'; import { NodeSwitcherDialog } from '../components/node-switcher-dialog';
import { useConfig } from './use-config'; import { useConfig } from './use-config';
@ -49,10 +55,15 @@ export const EnvironmentProvider = ({
children, children,
}: EnvironmentProviderProps) => { }: EnvironmentProviderProps) => {
const [networkError, setNetworkError] = useState<undefined | ErrorType>(); const [networkError, setNetworkError] = useState<undefined | ErrorType>();
const [isNodeSwitcherOpen, setNodeSwitcherOpen] = useState(false); const [isNodeSwitcherOpen, setNodeSwitcherIsOpen] = useState(false);
const [environment, updateEnvironment] = useState<Environment>( const [environment, updateEnvironment] = useState<Environment>(
compileEnvironment(definitions) compileEnvironment(definitions)
); );
const setNodeSwitcherOpen = useCallback((isOpen: boolean) => {
if (!('Cypress' in window)) {
setNodeSwitcherIsOpen(isOpen);
}
}, []);
const { loading, config } = useConfig( const { loading, config } = useConfig(
{ environment, defaultConfig }, { environment, defaultConfig },
(errorType) => { (errorType) => {
@ -126,7 +137,7 @@ export const EnvironmentProvider = ({
}} }}
> >
<NodeSwitcherDialog <NodeSwitcherDialog
dialogOpen={isNodeSwitcherOpen} dialogOpen={isNodeSwitcherOpen && !('Cypress' in window)}
initialErrorType={networkError} initialErrorType={networkError}
setDialogOpen={setNodeSwitcherOpen} setDialogOpen={setNodeSwitcherOpen}
loading={loading} loading={loading}

View File

@ -1,14 +1,34 @@
import create from 'zustand';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit'; import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
import type { Web3ReactHooks } from '@web3-react/core';
import type { Connector } from '@web3-react/types';
import { MetaMask } from '@web3-react/metamask'; import { MetaMask } from '@web3-react/metamask';
import { WalletConnect } from '@web3-react/walletconnect'; import { WalletConnect } from '@web3-react/walletconnect';
import type { Web3ReactHooks } from '@web3-react/core';
import type { Connector } from '@web3-react/types';
interface State {
isOpen: boolean;
connectors: [Connector, Web3ReactHooks][];
desiredChainId?: number;
}
interface Actions {
open: (connectors: State['connectors'], desiredChainId?: number) => void;
close: () => void;
}
export const useWeb3ConnectDialog = create<State & Actions>((set) => ({
isOpen: false,
connectors: [],
open: (connectors, desiredChainId) =>
set(() => ({ isOpen: true, connectors, desiredChainId })),
close: () =>
set(() => ({ isOpen: false, connectors: [], desiredChainId: undefined })),
}));
interface Web3ConnectDialogProps { interface Web3ConnectDialogProps {
dialogOpen: boolean; dialogOpen: boolean;
setDialogOpen: (isOpen: boolean) => void; setDialogOpen: (isOpen: boolean) => void;
connectors: [Connector, Web3ReactHooks][]; connectors: State['connectors'];
desiredChainId?: number; desiredChainId?: number;
} }
@ -48,6 +68,22 @@ export const Web3ConnectDialog = ({
); );
}; };
export const Web3ConnectUncontrolledDialog = () => {
const { isOpen, connectors, desiredChainId, open, close } =
useWeb3ConnectDialog();
const onChange = (isOpen: boolean) =>
isOpen ? open(connectors, desiredChainId) : close();
return (
<Web3ConnectDialog
dialogOpen={isOpen}
setDialogOpen={onChange}
connectors={connectors}
/>
);
};
function getConnectorInfo(connector: Connector) { function getConnectorInfo(connector: Connector) {
if (connector instanceof MetaMask) { if (connector instanceof MetaMask) {
return { return {

View File

@ -2,6 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing'; import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { Web3Container } from './web3-container'; import { Web3Container } from './web3-container';
import { Web3ConnectUncontrolledDialog } from './web3-connect-dialog';
import type { useWeb3React } from '@web3-react/core'; import type { useWeb3React } from '@web3-react/core';
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers'; import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
import { NetworkParamsDocument } from '@vegaprotocol/react-helpers'; import { NetworkParamsDocument } from '@vegaprotocol/react-helpers';
@ -73,6 +74,7 @@ function setup(mock = networkParamsQueryMock) {
</div> </div>
</Web3Container> </Web3Container>
</MockedProvider> </MockedProvider>
<Web3ConnectUncontrolledDialog />
</EnvironmentProvider> </EnvironmentProvider>
); );
} }

View File

@ -1,23 +1,28 @@
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { useEffect, useState, useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import { useWeb3React } from '@web3-react/core'; import { useWeb3React } from '@web3-react/core';
import { AsyncRenderer, Button, Splash } from '@vegaprotocol/ui-toolkit'; import { AsyncRenderer, Button, Splash } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { useEnvironment } from '@vegaprotocol/environment'; import { useEnvironment } from '@vegaprotocol/environment';
import { Web3Provider } from './web3-provider'; import { Web3Provider } from './web3-provider';
import { useEthereumConfig } from './use-ethereum-config'; import { useEthereumConfig } from './use-ethereum-config';
import { Web3ConnectDialog } from './web3-connect-dialog'; import { useWeb3ConnectDialog } from './web3-connect-dialog';
import { createConnectors } from './web3-connectors'; import { createConnectors } from './web3-connectors';
interface Web3ContainerProps { interface Web3ContainerProps {
children: ReactNode; children: ReactNode;
childrenOnly?: boolean;
connectEagerly?: boolean;
} }
export const Web3Container = ({ children }: Web3ContainerProps) => { export const Web3Container = ({
const [dialogOpen, setDialogOpen] = useState(false); children,
childrenOnly,
connectEagerly,
}: Web3ContainerProps) => {
const { config, loading, error } = useEthereumConfig(); const { config, loading, error } = useEthereumConfig();
const { ETHEREUM_PROVIDER_URL } = useEnvironment(); const { ETHEREUM_PROVIDER_URL } = useEnvironment();
const Connectors = useMemo(() => { const connectors = useMemo(() => {
if (config?.chain_id) { if (config?.chain_id) {
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config?.chain_id)); return createConnectors(ETHEREUM_PROVIDER_URL, Number(config?.chain_id));
} }
@ -25,20 +30,16 @@ export const Web3Container = ({ children }: Web3ContainerProps) => {
}, [config?.chain_id, ETHEREUM_PROVIDER_URL]); }, [config?.chain_id, ETHEREUM_PROVIDER_URL]);
return ( return (
<AsyncRenderer data={config} loading={loading} error={error}> <AsyncRenderer data={config} loading={loading} error={error}>
{Connectors && config && ( {connectors && config && (
<Web3Provider connectors={Connectors}> <Web3Provider connectors={connectors}>
<Web3Content <Web3Content
connectEagerly={connectEagerly}
childrenOnly={childrenOnly}
appChainId={Number(config.chain_id)} appChainId={Number(config.chain_id)}
setDialogOpen={setDialogOpen} connectors={connectors}
> >
{children} {children}
</Web3Content> </Web3Content>
<Web3ConnectDialog
connectors={Connectors}
dialogOpen={dialogOpen}
setDialogOpen={setDialogOpen}
desiredChainId={Number(config.chain_id)}
/>
</Web3Provider> </Web3Provider>
)} )}
</AsyncRenderer> </AsyncRenderer>
@ -47,19 +48,27 @@ export const Web3Container = ({ children }: Web3ContainerProps) => {
interface Web3ContentProps { interface Web3ContentProps {
children: ReactNode; children: ReactNode;
childrenOnly?: boolean;
connectEagerly?: boolean;
appChainId: number; appChainId: number;
setDialogOpen: (isOpen: boolean) => void; connectors: ReturnType<typeof createConnectors>;
} }
export const Web3Content = ({ export const Web3Content = ({
children, children,
childrenOnly,
connectEagerly,
appChainId, appChainId,
setDialogOpen, connectors,
}: Web3ContentProps) => { }: Web3ContentProps) => {
const { isActive, error, connector, chainId } = useWeb3React(); const { isActive, error, connector, chainId } = useWeb3React();
const openDialog = useWeb3ConnectDialog((state) => state.open);
useEffect(() => { useEffect(() => {
if (connector?.connectEagerly && !('Cypress' in window)) { if (
connector?.connectEagerly &&
(!('Cypress' in window) || connectEagerly)
) {
connector.connectEagerly(); connector.connectEagerly();
} }
// wallet connect doesnt handle connectEagerly being called when connector is also in the // wallet connect doesnt handle connectEagerly being called when connector is also in the
@ -67,6 +76,11 @@ export const Web3Content = ({
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
if (childrenOnly) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{children}</>;
}
if (error) { if (error) {
return ( return (
<SplashWrapper> <SplashWrapper>
@ -85,7 +99,7 @@ export const Web3Content = ({
{t('Connect your Ethereum wallet')} {t('Connect your Ethereum wallet')}
</p> </p>
<Button <Button
onClick={() => setDialogOpen(true)} onClick={() => openDialog(connectors, chainId)}
data-testid="connect-eth-wallet-btn" data-testid="connect-eth-wallet-btn"
> >
{t('Connect')} {t('Connect')}

View File

@ -1,4 +1,4 @@
export * from './lib/withdrawal-dialogs'; export * from './lib/withdrawal-dialog';
export * from './lib/withdraw-form'; export * from './lib/withdraw-form';
export * from './lib/withdraw-form-container'; export * from './lib/withdraw-form-container';
export * from './lib/withdraw-manager'; export * from './lib/withdraw-manager';

View File

@ -1,3 +1,4 @@
import create from 'zustand';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { Dialog } from '@vegaprotocol/ui-toolkit'; import { Dialog } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet'; import { useVegaWallet } from '@vegaprotocol/wallet';
@ -5,35 +6,51 @@ import { useCompleteWithdraw } from './use-complete-withdraw';
import { useCreateWithdraw } from './use-create-withdraw'; import { useCreateWithdraw } from './use-create-withdraw';
import { WithdrawFormContainer } from './withdraw-form-container'; import { WithdrawFormContainer } from './withdraw-form-container';
import { WithdrawalFeedback } from './withdrawal-feedback'; import { WithdrawalFeedback } from './withdrawal-feedback';
import { Web3Container } from '@vegaprotocol/web3';
export const WithdrawalDialogs = ({ import { useWeb3ConnectDialog } from '@vegaprotocol/web3';
withdrawDialog, interface State {
setWithdrawDialog, isOpen: boolean;
assetId,
}: {
withdrawDialog: boolean;
setWithdrawDialog: (open: boolean) => void;
assetId?: string; assetId?: string;
}) => { }
interface Actions {
open: (assetId?: string) => void;
close: () => void;
}
export const useWithdrawalDialog = create<State & Actions>((set) => ({
isOpen: false,
assetId: undefined,
open: (assetId) => set(() => ({ assetId, isOpen: true })),
close: () => set(() => ({ assetId: undefined, isOpen: false })),
}));
export const WithdrawalDialog = () => {
const { assetId, isOpen, open, close } = useWithdrawalDialog();
const { pubKey } = useVegaWallet(); const { pubKey } = useVegaWallet();
const createWithdraw = useCreateWithdraw(); const createWithdraw = useCreateWithdraw();
const completeWithdraw = useCompleteWithdraw(); const completeWithdraw = useCompleteWithdraw();
const connectWalletDialogIsOpen = useWeb3ConnectDialog(
(state) => state.isOpen
);
return ( return (
<> <>
<Dialog <Dialog
title={t('Withdraw')} title={t('Withdraw')}
open={withdrawDialog} open={isOpen && !connectWalletDialogIsOpen}
onChange={(isOpen) => setWithdrawDialog(isOpen)} onChange={(isOpen) => (isOpen ? open() : close())}
size="small" size="small"
> >
<WithdrawFormContainer <Web3Container connectEagerly>
assetId={assetId} <WithdrawFormContainer
partyId={pubKey ? pubKey : undefined} assetId={assetId}
submit={(args) => { partyId={pubKey ? pubKey : undefined}
setWithdrawDialog(false); submit={(args) => {
createWithdraw.submit(args); close();
}} createWithdraw.submit(args);
/> }}
/>
</Web3Container>
</Dialog> </Dialog>
<createWithdraw.Dialog <createWithdraw.Dialog
content={{ content={{