Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4b05dad21 | ||
|
|
2e07ada966 | ||
|
|
b81c4bc948 | ||
|
|
4f8d6bd876 | ||
|
|
52e5a37da3 | ||
|
|
22599673ec | ||
|
|
3c6a806ad3 | ||
|
|
7101d49d1d | ||
|
|
72e0cb76aa |
@@ -24,7 +24,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
|
||||
@@ -20,7 +20,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
|
||||
|
||||
@@ -13,7 +13,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
|
||||
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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
|
||||
@@ -18,7 +18,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
|
||||
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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||
|
||||
@@ -14,7 +14,7 @@ NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
|
||||
|
||||
@@ -15,19 +15,16 @@ export const CollapsibleToggle = ({
|
||||
dataTestId,
|
||||
children,
|
||||
}: CollapsibleToggleProps) => {
|
||||
const classes = classnames(
|
||||
'mb-4 transition-transform ease-in-out duration-300',
|
||||
{
|
||||
'rotate-180': toggleState,
|
||||
}
|
||||
);
|
||||
const classes = classnames('transition-transform ease-in-out duration-300', {
|
||||
'rotate-180': toggleState,
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => setToggleState(!toggleState)}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-baseline gap-3">
|
||||
{children}
|
||||
<div className={classes} data-testid="toggle-icon-wrapper">
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={20} />
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import classNames from 'classnames';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
interface HeadingProps {
|
||||
title?: string;
|
||||
title?: ReactNode;
|
||||
centerContent?: boolean;
|
||||
marginTop?: boolean;
|
||||
marginBottom?: boolean;
|
||||
|
||||
@@ -20,6 +20,7 @@ describe('getMultisigStatus', () => {
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.noNodes,
|
||||
showMultisigStatusError: true,
|
||||
zeroScoreNodes: [],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,6 +36,7 @@ describe('getMultisigStatus', () => {
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.correct,
|
||||
showMultisigStatusError: false,
|
||||
zeroScoreNodes: [],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -50,6 +52,22 @@ describe('getMultisigStatus', () => {
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.nodeNeedsRemoving,
|
||||
showMultisigStatusError: true,
|
||||
zeroScoreNodes: [
|
||||
{
|
||||
id: '1',
|
||||
rewardScore: {
|
||||
multisigScore: '0',
|
||||
},
|
||||
stakedTotal: '1000',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
rewardScore: {
|
||||
multisigScore: '0',
|
||||
},
|
||||
stakedTotal: '1000',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -65,6 +83,15 @@ describe('getMultisigStatus', () => {
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.nodeNeedsAdding,
|
||||
showMultisigStatusError: true,
|
||||
zeroScoreNodes: [
|
||||
{
|
||||
id: '1',
|
||||
rewardScore: {
|
||||
multisigScore: '0',
|
||||
},
|
||||
stakedTotal: '1000',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import type { PreviousEpochQuery } from '../routes/staking/__generated__/PreviousEpoch';
|
||||
import type {
|
||||
PreviousEpochQuery,
|
||||
ValidatorNodeFragment,
|
||||
} from '../routes/staking/__generated__/PreviousEpoch';
|
||||
|
||||
export enum MultisigStatus {
|
||||
'correct' = 'correct',
|
||||
@@ -17,12 +20,15 @@ export const getMultisigStatusInfo = (
|
||||
previousEpochData?.epoch.validatorsConnection?.edges
|
||||
);
|
||||
|
||||
const hasZero = allNodesInPreviousEpoch.some(
|
||||
(node) => Number(node?.rewardScore?.multisigScore) === 0
|
||||
);
|
||||
const hasOne = allNodesInPreviousEpoch.some(
|
||||
(node) => Number(node?.rewardScore?.multisigScore) === 1
|
||||
);
|
||||
const zeroScore = (node: ValidatorNodeFragment) =>
|
||||
Number(node.rewardScore?.multisigScore) === 0;
|
||||
const oneScore = (node: ValidatorNodeFragment) =>
|
||||
Number(node.rewardScore?.multisigScore) === 1;
|
||||
|
||||
const hasZero = allNodesInPreviousEpoch.some(zeroScore);
|
||||
const hasOne = allNodesInPreviousEpoch.some(oneScore);
|
||||
|
||||
const zeroScoreNodes = allNodesInPreviousEpoch.filter(zeroScore);
|
||||
|
||||
if (hasZero && hasOne) {
|
||||
// If any individual node has 0 it means that node is missing from the multisig and needs to be added
|
||||
@@ -38,5 +44,6 @@ export const getMultisigStatusInfo = (
|
||||
return {
|
||||
showMultisigStatusError: status !== MultisigStatus.correct,
|
||||
multisigStatus: status,
|
||||
zeroScoreNodes,
|
||||
};
|
||||
};
|
||||
|
||||
+9
-9
@@ -36,8 +36,8 @@ import { type Proposal, type BatchProposal } from '../../types';
|
||||
import { type ProposalTermsFieldsFragment } from '../../__generated__/Proposals';
|
||||
import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import { getIndicatorStyle } from '../proposal/colours';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
import { Indicator } from '../proposal/indicator';
|
||||
|
||||
const ProposalTypeTags = ({
|
||||
proposal,
|
||||
@@ -54,11 +54,8 @@ const ProposalTypeTags = ({
|
||||
|
||||
if (proposal.__typename === 'BatchProposal') {
|
||||
return (
|
||||
<div data-testid="proposal-type" className="flex gap-1">
|
||||
{proposal.subProposals?.map((subProposal, i) => {
|
||||
if (!subProposal?.terms) return null;
|
||||
return <ProposalTypeTag key={i} terms={subProposal.terms} />;
|
||||
})}
|
||||
<div data-testid="proposal-type">
|
||||
<ProposalInfoLabel variant="secondary">BatchProposal</ProposalInfoLabel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -253,7 +250,7 @@ const ProposalDetails = ({
|
||||
}}
|
||||
components={{
|
||||
// @ts-ignore children passed by i18next
|
||||
lozenge: <Lozenge />,
|
||||
lozenge: <Lozenge className="text-xs" />,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -315,8 +312,11 @@ const ProposalDetails = ({
|
||||
{proposal.subProposals.map((p, i) => {
|
||||
if (!p?.terms) return null;
|
||||
return (
|
||||
<li key={i} className="flex gap-3">
|
||||
<span className={getIndicatorStyle(i + 1)}>{i + 1}</span>
|
||||
<li
|
||||
key={i}
|
||||
className="grid grid-cols-[40px_minmax(0,1fr)] grid-rows-1 gap-3 items-center"
|
||||
>
|
||||
<Indicator indicator={i + 1} />
|
||||
<span>
|
||||
<div>{renderDetails(p.terms)}</div>
|
||||
<SubProposalStateText
|
||||
|
||||
@@ -18,7 +18,7 @@ export const ProposalJson = ({ proposal }: { proposal?: unknown }) => {
|
||||
<SubHeading title={t('proposalJson')} />
|
||||
</CollapsibleToggle>
|
||||
|
||||
{showDetails && <SyntaxHighlighter data={proposal} />}
|
||||
{showDetails && <SyntaxHighlighter size="smaller" data={proposal} />}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
+5
@@ -5,6 +5,11 @@ import {
|
||||
} from './proposal-market-changes';
|
||||
import type { JsonValue } from '../../../../components/json-diff';
|
||||
|
||||
jest.mock('../proposal/market-name.tsx', () => ({
|
||||
...jest.requireActual('../proposal/market-name.tsx'),
|
||||
MarketName: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('applyImmutableKeysFromEarlierVersion', () => {
|
||||
it('returns an empty object if any argument is not an object or null', () => {
|
||||
const earlierVersion: JsonValue = null;
|
||||
|
||||
+9
-2
@@ -18,6 +18,7 @@ import {
|
||||
type SingleProposalData,
|
||||
type SubProposalData,
|
||||
} from '../proposal/proposal-utils';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
|
||||
const immutableKeys = [
|
||||
'decimalPlaces',
|
||||
@@ -139,11 +140,17 @@ export const ProposalMarketChanges = ({
|
||||
setToggleState={setShowChanges}
|
||||
dataTestId={'proposal-market-changes-toggle'}
|
||||
>
|
||||
<SubHeading title={t('updatesToMarket')} />
|
||||
<SubHeading
|
||||
title={
|
||||
<>
|
||||
{t('UpdateToMarket')}: <MarketName marketId={marketId} truncate />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</CollapsibleToggle>
|
||||
|
||||
{showChanges && (
|
||||
<div className="mb-6">
|
||||
<div className="mb-6 bg-vega-cdark-900 p-2 rounded-lg">
|
||||
<JsonDiff left={left as JsonValue} right={right as JsonValue} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
+5
@@ -2,6 +2,11 @@ import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { ProposalUpdateMarketState } from './proposal-update-market-state';
|
||||
import { MarketUpdateType } from '@vegaprotocol/types';
|
||||
|
||||
jest.mock('../proposal/market-name.tsx', () => ({
|
||||
...jest.requireActual('../proposal/market-name.tsx'),
|
||||
MarketName: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('<ProposalUpdateMarketState />', () => {
|
||||
const suspendProposal = {
|
||||
__typename: 'UpdateMarketState' as const,
|
||||
|
||||
+16
-7
@@ -10,6 +10,7 @@ import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
|
||||
import { SubHeading } from '../../../../components/heading';
|
||||
import { type UpdateMarketStatesFragment } from '../../__generated__/Proposals';
|
||||
import { MarketUpdateTypeMapping } from '@vegaprotocol/types';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
|
||||
interface ProposalUpdateMarketStateProps {
|
||||
change: UpdateMarketStatesFragment | null;
|
||||
@@ -20,16 +21,18 @@ export const ProposalUpdateMarketState = ({
|
||||
}: ProposalUpdateMarketStateProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [showDetails, setShowDetails] = useState(false);
|
||||
let market;
|
||||
let isTerminate = false;
|
||||
|
||||
if (!change) {
|
||||
if (!change || change.__typename !== 'UpdateMarketState') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (change.__typename === 'UpdateMarketState') {
|
||||
market = change?.market;
|
||||
isTerminate = change?.updateType === 'MARKET_STATE_UPDATE_TYPE_TERMINATE';
|
||||
const market = change?.market;
|
||||
const isTerminate =
|
||||
change?.updateType === 'MARKET_STATE_UPDATE_TYPE_TERMINATE';
|
||||
|
||||
let toggleTitle = t(change.updateType);
|
||||
if (toggleTitle.length === 0) {
|
||||
toggleTitle = t('MarketDetails');
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -39,7 +42,13 @@ export const ProposalUpdateMarketState = ({
|
||||
setToggleState={setShowDetails}
|
||||
dataTestId="proposal-market-data-toggle"
|
||||
>
|
||||
<SubHeading title={t('MarketDetails')} />
|
||||
<SubHeading
|
||||
title={
|
||||
<>
|
||||
{toggleTitle}: <MarketName marketId={market?.id} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</CollapsibleToggle>
|
||||
|
||||
{showDetails && (
|
||||
|
||||
@@ -16,18 +16,31 @@ const getColour = (indicator: number, max = COLOURS.length) => {
|
||||
|
||||
export const getStyle = (indicator: number, max = COLOURS.length) =>
|
||||
classNames({
|
||||
'bg-vega-yellow-400': 'yellow' === getColour(indicator, max),
|
||||
'bg-vega-green-400': 'green' === getColour(indicator, max),
|
||||
'bg-vega-blue-400': 'blue' === getColour(indicator, max),
|
||||
'bg-vega-purple-400': 'purple' === getColour(indicator, max),
|
||||
'bg-vega-pink-400': 'pink' === getColour(indicator, max),
|
||||
'bg-vega-orange-400': 'orange' === getColour(indicator, max),
|
||||
'bg-vega-red-400': 'red' === getColour(indicator, max),
|
||||
'bg-vega-clight-600': 'none' === getColour(indicator, max),
|
||||
'bg-vega-yellow-400 before:bg-vega-yellow-400':
|
||||
'yellow' === getColour(indicator, max),
|
||||
'bg-vega-green-400 before:bg-vega-green-400':
|
||||
'green' === getColour(indicator, max),
|
||||
'bg-vega-blue-400 before:bg-vega-blue-400':
|
||||
'blue' === getColour(indicator, max),
|
||||
'bg-vega-purple-400 before:bg-vega-purple-400':
|
||||
'purple' === getColour(indicator, max),
|
||||
'bg-vega-pink-400 before:bg-vega-pink-400':
|
||||
'pink' === getColour(indicator, max),
|
||||
'bg-vega-orange-400 before:bg-vega-orange-400':
|
||||
'orange' === getColour(indicator, max),
|
||||
'bg-vega-red-400 before:bg-vega-red-400':
|
||||
'red' === getColour(indicator, max),
|
||||
'bg-vega-clight-600 before:bg-vega-clight-600':
|
||||
'none' === getColour(indicator, max),
|
||||
});
|
||||
|
||||
export const getIndicatorStyle = (indicator: number) =>
|
||||
classNames(
|
||||
'rounded-sm text-black inline-block px-1 py-1 font-alpha calt h-8',
|
||||
getStyle(indicator)
|
||||
'rounded-sm text-black inline-block px-1 py-1 font-alpha calt h-8 w-7 text-center',
|
||||
'text-border-1',
|
||||
getStyle(indicator),
|
||||
// Comment below if you want to remove the "chevron"
|
||||
'relative mr-[11px] z-1',
|
||||
'before:absolute before:z-0 before:top-1 before:right-[-11px] before:rounded-sm',
|
||||
"before:w-[22.62px] before:h-[22.62px] before:rotate-45 before:content-['']"
|
||||
);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { getIndicatorStyle } from './colours';
|
||||
|
||||
export const Indicator = ({ indicator }: { indicator: number }) => (
|
||||
<div className={getIndicatorStyle(indicator)}>
|
||||
<span className="absolute top-0 left-0 p-1 w-full text-center z-1">
|
||||
{indicator}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@@ -1,6 +1,13 @@
|
||||
import { useMarketInfoQuery } from '@vegaprotocol/markets';
|
||||
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const MarketName = ({ marketId }: { marketId?: string }) => {
|
||||
export const MarketName = ({
|
||||
marketId,
|
||||
truncate,
|
||||
}: {
|
||||
marketId?: string;
|
||||
truncate?: boolean;
|
||||
}) => {
|
||||
const { data } = useMarketInfoQuery({
|
||||
variables: {
|
||||
marketId: marketId || '',
|
||||
@@ -8,7 +15,7 @@ export const MarketName = ({ marketId }: { marketId?: string }) => {
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
return (
|
||||
<span>{data?.market?.tradableInstrument.instrument.code || marketId}</span>
|
||||
);
|
||||
const id = truncate ? truncateMiddle(marketId || '') : marketId;
|
||||
|
||||
return <span>{data?.market?.tradableInstrument.instrument.code || id}</span>;
|
||||
};
|
||||
|
||||
+29
-4
@@ -1,3 +1,4 @@
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { type ProposalTermsFieldsFragment } from '../../__generated__/Proposals';
|
||||
import { type Proposal, type BatchProposal } from '../../types';
|
||||
import { ListAsset } from '../list-asset';
|
||||
@@ -12,8 +13,10 @@ import {
|
||||
import { ProposalUpdateBenefitTiers } from '../proposal-update-benefit-tiers';
|
||||
import { ProposalUpdateMarketState } from '../proposal-update-market-state';
|
||||
import { ProposalVolumeDiscountProgramDetails } from '../proposal-volume-discount-program-details';
|
||||
import { getIndicatorStyle } from './colours';
|
||||
import { type ProposalNode } from './proposal-utils';
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import { Indicator } from './indicator';
|
||||
import { SubHeading } from '../../../../components/heading';
|
||||
|
||||
export const ProposalChangeDetails = ({
|
||||
proposal,
|
||||
@@ -26,6 +29,7 @@ export const ProposalChangeDetails = ({
|
||||
restData: ProposalNode | null;
|
||||
indicator?: number;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
let details = null;
|
||||
|
||||
switch (terms.change.__typename) {
|
||||
@@ -108,6 +112,25 @@ export const ProposalChangeDetails = ({
|
||||
'rewards.activityStreak.benefitTiers'
|
||||
) {
|
||||
details = <ProposalUpdateBenefitTiers change={terms.change} />;
|
||||
} else {
|
||||
details = (
|
||||
<div className="mb-4">
|
||||
<SubHeading title={t(terms.change.__typename as string)} />
|
||||
<span>
|
||||
<Trans
|
||||
i18nKey="Change <lozenge>{{key}}</lozenge> to <lozenge>{{value}}</lozenge>"
|
||||
values={{
|
||||
key: terms.change.networkParameter.key,
|
||||
value: terms.change.networkParameter.value,
|
||||
}}
|
||||
components={{
|
||||
// @ts-ignore children passed by i18next
|
||||
lozenge: <Lozenge />,
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -120,10 +143,12 @@ export const ProposalChangeDetails = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (indicator != null) {
|
||||
if (indicator != null && details != null) {
|
||||
details = (
|
||||
<div className="flex gap-3 mb-3">
|
||||
<div className={getIndicatorStyle(indicator)}>{indicator}</div>
|
||||
<div className="grid grid-cols-[40px_minmax(0,1fr)] grid-rows-1 gap-3 mb-3">
|
||||
<div className="w-10">
|
||||
<Indicator indicator={indicator} />
|
||||
</div>
|
||||
<div>{details}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -60,7 +60,7 @@ export const Proposal = ({ proposal, restData }: ProposalProps) => {
|
||||
<ProposalDescription description={proposal.rationale.description} />
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<div className="mb-4 flex flex-col gap-0">
|
||||
{proposal.__typename === 'Proposal' ? (
|
||||
<ProposalChangeDetails
|
||||
proposal={proposal}
|
||||
|
||||
@@ -206,7 +206,7 @@ export const ProposalsList = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
<section className="-mx-4 p-4 mb-8 bg-vega-dark-100">
|
||||
<section className="-mx-4 p-4 mb-8 bg-vega-cdark-900 rounded-l-sm">
|
||||
<SubHeading title={t('openProposals')} />
|
||||
|
||||
{sortedProposals.open.length > 0 ||
|
||||
|
||||
+156
-124
@@ -15,7 +15,8 @@ import {
|
||||
type VoteFieldsFragment,
|
||||
} from '../../__generated__/Proposals';
|
||||
import { useBatchVoteInformation } from '../../hooks/use-vote-information';
|
||||
import { getIndicatorStyle } from '../proposal/colours';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
import { Indicator } from '../proposal/indicator';
|
||||
|
||||
export const CompactVotes = ({ number }: { number: BigNumber }) => (
|
||||
<CompactNumber
|
||||
@@ -40,8 +41,9 @@ const VoteProgress = ({
|
||||
children,
|
||||
}: VoteProgressProps) => {
|
||||
const containerClasses = classNames(
|
||||
'relative h-10 rounded-md border border-vega-dark-300 overflow-hidden',
|
||||
colourfulBg ? 'bg-vega-pink' : 'bg-vega-dark-400'
|
||||
'relative h-2 rounded-md overflow-hidden',
|
||||
// 'border border-vega-dark-300',
|
||||
colourfulBg ? 'bg-vega-red' : 'bg-vega-dark-200'
|
||||
);
|
||||
|
||||
const progressClasses = classNames(
|
||||
@@ -50,17 +52,19 @@ const VoteProgress = ({
|
||||
);
|
||||
|
||||
const textClasses = classNames(
|
||||
'absolute top-0 left-0 w-full h-full flex items-center justify-start px-3 text-black'
|
||||
'w-full flex items-center justify-start text-white text-sm pb-1'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={containerClasses}>
|
||||
<div
|
||||
className={progressClasses}
|
||||
style={{ width: `${percentageFor}%` }}
|
||||
data-testid={testId}
|
||||
/>
|
||||
<div>
|
||||
<div className={textClasses}>{children}</div>
|
||||
<div className={containerClasses}>
|
||||
<div
|
||||
className={progressClasses}
|
||||
style={{ width: `${percentageFor}%` }}
|
||||
data-testid={testId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -79,14 +83,22 @@ const Status = ({ reached, threshold, text, testId }: StatusProps) => {
|
||||
<div data-testid={testId}>
|
||||
{reached ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<VegaIcon name={VegaIconNames.TICK} size={20} />
|
||||
<VegaIcon
|
||||
name={VegaIconNames.TICK}
|
||||
className="text-vega-green"
|
||||
size={20}
|
||||
/>
|
||||
<span>
|
||||
{threshold.toString()}% {text} {t('met')}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
<VegaIcon name={VegaIconNames.CROSS} size={20} />
|
||||
<VegaIcon
|
||||
name={VegaIconNames.CROSS}
|
||||
className="text-vega-red"
|
||||
size={20}
|
||||
/>
|
||||
<span>
|
||||
{threshold.toString()}% {text} {t('not met')}
|
||||
</span>
|
||||
@@ -152,7 +164,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
||||
<p className="flex gap-2 m-0 items-center">
|
||||
<VegaIcon
|
||||
name={VegaIconNames.CROSS}
|
||||
className="text-vega-pink"
|
||||
className="text-vega-red"
|
||||
size={20}
|
||||
/>
|
||||
{t(
|
||||
@@ -215,7 +227,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
||||
<p className="flex gap-2 m-0 items-center">
|
||||
<VegaIcon
|
||||
name={VegaIconNames.CROSS}
|
||||
className="text-vega-pink"
|
||||
className="text-vega-red"
|
||||
size={20}
|
||||
/>
|
||||
{t('Proposal failed: {{count}} of {{total}} proposals passed', {
|
||||
@@ -237,6 +249,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
||||
if (!p?.terms) return null;
|
||||
return (
|
||||
<VoteBreakdownBatchSubProposal
|
||||
indicator={i + 1}
|
||||
key={i}
|
||||
proposal={proposal}
|
||||
votes={proposal.votes}
|
||||
@@ -273,21 +286,37 @@ const VoteBreakdownBatchSubProposal = ({
|
||||
const isProposalOpen = proposal?.state === ProposalState.STATE_OPEN;
|
||||
const isUpdateMarket = terms?.change?.__typename === 'UpdateMarket';
|
||||
|
||||
const indicatorElement = indicator && (
|
||||
<span className={getIndicatorStyle(indicator)}>{indicator}</span>
|
||||
);
|
||||
let marketId = undefined;
|
||||
if (terms?.change?.__typename === 'UpdateMarket') {
|
||||
marketId = terms.change.marketId;
|
||||
}
|
||||
if (terms?.change?.__typename === 'UpdateMarketState') {
|
||||
marketId = terms.change.market.id;
|
||||
}
|
||||
|
||||
const marketName = marketId ? (
|
||||
<>
|
||||
: <MarketName marketId={marketId} />
|
||||
</>
|
||||
) : null;
|
||||
|
||||
const indicatorElement = indicator && <Indicator indicator={indicator} />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-baseline gap-3">
|
||||
<div className="mb-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
{indicatorElement}
|
||||
<h4>{t(terms.change.__typename)}</h4>
|
||||
<h4>
|
||||
{t(terms.change.__typename)} {marketName}
|
||||
</h4>
|
||||
</div>
|
||||
<div className="rounded-sm bg-vega-dark-100 p-3">
|
||||
<VoteBreakDownUI
|
||||
voteInfo={voteInfo}
|
||||
isProposalOpen={isProposalOpen}
|
||||
isUpdateMarket={isUpdateMarket}
|
||||
/>
|
||||
</div>
|
||||
<VoteBreakDownUI
|
||||
voteInfo={voteInfo}
|
||||
isProposalOpen={isProposalOpen}
|
||||
isUpdateMarket={isUpdateMarket}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -302,11 +331,13 @@ const VoteBreakdownNormal = ({ proposal }: { proposal: Proposal }) => {
|
||||
const isUpdateMarket = proposal?.terms?.change?.__typename === 'UpdateMarket';
|
||||
|
||||
return (
|
||||
<VoteBreakDownUI
|
||||
voteInfo={voteInfo}
|
||||
isProposalOpen={isProposalOpen}
|
||||
isUpdateMarket={isUpdateMarket}
|
||||
/>
|
||||
<div className="mb-6">
|
||||
<VoteBreakDownUI
|
||||
voteInfo={voteInfo}
|
||||
isProposalOpen={isProposalOpen}
|
||||
isUpdateMarket={isUpdateMarket}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -370,13 +401,13 @@ const VoteBreakDownUI = ({
|
||||
'flex justify-between flex-wrap gap-6'
|
||||
);
|
||||
const sectionClasses = classNames('min-w-[300px] flex-1 flex-grow');
|
||||
const headingClasses = classNames('mb-2 text-vega-dark-400');
|
||||
const headingClasses = classNames('mb-2 text-sm text-white font-bold');
|
||||
const progressDetailsClasses = classNames(
|
||||
'flex justify-between flex-wrap mt-2 text-sm'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<div>
|
||||
{isProposalOpen && (
|
||||
<div
|
||||
data-testid="vote-status"
|
||||
@@ -393,7 +424,7 @@ const VoteBreakDownUI = ({
|
||||
<VegaIcon
|
||||
name={VegaIconNames.CROSS}
|
||||
size={20}
|
||||
className="text-vega-pink"
|
||||
className="text-vega-red"
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
@@ -409,103 +440,13 @@ const VoteBreakDownUI = ({
|
||||
<p className="m-0">
|
||||
<Trans
|
||||
i18nKey={'Currently expected to <0>fail</0>'}
|
||||
components={[<span className="text-vega-pink" />]}
|
||||
components={[<span className="text-vega-red" />]}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isUpdateMarket && (
|
||||
<div className="mb-4">
|
||||
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
||||
<div className={sectionWrapperClasses}>
|
||||
<section
|
||||
className={sectionClasses}
|
||||
data-testid="lp-majority-breakdown"
|
||||
>
|
||||
<VoteProgress
|
||||
percentageFor={lpVoteWeight}
|
||||
colourfulBg={true}
|
||||
testId="lp-majority-progress"
|
||||
>
|
||||
<Status
|
||||
reached={majorityLPMet}
|
||||
threshold={requiredMajorityLPPercentage}
|
||||
text={t('majorityThreshold')}
|
||||
testId={
|
||||
majorityLPMet ? 'lp-majority-met' : 'lp-majority-not-met'
|
||||
}
|
||||
/>
|
||||
</VoteProgress>
|
||||
|
||||
<div className={progressDetailsClasses}>
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesFor')}:</span>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{lpVoteWeight.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{lpVoteWeight.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesAgainst')}:</span>
|
||||
<span>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{noLPPercentage.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className={sectionClasses}
|
||||
data-testid="lp-participation-breakdown"
|
||||
>
|
||||
<VoteProgress
|
||||
percentageFor={
|
||||
lpParticipationThresholdProgress || new BigNumber(0)
|
||||
}
|
||||
testId="lp-participation-progress"
|
||||
>
|
||||
<Status
|
||||
reached={participationLPMet}
|
||||
threshold={requiredParticipationLP || new BigNumber(1)}
|
||||
text={t('participationThreshold')}
|
||||
testId={
|
||||
participationLPMet
|
||||
? 'lp-participation-met'
|
||||
: 'lp-participation-not-met'
|
||||
}
|
||||
/>
|
||||
</VoteProgress>
|
||||
|
||||
<div className="flex mt-2 text-sm">
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('totalLiquidityProviderTokensVoted')}:</span>
|
||||
<Tooltip
|
||||
description={formatNumber(
|
||||
totalEquityLikeShareWeight,
|
||||
defaultDP
|
||||
)}
|
||||
>
|
||||
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
|
||||
<div className={sectionWrapperClasses}>
|
||||
<section
|
||||
@@ -605,6 +546,97 @@ const VoteBreakDownUI = ({
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{/** Liquidity provider vote */}
|
||||
{isUpdateMarket && (
|
||||
<div className="mt-3">
|
||||
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
||||
<div className={sectionWrapperClasses}>
|
||||
<section
|
||||
className={sectionClasses}
|
||||
data-testid="lp-majority-breakdown"
|
||||
>
|
||||
<VoteProgress
|
||||
percentageFor={lpVoteWeight}
|
||||
colourfulBg={true}
|
||||
testId="lp-majority-progress"
|
||||
>
|
||||
<Status
|
||||
reached={majorityLPMet}
|
||||
threshold={requiredMajorityLPPercentage}
|
||||
text={t('majorityThreshold')}
|
||||
testId={
|
||||
majorityLPMet ? 'lp-majority-met' : 'lp-majority-not-met'
|
||||
}
|
||||
/>
|
||||
</VoteProgress>
|
||||
|
||||
<div className={progressDetailsClasses}>
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesFor')}:</span>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{lpVoteWeight.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{lpVoteWeight.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesAgainst')}:</span>
|
||||
<span>
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{noLPPercentage.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className={sectionClasses}
|
||||
data-testid="lp-participation-breakdown"
|
||||
>
|
||||
<VoteProgress
|
||||
percentageFor={
|
||||
lpParticipationThresholdProgress || new BigNumber(0)
|
||||
}
|
||||
testId="lp-participation-progress"
|
||||
>
|
||||
<Status
|
||||
reached={participationLPMet}
|
||||
threshold={requiredParticipationLP || new BigNumber(1)}
|
||||
text={t('participationThreshold')}
|
||||
testId={
|
||||
participationLPMet
|
||||
? 'lp-participation-met'
|
||||
: 'lp-participation-not-met'
|
||||
}
|
||||
/>
|
||||
</VoteProgress>
|
||||
|
||||
<div className="flex mt-2 text-sm">
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('totalLiquidityProviderTokensVoted')}:</span>
|
||||
<Tooltip
|
||||
description={formatNumber(
|
||||
totalEquityLikeShareWeight,
|
||||
defaultDP
|
||||
)}
|
||||
>
|
||||
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
fragment ValidatorNode on Node {
|
||||
id
|
||||
stakedTotal
|
||||
rewardScore {
|
||||
rawValidatorScore
|
||||
performanceScore
|
||||
multisigScore
|
||||
validatorScore
|
||||
normalisedScore
|
||||
validatorStatus
|
||||
}
|
||||
rankingScore {
|
||||
status
|
||||
previousStatus
|
||||
rankingScore
|
||||
stakeScore
|
||||
performanceScore
|
||||
votingPower
|
||||
}
|
||||
}
|
||||
|
||||
query PreviousEpoch($epochId: ID) {
|
||||
epoch(id: $epochId) {
|
||||
id
|
||||
validatorsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
stakedTotal
|
||||
rewardScore {
|
||||
rawValidatorScore
|
||||
performanceScore
|
||||
multisigScore
|
||||
validatorScore
|
||||
normalisedScore
|
||||
validatorStatus
|
||||
}
|
||||
rankingScore {
|
||||
status
|
||||
previousStatus
|
||||
rankingScore
|
||||
stakeScore
|
||||
performanceScore
|
||||
votingPower
|
||||
}
|
||||
...ValidatorNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-20
@@ -3,6 +3,8 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ValidatorNodeFragment = { __typename?: 'Node', id: string, stakedTotal: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string, performanceScore: string, multisigScore: string, validatorScore: string, normalisedScore: string, validatorStatus: Types.ValidatorStatus } | null, rankingScore: { __typename?: 'RankingScore', status: Types.ValidatorStatus, previousStatus: Types.ValidatorStatus, rankingScore: string, stakeScore: string, performanceScore: string, votingPower: string } };
|
||||
|
||||
export type PreviousEpochQueryVariables = Types.Exact<{
|
||||
epochId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
}>;
|
||||
@@ -10,7 +12,28 @@ export type PreviousEpochQueryVariables = Types.Exact<{
|
||||
|
||||
export type PreviousEpochQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, validatorsConnection?: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, stakedTotal: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string, performanceScore: string, multisigScore: string, validatorScore: string, normalisedScore: string, validatorStatus: Types.ValidatorStatus } | null, rankingScore: { __typename?: 'RankingScore', status: Types.ValidatorStatus, previousStatus: Types.ValidatorStatus, rankingScore: string, stakeScore: string, performanceScore: string, votingPower: string } } } | null> | null } | null } };
|
||||
|
||||
|
||||
export const ValidatorNodeFragmentDoc = gql`
|
||||
fragment ValidatorNode on Node {
|
||||
id
|
||||
stakedTotal
|
||||
rewardScore {
|
||||
rawValidatorScore
|
||||
performanceScore
|
||||
multisigScore
|
||||
validatorScore
|
||||
normalisedScore
|
||||
validatorStatus
|
||||
}
|
||||
rankingScore {
|
||||
status
|
||||
previousStatus
|
||||
rankingScore
|
||||
stakeScore
|
||||
performanceScore
|
||||
votingPower
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const PreviousEpochDocument = gql`
|
||||
query PreviousEpoch($epochId: ID) {
|
||||
epoch(id: $epochId) {
|
||||
@@ -18,30 +41,13 @@ export const PreviousEpochDocument = gql`
|
||||
validatorsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
stakedTotal
|
||||
rewardScore {
|
||||
rawValidatorScore
|
||||
performanceScore
|
||||
multisigScore
|
||||
validatorScore
|
||||
normalisedScore
|
||||
validatorStatus
|
||||
}
|
||||
rankingScore {
|
||||
status
|
||||
previousStatus
|
||||
rankingScore
|
||||
stakeScore
|
||||
performanceScore
|
||||
votingPower
|
||||
}
|
||||
...ValidatorNode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
${ValidatorNodeFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __usePreviousEpochQuery__
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
import type { ReactNode } from 'react';
|
||||
import type { StakingNodeFieldsFragment } from '../__generated__/Staking';
|
||||
import type { PreviousEpochQuery } from '../__generated__/PreviousEpoch';
|
||||
import { getMultisigStatusInfo } from '../../../lib/get-multisig-status-info';
|
||||
|
||||
const statuses = {
|
||||
[Schema.ValidatorStatus.VALIDATOR_NODE_STATUS_ERSATZ]: 'status-ersatz',
|
||||
@@ -104,6 +105,10 @@ export const ValidatorTable = ({
|
||||
};
|
||||
}, [node, previousEpochData?.epoch.validatorsConnection?.edges]);
|
||||
|
||||
const multisigStatus = previousEpochData
|
||||
? getMultisigStatusInfo(previousEpochData)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="mb-12">
|
||||
@@ -281,6 +286,34 @@ export const ValidatorTable = ({
|
||||
</span>
|
||||
</Tooltip>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
<span className="uppercase">{t('multisigPenalty')}</span>
|
||||
|
||||
<span
|
||||
data-testid="multisig-penalty"
|
||||
className="flex gap-2 items-baseline"
|
||||
>
|
||||
{multisigStatus?.zeroScoreNodes.find(
|
||||
(n) => n.id === node.id
|
||||
) ? (
|
||||
<Tooltip
|
||||
description={t('multisigPenaltyThisNodeIndicator')}
|
||||
>
|
||||
<span className="inline-block w-2 h-2 rounded-full bg-vega-red-500"></span>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
<Tooltip description={t('multisigPenaltyDescription')}>
|
||||
<span>
|
||||
{formatNumberPercentage(
|
||||
BigNumber(
|
||||
multisigStatus?.showMultisigStatusError ? 100 : 0
|
||||
),
|
||||
2
|
||||
)}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow noBorder={true}>
|
||||
<span>
|
||||
<strong>{t('TOTAL PENALTIES')}</strong>
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
|
||||
@@ -14,7 +14,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
# Cosmic elevator flags
|
||||
|
||||
@@ -14,7 +14,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ 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://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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ 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/firefox/addon/vega-wallet-fairground
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/en-GB/firefox/addon/vega-wallet-beta/
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
# Cosmic elevator flags
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
useMaliciousOracle,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { useState } from 'react';
|
||||
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { type ProposalFragment } from '@vegaprotocol/proposals';
|
||||
import { MarketSuspendedBanner } from './market-suspended-banner';
|
||||
import { MarketUpdateBanner } from './market-update-banner';
|
||||
import { MarketUpdateStateBanner } from './market-update-state-banner';
|
||||
@@ -22,17 +22,17 @@ import {
|
||||
|
||||
type UpdateMarketBanner = {
|
||||
kind: 'UpdateMarket';
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
};
|
||||
|
||||
type UpdateMarketStateBanner = {
|
||||
kind: 'UpdateMarketState';
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
};
|
||||
|
||||
type NewMarketBanner = {
|
||||
kind: 'NewMarket'; // aka a proposal of NewMarket which succeeds the current market
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
};
|
||||
|
||||
type SettledBanner = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Fragment } from 'react';
|
||||
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { type ProposalFragment } from '@vegaprotocol/proposals';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { useT } from '../../lib/use-t';
|
||||
@@ -7,7 +7,7 @@ import { useT } from '../../lib/use-t';
|
||||
export const MarketSuccessorProposalBanner = ({
|
||||
proposals,
|
||||
}: {
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
}) => {
|
||||
const t = useT();
|
||||
const tokenLink = useLinks(DApp.Governance);
|
||||
@@ -28,7 +28,7 @@ export const MarketSuccessorProposalBanner = ({
|
||||
}
|
||||
)}{' '}
|
||||
{proposals.map((item, i) => {
|
||||
if (item.terms.change.__typename !== 'NewMarket') {
|
||||
if (item.terms?.change.__typename !== 'NewMarket') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { MarketUpdateBanner } from './market-update-banner';
|
||||
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { type ProposalFragment } from '@vegaprotocol/proposals';
|
||||
|
||||
describe('MarketUpdateBanner', () => {
|
||||
const change = {
|
||||
@@ -34,9 +34,7 @@ describe('MarketUpdateBanner', () => {
|
||||
|
||||
it('renders content for a single open proposal', () => {
|
||||
render(
|
||||
<MarketUpdateBanner
|
||||
proposals={[openProposal as MarketViewProposalFieldsFragment]}
|
||||
/>
|
||||
<MarketUpdateBanner proposals={[openProposal as ProposalFragment]} />
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -50,9 +48,7 @@ describe('MarketUpdateBanner', () => {
|
||||
|
||||
it('renders content for a single passed proposal', () => {
|
||||
render(
|
||||
<MarketUpdateBanner
|
||||
proposals={[passedProposal as MarketViewProposalFieldsFragment]}
|
||||
/>
|
||||
<MarketUpdateBanner proposals={[passedProposal as ProposalFragment]} />
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -65,10 +61,7 @@ describe('MarketUpdateBanner', () => {
|
||||
});
|
||||
|
||||
it('renders content for multiple passed proposals', () => {
|
||||
const proposals = [
|
||||
openProposal,
|
||||
openProposal,
|
||||
] as MarketViewProposalFieldsFragment[];
|
||||
const proposals = [openProposal, openProposal] as ProposalFragment[];
|
||||
|
||||
render(<MarketUpdateBanner proposals={proposals} />);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
TOKEN_PROPOSALS,
|
||||
useLinks,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { type ProposalFragment } from '@vegaprotocol/proposals';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { useT } from '../../lib/use-t';
|
||||
@@ -14,17 +14,17 @@ import { useT } from '../../lib/use-t';
|
||||
export const MarketUpdateBanner = ({
|
||||
proposals,
|
||||
}: {
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
}) => {
|
||||
const governanceLink = useLinks(DApp.Governance);
|
||||
const t = useT();
|
||||
const openProposals = sortBy(
|
||||
proposals.filter((p) => p.state === ProposalState.STATE_OPEN),
|
||||
(p) => p.terms.enactmentDatetime
|
||||
(p) => p.terms?.enactmentDatetime
|
||||
);
|
||||
const passedProposals = sortBy(
|
||||
proposals.filter((p) => p.state === ProposalState.STATE_PASSED),
|
||||
(p) => p.terms.enactmentDatetime
|
||||
(p) => p.terms?.enactmentDatetime
|
||||
);
|
||||
|
||||
let content = null;
|
||||
@@ -49,7 +49,7 @@ export const MarketUpdateBanner = ({
|
||||
content = (
|
||||
<p>
|
||||
{t('Proposal set to change market on {{date}}.', {
|
||||
date: format(new Date(proposal.terms.enactmentDatetime), 'dd MMMM'),
|
||||
date: format(new Date(proposal.terms?.enactmentDatetime), 'dd MMMM'),
|
||||
})}
|
||||
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>,
|
||||
</p>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { type ReactNode } from 'react';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import { format, formatDuration, intervalToDuration } from 'date-fns';
|
||||
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { type ProposalFragment } from '@vegaprotocol/proposals';
|
||||
import { MarketUpdateType, ProposalState } from '@vegaprotocol/types';
|
||||
import {
|
||||
DApp,
|
||||
TOKEN_PROPOSAL,
|
||||
@@ -19,18 +19,29 @@ export const MarketUpdateStateBanner = ({
|
||||
proposals,
|
||||
}: {
|
||||
market: Market;
|
||||
proposals: MarketViewProposalFieldsFragment[];
|
||||
proposals: ProposalFragment[];
|
||||
}) => {
|
||||
const t = useT();
|
||||
const governanceLink = useLinks(DApp.Governance);
|
||||
|
||||
const openTradingProposals = sortBy(
|
||||
proposals.filter(
|
||||
(p) =>
|
||||
p.terms &&
|
||||
p.terms.change.__typename === 'UpdateMarketState' &&
|
||||
p.terms.change.updateType ===
|
||||
MarketUpdateType.MARKET_STATE_UPDATE_TYPE_RESUME
|
||||
),
|
||||
(p) => p.terms?.enactmentDatetime
|
||||
);
|
||||
|
||||
const openProposals = sortBy(
|
||||
proposals.filter((p) => p.state === ProposalState.STATE_OPEN),
|
||||
(p) => p.terms.enactmentDatetime
|
||||
(p) => p.terms?.enactmentDatetime
|
||||
);
|
||||
const passedProposals = sortBy(
|
||||
proposals.filter((p) => p.state === ProposalState.STATE_PASSED),
|
||||
(p) => p.terms.enactmentDatetime
|
||||
(p) => p.terms?.enactmentDatetime
|
||||
);
|
||||
|
||||
if (!passedProposals.length && !openProposals.length) {
|
||||
@@ -45,12 +56,41 @@ export const MarketUpdateStateBanner = ({
|
||||
? governanceLink(TOKEN_PROPOSAL.replace(':id', openProposals[0]?.id))
|
||||
: undefined;
|
||||
|
||||
const openTradingProposalsLink =
|
||||
openTradingProposals[0]?.__typename === 'Proposal' &&
|
||||
openTradingProposals[0]?.id
|
||||
? governanceLink(
|
||||
TOKEN_PROPOSAL.replace(':id', openTradingProposals[0].id)
|
||||
)
|
||||
: openTradingProposals[0]?.__typename === 'ProposalDetail' &&
|
||||
openTradingProposals[0]?.batchId
|
||||
? governanceLink(
|
||||
TOKEN_PROPOSAL.replace(':id', openTradingProposals[0].batchId)
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const proposalsLink =
|
||||
openProposals.length > 1 ? governanceLink(TOKEN_PROPOSALS) : undefined;
|
||||
|
||||
let content: ReactNode;
|
||||
|
||||
if (passedProposals.length) {
|
||||
if (openTradingProposals.length >= 1) {
|
||||
content = (
|
||||
<>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'Trading on market {{name}} was suspended by governance. There are open proposals to resume trading on this market.',
|
||||
{ name }
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
<ExternalLink href={openTradingProposalsLink}>
|
||||
{t('View proposals')}
|
||||
</ExternalLink>
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
} else if (passedProposals.length) {
|
||||
const { date, duration, price } = getMessageVariables(passedProposals[0]);
|
||||
content = (
|
||||
<>
|
||||
@@ -116,20 +156,23 @@ export const MarketUpdateStateBanner = ({
|
||||
return <div data-testid={`update-state-banner-${market.id}`}>{content}</div>;
|
||||
};
|
||||
|
||||
const getMessageVariables = (proposal: MarketViewProposalFieldsFragment) => {
|
||||
const enactmentDatetime = new Date(proposal.terms.enactmentDatetime);
|
||||
const date = format(enactmentDatetime, 'dd MMMM');
|
||||
const duration = formatDuration(
|
||||
intervalToDuration({
|
||||
start: new Date(),
|
||||
end: enactmentDatetime,
|
||||
}),
|
||||
{
|
||||
format: ['days', 'hours'],
|
||||
}
|
||||
);
|
||||
const getMessageVariables = (proposal: ProposalFragment) => {
|
||||
const enactmentDatetime =
|
||||
proposal.terms && new Date(proposal.terms.enactmentDatetime);
|
||||
const date = enactmentDatetime && format(enactmentDatetime, 'dd MMMM');
|
||||
const duration =
|
||||
enactmentDatetime &&
|
||||
formatDuration(
|
||||
intervalToDuration({
|
||||
start: new Date(),
|
||||
end: enactmentDatetime,
|
||||
}),
|
||||
{
|
||||
format: ['days', 'hours'],
|
||||
}
|
||||
);
|
||||
const price =
|
||||
proposal.terms.change.__typename === 'UpdateMarketState'
|
||||
proposal.terms?.change.__typename === 'UpdateMarketState'
|
||||
? proposal.terms.change.price
|
||||
: '';
|
||||
return {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
useMarketProposals,
|
||||
type MarketViewProposalFieldsFragment,
|
||||
type ProposalFragment,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { ProposalState, ProposalType } from '@vegaprotocol/types';
|
||||
|
||||
const isPending = (p: MarketViewProposalFieldsFragment) => {
|
||||
const isPending = (p: ProposalFragment) => {
|
||||
return [ProposalState.STATE_OPEN, ProposalState.STATE_PASSED].includes(
|
||||
p.state
|
||||
);
|
||||
@@ -21,9 +21,10 @@ export const useUpdateMarketStateProposals = (
|
||||
|
||||
const proposals = data
|
||||
? data.filter(isPending).filter((p) => {
|
||||
const change = p.terms.change;
|
||||
const change = p.terms?.change;
|
||||
|
||||
if (
|
||||
change &&
|
||||
change.__typename === 'UpdateMarketState' &&
|
||||
change.market.id === marketId
|
||||
) {
|
||||
@@ -48,8 +49,9 @@ export const useUpdateMarketProposals = (
|
||||
|
||||
const proposals = data
|
||||
? data.filter(isPending).filter((p) => {
|
||||
const change = p.terms.change;
|
||||
const change = p.terms?.change;
|
||||
if (
|
||||
change &&
|
||||
change.__typename === 'UpdateMarket' &&
|
||||
change.marketId === marketId
|
||||
) {
|
||||
@@ -73,8 +75,9 @@ export const useSuccessorMarketProposals = (
|
||||
|
||||
const proposals = data
|
||||
? data.filter(isPending).filter((p) => {
|
||||
const change = p.terms.change;
|
||||
const change = p.terms?.change;
|
||||
if (
|
||||
change &&
|
||||
change.__typename === 'NewMarket' &&
|
||||
change.successorConfiguration?.parentMarketId === marketId
|
||||
) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useT } from '../../lib/use-t';
|
||||
import classNames from 'classnames';
|
||||
import { MarketHeaderStats } from '../../client-pages/market/market-header-stats';
|
||||
import { MarketMarkPrice } from '../market-mark-price';
|
||||
import { MarketBanner } from '../market-banner';
|
||||
/**
|
||||
* This is only rendered for the mobile navigation
|
||||
*/
|
||||
@@ -108,8 +109,11 @@ export const MobileMarketHeader = () => {
|
||||
}
|
||||
>
|
||||
{data && (
|
||||
<div className="px-3 py-6 text-sm grid grid-cols-2 items-center gap-x-4 gap-y-6">
|
||||
<MarketHeaderStats market={data} />
|
||||
<div>
|
||||
<MarketBanner market={data} />
|
||||
<div className="px-3 py-6 text-sm grid grid-cols-2 items-center gap-x-4 gap-y-6">
|
||||
<MarketHeaderStats market={data} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</FullScreenPopover>
|
||||
|
||||
@@ -182,7 +182,27 @@ def vega(request):
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def shared_vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
try:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
finally:
|
||||
cleanup_container(vega_instance)
|
||||
|
||||
@pytest.fixture
|
||||
def page_shared_vega(shared_vega, browser, request):
|
||||
with init_page(shared_vega, browser, request) as page_instance:
|
||||
yield page_instance
|
||||
|
||||
@pytest.fixture
|
||||
def auth_shared_vega(shared_vega: VegaServiceNull, page_shared_vega: Page):
|
||||
return auth_setup(shared_vega, page_shared_vega)
|
||||
|
||||
@pytest.fixture
|
||||
def risk_accepted_shared_vega(page_shared_vega: Page):
|
||||
risk_accepted_setup(page_shared_vega)
|
||||
|
||||
def cleanup_container(vega_instance):
|
||||
try:
|
||||
@@ -283,6 +303,10 @@ def opening_auction_market(vega):
|
||||
return setup_opening_auction_market(vega)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def shared_continuous_market(shared_vega:VegaServiceNull):
|
||||
return setup_continuous_market(shared_vega)
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def continuous_market(vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
@@ -2,35 +2,62 @@ import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from datetime import datetime, timedelta
|
||||
from conftest import init_vega, cleanup_container
|
||||
from conftest import init_page, risk_accepted_setup, auth_setup
|
||||
from fixtures.market import setup_continuous_market
|
||||
from actions.utils import wait_for_toast_confirmation
|
||||
from wallet_config import WalletConfig, MM_WALLET2
|
||||
|
||||
from actions.utils import (
|
||||
change_keys,
|
||||
create_and_faucet_wallet,
|
||||
)
|
||||
|
||||
order_size = "order-size"
|
||||
order_price = "order-price"
|
||||
place_order = "place-order"
|
||||
order_side_sell = "order-side-SIDE_SELL"
|
||||
order_side_buy = "order-side-SIDE_BUY"
|
||||
market_order = "order-type-Market"
|
||||
limit_order = "order-type-Limit"
|
||||
tif = "order-tif"
|
||||
expire = "expire"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function
|
||||
yield vega_instance
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(shared_vega, browser, request, continuous_market):
|
||||
with init_page(shared_vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(shared_vega, page)
|
||||
basic_key = WalletConfig("basic_key", "basic_key")
|
||||
create_and_faucet_wallet(vega=shared_vega, wallet=basic_key)
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
change_keys(page, shared_vega, "basic_key")
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def continuous_market(vega):
|
||||
return setup_continuous_market(vega)
|
||||
def continuous_market(shared_vega:VegaServiceNull):
|
||||
keypairs = shared_vega.wallet.get_keypairs("MarketSim")
|
||||
proposal_key = keypairs.get('market_maker')
|
||||
termination_key=keypairs.get('FJMKnwfZdd48C8NqvYrG')
|
||||
mm_2_key=keypairs.get('market_maker_2')
|
||||
|
||||
kwargs = {}
|
||||
if proposal_key is not None:
|
||||
kwargs['proposal_key'] = proposal_key
|
||||
if termination_key is not None:
|
||||
kwargs['termination_key'] = termination_key
|
||||
if mm_2_key is not None:
|
||||
kwargs['mm_2_key'] = mm_2_key
|
||||
|
||||
return setup_continuous_market(shared_vega, **kwargs)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_buy_order_GTT(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
def test_limit_buy_order_GTT( shared_vega: VegaServiceNull, page: Page):
|
||||
page.get_by_test_id(limit_order).click()
|
||||
page.get_by_test_id(order_side_buy).click()
|
||||
page.get_by_test_id(tif).select_option("Good 'til Time (GTT)")
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_price).fill("120")
|
||||
@@ -47,30 +74,31 @@ def test_limit_buy_order_GTT(continuous_market, vega: VegaServiceNull, page: Pag
|
||||
)
|
||||
page.get_by_test_id(place_order).click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
shared_vega.wait_fn(1)
|
||||
shared_vega.wait_for_total_catchup()
|
||||
page.get_by_test_id("All").click()
|
||||
page.reload()
|
||||
# 7002-SORD-017
|
||||
expect(page.get_by_role("row").nth(5)).to_contain_text("10+10LimitFilled120.00GTT:")
|
||||
expect(page.get_by_role("row").nth(4)).to_contain_text("10+10LimitFilled120.00GTT:")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
def test_limit_buy_order(shared_vega: VegaServiceNull, page: Page):
|
||||
page.get_by_test_id(limit_order).click()
|
||||
page.get_by_test_id(order_side_buy).click()
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_price).fill("120")
|
||||
page.get_by_test_id(place_order).click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.wait_fn(2)
|
||||
vega.wait_for_total_catchup()
|
||||
shared_vega.wait_fn(2)
|
||||
shared_vega.wait_for_total_catchup()
|
||||
page.get_by_test_id("All").click()
|
||||
page.reload()
|
||||
# 7002-SORD-017
|
||||
expect(page.get_by_role("row").nth(6)).to_contain_text("10+10LimitFilled120.00GTC")
|
||||
expect(page.get_by_role("row").nth(5)).to_contain_text("10+10LimitFilled120.00GTT")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
def test_limit_sell_order(shared_vega: VegaServiceNull, page: Page):
|
||||
page.get_by_test_id(limit_order).click()
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_price).fill("100")
|
||||
page.get_by_test_id(order_side_sell).click()
|
||||
@@ -84,15 +112,15 @@ def test_limit_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
)
|
||||
page.get_by_test_id(place_order).click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
shared_vega.wait_fn(1)
|
||||
shared_vega.wait_for_total_catchup()
|
||||
page.get_by_test_id("All").click()
|
||||
expect(page.get_by_role("row").nth(7)).to_contain_text("10-10LimitFilled100.00GFN")
|
||||
page.reload()
|
||||
expect(page.get_by_role("row").nth(6)).to_contain_text("10-10LimitFilled100.00GFN")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_market_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
def test_market_sell_order(shared_vega: VegaServiceNull, page: Page):
|
||||
page.get_by_test_id(market_order).click()
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_side_sell).click()
|
||||
@@ -105,32 +133,32 @@ def test_market_sell_order(continuous_market, vega: VegaServiceNull, page: Page)
|
||||
)
|
||||
page.get_by_test_id(place_order).click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
shared_vega.wait_fn(1)
|
||||
shared_vega.wait_for_total_catchup()
|
||||
|
||||
page.get_by_test_id("All").click()
|
||||
expect(page.get_by_role("row").nth(8)).to_contain_text("10-10MarketFilled-IOC")
|
||||
page.reload()
|
||||
expect(page.get_by_role("row").nth(7)).to_contain_text("10-10MarketFilled-IOC")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_market_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
def test_market_buy_order(shared_vega: VegaServiceNull, page: Page):
|
||||
page.get_by_test_id(market_order).click()
|
||||
page.get_by_test_id(order_side_buy).click()
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(tif).select_option("Fill or Kill (FOK)")
|
||||
page.get_by_test_id(place_order).click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
shared_vega.wait_fn(1)
|
||||
shared_vega.wait_for_total_catchup()
|
||||
page.get_by_test_id("All").click()
|
||||
page.reload()
|
||||
# 7002-SORD-010
|
||||
# 0003-WTXN-012
|
||||
# 0003-WTXN-003
|
||||
expect(page.get_by_role("row").nth(9)).to_contain_text("10+10MarketFilled-FOK")
|
||||
expect(page.get_by_role("row").nth(8)).to_contain_text("10+10MarketFilled-FOK")
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_sidebar_should_be_open_after_reload(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
def test_sidebar_should_be_open_after_reload(page: Page):
|
||||
expect(page.get_by_test_id("deal-ticket-form")).to_be_visible()
|
||||
page.get_by_test_id("Order").click()
|
||||
expect(page.get_by_test_id("deal-ticket-form")).not_to_be_visible()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import pytest
|
||||
""" import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
@@ -87,3 +87,4 @@ def test_margin_and_fees_estimations(continuous_market, vega: VegaServiceNull, p
|
||||
# expect(page.get_by_test_id("toast-content")).to_contain_text(
|
||||
# "Your transaction has been confirmed"
|
||||
# )
|
||||
"""
|
||||
@@ -44,25 +44,25 @@ def create_position(vega: VegaServiceNull, market_id):
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_stop_order_form_error_validation(continuous_market, page: Page):
|
||||
@pytest.mark.usefixtures("auth_shared_vega", "risk_accepted_shared_vega")
|
||||
def test_stop_order_form_error_validation(shared_continuous_market, page_shared_vega: Page):
|
||||
# 7002-SORD-032
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id(stop_order_btn).click()
|
||||
page.get_by_test_id(stop_limit_order_btn).is_visible()
|
||||
page.get_by_test_id(stop_limit_order_btn).click()
|
||||
page.get_by_test_id(order_side_sell).click()
|
||||
page.get_by_test_id(submit_stop_order).click()
|
||||
expect(page.get_by_test_id("stop-order-error-message-trigger-price")).to_have_text(
|
||||
page_shared_vega.goto(f"/#/markets/{shared_continuous_market}")
|
||||
page_shared_vega.get_by_test_id(stop_order_btn).click()
|
||||
page_shared_vega.get_by_test_id(stop_limit_order_btn).is_visible()
|
||||
page_shared_vega.get_by_test_id(stop_limit_order_btn).click()
|
||||
page_shared_vega.get_by_test_id(order_side_sell).click()
|
||||
page_shared_vega.get_by_test_id(submit_stop_order).click()
|
||||
expect(page_shared_vega.get_by_test_id("stop-order-error-message-trigger-price")).to_have_text(
|
||||
"You need provide a price"
|
||||
)
|
||||
expect(page.get_by_test_id("stop-order-error-message-size")).to_have_text(
|
||||
expect(page_shared_vega.get_by_test_id("stop-order-error-message-size")).to_have_text(
|
||||
"Size cannot be lower than 1"
|
||||
)
|
||||
|
||||
page.get_by_test_id(order_size).fill("1")
|
||||
page.get_by_test_id(order_price).fill("0.0000001")
|
||||
expect(page.get_by_test_id("stop-order-error-message-price")).to_have_text(
|
||||
page_shared_vega.get_by_test_id(order_size).fill("1")
|
||||
page_shared_vega.get_by_test_id(order_price).fill("0.0000001")
|
||||
expect(page_shared_vega.get_by_test_id("stop-order-error-message-price")).to_have_text(
|
||||
"Price cannot be lower than 0.00001"
|
||||
)
|
||||
|
||||
@@ -257,7 +257,7 @@ def test_submit_stop_limit_order_cancel(
|
||||
).to_have_text("Cancelled")
|
||||
|
||||
|
||||
class TestStopOcoValidation:
|
||||
""" class TestStopOcoValidation:
|
||||
@pytest.fixture(scope="class")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
@@ -296,3 +296,4 @@ class TestStopOcoValidation:
|
||||
expect(page.get_by_test_id("stop-order-warning-limit")).to_have_text(
|
||||
"There is a limit of 4 active stop orders per market. Orders submitted above the limit will be immediately rejected."
|
||||
)
|
||||
"""
|
||||
@@ -235,7 +235,7 @@ def test_submit_stop_oco_market_order_pending(
|
||||
"PendingOCO"
|
||||
)
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_oco_limit_order_pending(
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
|
||||
@@ -15,8 +15,7 @@ deal_ticket_deposit_dialog_button = "deal-ticket-deposit-dialog-button"
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(
|
||||
vega_instance)) # Register the cleanup function
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
|
||||
@@ -25,7 +24,6 @@ def continuous_market(vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd - issue only on the sim, should work in vega 0.74.0")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_should_display_info_and_button_for_deposit(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -33,17 +31,20 @@ def test_should_display_info_and_button_for_deposit(continuous_market, page: Pag
|
||||
page.get_by_test_id(order_price).fill("20")
|
||||
# 7002-SORD-060
|
||||
expect(page.get_by_test_id(deal_ticket_warning_margin)).to_have_text(
|
||||
"You may not have enough margin available to open this position.")
|
||||
"You may not have enough margin available to open this position."
|
||||
)
|
||||
page.get_by_test_id(deal_ticket_warning_margin).hover()
|
||||
expect(page.get_by_test_id("tooltip-content").nth(0)).to_have_text(
|
||||
"1,661,888.12901 tDAI is currently required.You have only 999,991.49731.Deposit tDAI")
|
||||
"1,661,888.12901 tDAI is currently required.You have only 999,991.49731.Deposit tDAI"
|
||||
)
|
||||
page.get_by_test_id(deal_ticket_deposit_dialog_button).nth(0).click()
|
||||
expect(page.get_by_test_id("sidebar-content")
|
||||
).to_contain_text("DepositFrom")
|
||||
expect(page.get_by_test_id("sidebar-content")).to_contain_text("DepositFrom")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
def test_should_show_an_error_if_your_balance_is_zero(
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
vega.create_key("key_empty")
|
||||
change_keys(page, vega, "key_empty")
|
||||
@@ -52,6 +53,7 @@ def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: V
|
||||
# 7002-SORD-060
|
||||
expect(page.get_by_test_id(place_order)).to_be_enabled()
|
||||
# 7002-SORD-003
|
||||
expect(page.get_by_test_id("deal-ticket-error-message-zero-balance")
|
||||
).to_have_text("You need tDAI in your wallet to trade in this market.Make a deposit")
|
||||
expect(page.get_by_test_id("deal-ticket-error-message-zero-balance")).to_have_text(
|
||||
"You need tDAI in your wallet to trade in this market.Make a deposit"
|
||||
)
|
||||
expect(page.get_by_test_id(deal_ticket_deposit_dialog_button)).to_be_visible()
|
||||
|
||||
@@ -107,7 +107,6 @@ def test_market_info_liquidation(page: Page):
|
||||
validate_info_section(page, fields)
|
||||
|
||||
|
||||
@pytest.mark.skip("core issue #5681")
|
||||
def test_market_info_key_details(page: Page, vega: VegaServiceNull):
|
||||
# 6002-MDET-201
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
@@ -117,8 +116,6 @@ def test_market_info_key_details(page: Page, vega: VegaServiceNull):
|
||||
fields = [
|
||||
["Market ID", short_market_id],
|
||||
["Name", "BTC:DAI_2023"],
|
||||
["Parent Market ID", "-"],
|
||||
["Insurance Pool Fraction", "-"],
|
||||
["Status", "Active"],
|
||||
["Trading Mode", "Continuous"],
|
||||
["Market Decimal Places", "5"],
|
||||
|
||||
@@ -9,6 +9,7 @@ from actions.utils import next_epoch
|
||||
from wallet_config import MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET
|
||||
from vega_sim.api import governance
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
|
||||
# 7002-SORD-001
|
||||
@@ -16,15 +17,18 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
|
||||
trading_mode = page.get_by_test_id("market-trading-mode").get_by_test_id(
|
||||
"item-value"
|
||||
)
|
||||
market_state = page.get_by_test_id("market-state").get_by_test_id("item-value")
|
||||
market_state = page.get_by_test_id(
|
||||
"market-state").get_by_test_id("item-value")
|
||||
|
||||
# setup market in proposed step, without liquidity provided
|
||||
market_id = proposed_market
|
||||
page.goto(f"/#/markets/{market_id}")
|
||||
# 6002-MDET-001
|
||||
expect(page.get_by_test_id("header-title")).to_have_text("BTC:DAI_2023Futr")
|
||||
expect(page.get_by_test_id("header-title")
|
||||
).to_have_text("BTC:DAI_2023Futr")
|
||||
# 6002-MDET-002
|
||||
expect(page.get_by_test_id("market-expiry")).to_have_text("ExpiryNot time-based")
|
||||
expect(page.get_by_test_id("market-expiry")
|
||||
).to_have_text("ExpiryNot time-based")
|
||||
page.get_by_test_id("market-expiry").hover()
|
||||
expect(page.get_by_test_id("expiry-tooltip").first).to_have_text(
|
||||
"This market expires when triggered by its oracle, not on a set date.View oracle specification"
|
||||
@@ -123,16 +127,16 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
|
||||
expect(market_state).to_have_text("Active")
|
||||
|
||||
vega.update_market_state(
|
||||
market_id = market_id,
|
||||
proposal_key = MM_WALLET.name,
|
||||
market_state = MarketStateUpdateType.Suspend,
|
||||
forward_time_to_enactment = False
|
||||
market_id=market_id,
|
||||
proposal_key=MM_WALLET.name,
|
||||
market_state=MarketStateUpdateType.Suspend,
|
||||
forward_time_to_enactment=False
|
||||
)
|
||||
|
||||
expect(
|
||||
page
|
||||
.get_by_test_id("market-banner")
|
||||
.get_by_test_id(f"update-state-banner-{market_id}")
|
||||
.get_by_test_id("market-banner")
|
||||
.get_by_test_id(f"update-state-banner-{market_id}")
|
||||
).to_be_visible()
|
||||
|
||||
next_epoch(vega=vega)
|
||||
@@ -143,12 +147,14 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
|
||||
|
||||
# banner should not show after resume
|
||||
vega.update_market_state(
|
||||
market_id = market_id,
|
||||
proposal_key = MM_WALLET.name,
|
||||
market_state = MarketStateUpdateType.Resume,
|
||||
forward_time_to_enactment = False
|
||||
market_id=market_id,
|
||||
proposal_key=MM_WALLET.name,
|
||||
market_state=MarketStateUpdateType.Resume,
|
||||
forward_time_to_enactment=False
|
||||
)
|
||||
|
||||
expect(page.get_by_test_id("market-banner")
|
||||
).to_have_text(" Trading on market BTC:DAI_2023 was suspended by governance. There are open proposals to resume trading on this market.View proposals1/2")
|
||||
next_epoch(vega=vega)
|
||||
|
||||
expect(page.get_by_test_id("market-banner")).not_to_be_visible()
|
||||
|
||||
@@ -1,39 +1,30 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect, Locator
|
||||
|
||||
from conftest import init_page, init_vega, cleanup_container
|
||||
from conftest import init_page, risk_accepted_setup
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
def page(shared_vega, browser, request):
|
||||
with init_page(shared_vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
page.goto("/#/disclaimer")
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
|
||||
def test_network_switcher(page: Page):
|
||||
page.goto("/#/disclaimer")
|
||||
navbar = page.locator('nav[aria-label="Main"]')
|
||||
assert_network_switcher(navbar)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
|
||||
def test_navbar_pages(page: Page):
|
||||
page.goto("/#/disclaimer")
|
||||
navbar = page.locator('nav[aria-label="Main"]')
|
||||
assert_links(navbar)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
|
||||
def test_navigation_mobile(page: Page):
|
||||
page.goto("/#/disclaimer")
|
||||
page.set_viewport_size({"width": 800, "height": 1040})
|
||||
navbar = page.locator('nav[aria-label="Main"]')
|
||||
|
||||
@@ -108,4 +99,4 @@ def assert_network_switcher(container: Locator):
|
||||
expect(mainnet_link).to_be_visible()
|
||||
# 0006-NETW-003
|
||||
expect(mainnet_link).to_have_attribute("href", "https://console.vega.xyz")
|
||||
expect(container.get_by_role("link", name="Fairground testnet")).to_be_visible()
|
||||
expect(container.get_by_role("link", name="Fairground testnet")).to_be_visible()
|
||||
@@ -49,7 +49,7 @@ def markets(vega: VegaServiceNull):
|
||||
price=130,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -63,7 +63,7 @@ def markets(vega: VegaServiceNull):
|
||||
price=88,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -77,7 +77,7 @@ def markets(vega: VegaServiceNull):
|
||||
price=88,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -92,7 +92,7 @@ def markets(vega: VegaServiceNull):
|
||||
wait=False,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -105,7 +105,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=100,
|
||||
price=104,
|
||||
)
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -120,7 +120,7 @@ def markets(vega: VegaServiceNull):
|
||||
expires_at=vega.get_blockchain_time() + 5 * 1e9,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -134,7 +134,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=20,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -148,7 +148,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=40,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -162,7 +162,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=60,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -177,7 +177,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=60,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -190,7 +190,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=10,
|
||||
price=150,
|
||||
)
|
||||
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -203,7 +203,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=10,
|
||||
price=160,
|
||||
)
|
||||
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -216,7 +216,7 @@ def markets(vega: VegaServiceNull):
|
||||
volume=10,
|
||||
price=60,
|
||||
)
|
||||
|
||||
vega.forward("5s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from typing import List
|
||||
from actions.vega import submit_order, submit_liquidity, submit_multiple_orders
|
||||
from conftest import init_vega, cleanup_container
|
||||
from fixtures.market import setup_simple_market
|
||||
from wallet_config import MM_WALLET, MM_WALLET2
|
||||
from actions.utils import next_epoch
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -15,7 +17,7 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def setup_market(vega):
|
||||
def setup_market(vega: VegaServiceNull):
|
||||
market_id = setup_simple_market(vega)
|
||||
submit_liquidity(vega, MM_WALLET.name, market_id)
|
||||
submit_multiple_orders(
|
||||
@@ -33,10 +35,9 @@ def setup_market(vega):
|
||||
[[10, 69.995], [5, 70], [5, 85], [3, 90], [3, 95]],
|
||||
)
|
||||
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
|
||||
return [
|
||||
vega,
|
||||
market_id,
|
||||
@@ -46,19 +47,19 @@ def setup_market(vega):
|
||||
# these values don't align with the multiple orders above as
|
||||
# creating a trade triggers the liquidity provision
|
||||
orderbook_content = [
|
||||
[130.00500, 10, 94],
|
||||
[130.00000, 3, 84],
|
||||
[120.00000, 7, 81],
|
||||
[110.00000, 5, 74],
|
||||
[105.00000, 2, 69],
|
||||
[101.00000, 67, 67],
|
||||
[130.00500, 10, 126],
|
||||
[130.00000, 3, 116],
|
||||
[120.00000, 7, 113],
|
||||
[110.00000, 5, 106],
|
||||
[105.00000, 2, 101],
|
||||
[101.00000, 99, 99],
|
||||
# mid
|
||||
[99.00000, 102, 102],
|
||||
[95.00000, 3, 105],
|
||||
[90.00000, 3, 108],
|
||||
[85.00000, 5, 113],
|
||||
[70.00000, 5, 118],
|
||||
[69.99500, 10, 128],
|
||||
[99.00000, 99, 99],
|
||||
[95.00000, 3, 102],
|
||||
[90.00000, 3, 105],
|
||||
[85.00000, 5, 110],
|
||||
[70.00000, 5, 115],
|
||||
[69.99500, 10, 125],
|
||||
]
|
||||
|
||||
|
||||
@@ -81,7 +82,6 @@ def verify_prices_descending(page: Page):
|
||||
assert prices == sorted(prices, reverse=True)
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_grid_content(setup_market, page: Page):
|
||||
vega = setup_market[0]
|
||||
@@ -109,6 +109,7 @@ def test_orderbook_grid_content(setup_market, page: Page):
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
next_epoch(vega)
|
||||
|
||||
# 6003-ORDB-001
|
||||
# 6003-ORDB-002
|
||||
@@ -120,7 +121,6 @@ def test_orderbook_grid_content(setup_market, page: Page):
|
||||
page.goto(f"/#/markets/{market_id}")
|
||||
|
||||
page.locator("[data-testid=Orderbook]").click()
|
||||
|
||||
# 6003-ORDB-013
|
||||
assert (
|
||||
float(page.locator("[data-testid*=last-traded]").text_content())
|
||||
@@ -144,50 +144,46 @@ def test_orderbook_grid_content(setup_market, page: Page):
|
||||
def test_orderbook_resolution_change(setup_market, page: Page):
|
||||
market_id = setup_market[1]
|
||||
# 6003-ORDB-008
|
||||
orderbook_content_0_00 = [
|
||||
[130.01, 10, 94],
|
||||
[130.00, 3, 84],
|
||||
[120.00, 7, 81],
|
||||
[110.00, 5, 74],
|
||||
[105.00, 2, 69],
|
||||
[101.00, 67, 67],
|
||||
orderbook_content_0_01 = [
|
||||
[130.01, 10, 126],
|
||||
[130.00, 3, 116],
|
||||
[120.00, 7, 113],
|
||||
[110.00, 5, 106],
|
||||
[105.00, 2, 101],
|
||||
[101.00, 99, 99],
|
||||
# mid
|
||||
[99.00, 102, 102],
|
||||
[95.00, 3, 105],
|
||||
[90.00, 3, 108],
|
||||
[85.00, 5, 113],
|
||||
[70.00, 15, 128],
|
||||
[99.00, 99, 99],
|
||||
[95.00, 3, 102],
|
||||
[90.00, 3, 105],
|
||||
[85.00, 5, 110],
|
||||
[70.00, 15, 125],
|
||||
]
|
||||
|
||||
orderbook_content_10 = [
|
||||
[130, 13, 94],
|
||||
[120, 7, 81],
|
||||
[110, 7, 74],
|
||||
[100, 67, 67],
|
||||
orderbook_content_1 = [
|
||||
[130, 13, 126],
|
||||
[120, 7, 113],
|
||||
[110, 5, 106],
|
||||
[105, 2, 101],
|
||||
[101, 99, 99],
|
||||
# mid
|
||||
[100, 105, 105],
|
||||
[90, 8, 113],
|
||||
[70, 15, 128],
|
||||
[99, 99, 99],
|
||||
[95, 3, 102],
|
||||
[90, 3, 105],
|
||||
[85, 5, 110],
|
||||
[70, 15, 125],
|
||||
]
|
||||
|
||||
orderbook_content_100 = [
|
||||
[100, 94, 94],
|
||||
# mid
|
||||
[100, 128, 128],
|
||||
]
|
||||
|
||||
resolutions = [
|
||||
["0.00", orderbook_content_0_00],
|
||||
["10", orderbook_content_10],
|
||||
["100", orderbook_content_100],
|
||||
["0.01", orderbook_content_0_01],
|
||||
["1", orderbook_content_1],
|
||||
]
|
||||
|
||||
page.goto(f"/#/markets/{market_id}")
|
||||
# temporary skip
|
||||
# for resolution in resolutions:
|
||||
# page.get_by_test_id("resolution").click()
|
||||
# page.get_by_role("menu").get_by_text(resolution[0], exact=True).click()
|
||||
# verify_orderbook_grid(page, resolution[1])
|
||||
for resolution in resolutions:
|
||||
page.get_by_test_id("resolution").click()
|
||||
page.get_by_role("menuitem").get_by_text(resolution[0], exact=True).click()
|
||||
verify_orderbook_grid(page, resolution[1])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
@@ -209,7 +205,6 @@ def test_orderbook_price_size_copy(setup_market, page: Page):
|
||||
expect(page.get_by_test_id("order-size")).to_have_value(volume.text_content())
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_price_movement(setup_market, page: Page):
|
||||
vega = setup_market[0]
|
||||
|
||||
@@ -119,7 +119,7 @@ def setup_market_and_referral_scheme(vega: VegaServiceNull, continuous_market: s
|
||||
forward_time(vega)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
setup_market_and_referral_scheme(vega, continuous_market, page)
|
||||
change_keys(page, vega, PARTY_B.name)
|
||||
@@ -163,7 +163,7 @@ def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaSer
|
||||
"1%", "1", "1%", "0", "1", "1"))
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_does_not_move_up_tiers_when_not_enough_epochs(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
setup_market_and_referral_scheme(vega, continuous_market, page)
|
||||
change_keys(page, vega, PARTY_B.name)
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import pytest
|
||||
from playwright.sync_api import expect, Page
|
||||
from conftest import init_vega, cleanup_container
|
||||
from conftest import init_page, risk_accepted_setup
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
def page(shared_vega, browser, request):
|
||||
with init_page(shared_vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_share_usage_data(page: Page):
|
||||
page.goto("/")
|
||||
page.get_by_test_id("Settings").click()
|
||||
@@ -41,7 +40,6 @@ ICON_TO_TOAST = {
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_toast_positions(page: Page):
|
||||
page.goto("/")
|
||||
page.get_by_test_id("Settings").click()
|
||||
@@ -52,10 +50,10 @@ def test_toast_positions(page: Page):
|
||||
expect(page.locator(f"[{toast_selector}]")).to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
|
||||
def test_dark_mode(page: Page):
|
||||
page.goto("/")
|
||||
page.get_by_test_id("Settings").click()
|
||||
expect(page.locator("html")).not_to_have_attribute("class", "dark")
|
||||
page.locator("#switch-settings-theme-switch").click()
|
||||
expect(page.locator("html")).to_have_attribute("class", "dark")
|
||||
expect(page.locator("html")).to_have_attribute("class", "dark")
|
||||
@@ -391,6 +391,8 @@
|
||||
"multisigContractIncorrect": "was incorrectly configured as at the end of the last epoch so rewards were penalised. Validator and delegator rewards will continue to be penalised until this is resolved.",
|
||||
"multisigContractLink": "Ethereum Multisig Contract",
|
||||
"multisigPenalty": "Multisig penalty",
|
||||
"multisigPenaltyThisNodeIndicator": "The multisig score for this node is equal to zero.",
|
||||
"multisigPenaltyDescription": "The multisig score is used in the calculation of rewards. For each validator that gets a multisig score of zero, no staking rewards are paid to that consensus validators and their nominators until the epoch following the one in which the configuration issue is resolved.",
|
||||
"myPendingStake": "My pending stake",
|
||||
"myStake": "My stake",
|
||||
"n/a": "N/A",
|
||||
|
||||
@@ -485,14 +485,45 @@ fragment MarketViewProposalFields on Proposal {
|
||||
}
|
||||
}
|
||||
|
||||
fragment SubProposal on ProposalDetail {
|
||||
id
|
||||
batchId
|
||||
reference
|
||||
state
|
||||
terms {
|
||||
closingDatetime
|
||||
enactmentDatetime
|
||||
change {
|
||||
__typename
|
||||
... on UpdateMarketState {
|
||||
...UpdateMarketStateFields
|
||||
}
|
||||
... on NewMarket {
|
||||
...NewMarketSuccessorFields
|
||||
}
|
||||
... on UpdateMarket {
|
||||
...UpdateMarketFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query MarketViewProposals(
|
||||
$proposalType: ProposalType
|
||||
$inState: ProposalState
|
||||
) {
|
||||
proposalsConnection(proposalType: $proposalType, inState: $inState) {
|
||||
edges {
|
||||
node {
|
||||
...MarketViewProposalFields
|
||||
proposalNode {
|
||||
... on BatchProposal {
|
||||
id
|
||||
subProposals {
|
||||
...SubProposal
|
||||
}
|
||||
}
|
||||
... on Proposal {
|
||||
...MarketViewProposalFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -500,6 +531,8 @@ query MarketViewProposals(
|
||||
|
||||
subscription MarketViewLiveProposals {
|
||||
proposals {
|
||||
...MarketViewProposalFields
|
||||
... on Proposal {
|
||||
...MarketViewProposalFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+44
-5
File diff suppressed because one or more lines are too long
@@ -1,6 +1,2 @@
|
||||
export {
|
||||
marketViewProposalsDataProvider,
|
||||
proposalsDataProvider,
|
||||
useMarketProposals,
|
||||
} from './proposals-data-provider';
|
||||
export * from './proposals-data-provider';
|
||||
export * from './__generated__/Proposals';
|
||||
|
||||
@@ -14,8 +14,13 @@ import {
|
||||
type MarketViewProposalsQuery,
|
||||
type MarketViewProposalsQueryVariables,
|
||||
type MarketViewLiveProposalsSubscriptionVariables,
|
||||
type SubProposalFragment,
|
||||
} from './__generated__/Proposals';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
|
||||
export type ProposalFragment =
|
||||
| MarketViewProposalFieldsFragment
|
||||
| SubProposalFragment;
|
||||
export type ProposalFragments = Array<ProposalFragment>;
|
||||
|
||||
const getData = (responseData: ProposalsListQuery | null) =>
|
||||
responseData?.proposalsConnection?.edges
|
||||
@@ -63,23 +68,23 @@ const ProposalTypeMap: Record<
|
||||
};
|
||||
|
||||
const matchFilter = (
|
||||
data: MarketViewProposalFieldsFragment,
|
||||
data: ProposalFragment,
|
||||
variables: MarketViewProposalsQueryVariables
|
||||
) => {
|
||||
return (
|
||||
(!variables.inState || data.state === variables.inState) &&
|
||||
(!variables.proposalType ||
|
||||
data.terms.change.__typename === ProposalTypeMap[variables.proposalType])
|
||||
data.terms?.change.__typename === ProposalTypeMap[variables.proposalType])
|
||||
);
|
||||
};
|
||||
|
||||
export const update: Update<
|
||||
MarketViewProposalFieldsFragment[] | null,
|
||||
MarketViewProposalFieldsFragment,
|
||||
ProposalFragment[] | null,
|
||||
ProposalFragment,
|
||||
MarketViewProposalsQueryVariables
|
||||
> = (
|
||||
data: MarketViewProposalFieldsFragment[] | null,
|
||||
delta: MarketViewProposalFieldsFragment,
|
||||
data: ProposalFragment[] | null,
|
||||
delta: ProposalFragment,
|
||||
reload,
|
||||
variables
|
||||
) => {
|
||||
@@ -104,13 +109,30 @@ export const update: Update<
|
||||
|
||||
const getMarketProposalsData = (
|
||||
responseData: MarketViewProposalsQuery | null
|
||||
) => removePaginationWrapper(responseData?.proposalsConnection?.edges) || [];
|
||||
): ProposalFragments => {
|
||||
const proposals: ProposalFragment[] = [];
|
||||
responseData?.proposalsConnection?.edges?.forEach((edge) => {
|
||||
if (edge?.proposalNode) {
|
||||
if (edge.proposalNode.__typename === 'Proposal') {
|
||||
proposals.push(edge.proposalNode);
|
||||
} else if (
|
||||
edge.proposalNode.__typename === 'BatchProposal' &&
|
||||
edge.proposalNode.subProposals
|
||||
) {
|
||||
proposals.push(
|
||||
...(edge.proposalNode.subProposals as ProposalFragments)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
return proposals;
|
||||
};
|
||||
|
||||
const subscriptionVariables: MarketViewLiveProposalsSubscriptionVariables = {};
|
||||
|
||||
export const marketViewProposalsDataProvider = makeDataProvider<
|
||||
MarketViewProposalsQuery,
|
||||
MarketViewProposalFieldsFragment[],
|
||||
ProposalFragments,
|
||||
MarketViewLiveProposalsSubscription,
|
||||
MarketViewProposalFieldsFragment,
|
||||
MarketViewProposalsQueryVariables,
|
||||
|
||||
@@ -23,13 +23,14 @@ const vegaCustomClasses = plugin(function ({ addUtilities }) {
|
||||
background: colors.white,
|
||||
color: colors.neutral[700],
|
||||
border: `1px solid ${colors.neutral[300]}`,
|
||||
borderRadius: '0.5rem',
|
||||
},
|
||||
'.syntax-highlighter-wrapper-sm .hljs': {
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: '1.25rem',
|
||||
fontSize: '0.75rem',
|
||||
lineHeight: '1rem',
|
||||
},
|
||||
'.dark .syntax-highlighter-wrapper .hljs': {
|
||||
background: colors.neutral[800],
|
||||
background: theme.colors.vega.cdark[900],
|
||||
color: theme.colors.vega.green.DEFAULT,
|
||||
border: 0,
|
||||
},
|
||||
|
||||
Generated
+22
-8
@@ -1232,6 +1232,14 @@ export type EpochTimestamps = {
|
||||
start?: Maybe<Scalars['Timestamp']>;
|
||||
};
|
||||
|
||||
export type EquityLikeShareWeightPerMarket = {
|
||||
__typename?: 'EquityLikeShareWeightPerMarket';
|
||||
/** The equity-like share weight for this market */
|
||||
equityLikeShareWeight: Scalars['String'];
|
||||
/** The market ID */
|
||||
marketId: Scalars['String'];
|
||||
};
|
||||
|
||||
/** Response for the signature bundle to allowlist an ERC20 token in the collateral bridge */
|
||||
export type Erc20ListAssetBundle = {
|
||||
__typename?: 'Erc20ListAssetBundle';
|
||||
@@ -1955,7 +1963,7 @@ export type LiquidityOrderReference = {
|
||||
/** Information about a liquidity provider */
|
||||
export type LiquidityProvider = {
|
||||
__typename?: 'LiquidityProvider';
|
||||
/** Information used for calculating an LP's fee share, such as the equity like share, average entry valuation and liquidity score, for the given liquidity provider and market */
|
||||
/** Information used for calculating an LP's fee share, such as the equity-like share, average entry valuation and liquidity score, for the given liquidity provider and market */
|
||||
feeShare?: Maybe<LiquidityProviderFeeShare>;
|
||||
/** Market ID the liquidity provision is for */
|
||||
marketId: Scalars['ID'];
|
||||
@@ -1983,7 +1991,7 @@ export type LiquidityProviderEdge = {
|
||||
node: LiquidityProvider;
|
||||
};
|
||||
|
||||
/** The equity like share of liquidity fee for each liquidity provider */
|
||||
/** The equity-like share of liquidity fee for each liquidity provider */
|
||||
export type LiquidityProviderFeeShare = {
|
||||
__typename?: 'LiquidityProviderFeeShare';
|
||||
/** The average entry valuation of the liquidity provider for the market */
|
||||
@@ -2483,7 +2491,7 @@ export type MarketData = {
|
||||
indicativeVolume: Scalars['String'];
|
||||
/** The last traded price (an unsigned integer) */
|
||||
lastTradedPrice: Scalars['String'];
|
||||
/** The equity like share of liquidity fee for each liquidity provider */
|
||||
/** The equity-like share of liquidity fee for each liquidity provider */
|
||||
liquidityProviderFeeShare?: Maybe<Array<LiquidityProviderFeeShare>>;
|
||||
/** SLA performance statistics */
|
||||
liquidityProviderSla?: Maybe<Array<LiquidityProviderSLA>>;
|
||||
@@ -3032,7 +3040,7 @@ export type Normaliser = {
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
/** The equity like share of liquidity fee for each liquidity provider */
|
||||
/** The equity-like share of liquidity fee for each liquidity provider */
|
||||
export type ObservableLiquidityProviderFeeShare = {
|
||||
__typename?: 'ObservableLiquidityProviderFeeShare';
|
||||
/** The average entry valuation of the liquidity provider for the market */
|
||||
@@ -3099,7 +3107,7 @@ export type ObservableMarketData = {
|
||||
indicativeVolume: Scalars['String'];
|
||||
/** The last traded price (an unsigned integer) */
|
||||
lastTradedPrice: Scalars['String'];
|
||||
/** The equity like share of liquidity fee for each liquidity provider */
|
||||
/** The equity-like share of liquidity fee for each liquidity provider */
|
||||
liquidityProviderFeeShare?: Maybe<Array<ObservableLiquidityProviderFeeShare>>;
|
||||
/** SLA performance statistics */
|
||||
liquidityProviderSla?: Maybe<Array<ObservableLiquidityProviderSLA>>;
|
||||
@@ -3830,12 +3838,14 @@ export type PartytradesConnectionArgs = {
|
||||
/** Represents a party on Vega, could be an ethereum wallet address in the future */
|
||||
export type PartytransfersConnectionArgs = {
|
||||
direction?: InputMaybe<TransferDirection>;
|
||||
fromAccountType?: InputMaybe<AccountType>;
|
||||
fromEpoch?: InputMaybe<Scalars['Int']>;
|
||||
gameId?: InputMaybe<Scalars['ID']>;
|
||||
isReward?: InputMaybe<Scalars['Boolean']>;
|
||||
pagination?: InputMaybe<Pagination>;
|
||||
scope?: InputMaybe<TransferScope>;
|
||||
status?: InputMaybe<TransferStatus>;
|
||||
toAccountType?: InputMaybe<AccountType>;
|
||||
toEpoch?: InputMaybe<Scalars['Int']>;
|
||||
};
|
||||
|
||||
@@ -4471,7 +4481,7 @@ export enum ProposalRejectionReason {
|
||||
PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_INVALID = 'PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_INVALID',
|
||||
/** Proposal terms timestamps are not compatible (Validation < Closing < Enactment) */
|
||||
PROPOSAL_ERROR_INCOMPATIBLE_TIMESTAMPS = 'PROPOSAL_ERROR_INCOMPATIBLE_TIMESTAMPS',
|
||||
/** The proposal is rejected because the party does not have enough equity like share in the market */
|
||||
/** The proposal is rejected because the party does not have enough equity-like share in the market */
|
||||
PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE = 'PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE',
|
||||
/** The proposer for this proposal has insufficient tokens */
|
||||
PROPOSAL_ERROR_INSUFFICIENT_TOKENS = 'PROPOSAL_ERROR_INSUFFICIENT_TOKENS',
|
||||
@@ -4653,7 +4663,7 @@ export type ProposalVoteEdge = {
|
||||
|
||||
export type ProposalVoteSide = {
|
||||
__typename?: 'ProposalVoteSide';
|
||||
/** Total equity like share weight for this side (only for UpdateMarket Proposals) */
|
||||
/** Total equity-like share weight for this side (only for UpdateMarket Proposals) */
|
||||
totalEquityLikeShareWeight: Scalars['String'];
|
||||
/** Total number of votes cast for this side */
|
||||
totalNumber: Scalars['String'];
|
||||
@@ -5466,6 +5476,7 @@ export type QuerytransferArgs = {
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type QuerytransfersConnectionArgs = {
|
||||
direction?: InputMaybe<TransferDirection>;
|
||||
fromAccountType?: InputMaybe<AccountType>;
|
||||
fromEpoch?: InputMaybe<Scalars['Int']>;
|
||||
gameId?: InputMaybe<Scalars['ID']>;
|
||||
isReward?: InputMaybe<Scalars['Boolean']>;
|
||||
@@ -5473,6 +5484,7 @@ export type QuerytransfersConnectionArgs = {
|
||||
partyId?: InputMaybe<Scalars['ID']>;
|
||||
scope?: InputMaybe<TransferScope>;
|
||||
status?: InputMaybe<TransferStatus>;
|
||||
toAccountType?: InputMaybe<AccountType>;
|
||||
toEpoch?: InputMaybe<Scalars['Int']>;
|
||||
};
|
||||
|
||||
@@ -7238,7 +7250,9 @@ export type Vote = {
|
||||
__typename?: 'Vote';
|
||||
/** RFC3339Nano time and date when the vote reached Vega network */
|
||||
datetime: Scalars['Timestamp'];
|
||||
/** The weight of this vote based on the total equity like share */
|
||||
/** The equity-like share weight per market (only for batch proposals) */
|
||||
equityLikeSharePerMarket?: Maybe<Array<Maybe<EquityLikeShareWeightPerMarket>>>;
|
||||
/** The weight of this vote based on the total equity-like share */
|
||||
equityLikeShareWeight: Scalars['String'];
|
||||
/** Total number of governance tokens for the party that cast the vote */
|
||||
governanceTokenBalance: Scalars['String'];
|
||||
|
||||
@@ -199,7 +199,6 @@
|
||||
"flush-promises": "^1.0.2",
|
||||
"glob": "^8.0.3",
|
||||
"husky": "^7.0.4",
|
||||
"inquirer": "^8.0.0",
|
||||
"jest": "29.4.3",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-environment-jsdom": "^29.4.1",
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
const { execSync } = require('child_process');
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
const getTags = (take) => {
|
||||
const tags = execSync(
|
||||
"git for-each-ref --sort=taggerdate --format '%(refname)' refs/tags"
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map((t) => t.replace('refs/tags/', ''))
|
||||
.reverse()
|
||||
.slice(0, take);
|
||||
return tags;
|
||||
};
|
||||
|
||||
const getReleaseBranches = () => {
|
||||
const branches = execSync('git branch --remote | grep origin/release/')
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map((b) => b.trim().replace('origin/release/', ''));
|
||||
return branches;
|
||||
};
|
||||
|
||||
const release = (tag, branch) => {
|
||||
const steps = [
|
||||
`git checkout ${branch}`,
|
||||
'git pull',
|
||||
`git reset --hard ${tag}`,
|
||||
'git push --force',
|
||||
];
|
||||
try {
|
||||
for (const cmd of steps) {
|
||||
const result = execSync(cmd).toString();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Could not make a release');
|
||||
}
|
||||
};
|
||||
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'tag',
|
||||
message: 'What version would you like to release?',
|
||||
choices: getTags(),
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'envs',
|
||||
message: 'To what environment you wish to release?',
|
||||
choices: ['mainnet', ...getReleaseBranches()],
|
||||
validate(answer) {
|
||||
return answer.length > 0;
|
||||
},
|
||||
},
|
||||
])
|
||||
.then((answers) => {
|
||||
inquirer
|
||||
.prompt({
|
||||
type: 'confirm',
|
||||
name: 'sure',
|
||||
message: `Are you sure? This will release ${
|
||||
answers.tag
|
||||
} to ${answers.envs.join(', ')}`,
|
||||
})
|
||||
.then(() => {
|
||||
for (const env of answers.envs) {
|
||||
const branch = env === 'mainnet' ? 'main' : `release/${env}`;
|
||||
release(answers.tag, branch);
|
||||
}
|
||||
execSync('git checkout develop');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Something went wrong', err.toString());
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Something went wrong', err.toString());
|
||||
});
|
||||
Reference in New Issue
Block a user