diff --git a/apps/governance/.env b/apps/governance/.env
index 2a0465470..91458552d 100644
--- a/apps/governance/.env
+++ b/apps/governance/.env
@@ -25,3 +25,5 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
CYPRESS_FAIRGROUND=false
LC_ALL="en_US.UTF-8"
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=true
\ No newline at end of file
diff --git a/apps/governance/.env.capsule b/apps/governance/.env.capsule
index d4099e074..b8814b856 100644
--- a/apps/governance/.env.capsule
+++ b/apps/governance/.env.capsule
@@ -25,3 +25,5 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
#Test configuration variables
CYPRESS_FAIRGROUND=false
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=false
\ No newline at end of file
diff --git a/apps/governance/.env.devnet b/apps/governance/.env.devnet
index 3c90793b6..51aa96100 100644
--- a/apps/governance/.env.devnet
+++ b/apps/governance/.env.devnet
@@ -16,3 +16,6 @@ NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=true
\ No newline at end of file
diff --git a/apps/governance/.env.mainnet b/apps/governance/.env.mainnet
index 8781da016..9ac987b42 100644
--- a/apps/governance/.env.mainnet
+++ b/apps/governance/.env.mainnet
@@ -17,3 +17,6 @@ NX_VEGA_REST_URL=https://api.vega.community/api/v2/
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=false
\ No newline at end of file
diff --git a/apps/governance/.env.mainnet-mirror b/apps/governance/.env.mainnet-mirror
index fab05ed68..22fd23a50 100644
--- a/apps/governance/.env.mainnet-mirror
+++ b/apps/governance/.env.mainnet-mirror
@@ -16,3 +16,6 @@ NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=false
\ No newline at end of file
diff --git a/apps/governance/.env.stagnet1 b/apps/governance/.env.stagnet1
index 2ac16547a..53f1e733f 100644
--- a/apps/governance/.env.stagnet1
+++ b/apps/governance/.env.stagnet1
@@ -11,4 +11,7 @@ NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/annou
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
-NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
\ No newline at end of file
+NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=true
\ No newline at end of file
diff --git a/apps/governance/.env.testnet b/apps/governance/.env.testnet
index 454b47479..0a817b1d2 100644
--- a/apps/governance/.env.testnet
+++ b/apps/governance/.env.testnet
@@ -16,4 +16,7 @@ NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
-NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
\ No newline at end of file
+NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=true
\ No newline at end of file
diff --git a/apps/governance/.env.validators-testnet b/apps/governance/.env.validators-testnet
index 169330f85..0064e8152 100644
--- a/apps/governance/.env.validators-testnet
+++ b/apps/governance/.env.validators-testnet
@@ -13,4 +13,7 @@ NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
-NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
\ No newline at end of file
+NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
+
+# Cosmic elevator flags
+NX_SUCCESSOR_MARKETS=false
\ No newline at end of file
diff --git a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx
index 855bccad8..f4a39187f 100644
--- a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx
+++ b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx
@@ -22,6 +22,16 @@ import {
} from '../../test-helpers/mocks';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { MockedResponse } from '@apollo/client/testing';
+import { FLAGS } from '@vegaprotocol/environment';
+import { BrowserRouter } from 'react-router-dom';
+
+jest.mock('@vegaprotocol/proposals', () => ({
+ ...jest.requireActual('@vegaprotocol/proposals'),
+ useSuccessorMarketProposalDetails: () => ({
+ code: 'PARENT_CODE',
+ parentMarketId: 'PARENT_ID',
+ }),
+}));
const renderComponent = (
proposal: ProposalQuery['proposal'],
@@ -30,20 +40,27 @@ const renderComponent = (
) =>
render(
-
-
-
-
-
+
+
+
+
+
+
+
);
describe('Proposal header', () => {
+ afterAll(() => {
+ jest.clearAllMocks();
+ });
it('Renders New market proposal', () => {
+ const mockedFlags = jest.mocked(FLAGS);
+ mockedFlags.SUCCESSOR_MARKETS = true;
renderComponent(
generateProposal({
rationale: {
@@ -76,6 +93,9 @@ describe('Proposal header', () => {
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
'tGBP settled future.'
);
+ expect(screen.getByTestId('proposal-successor-info')).toHaveTextContent(
+ 'PARENT_CODE'
+ );
});
it('Renders Update market proposal', () => {
diff --git a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx
index d4cd74214..c3cfdd2b6 100644
--- a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx
+++ b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx
@@ -11,6 +11,10 @@ import { ProposalInfoLabel } from '../proposal-info-label';
import { useUserVote } from '../vote-details/use-user-vote';
import { ProposalVotingStatus } from '../proposal-voting-status';
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters';
+import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
+import { FLAGS } from '@vegaprotocol/environment';
+import Routes from '../../../routes';
+import { Link } from 'react-router-dom';
export const ProposalHeader = ({
proposal,
@@ -39,6 +43,9 @@ export const ProposalHeader = ({
fallbackTitle = t('NewMarketProposal');
details = (
<>
+ {FLAGS.SUCCESSOR_MARKETS && (
+
+ )}
{t('Code')}: {change.instrument.code}.
{' '}
@@ -181,3 +188,20 @@ export const ProposalHeader = ({
>
);
};
+
+const SuccessorCode = ({ proposalId }: { proposalId?: string | null }) => {
+ const { t } = useTranslation();
+ const successor = useSuccessorMarketProposalDetails(proposalId);
+
+ return successor.parentMarketId || successor.code ? (
+
+ {t('Successor market to')}:{' '}
+
+ {successor.code || successor.parentMarketId}
+
+
+ ) : null;
+};
diff --git a/apps/trading/client-pages/markets/closed.spec.tsx b/apps/trading/client-pages/markets/closed.spec.tsx
index 4d6aa2bed..26c799b55 100644
--- a/apps/trading/client-pages/markets/closed.spec.tsx
+++ b/apps/trading/client-pages/markets/closed.spec.tsx
@@ -49,11 +49,6 @@ jest.mock('@vegaprotocol/markets', () => ({
: { data: undefined },
}));
-jest.mock('@vegaprotocol/environment', () => ({
- ...jest.requireActual('@vegaprotocol/environment'),
- FLAGS: { SUCCESSOR_MARKETS: true } as Partial,
-}));
-
jest.mock('@vegaprotocol/environment', () => {
const actual = jest.requireActual('@vegaprotocol/environment');
return {
@@ -61,7 +56,7 @@ jest.mock('@vegaprotocol/environment', () => {
FLAGS: {
...actual.FLAGS,
SUCCESSOR_MARKETS: true,
- },
+ } as FeatureFlags,
};
});
diff --git a/libs/markets/src/lib/components/market-info/market-info-panels.tsx b/libs/markets/src/lib/components/market-info/market-info-panels.tsx
index 185d16814..abfb16f7a 100644
--- a/libs/markets/src/lib/components/market-info/market-info-panels.tsx
+++ b/libs/markets/src/lib/components/market-info/market-info-panels.tsx
@@ -30,6 +30,7 @@ import { useOracleProofs } from '../../hooks';
import { OracleDialog } from '../oracle-dialog/oracle-dialog';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { useParentMarketIdQuery } from '../../__generated__';
+import { useSuccessorMarketProposalDetailsQuery } from '@vegaprotocol/proposals';
type MarketInfoProps = {
market: MarketInfo;
@@ -144,6 +145,14 @@ export const KeyDetailsInfoPanel = ({ market }: MarketInfoProps) => {
},
skip: !FLAGS.SUCCESSOR_MARKETS,
});
+
+ const { data: successor } = useSuccessorMarketProposalDetailsQuery({
+ variables: {
+ proposalId: market.proposal?.id || '',
+ },
+ skip: !FLAGS.SUCCESSOR_MARKETS || !market.proposal?.id,
+ });
+
const assetDecimals =
market.tradableInstrument.instrument.product.settlementAsset.decimals;
@@ -155,6 +164,11 @@ export const KeyDetailsInfoPanel = ({ market }: MarketInfoProps) => {
name: market.tradableInstrument.instrument.name,
marketID: market.id,
parentMarketID: parentData?.market?.parentMarketID || '-',
+ insurancePoolFraction:
+ (successor?.proposal?.terms.change.__typename === 'NewMarket' &&
+ successor.proposal.terms.change.successorConfiguration
+ ?.insurancePoolFraction) ||
+ '-',
tradingMode:
market.tradingMode &&
MarketTradingModeMapping[market.tradingMode],
diff --git a/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx b/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx
index 6c44f10f8..61c57ed4a 100644
--- a/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx
+++ b/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx
@@ -102,5 +102,8 @@ export const tooltipMapping: Record = {
`The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.`
),
suppliedStake: t('The current amount of liquidity supplied for this market.'),
- parentMarketID: t('The ID of the market this market succeeds'),
+ parentMarketID: t('The ID of the market this market succeeds.'),
+ insurancePoolFraction: t(
+ 'The fraction of the insurance pool balance that is carried over from the parent market to the successor.'
+ ),
};
diff --git a/libs/proposals/src/lib/proposals-hooks/Proposal.graphql b/libs/proposals/src/lib/proposals-hooks/Proposal.graphql
index 9a0857ac0..f736fbfc9 100644
--- a/libs/proposals/src/lib/proposals-hooks/Proposal.graphql
+++ b/libs/proposals/src/lib/proposals-hooks/Proposal.graphql
@@ -40,3 +40,30 @@ query ProposalOfMarket($marketId: ID!) {
}
}
}
+
+query SuccessorMarketProposalDetails($proposalId: ID!) {
+ proposal(id: $proposalId) {
+ id
+ terms {
+ change {
+ ... on NewMarket {
+ successorConfiguration {
+ parentMarketId
+ insurancePoolFraction
+ }
+ }
+ }
+ }
+ }
+}
+
+query InstrumentDetails($marketId: ID!) {
+ market(id: $marketId) {
+ tradableInstrument {
+ instrument {
+ code
+ name
+ }
+ }
+ }
+}
diff --git a/libs/proposals/src/lib/proposals-hooks/__generated__/Proposal.ts b/libs/proposals/src/lib/proposals-hooks/__generated__/Proposal.ts
index 18413086c..333217755 100644
--- a/libs/proposals/src/lib/proposals-hooks/__generated__/Proposal.ts
+++ b/libs/proposals/src/lib/proposals-hooks/__generated__/Proposal.ts
@@ -27,6 +27,20 @@ export type ProposalOfMarketQueryVariables = Types.Exact<{
export type ProposalOfMarketQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, terms: { __typename?: 'ProposalTerms', enactmentDatetime?: any | null } } | null };
+export type SuccessorMarketProposalDetailsQueryVariables = Types.Exact<{
+ proposalId: Types.Scalars['ID'];
+}>;
+
+
+export type SuccessorMarketProposalDetailsQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', successorConfiguration?: { __typename?: 'SuccessorConfiguration', parentMarketId: string, insurancePoolFraction: string } | null } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter' } } } | null };
+
+export type InstrumentDetailsQueryVariables = Types.Exact<{
+ marketId: Types.Scalars['ID'];
+}>;
+
+
+export type InstrumentDetailsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', code: string, name: string } } } | null };
+
export const ProposalEventFieldsFragmentDoc = gql`
fragment ProposalEventFields on Proposal {
id
@@ -147,4 +161,89 @@ export function useProposalOfMarketLazyQuery(baseOptions?: Apollo.LazyQueryHookO
}
export type ProposalOfMarketQueryHookResult = ReturnType;
export type ProposalOfMarketLazyQueryHookResult = ReturnType;
-export type ProposalOfMarketQueryResult = Apollo.QueryResult;
\ No newline at end of file
+export type ProposalOfMarketQueryResult = Apollo.QueryResult;
+export const SuccessorMarketProposalDetailsDocument = gql`
+ query SuccessorMarketProposalDetails($proposalId: ID!) {
+ proposal(id: $proposalId) {
+ id
+ terms {
+ change {
+ ... on NewMarket {
+ successorConfiguration {
+ parentMarketId
+ insurancePoolFraction
+ }
+ }
+ }
+ }
+ }
+}
+ `;
+
+/**
+ * __useSuccessorMarketProposalDetailsQuery__
+ *
+ * To run a query within a React component, call `useSuccessorMarketProposalDetailsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useSuccessorMarketProposalDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useSuccessorMarketProposalDetailsQuery({
+ * variables: {
+ * proposalId: // value for 'proposalId'
+ * },
+ * });
+ */
+export function useSuccessorMarketProposalDetailsQuery(baseOptions: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(SuccessorMarketProposalDetailsDocument, options);
+ }
+export function useSuccessorMarketProposalDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(SuccessorMarketProposalDetailsDocument, options);
+ }
+export type SuccessorMarketProposalDetailsQueryHookResult = ReturnType;
+export type SuccessorMarketProposalDetailsLazyQueryHookResult = ReturnType;
+export type SuccessorMarketProposalDetailsQueryResult = Apollo.QueryResult;
+export const InstrumentDetailsDocument = gql`
+ query InstrumentDetails($marketId: ID!) {
+ market(id: $marketId) {
+ tradableInstrument {
+ instrument {
+ code
+ name
+ }
+ }
+ }
+}
+ `;
+
+/**
+ * __useInstrumentDetailsQuery__
+ *
+ * To run a query within a React component, call `useInstrumentDetailsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useInstrumentDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useInstrumentDetailsQuery({
+ * variables: {
+ * marketId: // value for 'marketId'
+ * },
+ * });
+ */
+export function useInstrumentDetailsQuery(baseOptions: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(InstrumentDetailsDocument, options);
+ }
+export function useInstrumentDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(InstrumentDetailsDocument, options);
+ }
+export type InstrumentDetailsQueryHookResult = ReturnType;
+export type InstrumentDetailsLazyQueryHookResult = ReturnType;
+export type InstrumentDetailsQueryResult = Apollo.QueryResult;
\ No newline at end of file
diff --git a/libs/proposals/src/lib/proposals-hooks/index.ts b/libs/proposals/src/lib/proposals-hooks/index.ts
index 96bb36091..744b0bc5f 100644
--- a/libs/proposals/src/lib/proposals-hooks/index.ts
+++ b/libs/proposals/src/lib/proposals-hooks/index.ts
@@ -3,3 +3,4 @@ export * from './use-proposal-event';
export * from './use-proposal-submit';
export * from './use-update-proposal';
export * from './use-update-network-paramaters-toasts';
+export * from './use-successor-market-proposal-details';
diff --git a/libs/proposals/src/lib/proposals-hooks/use-successor-market-proposal-details.ts b/libs/proposals/src/lib/proposals-hooks/use-successor-market-proposal-details.ts
new file mode 100644
index 000000000..cea43aaf0
--- /dev/null
+++ b/libs/proposals/src/lib/proposals-hooks/use-successor-market-proposal-details.ts
@@ -0,0 +1,39 @@
+import omit from 'lodash/omit';
+import {
+ useInstrumentDetailsQuery,
+ useSuccessorMarketProposalDetailsQuery,
+} from './__generated__/Proposal';
+
+export const useSuccessorMarketProposalDetails = (
+ proposalId?: string | null
+) => {
+ const { data: proposal } = useSuccessorMarketProposalDetailsQuery({
+ variables: {
+ proposalId: proposalId || '',
+ },
+ skip: !proposalId || proposalId.length === 0,
+ });
+
+ const successorDetails =
+ (proposal?.proposal &&
+ proposal.proposal?.terms.change.__typename === 'NewMarket' &&
+ proposal.proposal.terms.change.successorConfiguration) ||
+ undefined;
+
+ const { data: market } = useInstrumentDetailsQuery({
+ variables: {
+ marketId: successorDetails?.parentMarketId || '',
+ },
+ skip:
+ !successorDetails?.parentMarketId ||
+ successorDetails.parentMarketId.length === 0,
+ });
+
+ const details = {
+ ...successorDetails,
+ code: market?.market?.tradableInstrument.instrument.code,
+ name: market?.market?.tradableInstrument.instrument.name,
+ };
+
+ return omit(details, '__typename');
+};