Compare commits

..
55 changed files with 183 additions and 809 deletions
+1 -1
View File
@@ -125,7 +125,7 @@ jobs:
#----------------------------------------------
- name: Run tests
working-directory: ./console-test
run: poetry run pytest -s --numprocesses auto --dist loadfile
run: poetry run pytest -s --numprocesses auto
- name: Check files
run: |
ls -al .
+2
View File
@@ -22,6 +22,8 @@ NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
#Test configuration variables
CYPRESS_FAIRGROUND=false
+1 -4
View File
@@ -19,9 +19,6 @@ NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
@@ -29,4 +26,4 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
CYPRESS_FAIRGROUND=false
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_SUCCESSOR_MARKETS=false
+1 -4
View File
@@ -14,11 +14,8 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_REST_URL=https://api.n00.devnet1.vega.xyz/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_SUCCESSOR_MARKETS=true
+1 -3
View File
@@ -14,11 +14,9 @@ NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_SUCCESSOR_MARKETS=false
+1 -3
View File
@@ -13,11 +13,9 @@ NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-mirror-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_SUCCESSOR_MARKETS=false
+1 -4
View File
@@ -10,11 +10,8 @@ NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_SUCCESSOR_MARKETS=true
+1 -4
View File
@@ -15,11 +15,8 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_SUCCESSOR_MARKETS=true
+1 -4
View File
@@ -12,11 +12,8 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_SUCCESSOR_MARKETS=false
+1 -1
View File
@@ -36,4 +36,4 @@ CYPRESS_VEGA_WALLET_API_TOKEN=
# Cosmic elevator flags (MUST be doubled with CYPRESS_ prefix)
NX_SUCCESSOR_MARKETS=true
CYPRESS_NX_SUCCESSOR_MARKETS=true
CYPRESS_NX_SUCCESSOR_MARKETS=true
@@ -259,12 +259,6 @@ describe('Closed markets', { tags: '@smoke' }, () => {
.find('[data-testid="market-code"]')
.should('have.text', settledMarket.tradableInstrument.instrument.code);
// 6001-MARK-071
cy.get(rowSelector)
.first()
.find('[title="Future"]')
.should('have.text', 'Futr');
// 6001-MARK-002
cy.get(rowSelector)
.first()
@@ -69,12 +69,6 @@ describe('markets all table', { tags: '@smoke' }, () => {
.find(colInstrumentCode)
.should('have.text', 'SOLUSD');
// 6001-MARK-073
cy.get(rowSelector)
.first()
.find('[title="Future"]')
.should('have.text', 'Futr');
// 6001-MARK-036
cy.get(rowSelector)
.first()
@@ -45,12 +45,6 @@ describe('markets proposed table', { tags: '@smoke' }, () => {
.find('[col-id="description"]')
.should('have.text', 'ETHUSD');
// 6001-MARK-074
cy.get(rowSelector)
.first()
.find('[title="Future"]')
.should('have.text', 'Futr');
// 6001-MARK-051
cy.get(rowSelector)
.first()
@@ -23,7 +23,7 @@ describe('deal ticket basics', { tags: '@smoke' }, () => {
// 0003-WTXN-001
cy.getByTestId('connect-vega-wallet'); // Not connected
cy.getByTestId(placeOrderBtn).should('exist');
cy.getByTestId('order-connect-wallet').should('exist');
cy.getByTestId('get-started-button').should('exist');
});
it('must be able to select order direction - long/short', function () {
@@ -44,7 +44,7 @@ describe('deal ticket basics', { tags: '@smoke' }, () => {
mockConnectWallet();
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('101');
cy.getByTestId('order-connect-wallet').click();
cy.getByTestId('get-started-button').click();
cy.getByTestId('dialog-content').should('be.visible');
cy.getByTestId('connectors-list')
.find('[data-testid="connector-jsonRpc"]')
@@ -222,17 +222,12 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
it('must see a filled order', () => {
// 7002-SORD-046
// 7003-MORD-020
// NOT COVERED: Must be able to see/link to all trades that were created from this order
updateOrder({
id: orderId,
status: Schema.OrderStatus.STATUS_FILLED,
});
cy.getByTestId(`order-status-${orderId}`).should('have.text', 'Filled');
cy.get('[col-id="market.tradableInstrument.instrument.code"]').contains(
'[title="Future"]',
'Futr'
);
});
it('must see a rejected order', () => {
+2 -1
View File
@@ -12,7 +12,8 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
-2
View File
@@ -12,8 +12,6 @@ NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
-2
View File
@@ -13,8 +13,6 @@ NX_VEGA_DOCS_URL=#
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
-2
View File
@@ -13,8 +13,6 @@ NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-mainnet/codfcglpplgmmlokgilfkpcjnmkbfiel
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet-mainnet
# TAG name of the current app version - TODO: bump to the latest upon release
NX_APP_VERSION=v0.20.21-core-0.71.6
-2
View File
@@ -13,8 +13,6 @@ NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-mainnet/codfcglpplgmmlokgilfkpcjnmkbfiel
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet-mainnet
# TAG name of the current app version - TODO: bump to the latest upon release
NX_APP_VERSION=v0.20.19-core-0.71.6
+1 -3
View File
@@ -13,11 +13,9 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
# NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS
# NX_PRODUCT_PERPETUALS
+1 -3
View File
@@ -14,8 +14,6 @@ NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
@@ -24,4 +22,4 @@ NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
-3
View File
@@ -15,9 +15,6 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false
+8
View File
@@ -1,2 +1,10 @@
import { t } from '@vegaprotocol/i18n';
export const THROTTLE_UPDATE_TIME = 500;
export const ONBOARDING_VIEWED_KEY = 'vega_onboarding_viewed';
export const MAINNET_WELCOME_HEADER = t(
'Trade cash settled futures on the fully decentralised Vega network.'
);
export const TESTNET_WELCOME_HEADER = t(
'Try out trading cash settled futures on the fully decentralised Vega network (Testnet).'
);
@@ -1,4 +1,4 @@
import { Fragment, useState } from 'react';
import { useState } from 'react';
import type {
SuccessorProposalListFieldsFragment,
NewMarketSuccessorFieldsFragment,
@@ -52,7 +52,7 @@ export const MarketSuccessorProposalBanner = ({
TOKEN_PROPOSAL.replace(':id', item.id || '')
);
return (
<Fragment key={i}>
<>
<ExternalLink href={externalLink} key={i}>
{
(item.terms?.change as NewMarketSuccessorFieldsFragment)
@@ -60,7 +60,7 @@ export const MarketSuccessorProposalBanner = ({
}
</ExternalLink>
{i < successors.length - 1 && ', '}
</Fragment>
</>
);
})}
</div>
@@ -3,7 +3,7 @@ import { Header, HeaderTitle } from '../header';
import { useParams } from 'react-router-dom';
import { MarketSelector } from '../../components/market-selector/market-selector';
import { MarketHeaderStats } from '../../client-pages/market/market-header-stats';
import { useMarket, useMarketList } from '@vegaprotocol/markets';
import { useMarket } from '@vegaprotocol/markets';
import { useState } from 'react';
export const MarketHeader = () => {
@@ -11,10 +11,6 @@ export const MarketHeader = () => {
const { data } = useMarket(marketId);
const [open, setOpen] = useState(false);
// Ensure that markets are kept cached so opening the list
// shows all markets instantly
useMarketList();
if (!data) return null;
return (
@@ -132,7 +132,6 @@ describe('MarketSelector', () => {
data: markets,
loading: false,
error: undefined,
reload: jest.fn(),
});
it('Button "All" should be selected by default', () => {
@@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
import uniqBy from 'lodash/uniqBy';
import { type MarketMaybeWithDataAndCandles } from '@vegaprotocol/markets';
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/markets';
import {
TradingInput,
TinyScroll,
@@ -8,7 +8,7 @@ import {
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import type { CSSProperties } from 'react';
import { useCallback, useState, useMemo, useRef, useEffect } from 'react';
import { useCallback, useState, useMemo, useRef } from 'react';
import { FixedSizeList } from 'react-window';
import { useMarketSelectorList } from './use-market-selector-list';
import type { ProductType } from './product-selector';
@@ -44,12 +44,7 @@ export const MarketSelector = ({
assets: [],
});
const allProducts = filter.product === Product.All;
const { markets, data, loading, error, reload } =
useMarketSelectorList(filter);
useEffect(() => {
reload();
}, [reload]);
const { markets, data, loading, error } = useMarketSelectorList(filter);
return (
<div data-testid="market-selector">
@@ -15,7 +15,6 @@ export const Sort = {
Gained: 'Gained',
Lost: 'Lost',
New: 'New',
TopTraded: 'TopTraded',
} as const;
export type SortType = keyof typeof Sort;
@@ -27,7 +26,6 @@ export const SortTypeMapping: {
[Sort.Gained]: 'Top gaining',
[Sort.Lost]: 'Top losing',
[Sort.New]: 'New markets',
[Sort.TopTraded]: 'Top traded',
};
const SortIconMapping: {
@@ -37,7 +35,6 @@ const SortIconMapping: {
[Sort.Gained]: VegaIconNames.TREND_UP,
[Sort.Lost]: VegaIconNames.TREND_DOWN,
[Sort.New]: VegaIconNames.STAR,
[Sort.TopTraded]: VegaIconNames.ARROW_UP,
};
export const SortDropdown = ({
@@ -1,11 +1,7 @@
import { useMemo } from 'react';
import orderBy from 'lodash/orderBy';
import { MarketState } from '@vegaprotocol/types';
import {
calcCandleVolume,
calcTradedFactor,
useMarketList,
} from '@vegaprotocol/markets';
import { calcCandleVolume, useMarketList } from '@vegaprotocol/markets';
import { priceChangePercentage } from '@vegaprotocol/utils';
import type { Filter } from '../../components/market-selector/market-selector';
import { Sort } from './sort-dropdown';
@@ -24,7 +20,7 @@ export const useMarketSelectorList = ({
sort,
searchTerm,
}: Filter) => {
const { data, loading, error, reload } = useMarketList();
const { data, loading, error } = useMarketList();
const markets = useMemo(() => {
if (!data?.length) return [];
@@ -98,14 +94,10 @@ export const useMarketSelectorList = ({
);
}
if (sort === Sort.TopTraded) {
return orderBy(markets, [(m) => calcTradedFactor(m)], ['desc']);
}
return markets;
}, [data, product, searchTerm, assets, sort]);
return { markets, data, loading, error, reload };
return { markets, data, loading, error };
};
export const isMarketActive = (state: MarketState) => {
@@ -1,6 +1,6 @@
import { VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import { MarketSelector } from '../market-selector';
import { useMarket, useMarketList } from '@vegaprotocol/markets';
import { useMarket } from '@vegaprotocol/markets';
import { t } from '@vegaprotocol/i18n';
import { useParams } from 'react-router-dom';
import * as PopoverPrimitive from '@radix-ui/react-popover';
@@ -14,10 +14,6 @@ export const NavHeader = () => {
const { data } = useMarket(marketId);
const [open, setOpen] = useState(false);
// Ensure that markets are kept cached so opening the list
// shows all markets instantly
useMarketList();
if (!marketId) return null;
return (
@@ -1,36 +1,16 @@
import { MemoryRouter } from 'react-router-dom';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { GetStarted } from './get-started';
import { render, screen } from '@testing-library/react';
let mockStep = 1;
jest.mock('./use-get-onboarding-step', () => ({
...jest.requireActual('./use-get-onboarding-step'),
useGetOnboardingStep: jest.fn(() => mockStep),
}));
describe('GetStarted', () => {
const renderComponent = (context: Partial<VegaWalletContextShape> = {}) => {
return render(
<MemoryRouter>
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
<GetStarted />
</VegaWalletContext.Provider>
</MemoryRouter>
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
<GetStarted />
</VegaWalletContext.Provider>
);
};
const checkTicks = (elements: Element[]) => {
elements.forEach((item, i) => {
if (i + 1 < mockStep) {
expect(item.querySelector('[data-testid="icon-tick"]')).toBeTruthy();
}
});
};
beforeEach(() => {
jest.clearAllMocks();
});
it('renders full get started content if not connected and no browser wallet detected', () => {
renderComponent();
@@ -40,71 +20,12 @@ describe('GetStarted', () => {
it('renders connect prompt if no pubKey but wallet installed', () => {
globalThis.window.vega = {} as Vega;
renderComponent();
expect(screen.getByTestId('get-started-banner')).toBeInTheDocument();
expect(screen.getByTestId('order-connect-wallet')).toBeInTheDocument();
globalThis.window.vega = undefined as unknown as Vega;
});
it('renders nothing if connected', () => {
mockStep = 0;
const { container } = renderComponent({ pubKey: 'my-pubkey' });
expect(container).toBeEmptyDOMElement();
});
it('steps should be ticked', () => {
const navigatorGetter: jest.SpyInstance = jest.spyOn(
window.navigator,
'userAgent',
'get'
);
navigatorGetter.mockReturnValue('Chrome');
mockStep = 1;
const { rerender, container } = renderComponent();
expect(screen.queryByTestId('icon-tick')).not.toBeInTheDocument();
expect(screen.getByTestId('get-wallet-button')).toBeInTheDocument();
mockStep = 2;
rerender(
<MemoryRouter>
<VegaWalletContext.Provider value={{} as VegaWalletContextShape}>
<GetStarted />
</VegaWalletContext.Provider>
</MemoryRouter>
);
checkTicks(screen.getAllByRole('listitem'));
expect(screen.getByRole('button', { name: 'Connect' })).toBeInTheDocument();
mockStep = 3;
rerender(
<MemoryRouter>
<VegaWalletContext.Provider value={{} as VegaWalletContextShape}>
<GetStarted />
</VegaWalletContext.Provider>
</MemoryRouter>
);
checkTicks(screen.getAllByRole('listitem'));
expect(screen.getByRole('button', { name: 'Deposit' })).toBeInTheDocument();
mockStep = 4;
rerender(
<MemoryRouter>
<VegaWalletContext.Provider value={{} as VegaWalletContextShape}>
<GetStarted />
</VegaWalletContext.Provider>
</MemoryRouter>
);
checkTicks(screen.getAllByRole('listitem'));
expect(screen.getByRole('button', { name: 'Dismiss' })).toBeInTheDocument();
mockStep = 5;
rerender(
<MemoryRouter>
<VegaWalletContext.Provider
value={{ pubKey: 'my-pubkey' } as VegaWalletContextShape}
>
<GetStarted />
</VegaWalletContext.Provider>
</MemoryRouter>
);
expect(container).toBeEmptyDOMElement();
});
});
@@ -1,96 +1,36 @@
import classNames from 'classnames';
import { t } from '@vegaprotocol/i18n';
import { ExternalLink, Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
import {
ExternalLink,
Intent,
TradingButton,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import {
GetWalletButton,
useVegaWallet,
useVegaWalletDialogStore,
isBrowserWalletInstalled,
} from '@vegaprotocol/wallet';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { useNavigate } from 'react-router-dom';
import {
OnboardingStep,
useGetOnboardingStep,
} from './use-get-onboarding-step';
import { Links, Routes } from '../../pages/client-router';
import { useGlobalStore } from '../../stores';
import { useSidebar, ViewType } from '../sidebar';
import * as constants from '../constants';
interface Props {
lead?: string;
}
const GetStartedButton = ({ step }: { step: OnboardingStep }) => {
const navigate = useNavigate();
const [, setOnboardingViewed] = useLocalStorage(
constants.ONBOARDING_VIEWED_KEY
);
const update = useGlobalStore((store) => store.update);
const marketId = useGlobalStore((store) => store.marketId);
const link = marketId ? Links[Routes.MARKET](marketId) : Links[Routes.HOME]();
const openVegaWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const setView = useSidebar((store) => store.setView);
let buttonText = t('Get started');
let onClickHandle = () => {
openVegaWalletDialog();
};
if (step === OnboardingStep.ONBOARDING_WALLET_STEP) {
return <GetWalletButton className="justify-between" />;
} else if (step === OnboardingStep.ONBOARDING_CONNECT_STEP) {
buttonText = t('Connect');
} else if (step === OnboardingStep.ONBOARDING_DEPOSIT_STEP) {
buttonText = t('Deposit');
onClickHandle = () => {
navigate(link);
setView({ type: ViewType.Deposit });
update({ onBoardingDismissed: true });
};
} else if (step === OnboardingStep.ONBOARDING_ORDER_STEP) {
buttonText = t('Dismiss');
onClickHandle = () => {
navigate(link);
setView({ type: ViewType.Order });
setOnboardingViewed('true');
};
}
return (
<TradingButton
onClick={onClickHandle}
size="small"
data-testid="get-started-button"
intent={Intent.Info}
>
{buttonText}
</TradingButton>
);
};
export const GetStarted = ({ lead }: Props) => {
const { pubKey } = useVegaWallet();
const { VEGA_ENV, VEGA_NETWORKS } = useEnvironment();
const CANONICAL_URL = VEGA_NETWORKS[VEGA_ENV] || 'https://console.vega.xyz';
const [onBoardingViewed] = useLocalStorage(constants.ONBOARDING_VIEWED_KEY);
const currentStep = useGetOnboardingStep();
const [, setOnboardingViewed] = useLocalStorage(
constants.ONBOARDING_VIEWED_KEY
);
const openVegaWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const getStartedNeeded =
onBoardingViewed !== 'true' &&
currentStep &&
currentStep < OnboardingStep.ONBOARDING_COMPLETE_STEP;
const onButtonClick = () => {
openVegaWalletDialog();
setOnboardingViewed('true');
};
const wrapperClasses = classNames(
'flex flex-col py-4 px-6 gap-4 rounded',
@@ -99,39 +39,27 @@ export const GetStarted = ({ lead }: Props) => {
{ 'mt-8': !lead }
);
if (getStartedNeeded) {
if (!pubKey && !isBrowserWalletInstalled()) {
return (
<div className={wrapperClasses} data-testid="get-started-banner">
{lead && <h2>{lead}</h2>}
<h3 className="text-lg">{t('Get started')}</h3>
<div>
<ul className="list-none">
<Step
step={1}
text={t('Get a Vega wallet')}
complete={currentStep > OnboardingStep.ONBOARDING_WALLET_STEP}
/>
<Step
step={2}
text={t('Connect')}
complete={Boolean(
currentStep > OnboardingStep.ONBOARDING_CONNECT_STEP || pubKey
)}
/>
<Step
step={3}
text={t('Deposit funds')}
complete={currentStep > OnboardingStep.ONBOARDING_DEPOSIT_STEP}
/>
<Step
step={4}
text={t('Open a position')}
complete={currentStep > OnboardingStep.ONBOARDING_ORDER_STEP}
/>
<ul className="list-decimal list-inside">
<li>{t('Get a Vega wallet')}</li>
<li>{t('Connect')}</li>
<li>{t('Deposit funds')}</li>
<li>{t('Open a position')}</li>
</ul>
</div>
<div>
<GetStartedButton step={currentStep} />
<TradingButton
intent={Intent.Info}
onClick={onButtonClick}
data-testid="get-started-button"
>
{t('Get started')}
</TradingButton>
</div>
{VEGA_ENV === Networks.MAINNET && (
<p className="text-sm">
@@ -156,7 +84,7 @@ export const GetStarted = ({ lead }: Props) => {
if (!pubKey) {
return (
<div className={wrapperClasses}>
<p className="mb-1 text-sm">
<p className="text-sm mb-1">
You need a{' '}
<ExternalLink href="https://vega.xyz/wallet">
Vega wallet
@@ -177,34 +105,3 @@ export const GetStarted = ({ lead }: Props) => {
return null;
};
const Step = ({
step,
text,
complete,
}: {
step: number;
text: string;
complete: boolean;
}) => {
return (
<li
className={classNames('flex', {
'text-vega-clight-200 dark:text-vega-cdark-200': complete,
})}
>
<div className="flex justify-center w-5">
{complete ? <Tick /> : <span>{step}.</span>}
</div>
<div className="ml-1">{text}</div>
</li>
);
};
const Tick = () => {
return (
<span className="relative right-[2px]">
<VegaIcon name={VegaIconNames.TICK} size={18} />
</span>
);
};
@@ -1,97 +0,0 @@
import type { ReactNode } from 'react';
import { renderHook } from '@testing-library/react';
import {
useGetOnboardingStep,
OnboardingStep,
} from './use-get-onboarding-step';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { depositsProvider } from '@vegaprotocol/deposits';
import { aggregatedAccountsDataProvider } from '@vegaprotocol/accounts';
import { ordersWithMarketProvider } from '@vegaprotocol/orders';
import { positionsDataProvider } from '@vegaprotocol/positions';
let mockData: object[] | null = [{ id: 'item-id' }];
jest.mock('@vegaprotocol/data-provider', () => ({
...jest.requireActual('@vegaprotocol/data-provider'),
useDataProvider: jest.fn(() => ({ data: mockData })),
}));
let mockContext: Partial<VegaWalletContextShape> = { pubKey: 'test-pubkey' };
describe('useGetOnboardingStep', () => {
beforeEach(() => {
jest.clearAllMocks();
mockData = [{ id: 'item-id' }];
mockContext = { pubKey: 'test-pubkey' };
globalThis.window.vega = {} as Vega;
});
const wrapper = ({ children }: { children: ReactNode }) => (
<VegaWalletContext.Provider
value={mockContext as unknown as VegaWalletContextShape}
>
{children}
</VegaWalletContext.Provider>
);
it('should return properly ONBOARDING_UNKNOWN_STEP', () => {
mockData = null;
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
expect(result.current).toEqual(OnboardingStep.ONBOARDING_UNKNOWN_STEP);
});
it('should return properly ONBOARDING_WALLET_STEP', () => {
// @ts-ignore test only purpose
globalThis.window.vega = undefined;
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
expect(result.current).toEqual(OnboardingStep.ONBOARDING_WALLET_STEP);
});
it('should return properly ONBOARDING_CONNECT_STEP', () => {
mockContext = { pubKey: null };
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
expect(result.current).toEqual(OnboardingStep.ONBOARDING_CONNECT_STEP);
});
it('should return properly ONBOARDING_DEPOSIT_STEP', async () => {
(useDataProvider as jest.Mock).mockImplementation((args) => {
if (
args.dataProvider === depositsProvider ||
args.dataProvider === aggregatedAccountsDataProvider
) {
return { data: [] };
}
return { data: mockData };
});
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
await expect(result.current).toEqual(
OnboardingStep.ONBOARDING_DEPOSIT_STEP
);
});
it('should return properly ONBOARDING_ORDER_STEP', async () => {
(useDataProvider as jest.Mock).mockImplementation((args) => {
if (
args.dataProvider === ordersWithMarketProvider ||
args.dataProvider === positionsDataProvider
) {
return { data: [] };
}
return { data: mockData };
});
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
await expect(result.current).toEqual(OnboardingStep.ONBOARDING_ORDER_STEP);
});
it('should return properly ONBOARDING_COMPLETE_STEP', async () => {
(useDataProvider as jest.Mock).mockImplementation(() => {
return { data: mockData };
});
const { result } = renderHook(() => useGetOnboardingStep(), { wrapper });
await expect(result.current).toEqual(
OnboardingStep.ONBOARDING_COMPLETE_STEP
);
});
});
@@ -1,82 +0,0 @@
import { isBrowserWalletInstalled, useVegaWallet } from '@vegaprotocol/wallet';
import { depositsProvider } from '@vegaprotocol/deposits';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { ordersWithMarketProvider } from '@vegaprotocol/orders';
import * as Types from '@vegaprotocol/types';
import { aggregatedAccountsDataProvider } from '@vegaprotocol/accounts';
import { positionsDataProvider } from '@vegaprotocol/positions';
import { useGlobalStore } from '../../stores';
export enum OnboardingStep {
ONBOARDING_UNKNOWN_STEP,
ONBOARDING_WALLET_STEP,
ONBOARDING_CONNECT_STEP,
ONBOARDING_DEPOSIT_STEP,
ONBOARDING_ORDER_STEP,
ONBOARDING_COMPLETE_STEP,
}
export const useGetOnboardingStep = () => {
const connecting = useGlobalStore((store) => store.eagerConnecting);
const { pubKey = '', pubKeys } = useVegaWallet();
const { data: depositsData } = useDataProvider({
dataProvider: depositsProvider,
variables: { partyId: pubKey || '' },
skip: !pubKey,
});
const { data: collateralData } = useDataProvider({
dataProvider: aggregatedAccountsDataProvider,
variables: { partyId: pubKey || '' },
skip: !pubKey,
});
const collaterals = Boolean(collateralData?.length);
const deposits =
depositsData?.some(
(item) => item.status === Types.DepositStatus.STATUS_FINALIZED
) || false;
const { data: ordersData } = useDataProvider({
dataProvider: ordersWithMarketProvider,
variables: {
partyId: pubKey || '',
pagination: {
first: 1,
},
},
skip: !pubKey,
});
const orders = Boolean(ordersData?.length);
const partyIds = pubKeys?.map((item) => item.publicKey) || [];
const { data: positionsData } = useDataProvider({
dataProvider: positionsDataProvider,
variables: {
partyIds,
},
skip: !partyIds?.length,
});
const positions = Boolean(positionsData?.length);
const isLoading = Boolean(
(connecting || pubKey) &&
(depositsData === null ||
ordersData === null ||
collateralData === null ||
positionsData === null)
);
if (isLoading) {
return OnboardingStep.ONBOARDING_UNKNOWN_STEP;
}
if (!isBrowserWalletInstalled()) {
return OnboardingStep.ONBOARDING_WALLET_STEP;
}
if (!pubKey) {
return OnboardingStep.ONBOARDING_CONNECT_STEP;
}
if (!deposits && !collaterals) {
return OnboardingStep.ONBOARDING_DEPOSIT_STEP;
}
if (!orders && !positions) {
return OnboardingStep.ONBOARDING_ORDER_STEP;
}
return OnboardingStep.ONBOARDING_COMPLETE_STEP;
};
@@ -3,19 +3,21 @@ import { GetStarted } from './get-started';
import { TradingButton } from '@vegaprotocol/ui-toolkit';
import { useNavigate } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import * as constants from '../constants';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import type { ReactNode } from 'react';
import { useGlobalStore } from '../../stores';
export const WelcomeDialogContent = () => {
const { VEGA_ENV } = useEnvironment();
const update = useGlobalStore((store) => store.update);
const [, setOnboardingViewed] = useLocalStorage(
constants.ONBOARDING_VIEWED_KEY
);
const navigate = useNavigate();
const browseMarkets = () => {
const link = Links[Routes.MARKETS]();
navigate(link);
update({ onBoardingDismissed: true });
setOnboardingViewed('true');
};
const lead =
VEGA_ENV === Networks.MAINNET
@@ -55,7 +57,7 @@ export const WelcomeDialogContent = () => {
{t('Browse the markets')}
</TradingButton>
</div>
<div className="sm:w-1/2 flex grow">
<div className="sm:w-1/2">
<GetStarted lead={lead} />
</div>
</div>
@@ -2,38 +2,31 @@ import React from 'react';
import { useNavigate } from 'react-router-dom';
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useEnvironment } from '@vegaprotocol/environment';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { useEnvironment } from '@vegaprotocol/environment';
import { isBrowserWalletInstalled } from '@vegaprotocol/wallet';
import * as constants from '../constants';
import { WelcomeDialogContent } from './welcome-dialog-content';
import { getConfig } from '@vegaprotocol/wallet';
import { Links, Routes } from '../../pages/client-router';
import { useGlobalStore } from '../../stores';
import {
useGetOnboardingStep,
OnboardingStep,
} from './use-get-onboarding-step';
import * as constants from '../constants';
export const WelcomeDialog = () => {
const { VEGA_ENV } = useEnvironment();
const [onBoardingViewed] = useLocalStorage(constants.ONBOARDING_VIEWED_KEY);
const update = useGlobalStore((store) => store.update);
const dismissed = useGlobalStore((store) => store.onBoardingDismissed);
const currentStep = useGetOnboardingStep();
const [onBoardingViewed, setOnboardingViewed] = useLocalStorage(
constants.ONBOARDING_VIEWED_KEY
);
const navigate = useNavigate();
const isOnboardingDialogNeeded =
onBoardingViewed !== 'true' &&
currentStep &&
currentStep < OnboardingStep.ONBOARDING_COMPLETE_STEP &&
!dismissed;
onBoardingViewed !== 'true' && !isBrowserWalletInstalled() && !getConfig();
const marketId = useGlobalStore((store) => store.marketId);
const onClose = () => {
setOnboardingViewed('true');
const link = marketId
? Links[Routes.MARKET](marketId)
: Links[Routes.HOME]();
navigate(link);
update({ onBoardingDismissed: true });
};
const title = (
<span className="font-alpha calt" data-testid="welcome-title">
+3 -7
View File
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import Head from 'next/head';
import type { AppProps } from 'next/app';
import { t } from '@vegaprotocol/i18n';
@@ -23,7 +23,7 @@ import {
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import './styles.css';
import { useGlobalStore, usePageTitleStore } from '../stores';
import { usePageTitleStore } from '../stores';
import DialogsContainer from './dialogs-container';
import ToastsManager from './toasts-manager';
import {
@@ -170,8 +170,7 @@ const PartyData = () => {
const MaybeConnectEagerly = () => {
const { VEGA_ENV, SENTRY_DSN } = useEnvironment();
const update = useGlobalStore((store) => store.update);
const eagerConnecting = useVegaEagerConnect(Connectors);
useVegaEagerConnect(Connectors);
const [isTelemetryApproved] = useTelemetryApproval();
useEthereumEagerConnect(
isTelemetryApproved ? { dsn: SENTRY_DSN, env: VEGA_ENV } : {}
@@ -183,8 +182,5 @@ const MaybeConnectEagerly = () => {
if (query && !pubKey) {
connect(Connectors['view']);
}
useEffect(() => {
update({ eagerConnecting });
}, [update, eagerConnecting]);
return null;
};
-4
View File
@@ -4,8 +4,6 @@ import produce from 'immer';
interface GlobalStore {
marketId: string | null;
onBoardingDismissed: boolean;
eagerConnecting: boolean;
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
}
@@ -16,8 +14,6 @@ interface PageTitleStore {
export const useGlobalStore = create<GlobalStore>()((set) => ({
marketId: LocalStorage.getItem('marketId') || null,
onBoardingDismissed: false,
eagerConnecting: false,
update: (newState) => {
set(
produce((state: GlobalStore) => {
+2 -55
View File
@@ -1,10 +1,6 @@
import * as Schema from '@vegaprotocol/types';
import type { Market, MarketMaybeWithDataAndCandles } from './markets-provider';
import {
calcTradedFactor,
filterAndSortMarkets,
totalFeesPercentage,
} from './market-utils';
import type { Market } from './markets-provider';
import { filterAndSortMarkets, totalFeesPercentage } from './market-utils';
const { MarketState, MarketTradingMode } = Schema;
const MARKET_A: Partial<Market> = {
@@ -81,52 +77,3 @@ describe('totalFees', () => {
expect(totalFeesPercentage(i)).toEqual(o);
});
});
describe('calcTradedFactor', () => {
const marketA = {
data: {
markPrice: '10',
},
candles: [
{
volume: '1000',
},
],
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
decimals: 18,
quantum: '1000000000000000000', // 1
},
},
},
},
};
const marketB = {
data: {
markPrice: '10',
},
candles: [
{
volume: '1000',
},
],
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
decimals: 18,
quantum: '1', // 0.0000000000000000001
},
},
},
},
};
it('a is "traded" more than b', () => {
const fa = calcTradedFactor(marketA as MarketMaybeWithDataAndCandles);
const fb = calcTradedFactor(marketB as MarketMaybeWithDataAndCandles);
// it should be true because market a's asset is "more valuable" than b's
expect(fa > fb).toBeTruthy();
});
});
+2 -22
View File
@@ -1,13 +1,8 @@
import { formatNumberPercentage, toBigNum } from '@vegaprotocol/utils';
import { formatNumberPercentage } from '@vegaprotocol/utils';
import * as Schema from '@vegaprotocol/types';
import BigNumber from 'bignumber.js';
import orderBy from 'lodash/orderBy';
import type {
Market,
Candle,
MarketMaybeWithData,
MarketMaybeWithDataAndCandles,
} from '../';
import type { Market, Candle, MarketMaybeWithData } from '../';
const { MarketState, MarketTradingMode } = Schema;
export const totalFees = (fees: Market['fees']['factors']) => {
@@ -91,18 +86,3 @@ export const calcCandleHigh = (candles: Candle[]): string | undefined => {
export const calcCandleVolume = (candles: Candle[]): string | undefined =>
candles &&
candles.reduce((acc, c) => new BigNumber(acc).plus(c.volume).toString(), '0');
export const calcTradedFactor = (m: MarketMaybeWithDataAndCandles) => {
const volume = Number(calcCandleVolume(m.candles || []) || 0);
const price = m.data?.markPrice ? Number(m.data.markPrice) : 0;
const quantum = Number(
m.tradableInstrument.instrument.product.settlementAsset.quantum
);
const decimals = Number(
m.tradableInstrument.instrument.product.settlementAsset.decimals
);
const fp = toBigNum(price, decimals);
const fq = toBigNum(quantum, decimals);
const factor = fq.multipliedBy(fp).multipliedBy(volume);
return factor.toNumber();
};
@@ -128,9 +128,6 @@ fragment StopOrderFields on StopOrder {
updatedAt
partyId
marketId
order {
...OrderFields
}
trigger {
... on StopOrderPrice {
price
@@ -34,51 +34,22 @@ export type OrdersUpdateSubscription = { __typename?: 'Subscription', orders?: A
export type OrderSubmissionFieldsFragment = { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null };
export type StopOrderFieldsFragment = { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, order?: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } | null, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } };
export type StopOrderFieldsFragment = { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } };
export type StopOrdersQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type StopOrdersQuery = { __typename?: 'Query', stopOrders?: { __typename?: 'StopOrderConnection', edges?: Array<{ __typename?: 'StopOrderEdge', node?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, order?: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } | null, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null }> | null } | null };
export type StopOrdersQuery = { __typename?: 'Query', stopOrders?: { __typename?: 'StopOrderConnection', edges?: Array<{ __typename?: 'StopOrderEdge', node?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null }> | null } | null };
export type StopOrderByIdQueryVariables = Types.Exact<{
stopOrderId: Types.Scalars['ID'];
}>;
export type StopOrderByIdQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, order?: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } | null, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null };
export type StopOrderByIdQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null };
export const OrderUpdateFieldsFragmentDoc = gql`
fragment OrderUpdateFields on OrderUpdate {
id
marketId
type
side
size
status
rejectionReason
price
timeInForce
remaining
expiresAt
createdAt
updatedAt
liquidityProvisionId
peggedOrder {
__typename
reference
offset
}
icebergOrder {
__typename
peakSize
minimumVisibleSize
reservedRemaining
}
}
`;
export const OrderFieldsFragmentDoc = gql`
fragment OrderFields on Order {
id
@@ -114,6 +85,35 @@ export const OrderFieldsFragmentDoc = gql`
}
}
`;
export const OrderUpdateFieldsFragmentDoc = gql`
fragment OrderUpdateFields on OrderUpdate {
id
marketId
type
side
size
status
rejectionReason
price
timeInForce
remaining
expiresAt
createdAt
updatedAt
liquidityProvisionId
peggedOrder {
__typename
reference
offset
}
icebergOrder {
__typename
peakSize
minimumVisibleSize
reservedRemaining
}
}
`;
export const OrderSubmissionFieldsFragmentDoc = gql`
fragment OrderSubmissionFields on OrderSubmission {
marketId
@@ -144,9 +144,6 @@ export const StopOrderFieldsFragmentDoc = gql`
updatedAt
partyId
marketId
order {
...OrderFields
}
trigger {
... on StopOrderPrice {
price
@@ -159,8 +156,7 @@ export const StopOrderFieldsFragmentDoc = gql`
...OrderSubmissionFields
}
}
${OrderFieldsFragmentDoc}
${OrderSubmissionFieldsFragmentDoc}`;
${OrderSubmissionFieldsFragmentDoc}`;
export const OrderByIdDocument = gql`
query OrderById($orderId: ID!) {
orderByID(id: $orderId) {
@@ -296,7 +296,7 @@ export const OrderListTable = memo<
</ButtonLink>
</>
)}
<ActionsDropdown data-testid="order-actions-content">
<ActionsDropdown data-testid="market-actions-content">
<TradingDropdownCopyItem
value={data.id}
text={t('Copy order ID')}
@@ -1,13 +1,11 @@
import { t } from '@vegaprotocol/i18n';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect } from 'react';
import { StopOrdersTable } from '../stop-orders-table/stop-orders-table';
import type { useDataGridEvents } from '@vegaprotocol/datagrid';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import type { StopOrder } from '../order-data-provider/stop-orders-data-provider';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { stopOrdersWithMarketProvider } from '../order-data-provider/stop-orders-data-provider';
import { OrderViewDialog } from '../order-list/order-view-dialog';
import type { Order } from '../order-data-provider';
export interface StopOrdersManagerProps {
partyId: string;
@@ -25,7 +23,6 @@ export const StopOrdersManager = ({
gridProps,
}: StopOrdersManagerProps) => {
const create = useVegaTransactionStore((state) => state.create);
const [viewOrder, setViewOrder] = useState<Order | null>(null);
const variables = { partyId };
const { data, error, reload } = useDataProvider({
@@ -56,25 +53,14 @@ export const StopOrdersManager = ({
);
return (
<>
<StopOrdersTable
rowData={data}
onCancel={cancel}
onView={setViewOrder}
onMarketClick={onMarketClick}
isReadOnly={isReadOnly}
suppressAutoSize
overlayNoRowsTemplate={error ? error.message : t('No stop orders')}
{...gridProps}
/>
{viewOrder && (
<OrderViewDialog
isOpen={Boolean(viewOrder)}
order={viewOrder}
onChange={() => setViewOrder(null)}
onMarketClick={onMarketClick}
/>
)}
</>
<StopOrdersTable
rowData={data}
onCancel={cancel}
onMarketClick={onMarketClick}
isReadOnly={isReadOnly}
suppressAutoSize
overlayNoRowsTemplate={error ? error.message : t('No stop orders')}
{...gridProps}
/>
);
};
@@ -4,7 +4,6 @@ import type { PartialDeep } from 'type-fest';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { MockedProvider } from '@apollo/client/testing';
import userEvent from '@testing-library/user-event';
import {
StopOrdersTable,
type StopOrdersTableProps,
@@ -28,7 +27,6 @@ jest.mock('@vegaprotocol/utils', () => ({
}));
const defaultProps: StopOrdersTableProps = {
onView: jest.fn(),
rowData: [],
onCancel: jest.fn(),
isReadOnly: false,
@@ -106,7 +104,6 @@ const rowData = [
generateStopOrder({
id: 'stop-order-6',
status: Schema.StopOrderStatus.STATUS_TRIGGERED,
order: { id: 'order-id' },
}),
];
@@ -237,37 +234,4 @@ describe('StopOrdersTable', () => {
);
});
});
it('shows actions dropdown only for triggered stop orders', async () => {
await act(async () => {
render(generateJsx({ rowData }));
});
const dropdownMenuButtons = screen.getAllByTestId('dropdown-menu');
expect(dropdownMenuButtons).toHaveLength(1);
dropdownMenuButtons.forEach((dropdownMenuButton) => {
const id = dropdownMenuButton
.closest('[role="row"]')
?.getAttribute('row-id');
expect(rowData.find((row) => row.id === id)?.status).toEqual(
Schema.StopOrderStatus.STATUS_TRIGGERED
);
});
});
it('action dropdown has copy and view order actions', async () => {
const onView = jest.fn();
const user = userEvent.setup();
await act(async () => {
render(generateJsx({ rowData, onView }));
});
const dropdownMenuButtons = screen.getByTestId('dropdown-menu');
dropdownMenuButtons.click();
await user.click(dropdownMenuButtons as HTMLButtonElement);
const menuItems = screen.getAllByRole('menuitem');
expect(menuItems).toHaveLength(2);
expect(menuItems[0]).toHaveTextContent('Copy order ID');
expect(menuItems[1]).toHaveTextContent('View order details');
menuItems[1].click();
expect(onView).toBeCalled();
});
});
@@ -7,14 +7,7 @@ import {
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import * as Schema from '@vegaprotocol/types';
import {
ActionsDropdown,
ButtonLink,
VegaIcon,
VegaIconNames,
DropdownMenuItem,
TradingDropdownCopyItem,
} from '@vegaprotocol/ui-toolkit';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import type { ForwardedRef } from 'react';
import { memo, useMemo } from 'react';
import {
@@ -35,7 +28,6 @@ import type {
import type { AgGridReact } from 'ag-grid-react';
import type { StopOrder } from '../order-data-provider/stop-orders-data-provider';
import type { ColDef } from 'ag-grid-community';
import type { Order } from '../order-data-provider';
const defaultColDef = {
resizable: true,
@@ -46,13 +38,12 @@ const defaultColDef = {
export type StopOrdersTableProps = TypedDataAgGrid<StopOrder> & {
onCancel: (order: StopOrder) => void;
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
onView: (order: Order) => void;
isReadOnly: boolean;
};
export const StopOrdersTable = memo<
StopOrdersTableProps & { ref?: ForwardedRef<AgGridReact> }
>(({ onCancel, onView, onMarketClick, ...props }: StopOrdersTableProps) => {
>(({ onCancel, onMarketClick, ...props }: StopOrdersTableProps) => {
const showAllActions = !props.isReadOnly;
const columnDefs: ColDef[] = useMemo(
() => [
@@ -245,32 +236,12 @@ export const StopOrdersTable = memo<
{t('Cancel')}
</ButtonLink>
)}
{data.status === Schema.StopOrderStatus.STATUS_TRIGGERED &&
data.order && (
<ActionsDropdown data-testid="stop-order-actions-content">
<TradingDropdownCopyItem
value={data.order.id}
text={t('Copy order ID')}
/>
<DropdownMenuItem
key={'view-order'}
data-testid="view-order"
onClick={() =>
data.order &&
onView({ ...data.order, market: data.market })
}
>
<VegaIcon name={VegaIconNames.INFO} size={16} />
{t('View order details')}
</DropdownMenuItem>
</ActionsDropdown>
)}
</div>
);
},
},
],
[onCancel, onMarketClick, onView, props.isReadOnly, showAllActions]
[onCancel, onMarketClick, props.isReadOnly, showAllActions]
);
return (
@@ -181,7 +181,7 @@ const getSubscriptionVariables = (
): PositionsSubscriptionSubscriptionVariables[] =>
([] as string[]).concat(variables.partyIds).map((partyId) => ({ partyId }));
export const positionsDataProvider = makeDataProvider<
const positionsDataProvider = makeDataProvider<
PositionsQuery,
PositionFieldsFragment[],
PositionsSubscriptionSubscription,
@@ -5,7 +5,7 @@ import { VegaIconNameMap } from './vega-icon-record';
export interface VegaIconProps {
name: VegaIconNames;
size?: 8 | 10 | 12 | 13 | 14 | 16 | 18 | 20 | 24 | 32;
size?: 8 | 10 | 12 | 13 | 14 | 16 | 20 | 24 | 32;
}
export const VegaIcon = ({ size = 16, name }: VegaIconProps) => {
@@ -204,7 +204,6 @@ const ConnectorList = ({
setWalletUrl: (value: string) => void;
isDesktopWalletRunning: boolean | null;
}) => {
const { pubKey } = useVegaWallet();
const title = isBrowserWalletInstalled()
? t('Connect Vega wallet')
: t('Get a Vega wallet');
@@ -235,7 +234,7 @@ const ConnectorList = ({
onClick={() => onSelect('injected')}
/>
) : (
<GetWalletButton />
<GetWallet />
)}
</div>
<div>
@@ -243,7 +242,6 @@ const ConnectorList = ({
type="view"
text={t('View as party')}
onClick={() => onSelect('view')}
disabled={Boolean(pubKey)}
/>
</div>
<div className="last:mb-0">
@@ -320,7 +318,7 @@ const SelectedForm = ({
throw new Error('No connector selected');
};
export const GetWalletButton = ({ className }: { className?: string }) => {
const GetWallet = () => {
const { MOZILLA_EXTENSION_URL, CHROME_EXTENSION_URL } = useEnvironment();
const isItChrome = window.navigator.userAgent.includes('Chrome');
const isItMozilla =
@@ -349,13 +347,10 @@ export const GetWalletButton = ({ className }: { className?: string }) => {
return !isItChrome && !isItMozilla ? (
<div
className={classNames(
[
'bg-vega-blue-350 hover:bg-vega-blue-400 dark:bg-vega-blue-650 dark:hover:bg-vega-blue-600',
'flex gap-2 items-center justify-center rounded h-8 px-3 relative',
],
className
)}
className={classNames([
'bg-vega-blue-350 hover:bg-vega-blue-400 dark:bg-vega-blue-650 dark:hover:bg-vega-blue-600',
'flex gap-2 items-center justify-center rounded h-8 px-3 relative',
])}
data-testid="get-wallet-button"
>
{buttonContent}
@@ -365,7 +360,7 @@ export const GetWalletButton = ({ className }: { className?: string }) => {
onClick={onClick}
intent={Intent.Info}
data-testid="get-wallet-button"
className={classNames('relative', className)}
className="relative"
size="small"
fill
>
@@ -414,7 +409,6 @@ const CustomUrlInput = ({
isDesktopWalletRunning: boolean | null;
onSelect: (type: WalletType) => void;
}) => {
const { pubKey } = useVegaWallet();
const [urlInputExpanded, setUrlInputExpanded] = useState(false);
return urlInputExpanded ? (
<>
@@ -439,7 +433,7 @@ const CustomUrlInput = ({
/>
</TradingFormGroup>
<ConnectionOption
disabled={!isDesktopWalletRunning || Boolean(pubKey)}
disabled={!isDesktopWalletRunning}
type="jsonRpc"
text={t('Connect the App/CLI')}
onClick={() => onSelect('jsonRpc')}
@@ -448,7 +442,7 @@ const CustomUrlInput = ({
) : (
<>
<ConnectionOption
disabled={!isDesktopWalletRunning || Boolean(pubKey)}
disabled={!isDesktopWalletRunning}
type="jsonRpc"
text={t('Use the Desktop App/CLI')}
onClick={() => onSelect('jsonRpc')}
@@ -459,7 +453,6 @@ const CustomUrlInput = ({
<button
className="underline text-default"
onClick={() => setUrlInputExpanded(true)}
disabled={Boolean(pubKey)}
>
{t('Enter a custom wallet location')}{' '}
<VegaIcon name={VegaIconNames.ARROW_RIGHT} />
@@ -474,7 +467,6 @@ const CustomUrlInput = ({
<button
className="underline"
onClick={() => setUrlInputExpanded(true)}
disabled={Boolean(pubKey)}
>
{t('custom wallet location')}
</button>
@@ -12,9 +12,7 @@ export const useIsWalletServiceRunning = (
const checkState = useCallback(async () => {
const connector = connectors['jsonRpc'] as JsonRpcConnector;
if (url && url !== connector.url) {
connector.url = url;
}
connector.url = url;
try {
await connector.checkCompat();
const chainIdResult = await connector.getChainId();
+2 -1
View File
@@ -21,7 +21,8 @@
"echo $NX_TENDERMINT_URL",
"echo $NX_TENDERMINT_WEBSOCKET_URL",
"echo $NX_ETHEREUM_PROVIDER_URL"
]
],
"url": "https://cloud.nx.app"
}
}
},
+1 -1
View File
@@ -166,7 +166,7 @@
"babel-jest": "29.4.3",
"babel-loader": "8.1.0",
"css-loader": "^6.4.0",
"cypress": "12.17.0",
"cypress": "^12.2.0",
"cypress-mochawesome-reporter": "^3.3.0",
"cypress-real-events": "^1.8.1",
"dotenv": "^16.0.1",
+6 -18
View File
@@ -1,34 +1,22 @@
# First use & get started steps
## "Onboarding" state is gradable and has following steps: (<a name="0007-FUGS-002" href="#0007-FUGS-002">0007-FUGS-003</a>)
- New visitor - has no wallet nor any dapps running.
- I **must** see CTA button "Get started", which clicking launches the get wallet flow (wallet connection window with links to the Chrome and FF stores)
- Has wallet - Once wallet detected set to this.
- I **must** see CTA button "Connect", which clicking launches the wallet connection
- Has connected - Once user has connected set to this.
- I **must** see CTA button "Deposit", which clicking launches the deposit ticket.
- Has deposited - Once user has made AT LEAST one deposit of ANY settlement asset set to this.
- I **must** see CTA button "Dismiss", which clicking updates the state to Ready to trade - Get started box should now disappear forever.
- Ready to trade - Once user has made at least one deposit AND has dismissed the "Get Started" box in the ticket.
- Onboarding window nor contextual "Get started" banner should be not displayed anymore.
## When first enter the app or next times, but I didn't accomplish all onboarding steps.
## When first enter the app
- **Must** When I open Console for the first time I can see what it is i.e. a short description and key features in auto opened dialog window (first use popup) (<a name="0007-FUGS-001" href="#0007-FUGS-001">0007-FUGS-001</a>)
- If full "onboarding" hasn't been accomplished yet, I **must** see the popup with my progress marked. (<a name="0007-FUGS-002" href="#0007-FUGS-002">0007-FUGS-002</a>)
- **Must** If my wallet is already connected I don't see the first use popup (<a name="0007-FUGS-002" href="#0007-FUGS-002">0007-FUGS-002</a>)
- - **Must** If window.vega is detected (browser wallet is installed), don't open first use popup (<a name="0007-FUGS-003" href="#0007-FUGS-003">0007-FUGS-003</a>)
- - **Must** If we detect previous connection using localStorage for desktop/cli wallet, don't open first use popup (<a name="0007-FUGS-004" href="#0007-FUGS-004">0007-FUGS-004</a>)
- **Must** There is a call to action to browse markets, linking to the market view market/all (<a name="0007-FUGS-005" href="#0007-FUGS-005">0007-FUGS-005</a>)
- **Must** I can see the steps I need to take to get started trading (<a name="0007-FUGS-007" href="#0007-FUGS-006">0007-FUGS-006</a>)
- **Must** There is a call to action to get started, triggering the connect modal (<a name="0007-FUGS-007" href="#0007-FUGS-007">0007-FUGS-007</a>)
- **Must** There is a link to try out trading on Fairground when I'm on Mainnet (<a name="0007-FUGS-008" href="#0007-FUGS-008">0007-FUGS-008</a>)
- **Must** There is a link to trade with real funds on Mainnet when I am on Fairground (<a name="0007-FUGS-010" href="#0007-FUGS-010">0007-FUGS-010</a>)
- **Must** When I am on the Fairground version, I can see a warning / call out that this is Fairground meaning I can try out with virtual assets at no risk (<a name="0007-FUGS-011" href="#0007-FUGS-011">0007-FUGS-011</a>)
- If I dismiss the popup, I **must** not see it unless I NOT accomplish full "onboarding"
- If I dismiss the popup, I land on the default market (<a name="0007-FUGS-012" href="#0007-FUGS-012">0007-FUGS-012</a>)
## When the popup has been dismissed:
## When first use popup has been seen, but no browser wallet is installed
- **Must** I can see the steps to get started with a visible call to action (according to my progress) in the context of the deal ticket, deposit, withdraw, transfer components in the sidebar (<a name="0007-FUGS-013" href="#0007-FUGS-013">0007-FUGS-013</a>)
- **Must** I can see the steps to get started with a visible call to action to "get started" in the context of the deal ticket, deposit, withdraw, transfer components in the sidebar (<a name="0007-FUGS-013" href="#0007-FUGS-013">0007-FUGS-013</a>)
- **Must** Remove buttons from pane containers that prompt to connect wallet (<a name="0007-FUGS-014" href="#0007-FUGS-014">0007-FUGS-014</a>)
- **Must** We've replaced "connect wallet" in the top right with "get started" (<a name="0007-FUGS-015" href="#0007-FUGS-015">0007-FUGS-015</a>)
- **Must** When I press the get started CTA, I see the wallet connect popup (<a name="0007-FUGS-016" href="#0007-FUGS-016">0007-FUGS-016</a>)
+27 -28
View File
@@ -2881,9 +2881,9 @@
globby "^11.0.4"
"@cypress/request@^2.88.10":
version "2.88.12"
resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.12.tgz#ba4911431738494a85e93fb04498cb38bc55d590"
integrity sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==
version "2.88.10"
resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce"
integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
@@ -2898,9 +2898,9 @@
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
performance-now "^2.1.0"
qs "~6.10.3"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "^4.1.3"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^8.3.2"
@@ -8247,9 +8247,9 @@
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
"@types/node@^14.14.31":
version "14.18.55"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.55.tgz#c60ad83c7d87c2d933cc4c1cb7d54d98ae50e460"
integrity sha512-PiNZnJDie6lgSWfjWYcQ8KWrEHp0bGv1WgnQAUuaao/HpUBKNX+HXubScoMRdLXBuovbte0djGtsxiWScvlQUQ==
version "14.18.32"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.32.tgz#8074f7106731f1a12ba993fe8bad86ee73905014"
integrity sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==
"@types/node@^16.0.0":
version "16.18.37"
@@ -12337,10 +12337,10 @@ cypress-real-events@^1.8.1:
resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.8.1.tgz#d00c7fe93124bbe7c0f27296684838614d24a840"
integrity sha512-8fFnA8EzS3EVbAmpSEUf3A8yZCmfU3IPOSGUDVFCdE1ke1gYL1A+gvXXV6HKUbTPRuvKKt2vpaMbUwYLpDRswQ==
cypress@12.17.0:
version "12.17.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.17.0.tgz#3a907a41c4afbb44be7b84e822e4914d734a6bb0"
integrity sha512-nq0ug8Zrjq/2khHU1PTNxg+3/n1oqtmAFCxwQhS6QzkQ4mR6RLitX+cGIOuIMfnEbDAtVub0hZh661FOA16JxA==
cypress@^12.2.0:
version "12.16.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.16.0.tgz#d0dcd0725a96497f4c60cf54742242259847924c"
integrity sha512-mwv1YNe48hm0LVaPgofEhGCtLwNIQEjmj2dJXnAkY1b4n/NE9OtgPph4TyS+tOtYp5CKtRmDvBzWseUXQTjbTg==
dependencies:
"@cypress/request" "^2.88.10"
"@cypress/xvfb" "^1.2.4"
@@ -12379,7 +12379,7 @@ cypress@12.17.0:
pretty-bytes "^5.6.0"
proxy-from-env "1.0.0"
request-progress "^3.0.0"
semver "^7.5.3"
semver "^7.3.2"
supports-color "^8.1.1"
tmp "~0.2.1"
untildify "^4.0.0"
@@ -20881,7 +20881,7 @@ prr@~1.0.1:
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==
psl@^1.1.33:
psl@^1.1.28, psl@^1.1.33:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
@@ -20998,12 +20998,10 @@ qs@^6.10.3:
dependencies:
side-channel "^1.0.4"
qs@~6.10.3:
version "6.10.5"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4"
integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==
dependencies:
side-channel "^1.0.4"
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
query-string@6.13.5:
version "6.13.5"
@@ -22271,13 +22269,6 @@ semver@^7.5.1:
dependencies:
lru-cache "^6.0.0"
semver@^7.5.3:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
semver@~7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
@@ -23531,7 +23522,7 @@ toml@^3.0.0:
resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee"
integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==
tough-cookie@^4.1.2, tough-cookie@^4.1.3:
tough-cookie@^4.1.2:
version "4.1.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf"
integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==
@@ -23541,6 +23532,14 @@ tough-cookie@^4.1.2, tough-cookie@^4.1.3:
universalify "^0.2.0"
url-parse "^1.5.3"
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tr46@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"