Compare commits

..

10 Commits

Author SHA1 Message Date
cc782b5eae Remove '.git' from .dockerignore; the Vega build process uses git commands ('rev-parse') to navigate 2024-03-29 19:59:16 -07:00
Alessio
703792fbda Add a simple path prefix for static assets 2024-03-29 19:59:16 -07:00
daro-maj
029357b5ab
fix(trading): fix market sim tests (#6132) 2024-03-29 10:21:23 +00:00
m.ray
954b4b2755
fix(trading): recurring governance transfers after 0.75.1 (#6122) 2024-03-28 15:50:07 +00:00
Matthew Russell
d238662c9d
fix(trading,governance): align validator testnet name, add chain config (#6133) 2024-03-28 15:00:01 +00:00
Matthew Russell
88251fae4d
fix(trading): check for mark price configuration 2024-03-28 14:24:08 +00:00
m.ray
17946ae149
feat(trading): show oracle spec in index price stats (#6113)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2024-03-28 13:09:53 +00:00
Matthew Russell
ebb0db3b37
fix(governance): fix market info not showing in proposals (#6104) 2024-03-28 11:09:40 +00:00
Bartłomiej Głownia
df21996707
chore(markets): remove trading mode and type from market query (#6117)
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2024-03-28 11:09:18 +00:00
Matthew Russell
bb2464ddc2
fix(markets): use position decimals in notional calculation (#6125) 2024-03-28 11:07:06 +00:00
75 changed files with 647 additions and 498 deletions

View File

@ -4,6 +4,5 @@ tmp/*
.dockerignore
dockerfiles
node_modules
.git
.github
.vscode

View File

@ -10,7 +10,7 @@ on:
inputs:
console-test-branch:
type: choice
description: 'main: v0.74.10, develop: v0.75.1'
description: 'main: v0.74.10, develop: v0.75.5'
options:
- main
- develop

View File

@ -1,5 +1,5 @@
# App configuration variables
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_ENV=VALIDATORS_TESTNET
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.toml
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_REST=https://api-validators-testnet.vega.rocks/

View File

@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { getAsset, type MarketFieldsFragment } from '@vegaprotocol/markets';
import { getAsset, type MarketMaybeWithData } from '@vegaprotocol/markets';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { type AgGridReact } from 'ag-grid-react';
@ -17,7 +17,7 @@ import { type RowClickedEvent } from 'ag-grid-community';
import { Link, useNavigate } from 'react-router-dom';
type MarketsTableProps = {
data: MarketFieldsFragment[] | null;
data: MarketMaybeWithData[] | null;
};
export const MarketsTable = ({ data }: MarketsTableProps) => {
const openAssetDetailsDialog = useAssetDetailsDialogStore(
@ -56,10 +56,10 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
headerName: t('Status'),
field: 'state',
hide: window.innerWidth <= BREAKPOINT_MD,
valueGetter: ({
data,
}: VegaValueGetterParams<MarketFieldsFragment>) => {
return data?.state ? MarketStateMapping[data?.state] : '-';
valueGetter: ({ data }: VegaValueGetterParams<MarketMaybeWithData>) => {
return data?.data?.marketState
? MarketStateMapping[data?.data.marketState]
: '-';
},
},
{
@ -70,7 +70,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
cellRenderer: ({
data,
}: VegaICellRendererParams<
MarketFieldsFragment,
MarketMaybeWithData,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value = data && getAsset(data);
@ -99,7 +99,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
field: 'id',
cellRenderer: ({
value,
}: VegaICellRendererParams<MarketFieldsFragment, 'id'>) =>
}: VegaICellRendererParams<MarketMaybeWithData, 'id'>) =>
value ? (
<Link className="underline" to={value}>
{t('View details')}
@ -116,7 +116,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
<AgGrid
ref={gridRef}
rowData={data}
getRowId={({ data }: { data: MarketFieldsFragment }) => data.id}
getRowId={({ data }: { data: MarketMaybeWithData }) => data.id}
overlayNoRowsTemplate={t('This chain has no markets')}
domLayout="autoHeight"
defaultColDef={{

View File

@ -1,6 +1,6 @@
import { useScrollToLocation } from '../../hooks/scroll-to-location';
import { useDocumentTitle } from '../../hooks/use-document-title';
import { marketsProvider } from '@vegaprotocol/markets';
import { marketsWithDataProvider } from '@vegaprotocol/markets';
import { RouteTitle } from '../../components/route-title';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
@ -12,7 +12,7 @@ export const MarketsPage = () => {
useScrollToLocation();
const { data, loading, error } = useDataProvider({
dataProvider: marketsProvider,
dataProvider: marketsWithDataProvider,
variables: undefined,
skipUpdates: true,
});

View File

@ -1,5 +1,5 @@
# App configuration variables
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_ENV=VALIDATORS_TESTNET
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.toml
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_REST=https://api-validators-testnet.vega.rocks/

View File

@ -47,7 +47,7 @@ export const SubHeading = ({
return (
<h2
className={classNames('text-2xl font-alpha calt uppercase break-words', {
className={classNames('text-2xl font-alpha calt break-words', {
'mx-auto': centerContent,
'mb-0': !marginBottom,
'mb-4': marginBottom,

View File

@ -41,7 +41,7 @@ export const ContractAddresses: {
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
lockedAddress: '0x0', // TODO not deployed to this env
},
VALIDATOR_TESTNET: {
VALIDATORS_TESTNET: {
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
lockedAddress: '0x0', // TODO not deployed to this env
// This is a fallback contract address for the validator testnet network which does not

View File

@ -6,6 +6,7 @@ import {
ViewPartyConnector,
createConfig,
fairground,
validatorsTestnet,
stagnet,
mainnet,
} from '@vegaprotocol/wallet';
@ -31,7 +32,7 @@ export const useVegaWalletConfig = () => {
const viewParty = new ViewPartyConnector();
const config = createConfig({
chains: [mainnet, fairground, stagnet],
chains: [mainnet, fairground, validatorsTestnet, stagnet],
defaultChainId: CHAIN_IDS[VEGA_ENV],
connectors: [injected, snap, jsonRpc, viewParty],
});

View File

@ -50,7 +50,7 @@ export const useMarketDataDialogStore = create<MarketDataDialogState>(
const marketDataHeaderStyles =
'font-alpha calt text-base border-b border-vega-dark-200 mt-2 py-2';
export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
export const ProposalMarketData = ({ marketId }: { marketId: string }) => {
const { t } = useTranslation();
const { isOpen, open, close } = useMarketDataDialogStore();
const [showDetails, setShowDetails] = useState(false);
@ -59,7 +59,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
dataProvider: marketInfoProvider,
skipUpdates: true,
variables: {
marketId: proposalId,
marketId: marketId,
},
});
@ -72,7 +72,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
},
});
if (!marketData || !parentMarketData) {
if (!marketData) {
return null;
}
@ -134,13 +134,13 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
<h2 className={marketDataHeaderStyles}>{t('Key details')}</h2>
<KeyDetailsInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData ? parentMarketData : undefined}
/>
<h2 className={marketDataHeaderStyles}>{t('Instrument')}</h2>
<InstrumentInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData ? parentMarketData : undefined}
/>
{settlementData &&
@ -156,7 +156,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
isParentSettlementDataEqual ||
isParentSettlementScheduleDataEqual
? undefined
: parentMarketData
: parentMarketData || undefined
}
/>
</>
@ -169,7 +169,9 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
market={marketData}
type="settlementData"
parentMarket={
isParentSettlementDataEqual ? undefined : parentMarketData
isParentSettlementDataEqual
? undefined
: parentMarketData || undefined
}
/>
@ -185,7 +187,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
parentMarket={
isParentTerminationDataEqual
? undefined
: parentMarketData
: parentMarketData || undefined
}
/>
</div>
@ -203,7 +205,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
parentMarket={
isParentSettlementScheduleDataEqual
? undefined
: parentMarketData
: parentMarketData || undefined
}
/>
</div>
@ -217,19 +219,19 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
<h2 className={marketDataHeaderStyles}>{t('Settlement assets')}</h2>
<SettlementAssetInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>{t('Metadata')}</h2>
<MetadataInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>{t('Risk model')}</h2>
<RiskModelInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>
@ -237,13 +239,13 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
</h2>
<MarginScalingFactorsPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>{t('Risk factors')}</h2>
<RiskFactorsInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
{showParentPriceMonitoringBounds && (
@ -268,14 +270,14 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
</h2>
<LiquidityMonitoringParametersInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>
{t('Liquidity price range')}
</h2>
<LiquidityPriceRangeInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
<h2 className={marketDataHeaderStyles}>
@ -283,7 +285,7 @@ export const ProposalMarketData = ({ proposalId }: { proposalId: string }) => {
</h2>
<LiquiditySLAParametersInfoPanel
market={marketData}
parentMarket={parentMarketData}
parentMarket={parentMarketData || undefined}
/>
</div>
</>

View File

@ -17,17 +17,20 @@ import { type ProposalNode } from './proposal-utils';
import { Lozenge } from '@vegaprotocol/ui-toolkit';
import { Indicator } from './indicator';
import { SubHeading } from '../../../../components/heading';
import { determineId } from '@vegaprotocol/wallet';
export const ProposalChangeDetails = ({
proposal,
terms,
restData,
indicator,
termsCount = 0,
}: {
proposal: Proposal | BatchProposal;
terms: ProposalTermsFieldsFragment;
restData: ProposalNode | null;
indicator?: number;
termsCount?: number;
}) => {
const { t } = useTranslation();
let details = null;
@ -61,7 +64,18 @@ export const ProposalChangeDetails = ({
}
case 'NewMarket': {
if (proposal.id) {
details = <ProposalMarketData proposalId={proposal.id} />;
let marketId = proposal.id;
// TODO: when https://github.com/vegaprotocol/vega/issues/11005 gets merged
// this will need to be updated to loop forward from 0. Right now subProposals
// are returned (when using GQL) in the reverse order
if (proposal.__typename === 'BatchProposal') {
for (let i = termsCount - 1; i >= 0; i--) {
marketId = determineId(marketId);
}
}
details = <ProposalMarketData marketId={marketId} />;
}
break;
}
@ -69,7 +83,7 @@ export const ProposalChangeDetails = ({
if (proposal.id) {
details = (
<div className="flex flex-col gap-4">
<ProposalMarketData proposalId={proposal.id} />
<ProposalMarketData marketId={proposal.id} />
<ProposalMarketChanges
indicator={indicator}
marketId={terms.change.marketId}

View File

@ -78,6 +78,7 @@ export const Proposal = ({ proposal, restData }: ProposalProps) => {
proposal={proposal}
terms={p.terms}
restData={restData}
termsCount={proposal.subProposals?.length}
/>
);
})

View File

@ -13,7 +13,7 @@
}
h1 {
@apply text-2xl text-white uppercase mb-4;
@apply text-2xl text-white mb-4;
}
h2 {
@apply text-xl text-white mb-4;

View File

@ -2,4 +2,4 @@
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.tom
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_NETWORKS={'{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_ENV=VALIDATORS_TESTNET

View File

@ -4,7 +4,7 @@ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.toml
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_ENV=VALIDATORS_TESTNET
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks
NX_VEGA_NETWORKS={\"MAINNET\":\"https://console.vega.xyz\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\",\"TESTNET\":\"https://console.fairground.wtf\"}
NX_VEGA_TOKEN_URL=https://governance.validators-testnet.vega.rocks

View File

@ -5,8 +5,8 @@ import type { Market } from '@vegaprotocol/markets';
import {
addDecimalsFormatNumber,
fromNanoSeconds,
getExpiryDate,
getMarketExpiryDate,
useExpiryDate,
} from '@vegaprotocol/utils';
import {
Last24hPriceChange,
@ -20,6 +20,7 @@ import {
useMarketTradingMode,
useExternalTwap,
getQuoteName,
useMarketState,
} from '@vegaprotocol/markets';
import { MarketState as State } from '@vegaprotocol/types';
import { HeaderStat } from '../../components/header';
@ -44,6 +45,12 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
const asset = getAsset(market);
const quoteUnit = getQuoteName(market);
const dataSourceSpec = market.markPriceConfiguration?.dataSourcesSpec?.[1];
const sourceType =
dataSourceSpec?.sourceType.__typename === 'DataSourceDefinitionExternal' &&
dataSourceSpec?.sourceType.sourceType.__typename === 'EthCallSpec' &&
dataSourceSpec?.sourceType.sourceType;
return (
<>
<HeaderStat heading={t('Mark Price')} testId="market-price">
@ -66,11 +73,8 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
quoteUnit={quoteUnit}
/>
</HeaderStat>
<HeaderStatMarketTradingMode
marketId={market.id}
initialTradingMode={market.tradingMode}
/>
<MarketState market={market} />
<HeaderStatMarketTradingMode marketId={market.id} />
<MarketState marketId={market.id} />
{asset ? (
<HeaderStat
heading={t('Settlement asset')}
@ -127,6 +131,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
{t(
'The external time weighted average price (TWAP) received from the data source defined in the data sourcing specification.'
)}
<div className="flex flex-col gap-1">
{DocsLinks && (
<ExternalLink
href={DocsLinks.ETH_DATA_SOURCES}
@ -135,6 +140,16 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
{t('Find out more')}
</ExternalLink>
)}
{sourceType && (
<ExternalLink
data-testid="oracle-spec-links"
href={`${VEGA_EXPLORER_URL}/markets/${market.id}/oracles#${sourceType.address}`}
className="text-xs my-1"
>
{t('Oracle specification')}
</ExternalLink>
)}
</div>
</div>
}
testId="index-price"
@ -264,13 +279,13 @@ export const FundingCountdown = ({ marketId }: { marketId: string }) => {
};
const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
const content = market.tradableInstrument.instrument.metadata.tags
? getExpiryDate(
const { data: marketState } = useMarketState(market.id);
const content =
useExpiryDate(
market.tradableInstrument.instrument.metadata.tags,
market.marketTimestamps.close,
market.state
)
: '-';
marketState
) || '-';
return <div data-testid="trading-expiry">{content}</div>;
};
@ -283,6 +298,7 @@ const ExpiryTooltipContent = ({
market,
explorerUrl,
}: ExpiryTooltipContentProps) => {
const { data: state } = useMarketState(market.id);
const t = useT();
if (market.marketTimestamps.close === null) {
const oracleId =
@ -298,8 +314,8 @@ const ExpiryTooltipContent = ({
const isExpired =
metadataExpiryDate &&
Date.now() - metadataExpiryDate.valueOf() > 0 &&
(market.state === State.STATE_TRADING_TERMINATED ||
market.state === State.STATE_SETTLED);
(state === State.STATE_TRADING_TERMINATED ||
state === State.STATE_SETTLED);
return (
<section data-testid="expiry-tooltip">

View File

@ -40,7 +40,6 @@ describe('Closed', () => {
const market = createMarketFragment({
id: marketId,
state: MarketState.STATE_SETTLED,
tradableInstrument: {
instrument: {
metadata: {
@ -96,6 +95,7 @@ describe('Closed', () => {
const marketsData = createMarketsDataFragment({
__typename: 'MarketData',
marketState: MarketState.STATE_SETTLED,
market: {
__typename: 'Market',
id: marketId,
@ -208,7 +208,7 @@ describe('Closed', () => {
const cells = screen.getAllByRole('gridcell');
const expectedValues = [
market.tradableInstrument.instrument.code,
MarketStateMapping[market.state],
MarketStateMapping[marketsData.marketState],
'3 days ago',
/* eslint-disable @typescript-eslint/no-non-null-assertion */
addDecimalsFormatNumber(marketsData.bestBidPrice, market.decimalPlaces),
@ -227,87 +227,6 @@ describe('Closed', () => {
});
});
it('only renders settled and terminated markets', async () => {
const mixedMarkets = [
{
// include as settled
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'include-0',
state: MarketState.STATE_SETTLED,
}),
},
{
// omit this market
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'discard-0',
state: MarketState.STATE_SUSPENDED,
}),
},
{
// include as terminated
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'include-1',
state: MarketState.STATE_TRADING_TERMINATED,
}),
},
{
// omit this market
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'discard-1',
state: MarketState.STATE_ACTIVE,
}),
},
];
const mixedMarketsMock: MockedResponse<MarketsQuery> = {
request: {
query: MarketsDocument,
},
result: {
data: {
marketsConnection: {
__typename: 'MarketConnection',
edges: mixedMarkets,
},
},
},
};
await renderComponent([mixedMarketsMock, marketsDataMock, oracleDataMock]);
// check that the number of rows in datagrid is 2
const container = within(
document.querySelector('.ag-center-cols-container') as HTMLElement
);
const expectedRows = mixedMarkets.filter((m) => {
return [
MarketState.STATE_SETTLED,
MarketState.STATE_TRADING_TERMINATED,
].includes(m.node.state);
});
await waitFor(() => {
// check rows length is correct
const rows = container.getAllByRole('row');
expect(rows).toHaveLength(expectedRows.length);
});
// check that only included ids are shown
const cells = screen
.getAllByRole('gridcell')
.filter((cell) => cell.getAttribute('col-id') === 'code')
.map((cell) => {
const marketCode = within(cell).getByTestId('stack-cell-primary');
return marketCode.textContent;
});
expect(cells).toEqual(
expectedRows.map((m) => m.node.tradableInstrument.instrument.code)
);
});
it('display market actions', async () => {
// Use market with a successor Id as the actions dropdown will optionally
// show a link to the successor market
@ -315,8 +234,7 @@ describe('Closed', () => {
{
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'include-0',
state: MarketState.STATE_SETTLED,
id: marketId,
successorMarketID: 'successor',
parentMarketID: 'parent',
}),
@ -375,8 +293,7 @@ describe('Closed', () => {
{
__typename: 'MarketEdge' as const,
node: createMarketFragment({
id: 'include-0',
state: MarketState.STATE_SETTLED,
id: marketId,
successorMarketID: 'successor',
}),
},

View File

@ -15,7 +15,7 @@ import {
addDecimalsFormatNumber,
getMarketExpiryDate,
} from '@vegaprotocol/utils';
import { closedMarketsWithDataProvider, getAsset } from '@vegaprotocol/markets';
import { closedMarketsProvider, getAsset } from '@vegaprotocol/markets';
import type { DataSourceFilterFragment } from '@vegaprotocol/markets';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
@ -35,7 +35,7 @@ interface Row {
code: string;
name: string;
decimalPlaces: number;
state: MarketState;
state?: MarketState;
metadata: string[];
closeTimestamp: string | null;
bestBidPrice: string | undefined;
@ -53,7 +53,7 @@ interface Row {
export const Closed = () => {
const { data: marketData, error } = useDataProvider({
dataProvider: closedMarketsWithDataProvider,
dataProvider: closedMarketsProvider,
variables: undefined,
});
@ -87,7 +87,7 @@ export const Closed = () => {
code: instrument.code,
name: instrument.name,
decimalPlaces: market.decimalPlaces,
state: market.state,
state: market.data?.marketState,
metadata: instrument.metadata.tags ?? [],
closeTimestamp: market.marketTimestamps.close,
bestBidPrice: market.data?.bestBidPrice,

View File

@ -3,11 +3,17 @@ import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { ProposalsList } from './proposals-list';
import { MarketState } from '@vegaprotocol/types';
import { createMarketFragment } from '@vegaprotocol/mock';
import {
createMarketFragment,
createMarketsDataFragment,
} from '@vegaprotocol/mock';
import {
type MarketsQuery,
MarketsDocument,
type MarketsQueryVariables,
type MarketsDataQuery,
type MarketsDataQueryVariables,
MarketsDataDocument,
} from '@vegaprotocol/markets';
const parentMarketName = 'Parent Market Name';
@ -15,12 +21,13 @@ const ParentMarketCell = () => <span>{parentMarketName}</span>;
describe('ProposalsList', () => {
const rowContainerSelector = '.ag-center-cols-container';
const market = createMarketFragment({
state: MarketState.STATE_PROPOSED,
const market = createMarketFragment();
const marketData = createMarketsDataFragment({
marketState: MarketState.STATE_PROPOSED,
});
it('should be properly rendered', async () => {
const mock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
const marketMock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
request: {
query: MarketsDocument,
},
@ -37,8 +44,28 @@ describe('ProposalsList', () => {
},
};
const marketDataMock: MockedResponse<
MarketsDataQuery,
MarketsDataQueryVariables
> = {
request: {
query: MarketsDataDocument,
},
result: {
data: {
marketsConnection: {
edges: [
{
node: { data: marketData },
},
],
},
},
},
};
render(
<MockedProvider mocks={[mock]}>
<MockedProvider mocks={[marketMock, marketDataMock]}>
<ProposalsList cellRenderers={{ ParentMarketCell }} />
</MockedProvider>
);
@ -69,7 +96,7 @@ describe('ProposalsList', () => {
expect(await container.findAllByRole('row')).toHaveLength(
// @ts-ignore data is mocked
mock?.result?.data.marketsConnection.edges.length
marketMock?.result?.data.marketsConnection.edges.length
);
expect(
@ -81,7 +108,7 @@ describe('ProposalsList', () => {
});
it('empty response should causes no data message display', async () => {
const mock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
const marketMock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
request: {
query: MarketsDocument,
},
@ -93,8 +120,23 @@ describe('ProposalsList', () => {
},
},
};
const marketDataMock: MockedResponse<
MarketsDataQuery,
MarketsDataQueryVariables
> = {
request: {
query: MarketsDataDocument,
},
result: {
data: {
marketsConnection: {
edges: [],
},
},
},
};
render(
<MockedProvider mocks={[mock]}>
<MockedProvider mocks={[marketMock, marketDataMock]}>
<ProposalsList cellRenderers={{ ParentMarketCell }} />
</MockedProvider>
);

View File

@ -19,7 +19,7 @@ import {
} from '@vegaprotocol/types';
import { ProposalActionsDropdown } from './proposal-actions-dropdown';
import {
type MarketFieldsFragment,
type MarketMaybeWithData,
getProductType,
} from '@vegaprotocol/markets';
import { useT } from '../../../lib/use-t';
@ -40,7 +40,7 @@ export const useColumnDefs = () => {
data,
}: {
value: string;
data: MarketFieldsFragment;
data: MarketMaybeWithData;
}) => {
if (!value || !data) return '-';
@ -70,10 +70,13 @@ export const useColumnDefs = () => {
{
colId: 'state',
headerName: t('State'),
field: 'state',
field: 'data.marketState',
valueFormatter: ({
value,
}: VegaValueFormatterParams<MarketFieldsFragment, 'state'>) => {
}: VegaValueFormatterParams<
MarketMaybeWithData,
'data.marketState'
>) => {
return value ? MarketStateMapping[value] : '-';
},
filter: SetFilter,
@ -93,7 +96,7 @@ export const useColumnDefs = () => {
valueFormatter: ({
value,
}: VegaValueFormatterParams<
MarketFieldsFragment,
MarketMaybeWithData,
'marketTimestamps.pending'
>) => {
return value ? getDateTimeFormat().format(new Date(value)) : '-';
@ -107,7 +110,7 @@ export const useColumnDefs = () => {
valueFormatter: ({
value,
}: VegaValueFormatterParams<
MarketFieldsFragment,
MarketMaybeWithData,
'marketTimestamps.open'
>) => (value ? getDateTimeFormat().format(new Date(value)) : '-'),
filter: DateRangeFilter,
@ -117,7 +120,7 @@ export const useColumnDefs = () => {
...COL_DEFS.actions,
cellRenderer: ({
data,
}: VegaICellRendererParams<MarketFieldsFragment>) => {
}: VegaICellRendererParams<MarketMaybeWithData>) => {
if (!data?.marketProposal?.id) return null;
return <ProposalActionsDropdown id={data.marketProposal.id} />;

View File

@ -9,7 +9,7 @@ export interface SettlementDataCellProps {
oracleSpecId: string;
metaDate: Date | null;
closeTimestamp: string | null;
marketState: MarketState;
marketState?: MarketState;
}
export const SettlementDateCell = ({

View File

@ -125,7 +125,9 @@ export const useMarketsColumnDefs = () => {
valueFormatter: ({
data,
}: VegaValueFormatterParams<MarketMaybeWithData, 'state'>) => {
return data?.state ? Schema.MarketStateMapping[data.state] : '-';
return data?.data?.marketState
? Schema.MarketStateMapping[data?.data?.marketState]
: '-';
},
filter: SetFilter,
filterParams: {
@ -170,7 +172,12 @@ export const useMarketsColumnDefs = () => {
const vol = candles ? calcCandleVolume(candles) : '0';
const quoteName = getQuoteName(data);
const volPrice =
candles && calcCandleVolumePrice(candles, data.decimalPlaces);
candles &&
calcCandleVolumePrice(
candles,
data.decimalPlaces,
data.positionDecimalPlaces
);
const volume =
data && vol && vol !== '0'

View File

@ -40,7 +40,10 @@ export const applyFilter = (
return true;
}
if (transfer.kind.__typename !== 'RecurringTransfer') {
if (
transfer.kind.__typename !== 'RecurringTransfer' &&
transfer.kind.__typename !== 'RecurringGovernanceTransfer'
) {
return false;
}

View File

@ -72,11 +72,11 @@ const MarketData = ({
const marketTradingMode = marketData
? marketData.marketTradingMode
: market.data
? market.data.marketTradingMode
: market.tradingMode;
: market.data?.marketTradingMode;
const mode = [
const mode =
marketTradingMode &&
[
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,

View File

@ -120,7 +120,7 @@ export const MarketSelector = ({
<div data-testid="market-selector-list">
<MarketList
data={markets}
loading={loading}
loading={loading && !data}
error={error}
searchTerm={filter.searchTerm}
currentMarketId={currentMarketId}

View File

@ -409,7 +409,6 @@ describe('useMarketSelectorList', () => {
}),
createMarketFragment({
id: 'market-1',
state: MarketState.STATE_ACTIVE,
// @ts-ignore data not on fragment
data: createMarketsDataFragment({
marketState: MarketState.STATE_ACTIVE,
@ -424,7 +423,6 @@ describe('useMarketSelectorList', () => {
}),
createMarketFragment({
id: 'market-2',
state: MarketState.STATE_ACTIVE,
// @ts-ignore data not on fragment
data: createMarketsDataFragment({
marketState: MarketState.STATE_ACTIVE,
@ -439,7 +437,6 @@ describe('useMarketSelectorList', () => {
}),
createMarketFragment({
id: 'market-3',
state: MarketState.STATE_ACTIVE,
// @ts-ignore data not on fragment
data: createMarketsDataFragment({
marketState: MarketState.STATE_ACTIVE,

View File

@ -1,48 +1,18 @@
import throttle from 'lodash/throttle';
import type { MarketData, Market } from '@vegaprotocol/markets';
import { marketDataProvider } from '@vegaprotocol/markets';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { useMarketState } from '@vegaprotocol/markets';
import * as Schema from '@vegaprotocol/types';
import { HeaderStat } from '../header';
import { useCallback, useRef, useState } from 'react';
import * as constants from '../constants';
import { DocsLinks } from '@vegaprotocol/environment';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { useT } from '../../lib/use-t';
export const MarketState = ({ market }: { market: Market | null }) => {
export const MarketState = ({ marketId }: { marketId?: string }) => {
const t = useT();
const [marketState, setMarketState] = useState<Schema.MarketState | null>(
null
);
const throttledSetMarketState = useRef(
throttle((state: Schema.MarketState) => {
setMarketState(state);
}, constants.THROTTLE_UPDATE_TIME)
).current;
const update = useCallback(
({ data: marketData }: { data: MarketData | null }) => {
if (marketData) {
throttledSetMarketState(marketData.marketState);
}
return true;
},
[throttledSetMarketState]
);
useDataProvider({
dataProvider: marketDataProvider,
update,
variables: { marketId: market?.id || '' },
skip: !market?.id,
});
const { data: marketState } = useMarketState(marketId);
return (
<HeaderStat
heading={t('Status')}
description={useGetMarketStateTooltip(marketState)}
description={useGetMarketStateTooltip(marketState ?? undefined)}
testId="market-state"
>
{marketState ? Schema.MarketStateMapping[marketState] : '-'}
@ -50,7 +20,7 @@ export const MarketState = ({ market }: { market: Market | null }) => {
);
};
const useGetMarketStateTooltip = (state: Schema.MarketState | null) => {
const useGetMarketStateTooltip = (state?: Schema.MarketState) => {
const t = useT();
if (state === Schema.MarketState.STATE_ACTIVE) {
return t('Enactment date reached and usual auction exit checks pass');

View File

@ -26,20 +26,15 @@ const getTradingModeLabel = (
interface HeaderStatMarketTradingModeProps {
marketId?: string;
onSelect?: (marketId: string, metaKey?: boolean) => void;
initialTradingMode?: Schema.MarketTradingMode;
initialTrigger?: Schema.AuctionTrigger;
}
export const HeaderStatMarketTradingMode = ({
marketId,
onSelect,
initialTradingMode,
initialTrigger,
}: HeaderStatMarketTradingModeProps) => {
const t = useT();
const { data } = useStaticMarketData(marketId);
const marketTradingMode = data?.marketTradingMode ?? initialTradingMode;
const trigger = data?.trigger ?? initialTrigger;
const { marketTradingMode, trigger } = data || {};
return (
<HeaderStat
@ -56,8 +51,6 @@ export const HeaderStatMarketTradingMode = ({
export const MarketTradingMode = ({
marketId,
initialTradingMode,
initialTrigger,
inViewRoot,
}: Omit<HeaderStatMarketTradingModeProps, 'onUpdate'> & {
inViewRoot?: RefObject<Element>;
@ -72,10 +65,7 @@ export const MarketTradingMode = ({
}
>
<span ref={ref}>
{getTradingModeLabel(
data?.marketTradingMode ?? initialTradingMode,
data?.trigger ?? initialTrigger
)}
{getTradingModeLabel(data?.marketTradingMode, data?.trigger)}
</span>
</Tooltip>
);

View File

@ -38,7 +38,10 @@ export const applyFilter = (
return true;
}
if (transfer.kind.__typename !== 'RecurringTransfer') {
if (
transfer.kind.__typename !== 'RecurringTransfer' &&
transfer.kind.__typename !== 'RecurringGovernanceTransfer'
) {
return false;
}

View File

@ -948,13 +948,13 @@ const EntityIcon = ({
export const areAllMarketsSettled = (transferNode: EnrichedRewardTransfer) => {
const settledMarkets = transferNode.markets?.filter(
(m) =>
m?.state &&
m?.data?.marketState &&
[
MarketState.STATE_TRADING_TERMINATED,
MarketState.STATE_SETTLED,
MarketState.STATE_CANCELLED,
MarketState.STATE_CLOSED,
].includes(m.state)
].includes(m?.data?.marketState)
);
return (
@ -969,8 +969,8 @@ export const areAllMarketsSuspended = (
return (
transferNode.markets?.filter(
(m) =>
m?.state === MarketState.STATE_SUSPENDED ||
m?.state === MarketState.STATE_SUSPENDED_VIA_GOVERNANCE
m?.data?.marketState === MarketState.STATE_SUSPENDED ||
m?.data?.marketState === MarketState.STATE_SUSPENDED_VIA_GOVERNANCE
).length === transferNode.markets?.length &&
Boolean(transferNode.markets && transferNode.markets.length > 0)
);

View File

@ -1,4 +1,4 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
VEGA_VERSION=v0.75.1
VEGA_VERSION=v0.75.5
LOCAL_SERVER=false
VEGA_ENV=STAGNET1

View File

@ -1,4 +1,4 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:develop
VEGA_VERSION=v0.75.1
VEGA_VERSION=v0.75.5
LOCAL_SERVER=false
VEGA_ENV=STAGNET1

View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "certifi"
@ -1165,8 +1165,8 @@ profile = ["pytest-profiling", "snakeviz"]
[package.source]
type = "git"
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
reference = "HEAD"
resolved_reference = "b2b4cd004800ba2732448f329b0fa8f0746d4d0b"
reference = "pre-release/vega-v0.75.5"
resolved_reference = "b2a3437fc13ced2b7ecd582ca4778bbc4b0fe3a6"
[[package]]
name = "websocket-client"
@ -1347,4 +1347,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = ">=3.9,<3.11"
content-hash = "39ce8400de7bf060857447281ef27bd78c9b1d9639da063b051e3ae6e7887a67"
content-hash = "80e87cbde486e7bb150fce0b1c974de38501bc16732952b455d43cb843426623"

View File

@ -13,7 +13,7 @@ pytest-playwright = "^0.4.2"
docker = "^6.1.3"
pytest-xdist = "^3.3.1"
python-dotenv = "^1.0.0"
vega-sim = { git = "https://github.com/vegaprotocol/vega-market-sim.git/" }
vega-sim = { git = "https://github.com/vegaprotocol/vega-market-sim.git/", branch = "pre-release/vega-v0.75.5"}
[build-system]
requires = ["poetry-core"]

View File

@ -13,7 +13,7 @@ pytest-playwright = "^0.4.2"
docker = "^6.1.3"
pytest-xdist = "^3.3.1"
python-dotenv = "^1.0.0"
vega-sim = { git = "https://github.com/vegaprotocol/vega-market-sim.git/" }
vega-sim = { git = "https://github.com/vegaprotocol/vega-market-sim.git/", branch = "pre-release/vega-v0.75.5"}
[build-system]
requires = ["poetry-core"]

View File

@ -43,7 +43,8 @@ class TestSettledMarket:
"",
]
page.wait_for_selector('[data-testid="tab-closed-markets"]', state="visible")
page.wait_for_selector(
'[data-testid="tab-closed-markets"]', state="visible")
page_headers = (
page.get_by_test_id("tab-closed-markets")
.locator(".ag-header-cell-text")
@ -64,16 +65,19 @@ class TestSettledMarket:
).first
# 6001-MARK-001
expect(row_selector.locator('[col-id="code"]')).to_have_text("BTC:DAI_2023Futr")
expect(row_selector.locator('[col-id="code"]')
).to_have_text("BTC:DAI_2023Futr")
# 6001-MARK-003
expect(row_selector.locator('[col-id="state"]')).to_have_text("Settled")
expect(row_selector.locator(
'[col-id="state"]')).to_have_text("Settled")
# 6001-MARK-004
# 6001-MARK-005
# 6001-MARK-009
# 6001-MARK-008
# 6001-MARK-010
pattern = r"(\d+)\s+(months|hours|days|minutes)\s+ago"
date_text = row_selector.locator('[col-id="settlementDate"]').inner_text()
date_text = row_selector.locator(
'[col-id="settlementDate"]').inner_text()
assert re.match(
pattern, date_text
), f"Expected text to match pattern but got {date_text}"
@ -86,11 +90,14 @@ class TestSettledMarket:
actual_href
), f"Expected href to match {expected_pattern.pattern}, but got {actual_href}"
# 6001-MARK-011
expect(row_selector.locator('[col-id="bestBidPrice"]')).to_have_text("0.00")
expect(row_selector.locator(
'[col-id="bestBidPrice"]')).to_have_text("0.00")
# 6001-MARK-012
expect(row_selector.locator('[col-id="bestOfferPrice"]')).to_have_text("0.00")
expect(row_selector.locator(
'[col-id="bestOfferPrice"]')).to_have_text("0.00")
# 6001-MARK-013
expect(row_selector.locator('[col-id="markPrice"]')).to_have_text("110.00")
expect(row_selector.locator(
'[col-id="markPrice"]')).to_have_text("110.00")
# 6001-MARK-014
# 6001-MARK-015
# 6001-MARK-016
@ -107,7 +114,8 @@ class TestSettledMarket:
), f"Expected href to match {expected_pattern.pattern}, but got {actual_href}"
# 6001-MARK-018
expect(row_selector.locator('[col-id="settlementAsset"]')).to_have_text("tDAI")
expect(row_selector.locator(
'[col-id="settlementAsset"]')).to_have_text("tDAI")
# 6001-MARK-020
assert re.match(
pattern, date_text
@ -129,8 +137,10 @@ def test_terminated_market_no_settlement_date(page: Page, vega: VegaServiceNull)
row_selector = page.locator(
'[data-testid="tab-closed-markets"] .ag-center-cols-container .ag-row'
).first
expect(row_selector.locator('[col-id="state"]')).to_have_text("Trading Terminated")
expect(row_selector.locator('[col-id="settlementDate"]')).to_have_text("Unknown")
expect(row_selector.locator('[col-id="state"]')
).to_have_text("Trading Terminated")
expect(row_selector.locator(
'[col-id="settlementDate"]')).to_have_text("Unknown")
# TODO Create test for terminated market with settlement date in future
# TODO Create test for terminated market with settlement date in past

View File

@ -7,6 +7,7 @@ from fixtures.market import setup_continuous_market
from conftest import init_vega, cleanup_container, init_page, auth_setup, risk_accepted_setup
from wallet_config import MM_WALLET, MM_WALLET2
@pytest.fixture(scope="module")
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
with init_vega(request) as vega:
@ -22,7 +23,8 @@ def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None
side="SIDE_BUY",
volume=10,
price=60,
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=1),
pegged_order=PeggedOrder(
reference="PEGGED_REFERENCE_MID", offset=1),
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
@ -66,7 +68,8 @@ def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None
1,
1 + 0.1 / 2,
)
submit_order(vega, MM_WALLET.name, market_id, "SIDE_SELL", 1, 1 + 0.1 / 2)
submit_order(vega, MM_WALLET.name, market_id,
"SIDE_SELL", 1, 1 + 0.1 / 2)
submit_order(vega, MM_WALLET2.name, market_id, "SIDE_SELL", 1, 1)
vega.wait_fn(1)
@ -89,25 +92,31 @@ def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None
yield page, market_id
def test_parked_order(
setup_environment: Tuple[Page, str, str],
) -> None:
page, market_id, = setup_environment
page.goto(f"/#/markets/{market_id}")
page.get_by_test_id("All").click()
expect(page.get_by_role("row").nth(5)).to_contain_text("0+10Mid - 1.00 Peg limitParked0.00GTC")
expect(page.get_by_role("row").nth(5)).to_contain_text(
"0+10Mid - 1.00 Peg limitParked0.00GTC")
def test_trading_mode(
setup_environment: Tuple[Page, str, str],
setup_environment: Tuple[Page, str, str],
) -> None:
page, market_id, = setup_environment
expect(page.get_by_test_id("market-trading-mode")).to_have_text("Trading modeMonitoring auction - price")
page.goto(f"/#/markets/{market_id}")
expect(page.get_by_test_id("market-trading-mode")
).to_have_text("Trading modeMonitoring auction - price")
expect(page.get_by_test_id("market-state")).to_have_text("StatusSuspended")
def test_market_info_price_monitoring_asd(
setup_environment: Tuple[Page, str, str],
setup_environment: Tuple[Page, str, str],
) -> None:
page, market_id, = setup_environment
page.goto(f"/#/markets/{market_id}")
page.get_by_test_id("Info").click()
page.get_by_test_id("accordion-title").get_by_text(
"Key details").click()

View File

@ -20,15 +20,17 @@ from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET
row_selector = '[data-testid="tab-funding-payments"] .ag-center-cols-container .ag-row'
col_amount = '[col-id="amount"]'
@pytest.fixture(scope="module")
def setup_environment(
request, browser
) -> Generator[Tuple[Page, VegaServiceNull, str], None, None]:
) -> Generator[Tuple[Page, VegaServiceNull, str], None, None]:
with init_vega(request) as vega:
request.addfinalizer(lambda: cleanup_container(vega))
perps_market = setup_perps_market(vega)
submit_multiple_orders(
vega, MM_WALLET.name, perps_market, "SIDE_SELL", [[1, 110], [1, 105]]
vega, MM_WALLET.name, perps_market, "SIDE_SELL", [
[1, 110], [1, 105]]
)
submit_multiple_orders(
vega, MM_WALLET2.name, perps_market, "SIDE_BUY", [[1, 90], [1, 95]]
@ -41,10 +43,12 @@ def setup_environment(
vega.wait_fn(1)
vega.wait_for_total_catchup()
submit_multiple_orders(
vega, MM_WALLET.name, perps_market, "SIDE_SELL", [[1, 110], [1, 105]]
vega, MM_WALLET.name, perps_market, "SIDE_SELL", [
[1, 110], [1, 105]]
)
submit_multiple_orders(
vega, MM_WALLET2.name, perps_market, "SIDE_BUY", [[1, 112], [1, 115]]
vega, MM_WALLET2.name, perps_market, "SIDE_BUY", [
[1, 112], [1, 115]]
)
vega.submit_settlement_data(
settlement_key=TERMINATE_WALLET.name,
@ -58,6 +62,8 @@ def setup_environment(
risk_accepted_setup(page)
auth_setup(vega, page)
yield page, vega, perps_market
class TestPerpetuals:
def test_funding_payment_profit(self,
setup_environment: Tuple[Page, str, str],
@ -86,7 +92,8 @@ class TestPerpetuals:
expect(page.get_by_test_id("market-funding")).to_contain_text(
"Funding Rate / Countdown-8.1818%"
)
expect(page.get_by_test_id("index-price")).to_have_text("Index Price110.00")
expect(page.get_by_test_id("index-price")
).to_have_text("Index Price110.00")
@pytest.mark.skip("Skipped due to issue #5421")
def test_funding_payment_history(perps_market, page: Page, vega):
@ -106,6 +113,7 @@ class TestPerpetuals:
print("Bounding box not found for the element")
@pytest.mark.skip("need to be clarify")
@pytest.mark.usefixtures("risk_accepted", "auth")
def test_perps_market_termination_proposed(page: Page, vega: VegaServiceNull):
perpetual_market = setup_perps_market(vega)
@ -115,7 +123,7 @@ def test_perps_market_termination_proposed(page: Page, vega: VegaServiceNull):
market_id=perpetual_market,
market_state=MarketStateUpdateType.Terminate,
price=100,
vote_closing_time=datetime.now() + timedelta(seconds=15),
vote_closing_time=datetime.now() + timedelta(seconds=30),
vote_enactment_time=datetime.now() + timedelta(seconds=60),
approve_proposal=True,
forward_time_to_enactment=False,
@ -150,9 +158,12 @@ def test_perps_market_terminated(page: Page, vega: VegaServiceNull):
page.goto(f"/#/markets/{perpetual_market}")
# TODO change back to have text once bug #5465 is fixed
expect(page.get_by_test_id("market-price")).to_have_text("Mark Price100.00")
expect(page.get_by_test_id("market-change")).to_contain_text("Change (24h)")
expect(page.get_by_test_id("market-volume")).to_contain_text("Volume (24h)")
expect(page.get_by_test_id("market-price")
).to_have_text("Mark Price100.00")
expect(page.get_by_test_id("market-change")
).to_contain_text("Change (24h)")
expect(page.get_by_test_id("market-volume")
).to_contain_text("Volume (24h)")
expect(page.get_by_test_id("market-trading-mode")).to_have_text(
"Trading modeNo trading"
)

View File

@ -41,6 +41,55 @@ query RewardsPage($partyId: ID!) {
}
}
fragment RecurringTransferFields on TransferKind {
... on RecurringGovernanceTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
... on RecurringTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
}
query ActiveRewards(
$isReward: Boolean
$partyId: ID
@ -75,29 +124,7 @@ query ActiveRewards(
timestamp
gameId
kind {
... on RecurringTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
...RecurringTransferFields
}
reason
}

View File

@ -10,6 +10,16 @@ export type RewardsPageQueryVariables = Types.Exact<{
export type RewardsPageQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, vestingStats?: { __typename?: 'PartyVestingStats', rewardBonusMultiplier: string, quantumBalance: string, epochSeq: number } | null, activityStreak?: { __typename?: 'PartyActivityStreak', activeFor: number, isActive: boolean, inactiveFor: number, rewardDistributionMultiplier: string, rewardVestingMultiplier: string, epoch: number, tradedVolume: string, openVolume: string } | null, vestingBalancesSummary: { __typename?: 'PartyVestingBalancesSummary', epoch?: number | null, vestingBalances?: Array<{ __typename?: 'PartyVestingBalance', balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number, quantum: string } }> | null, lockedBalances?: Array<{ __typename?: 'PartyLockedBalance', balance: string, untilEpoch: number, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number, quantum: string } }> | null } } | null };
export type RecurringTransferFields_OneOffGovernanceTransfer_Fragment = { __typename?: 'OneOffGovernanceTransfer' };
export type RecurringTransferFields_OneOffTransfer_Fragment = { __typename?: 'OneOffTransfer' };
export type RecurringTransferFields_RecurringGovernanceTransfer_Fragment = { __typename?: 'RecurringGovernanceTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', capRewardFeeMultiple?: string | null, dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null };
export type RecurringTransferFields_RecurringTransfer_Fragment = { __typename?: 'RecurringTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', capRewardFeeMultiple?: string | null, dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null };
export type RecurringTransferFieldsFragment = RecurringTransferFields_OneOffGovernanceTransfer_Fragment | RecurringTransferFields_OneOffTransfer_Fragment | RecurringTransferFields_RecurringGovernanceTransfer_Fragment | RecurringTransferFields_RecurringTransfer_Fragment;
export type ActiveRewardsQueryVariables = Types.Exact<{
isReward?: Types.InputMaybe<Types.Scalars['Boolean']>;
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
@ -18,7 +28,7 @@ export type ActiveRewardsQueryVariables = Types.Exact<{
}>;
export type ActiveRewardsQuery = { __typename?: 'Query', transfersConnection?: { __typename?: 'TransferConnection', edges?: Array<{ __typename?: 'TransferEdge', node: { __typename?: 'TransferNode', transfer: { __typename?: 'Transfer', amount: string, id: string, from: string, fromAccountType: Types.AccountType, to: string, toAccountType: Types.AccountType, reference?: string | null, status: Types.TransferStatus, timestamp: any, gameId?: string | null, reason?: string | null, asset?: { __typename?: 'Asset', id: string, symbol: string, decimals: number, name: string, quantum: string, status: Types.AssetStatus } | null, kind: { __typename?: 'OneOffGovernanceTransfer' } | { __typename?: 'OneOffTransfer' } | { __typename?: 'RecurringGovernanceTransfer' } | { __typename?: 'RecurringTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', capRewardFeeMultiple?: string | null, dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null } }, fees?: Array<{ __typename?: 'TransferFee', transferId: string, amount: string, epoch: number } | null> | null } } | null> | null } | null };
export type ActiveRewardsQuery = { __typename?: 'Query', transfersConnection?: { __typename?: 'TransferConnection', edges?: Array<{ __typename?: 'TransferEdge', node: { __typename?: 'TransferNode', transfer: { __typename?: 'Transfer', amount: string, id: string, from: string, fromAccountType: Types.AccountType, to: string, toAccountType: Types.AccountType, reference?: string | null, status: Types.TransferStatus, timestamp: any, gameId?: string | null, reason?: string | null, asset?: { __typename?: 'Asset', id: string, symbol: string, decimals: number, name: string, quantum: string, status: Types.AssetStatus } | null, kind: { __typename?: 'OneOffGovernanceTransfer' } | { __typename?: 'OneOffTransfer' } | { __typename?: 'RecurringGovernanceTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', capRewardFeeMultiple?: string | null, dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null } | { __typename?: 'RecurringTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', capRewardFeeMultiple?: string | null, dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null } }, fees?: Array<{ __typename?: 'TransferFee', transferId: string, amount: string, epoch: number } | null> | null } } | null> | null } | null };
export type TWAPQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
@ -53,7 +63,56 @@ export type MarketForRewardsQueryVariables = Types.Exact<{
export type MarketForRewardsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null } } } } | null };
export const RecurringTransferFieldsFragmentDoc = gql`
fragment RecurringTransferFields on TransferKind {
... on RecurringGovernanceTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
... on RecurringTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
}
`;
export const RewardsPageDocument = gql`
query RewardsPage($partyId: ID!) {
party(id: $partyId) {
@ -156,29 +215,7 @@ export const ActiveRewardsDocument = gql`
timestamp
gameId
kind {
... on RecurringTransfer {
startEpoch
endEpoch
dispatchStrategy {
capRewardFeeMultiple
dispatchMetric
dispatchMetricAssetId
marketIdsInScope
entityScope
individualScope
teamScope
nTopPerformers
stakingRequirement
notionalTimeWeightedAveragePositionRequirement
windowLength
lockPeriod
distributionStrategy
rankTable {
startRank
shareRatio
}
}
}
...RecurringTransferFields
}
reason
}
@ -191,7 +228,7 @@ export const ActiveRewardsDocument = gql`
}
}
}
`;
${RecurringTransferFieldsFragmentDoc}`;
/**
* __useActiveRewardsQuery__

View File

@ -4,9 +4,9 @@ import {
} from '@vegaprotocol/assets';
import { useActiveRewardsQuery } from './__generated__/Rewards';
import {
type MarketFieldsFragment,
useMarketsMapProvider,
type MarketMaybeWithData,
getAsset,
marketsWithDataProvider,
} from '@vegaprotocol/markets';
import {
type RecurringTransfer,
@ -20,6 +20,7 @@ import {
import { type ApolloError } from '@apollo/client';
import compact from 'lodash/compact';
import { useEpochInfoQuery } from './__generated__/Epoch';
import { useDataProvider } from '@vegaprotocol/data-provider';
export type RewardTransfer = TransferNode & {
transfer: {
@ -35,7 +36,7 @@ export type EnrichedRewardTransfer = RewardTransfer & {
/** A flag determining whether a reward asset is being traded on any of the active markets */
isAssetTraded?: boolean;
/** A list of markets in scope */
markets?: MarketFieldsFragment[];
markets?: MarketMaybeWithData[];
};
/**
@ -46,7 +47,8 @@ export type EnrichedRewardTransfer = RewardTransfer & {
*/
export const isReward = (node: TransferNode): node is RewardTransfer => {
if (
(node.transfer.kind.__typename === 'RecurringTransfer' &&
((node.transfer.kind.__typename === 'RecurringTransfer' ||
node.transfer.kind.__typename === 'RecurringGovernanceTransfer') &&
node.transfer.kind.dispatchStrategy != null) ||
node.transfer.toAccountType === AccountType.ACCOUNT_TYPE_GLOBAL_REWARD
) {
@ -115,11 +117,15 @@ export const useRewards = ({
loading: assetsLoading,
error: assetsError,
} = useAssetsMapProvider();
const {
data: markets,
loading: marketsLoading,
error: marketsError,
} = useMarketsMapProvider();
} = useDataProvider({
dataProvider: marketsWithDataProvider,
variables: undefined,
});
const enriched = compact(
data?.transfersConnection?.edges?.map((n) => n?.node)
@ -140,7 +146,7 @@ export const useRewards = ({
undefined;
const marketsInScope = compact(
node.transfer.kind.dispatchStrategy.marketIdsInScope?.map(
(id) => markets && markets[id]
(id) => markets && markets.find((m) => m.id === id)
)
);
const isAssetTraded =
@ -151,7 +157,7 @@ export const useRewards = ({
return (
mAsset.id ===
node.transfer.kind.dispatchStrategy.dispatchMetricAssetId &&
m.state === MarketState.STATE_ACTIVE
m.data?.marketState === MarketState.STATE_ACTIVE
);
} catch {
// NOOP

View File

@ -5,7 +5,9 @@ import { isMarketActive } from '../utils';
export const useTopTradedMarkets = () => {
const { data, loading, error } = useMarketList();
const activeMarkets = data?.filter((m) => isMarketActive(m.state));
const activeMarkets = data?.filter(
(m) => m.data?.marketState && isMarketActive(m.data?.marketState)
);
const marketsByTopTraded = data
? orderBy(activeMarkets, (m) => calcTradedFactor(m), 'desc')
: undefined;

View File

@ -5,6 +5,7 @@ import {
ViewPartyConnector,
createConfig,
fairground,
validatorsTestnet,
mainnet,
stagnet,
} from '@vegaprotocol/wallet';
@ -36,7 +37,7 @@ export const useVegaWalletConfig = () => {
const viewParty = new ViewPartyConnector();
const config = createConfig({
chains: [mainnet, fairground, stagnet],
chains: [mainnet, fairground, validatorsTestnet, stagnet],
defaultChainId: CHAIN_IDS[VEGA_ENV],
connectors: [injected, snap, jsonRpc, viewParty],
});

View File

@ -39,6 +39,8 @@ const nextConfig = {
GIT_COMMIT: commitHash,
GIT_TAG: tag,
},
basePath: '/apps/vegas', // Set the base path
assetPrefix: '/apps/vegas', // Set the asset prefix
};
module.exports = SENTRY_AUTH_TOKEN

View File

@ -850,9 +850,8 @@ describe('DealTicket', () => {
];
it.each(states)('handles state %s correctly', async (marketState) => {
const marketOverrides = { state: marketState };
const marketDataOverrides = { marketState: marketState };
render(generateJsx([], marketOverrides, marketDataOverrides));
render(generateJsx([], {}, marketDataOverrides));
const text = `This market is ${marketState
.split('_')

View File

@ -9,8 +9,6 @@ export function generateMarket(override?: PartialDeep<Market>): Market {
id: 'market-id',
decimalPlaces: 2,
positionDecimalPlaces: 1,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: Schema.MarketState.STATE_ACTIVE,
tickSize: '1',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -19,6 +17,14 @@ export function generateMarket(override?: PartialDeep<Market>): Market {
close: '',
open: '',
},
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Schema.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {

View File

@ -199,8 +199,6 @@ const mockMarket: MarketFieldsFragment = {
id: 'marketId',
decimalPlaces: 1,
positionDecimalPlaces: 4,
state: Schema.MarketState.STATE_ACTIVE,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
} as MarketFieldsFragment;
const orderFormValues: OrderFormValues = {

View File

@ -7,7 +7,7 @@ export const CHAIN_IDS: {
[Networks.STAGNET1]: 'vega-stagnet1-202307191148',
[Networks.TESTNET]: 'vega-fairground-202305051805',
[Networks.MAINNET_MIRROR]: '',
[Networks.VALIDATOR_TESTNET]: 'testnet-001',
[Networks.VALIDATORS_TESTNET]: 'vega-testnet-0002-v4',
[Networks.CUSTOM]: 'vega-stagnet1-202307191148',
[Networks.MAINNET]: 'vega-mainnet-0011',
};

View File

@ -160,7 +160,7 @@ describe('Network switcher', () => {
[Networks.CUSTOM]: undefined,
[Networks.MAINNET]: 'https://main.net',
[Networks.TESTNET]: 'https://test.net',
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
[Networks.VALIDATORS_TESTNET]: 'https://validator-test.net',
[Networks.MAINNET_MIRROR]: 'https://mainnet-mirror.net',
[Networks.DEVNET]: 'https://dev.net',
[Networks.STAGNET1]: 'https://stag1.net',
@ -196,7 +196,7 @@ describe('Network switcher', () => {
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
[Networks.CUSTOM]: undefined,
[Networks.MAINNET]: 'https://main.net',
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
[Networks.VALIDATORS_TESTNET]: 'https://validator-test.net',
[Networks.MAINNET_MIRROR]: 'https://mainnet-mirror.net',
[Networks.TESTNET]: 'https://test.net',
[Networks.DEVNET]: 'https://dev.net',
@ -226,7 +226,7 @@ describe('Network switcher', () => {
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
[Networks.CUSTOM]: undefined,
[Networks.MAINNET]: undefined,
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
[Networks.VALIDATORS_TESTNET]: 'https://validator-test.net',
[Networks.MAINNET_MIRROR]: 'https://mainnet-mirror.net',
[Networks.TESTNET]: 'https://test.net',
[Networks.DEVNET]: 'https://dev.net',

View File

@ -17,7 +17,7 @@ import { useT } from '../../use-t';
export const useEnvNameMapping: () => Record<Networks, string> = () => {
const t = useT();
return {
[Networks.VALIDATOR_TESTNET]: t('VALIDATOR_TESTNET', {
[Networks.VALIDATORS_TESTNET]: t('VALIDATORS_TESTNET', {
contextSeparator: '|',
}),
[Networks.MAINNET_MIRROR]: t('Mainnet-mirror'),
@ -41,7 +41,7 @@ export const useEnvDescriptionMapping: () => Record<Networks, string> = () => {
const t = useT();
return {
[Networks.CUSTOM]: '',
[Networks.VALIDATOR_TESTNET]: t('The validator deployed testnet'),
[Networks.VALIDATORS_TESTNET]: t('The validator deployed testnet'),
[Networks.MAINNET_MIRROR]: t('The mainnet-mirror network'),
[Networks.DEVNET]: t('The latest Vega code auto-deployed'),
[Networks.STAGNET1]: t('A release candidate for the staging environment'),

View File

@ -20,7 +20,7 @@ type DAppLinks = {
};
const EmptyLinks: DAppLinks = {
[Networks.VALIDATOR_TESTNET]: '',
[Networks.VALIDATORS_TESTNET]: '',
[Networks.MAINNET_MIRROR]: '',
[Networks.DEVNET]: '',
[Networks.STAGNET1]: '',
@ -32,7 +32,7 @@ const ExplorerLinks = {
...EmptyLinks,
[Networks.STAGNET1]: 'https://explorer.stagnet1.vega.rocks',
[Networks.TESTNET]: 'https://explorer.fairground.wtf',
[Networks.VALIDATOR_TESTNET]:
[Networks.VALIDATORS_TESTNET]:
'https://explorer.validators-testnet.vega.rocks',
[Networks.MAINNET_MIRROR]: 'https://explorer.mainnet-mirror.vega.rocks/',
[Networks.MAINNET]: 'https://explorer.vega.xyz',
@ -51,7 +51,7 @@ const GovernanceLinks = {
[Networks.DEVNET]: 'https://dev.governance.vega.xyz',
[Networks.STAGNET1]: 'https://governance.stagnet1.vega.rocks',
[Networks.TESTNET]: 'https://governance.fairground.wtf',
[Networks.VALIDATOR_TESTNET]:
[Networks.VALIDATORS_TESTNET]:
'https://governance.validators-testnet.vega.rocks',
[Networks.MAINNET_MIRROR]: 'https://governance.mainnet-mirror.vega.rocks',
[Networks.MAINNET]: 'https://governance.vega.xyz',

View File

@ -6,7 +6,7 @@ import type {
} from './utils/validate-environment';
export enum Networks {
VALIDATOR_TESTNET = 'VALIDATOR_TESTNET',
VALIDATORS_TESTNET = 'VALIDATORS_TESTNET',
MAINNET_MIRROR = 'MAINNET_MIRROR',
CUSTOM = 'CUSTOM',
TESTNET = 'TESTNET',

View File

@ -3,8 +3,6 @@ import type { PartialDeep } from 'type-fest';
import * as Schema from '@vegaprotocol/types';
import type { Trade } from './fills-data-provider';
const { MarketState, MarketTradingMode } = Schema;
export const generateFill = (override?: PartialDeep<Trade>) => {
const defaultFill: Trade = {
__typename: 'Trade',
@ -52,9 +50,15 @@ export const generateFill = (override?: PartialDeep<Trade>) => {
id: 'market-id',
positionDecimalPlaces: 0,
decimalPlaces: 5,
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
tickSize: '1',
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Schema.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
fees: {
__typename: 'Fees',
factors: {

View File

@ -1,9 +1,7 @@
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
import * as Schema from '@vegaprotocol/types';
import type { FundingPayment } from './funding-payments-data-provider';
const { MarketState, MarketTradingMode } = Schema;
import { CompositePriceType } from '@vegaprotocol/types';
export const generateFundingPayment = (
override?: PartialDeep<FundingPayment>
@ -20,8 +18,6 @@ export const generateFundingPayment = (
id: 'market-id',
positionDecimalPlaces: 0,
decimalPlaces: 5,
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
tickSize: '1',
fees: {
__typename: 'Fees',
@ -32,6 +28,13 @@ export const generateFundingPayment = (
makerFee: '0.1',
},
},
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType: CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2005-03-31T19:37:00.000Z',

View File

@ -154,7 +154,7 @@
"TYPE_SELECTOR_LIQUIDITY_MONITORING_AUCTION": "This market is in auction until it reaches <0>sufficient liquidity</0>. Only limit orders are permitted when market is in auction.",
"TYPE_SELECTOR_PRICE_MONITORING_AUCTION": "This market is in auction due to <0>high price volatility</0>. Only limit orders are permitted when market is in auction.",
"Until the auction ends, you can only place GFA, GTT, or GTC limit orders": "Until the auction ends, you can only place GFA, GTT, or GTC limit orders",
"VALIDATOR_TESTNET": "VALIDATOR_TESTNET",
"VALIDATORS_TESTNET": "VALIDATORS_TESTNET",
"Volume discount": "Volume discount",
"When the order trades and its size falls below this threshold, it will be reset to the peak size and moved to the back of the priority order. Must be less than or equal to peak size, and greater than 0.": "When the order trades and its size falls below this threshold, it will be reset to the peak size and moved to the back of the priority order. Must be less than or equal to peak size, and greater than 0.",
"You are setting this market to cross-margin mode.": "You are setting this market to cross-margin mode.",

View File

@ -36,7 +36,7 @@
"The validator deployed testnet": "The validator deployed testnet",
"The vega mainnet": "The vega mainnet",
"This app will only work on {{VEGA_ENV}}. Select a node to connect to.": "This app will only work on {{VEGA_ENV}}. Select a node to connect to.",
"VALIDATOR_TESTNET": "VALIDATOR_TESTNET",
"VALIDATORS_TESTNET": "VALIDATORS_TESTNET",
"View on Etherscan (opens in a new tab)": "View on Etherscan (opens in a new tab)",
"View on {{chainLabel}} (opens in a new tab)": "View on {{chainLabel}} (opens in a new tab)",
"Warning delay ( >{{warningLatency}} sec): {{blockUpdateLatency}} sec": "Warning delay ( >{{warningLatency}} sec): {{blockUpdateLatency}} sec",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,10 +10,10 @@ import { useT } from '../../use-t';
interface Props {
marketId?: string;
positionDecimalPlaces?: number;
formatDecimals?: number;
initialValue?: string;
marketDecimals: number;
positionDecimalPlaces: number;
quoteUnit?: string;
}
@ -41,7 +41,11 @@ export const Last24hVolume = ({
: initialValue;
const candleVolumePrice = oneDayCandles
? calcCandleVolumePrice(oneDayCandles, marketDecimals)
? calcCandleVolumePrice(
oneDayCandles,
marketDecimals,
positionDecimalPlaces
)
: initialValue;
return (

View File

@ -1,5 +1,9 @@
import * as Schema from '@vegaprotocol/types';
import type { Market, MarketMaybeWithDataAndCandles } from './markets-provider';
import type {
Market,
MarketMaybeWithData,
MarketMaybeWithDataAndCandles,
} from './markets-provider';
import {
calcCandleVolumePrice,
calcTradedFactor,
@ -7,9 +11,10 @@ import {
sumFeesFactors,
totalFeesFactorsPercentage,
} from './market-utils';
import type { MarketData } from './market-data-provider';
const { MarketState, MarketTradingMode } = Schema;
const MARKET_A: Partial<Market> = {
const MARKET_A: Partial<MarketMaybeWithData> = {
id: '1',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -18,11 +23,13 @@ const MARKET_A: Partial<Market> = {
open: '2022-05-18T13:08:27.693537312Z',
close: null,
},
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
data: {
marketState: MarketState.STATE_ACTIVE,
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
} as MarketData,
};
const MARKET_B: Partial<Market> = {
const MARKET_B: Partial<MarketMaybeWithData> = {
id: '2',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -31,11 +38,13 @@ const MARKET_B: Partial<Market> = {
open: '2022-05-18T13:00:39.328347732Z',
close: null,
},
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
data: {
marketState: MarketState.STATE_ACTIVE,
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
} as MarketData,
};
const MARKET_C: Partial<Market> = {
const MARKET_C: Partial<MarketMaybeWithData> = {
id: '3',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -44,11 +53,13 @@ const MARKET_C: Partial<Market> = {
open: '2022-05-17T13:00:39.328347732Z',
close: null,
},
state: MarketState.STATE_REJECTED,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
data: {
marketState: MarketState.STATE_REJECTED,
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
} as MarketData,
};
const MARKET_D: Partial<Market> = {
const MARKET_D: Partial<MarketMaybeWithData> = {
id: '4',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -57,8 +68,10 @@ const MARKET_D: Partial<Market> = {
open: '2022-05-16T13:00:39.328347732Z',
close: null,
},
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
data: {
marketState: MarketState.STATE_ACTIVE,
marketTradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
} as MarketData,
};
describe('mapDataToMarketList', () => {
@ -68,7 +81,7 @@ describe('mapDataToMarketList', () => {
MARKET_B,
MARKET_C,
MARKET_D,
] as unknown as Market[]);
] as unknown as MarketMaybeWithData[]);
expect(result).toEqual([MARKET_B, MARKET_A]);
});
});
@ -177,7 +190,11 @@ describe('calcCandleVolumePrice', () => {
periodStart: '2022-05-18T14:08:27.693537312Z',
},
];
const decimalPlaces = 2;
expect(calcCandleVolumePrice(candles, decimalPlaces)).toEqual('2');
const marketDecimals = 3;
const positionDecimalPlaces = 2;
expect(
calcCandleVolumePrice(candles, marketDecimals, positionDecimalPlaces)
).toEqual('0.002');
});
});

View File

@ -89,8 +89,8 @@ export const filterAndSortMarkets = (markets: MarketMaybeWithData[]) => {
];
const orderedMarkets = orderBy(
markets?.filter((m) => {
const state = m.data?.marketState || m.state;
const tradingMode = m.data?.marketTradingMode || m.tradingMode;
const state = m.data?.marketState;
const tradingMode = m.data?.marketTradingMode;
return (
state !== MarketState.STATE_REJECTED &&
tradingMode !== MarketTradingMode.TRADING_MODE_NO_TRADING
@ -101,19 +101,26 @@ export const filterAndSortMarkets = (markets: MarketMaybeWithData[]) => {
);
return orderedMarkets.sort(
(a, b) =>
tradingModesOrdering.indexOf(a.data?.marketTradingMode || a.tradingMode) -
tradingModesOrdering.indexOf(b.data?.marketTradingMode || b.tradingMode)
(a.data?.marketTradingMode
? tradingModesOrdering.indexOf(a.data?.marketTradingMode)
: -1) -
(b.data?.marketTradingMode
? tradingModesOrdering.indexOf(b.data?.marketTradingMode)
: -1)
);
};
export const filterAndSortClosedMarkets = (markets: MarketMaybeWithData[]) => {
return markets.filter((m) => {
return [
return (
m.data?.marketState &&
[
MarketState.STATE_SETTLED,
MarketState.STATE_TRADING_TERMINATED,
MarketState.STATE_CLOSED,
MarketState.STATE_CANCELLED,
].includes(m.data?.marketState || m.state);
].includes(m.data.marketState)
);
});
};
@ -121,8 +128,9 @@ export const filterAndSortProposedMarkets = (
markets: MarketMaybeWithData[]
) => {
return markets.filter((m) => {
return [MarketState.STATE_PROPOSED].includes(
m.data?.marketState || m.state
return (
m.data?.marketState &&
[MarketState.STATE_PROPOSED].includes(m.data?.marketState)
);
});
};
@ -178,12 +186,16 @@ export const calcCandleVolume = (candles: Candle[]): string | undefined =>
*/
export const calcCandleVolumePrice = (
candles: Candle[],
decimalPlaces: number
marketDecimals: number,
positionDecimals: number
): string | undefined =>
candles &&
candles.reduce(
(acc, c) =>
new BigNumber(acc).plus(toBigNum(c.notional, decimalPlaces)).toString(),
new BigNumber(acc)
// Using notional both price and size need conversion with decimals, we can acheive the same result by just combining them
.plus(toBigNum(c.notional, marketDecimals + positionDecimals))
.toString(),
'0'
);

View File

@ -110,19 +110,30 @@ export const marketWithDataProvider = makeDerivedDataProvider<
};
});
export const activeMarketsProvider = makeDerivedDataProvider<Market[], never>(
[marketsProvider],
([markets]) => filterAndSortMarkets(markets)
export const marketsWithDataProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([marketsProvider, marketsDataProvider], (parts) =>
addData(parts[0] as Market[], parts[1] as MarketData[])
);
export const closedMarketsProvider = makeDerivedDataProvider<Market[], never>(
[marketsProvider],
([markets]) => filterAndSortClosedMarkets(markets)
export const activeMarketsProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([marketsWithDataProvider], ([markets]) => filterAndSortMarkets(markets));
export const closedMarketsProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([marketsWithDataProvider], ([markets]) =>
filterAndSortClosedMarkets(markets)
);
export const proposedMarketsProvider = makeDerivedDataProvider<Market[], never>(
[marketsProvider],
([markets]) => filterAndSortProposedMarkets(markets)
export const proposedMarketsProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([marketsWithDataProvider], ([markets]) =>
filterAndSortProposedMarkets(markets)
);
export type MarketMaybeWithCandles = Market & { candles?: Candle[] };
@ -157,28 +168,7 @@ const addData = <T extends Market>(markets: T[], marketsData: MarketData[]) =>
data: marketsData.find((data) => data.market.id === market.id),
}));
export const marketsWithDataProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([activeMarketsProvider, marketsDataProvider], (parts) =>
addData(parts[0] as Market[], parts[1] as MarketData[])
);
export const closedMarketsWithDataProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([closedMarketsProvider, marketsDataProvider], (parts) =>
addData(parts[0] as Market[], parts[1] as MarketData[])
);
export const allMarketsWithDataProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
never
>([marketsProvider, marketsDataProvider], (parts) =>
addData(parts[0] as Market[], parts[1] as MarketData[])
);
export const allMarketsWithLiveDataProvider = makeDerivedDataProvider<
export const marketsWithLiveDataProvider = makeDerivedDataProvider<
MarketMaybeWithData[],
MarketMaybeWithData,
{ marketIds: string[] }

View File

@ -61,10 +61,11 @@ fragment MarketFields on Market {
decimalPlaces
positionDecimalPlaces
tickSize
state
tradingMode
parentMarketID
successorMarketID
markPriceConfiguration {
...PriceConfiguration
}
fees {
factors {
makerFee

View File

@ -36,8 +36,6 @@ export const createMarketFragment = (
id: 'market-0',
decimalPlaces: 5,
positionDecimalPlaces: 0,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: Schema.MarketState.STATE_ACTIVE,
tickSize: '1',
marketTimestamps: {
__typename: 'MarketTimestamps',
@ -161,6 +159,14 @@ export const createMarketFragment = (
__typename: 'TradableInstrument',
},
__typename: 'Market',
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Schema.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
};
return merge(cloneDeep(defaultFragment), override);
@ -190,8 +196,6 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
}),
createMarketFragment({
id: 'market-2',
tradingMode: Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
state: Schema.MarketState.STATE_SUSPENDED,
marketTimestamps: {
proposed: '2022-08-23T11:36:32.252490405Z',
pending: '2022-08-24T11:36:32.252490405Z',

View File

@ -21,6 +21,14 @@ export const generateOrder = (partialOrder?: PartialDeep<Order>) => {
makerFee: '0.1',
},
},
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Schema.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-08-23T11:36:32.252490405Z',
@ -29,7 +37,6 @@ export const generateOrder = (partialOrder?: PartialDeep<Order>) => {
close: null,
},
positionDecimalPlaces: 2,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
@ -86,7 +93,6 @@ export const generateOrder = (partialOrder?: PartialDeep<Order>) => {
},
},
},
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
},
size: '10',
type: Schema.OrderType.TYPE_MARKET,

View File

@ -31,6 +31,14 @@ export const generateStopOrder = (
makerFee: '0.1',
},
},
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Schema.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2005-04-02T19:37:00.000Z',
@ -39,7 +47,6 @@ export const generateStopOrder = (
open: '',
},
positionDecimalPlaces: 2,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
@ -96,7 +103,6 @@ export const generateStopOrder = (
},
},
},
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
},
submission: {
marketId: 'market-id',

View File

@ -132,7 +132,8 @@ export const update = <T extends Omit<OrderFieldsFragment, 'market'> & Cursor>(
): T[] => {
const updatedData = data ? [...data] : ([] as T[]);
delta.forEach((orderUpdate) => {
const index = data?.findIndex((order) => order.id === orderUpdate.id) ?? -1;
const index =
data?.findIndex((order) => order?.id === orderUpdate.id) ?? -1;
const newer = !data?.length || orderUpdate.createdAt >= data[0].createdAt;
const doesFilterPass =
!variables || orderMatchFilters(orderUpdate, variables);
@ -204,7 +205,7 @@ export const activeOrdersProvider = makeDerivedDataProvider<
}
const orders = partsData[0] as ReturnType<typeof getData>;
return variables.marketId
? orders.filter((order) => variables.marketId === order.market.id)
? orders.filter((order) => variables.marketId === order?.market.id)
: orders;
}
);

View File

@ -3,8 +3,7 @@ import { OrderViewDialog } from './order-view-dialog';
import type { Order } from '../order-data-provider';
import { BrowserRouter } from 'react-router-dom';
import {
MarketState,
MarketTradingMode,
CompositePriceType,
OrderStatus,
OrderTimeInForce,
OrderType,
@ -20,8 +19,14 @@ describe('OrderViewDialog', () => {
id: 'b66cd4be223dfd900a4750bb5175e17d8f678996877d262be4c749a99e22a970',
decimalPlaces: 5,
positionDecimalPlaces: 3,
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
tickSize: '1',
fees: {
__typename: 'Fees',

View File

@ -111,7 +111,6 @@ const marketsData = [
__typename: 'Market',
id: '5e6035fe6a6df78c9ec44b333c231e63d357acef0a0620d2c243f5865d1dc0d8',
decimalPlaces: 5,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
positionDecimalPlaces: 0,
tradableInstrument: {
__typename: 'TradableInstrument',
@ -131,6 +130,8 @@ const marketsData = [
},
data: {
__typename: 'MarketData',
marketTradingMode:
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
markPrice: '9431775',
market: {
__typename: 'Market',
@ -142,7 +143,6 @@ const marketsData = [
__typename: 'Market',
id: '10c4b1114d2f6fda239b73d018bca55888b6018f0ac70029972a17fea0a6a56e',
decimalPlaces: 5,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
positionDecimalPlaces: 0,
tradableInstrument: {
__typename: 'TradableInstrument',
@ -162,6 +162,7 @@ const marketsData = [
},
data: {
__typename: 'MarketData',
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
markPrice: '869762',
market: {
__typename: 'Market',

View File

@ -17,7 +17,7 @@ import {
import {
type MarketMaybeWithData,
type MarketDataQueryVariables,
allMarketsWithLiveDataProvider,
marketsWithLiveDataProvider,
getAsset,
marketInfoProvider,
type MarketInfo,
@ -57,8 +57,8 @@ export interface Position {
marketDecimalPlaces: number;
marketId: string;
marketCode: string;
marketTradingMode: MarketTradingMode;
marketState: MarketState;
marketTradingMode?: MarketTradingMode;
marketState?: MarketState;
markPrice: string | undefined;
notional: string | undefined;
openVolume: string;
@ -171,8 +171,8 @@ export const getMetrics = (
marketDecimalPlaces,
marketId: market.id,
marketCode: market.tradableInstrument.instrument.code,
marketTradingMode: market.tradingMode,
marketState: market.state,
marketTradingMode: market.data?.marketTradingMode,
marketState: market.data?.marketState,
markPrice: marketData ? marketData.markPrice : undefined,
notional: notional
? notional.multipliedBy(10 ** marketDecimalPlaces).toFixed(0)
@ -325,6 +325,7 @@ export const preparePositions = (metrics: Position[], showClosed: boolean) => {
}
if (
p.marketState &&
[
MarketState.STATE_ACTIVE,
MarketState.STATE_PENDING,
@ -369,7 +370,7 @@ export const positionsMetricsProvider = makeDerivedDataProvider<
partyId: firstOrSelf(variables.partyIds),
}),
(callback, client, variables) =>
allMarketsWithLiveDataProvider(callback, client, {
marketsWithLiveDataProvider(callback, client, {
marketIds: variables.marketIds,
}),
(callback, client, variables) =>

View File

@ -35,10 +35,10 @@ export const getMarketExpiryDateFormatted = (
return null;
};
export const getExpiryDate = (
tags: ReadonlyArray<string> | null,
close: string | null,
state: MarketState
export const useExpiryDate = (
tags?: ReadonlyArray<string> | null,
close?: string | null,
state?: MarketState | null
): string => {
const t = useT();
const metadataExpiryDate = getMarketExpiryDate(tags);

View File

@ -16,6 +16,12 @@ export const fairground = {
name: 'Fairground',
};
export const validatorsTestnet = {
id: 'vega-testnet-0002-v4',
testnet: true,
name: 'Validators Testnet',
};
export const stagnet = {
id: 'vega-stagnet1-202307191148',
testnet: true,

View File

@ -3,7 +3,14 @@ export * from './types';
export * from './transaction-types';
// Core
export { mainnet, fairground, stagnet, mockChain, type Chain } from './chains';
export {
mainnet,
fairground,
validatorsTestnet,
stagnet,
mockChain,
type Chain,
} from './chains';
export { createConfig, coreStoreSlice, singleKeyStoreSlice } from './wallet';
// Connectors

View File

@ -138,8 +138,6 @@ describe('WithdrawFormContainer', () => {
id: 'marketId-1',
decimalPlaces: 5,
positionDecimalPlaces: 0,
state: Types.MarketState.STATE_SUSPENDED,
tradingMode: Types.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
tickSize: '1',
fees: {
__typename: 'Fees',
@ -150,6 +148,14 @@ describe('WithdrawFormContainer', () => {
liquidityFee: '0.001',
},
},
markPriceConfiguration: {
decayWeight: '',
decayPower: 0,
cashAmount: '',
SourceStalenessTolerance: [],
CompositePriceType:
Types.CompositePriceType.COMPOSITE_PRICE_TYPE_LAST_TRADE,
},
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {

View File

@ -16,7 +16,7 @@ bucket_name = ''
if 'release/' in args.github_ref:
if 'mainnet-mirror' in args.github_ref:
env_name = 'mainnet-mirror'
elif 'validators-testnet' in args.github_ref or 'validator-testnet' in args.github_ref:
elif 'validators-testnet' in args.github_ref:
env_name = 'validators-testnet'
else:
# remove prefixing release/ and take the first string limited by - which is supposed to be name of the environment for releasing (format: release/testnet-trading)