diff --git a/apps/trading-e2e/src/integration/capsule.cy.ts b/apps/trading-e2e/src/integration/capsule.cy.ts index 3335cfab6..023917ba0 100644 --- a/apps/trading-e2e/src/integration/capsule.cy.ts +++ b/apps/trading-e2e/src/integration/capsule.cy.ts @@ -2,7 +2,6 @@ import { removeDecimal } from '@vegaprotocol/cypress'; import * as Schema from '@vegaprotocol/types'; import { OrderStatusMapping, - OrderTimeInForceMapping, OrderTypeMapping, Side, } from '@vegaprotocol/types'; @@ -17,7 +16,6 @@ const orderStatus = 'status'; const orderRemaining = 'remaining'; const orderPrice = 'price'; const orderTimeInForce = 'timeInForce'; -const orderCreatedAt = 'createdAt'; const orderUpdatedAt = 'updatedAt'; const assetSelectField = 'select[name="asset"]'; const amountField = 'input[name="amount"]'; @@ -260,10 +258,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => { OrderStatusMapping.STATUS_ACTIVE ); - cy.get(`[col-id='${orderRemaining}']`).should( - 'contain.text', - `0.00/${order.size}` - ); + cy.get(`[col-id='${orderRemaining}']`).should('contain.text', '0.00'); cy.get(`[col-id='${orderPrice}']`).then(($price) => { expect(parseFloat($price.text())).to.equal(parseFloat(order.price)); @@ -271,10 +266,10 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => { cy.get(`[col-id='${orderTimeInForce}']`).should( 'contain.text', - OrderTimeInForceMapping[order.timeInForce] + 'GTC' ); - checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderCreatedAt); + checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderUpdatedAt); }); }); }); diff --git a/apps/trading-e2e/src/integration/market-info.cy.ts b/apps/trading-e2e/src/integration/market-info.cy.ts index 128ef3e66..68b83ddcb 100644 --- a/apps/trading-e2e/src/integration/market-info.cy.ts +++ b/apps/trading-e2e/src/integration/market-info.cy.ts @@ -68,14 +68,15 @@ describe('market info is displayed', { tags: '@smoke' }, () => { validateMarketDataRow(0, 'Name', 'BTCUSD Monthly (30 Jun 2022)'); validateMarketDataRow(1, 'Market ID', 'market-0'); + validateMarketDataRow(2, 'Parent Market ID', 'market-1'); validateMarketDataRow( - 2, + 3, 'Trading Mode', MarketTradingModeMapping.TRADING_MODE_CONTINUOUS ); - validateMarketDataRow(3, 'Market Decimal Places', '5'); - validateMarketDataRow(4, 'Position Decimal Places', '0'); - validateMarketDataRow(5, 'Settlement Asset Decimal Places', '5'); + validateMarketDataRow(4, 'Market Decimal Places', '5'); + validateMarketDataRow(5, 'Position Decimal Places', '0'); + validateMarketDataRow(6, 'Settlement Asset Decimal Places', '5'); }); it('instrument displayed', () => { diff --git a/apps/trading/client-pages/market/trade-grid.tsx b/apps/trading/client-pages/market/trade-grid.tsx index 0608a2d42..e94e9648b 100644 --- a/apps/trading/client-pages/market/trade-grid.tsx +++ b/apps/trading/client-pages/market/trade-grid.tsx @@ -27,6 +27,7 @@ import { import { TradingViews } from './trade-views'; import { MarketSelector } from './market-selector'; import { HeaderStats } from './header-stats'; +import { MarketSuccessorBanner } from '../../components/market-banner'; interface TradeGridProps { market: Market | null; @@ -317,6 +318,7 @@ export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
+
{sidebarOpen && ( diff --git a/apps/trading/client-pages/market/trade-panels.tsx b/apps/trading/client-pages/market/trade-panels.tsx index c55c4a91c..491f9ff08 100644 --- a/apps/trading/client-pages/market/trade-panels.tsx +++ b/apps/trading/client-pages/market/trade-panels.tsx @@ -21,6 +21,7 @@ import { HeaderStats } from './header-stats'; import * as DialogPrimitives from '@radix-ui/react-dialog'; import { HeaderTitle } from '../../components/header'; import { MarketSelector } from './market-selector'; +import { MarketSuccessorBanner } from '../../components/market-banner'; interface TradePanelsProps { market: Market | null; @@ -92,6 +93,7 @@ export const TradePanels = ({
+
diff --git a/apps/trading/components/market-banner/index.ts b/apps/trading/components/market-banner/index.ts new file mode 100644 index 000000000..52d75d62a --- /dev/null +++ b/apps/trading/components/market-banner/index.ts @@ -0,0 +1 @@ +export * from './market-successor-banner'; diff --git a/apps/trading/components/market-banner/market-successor-banner.spec.tsx b/apps/trading/components/market-banner/market-successor-banner.spec.tsx new file mode 100644 index 000000000..c16b97894 --- /dev/null +++ b/apps/trading/components/market-banner/market-successor-banner.spec.tsx @@ -0,0 +1,188 @@ +import { render, screen } from '@testing-library/react'; +import { MockedProvider } from '@apollo/react-testing'; +import * as dataProviders from '@vegaprotocol/data-provider'; +import { MarketSuccessorBanner } from './market-successor-banner'; +import * as Types from '@vegaprotocol/types'; +import * as allUtils from '@vegaprotocol/utils'; +import type { Market } from '@vegaprotocol/markets'; +import type { PartialDeep } from 'type-fest'; + +const market = { + id: 'marketId', + tradableInstrument: { + instrument: { + metadata: { + tags: [], + }, + }, + }, + marketTimestamps: { + close: null, + }, + successorMarketID: 'successorMarketID', +} as unknown as Market; + +let mockDataSuccessorMarket: PartialDeep | null = null; +jest.mock('@vegaprotocol/data-provider', () => ({ + ...jest.requireActual('@vegaprotocol/data-provider'), + useDataProvider: jest.fn().mockImplementation((args) => { + if (args.skip) { + return { + data: null, + error: null, + }; + } + return { + data: mockDataSuccessorMarket, + error: null, + }; + }), +})); +jest.mock('@vegaprotocol/utils', () => ({ + ...jest.requireActual('@vegaprotocol/utils'), + getMarketExpiryDate: jest.fn(), +})); +let mockCandles = {}; +jest.mock('@vegaprotocol/markets', () => ({ + ...jest.requireActual('@vegaprotocol/markets'), + useCandles: () => mockCandles, +})); + +describe('MarketSuccessorBanner', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDataSuccessorMarket = { + id: 'successorMarketID', + state: Types.MarketState.STATE_ACTIVE, + tradingMode: Types.MarketTradingMode.TRADING_MODE_CONTINUOUS, + tradableInstrument: { + instrument: { + name: 'Successor Market Name', + }, + }, + }; + }); + describe('should be hidden', () => { + it('when no market', () => { + const { container } = render(, { + wrapper: MockedProvider, + }); + expect(container).toBeEmptyDOMElement(); + }); + + it('when no successorMarketID', () => { + const amendedMarket = { + ...market, + successorMarketID: null, + }; + const { container } = render( + , + { + wrapper: MockedProvider, + } + ); + expect(container).toBeEmptyDOMElement(); + expect(dataProviders.useDataProvider).lastCalledWith( + expect.objectContaining({ skip: true }) + ); + }); + + it('no successor market data', () => { + mockDataSuccessorMarket = null; + const { container } = render(, { + wrapper: MockedProvider, + }); + expect(container).toBeEmptyDOMElement(); + expect(dataProviders.useDataProvider).lastCalledWith( + expect.objectContaining({ + variables: { marketId: 'successorMarketID' }, + skip: false, + }) + ); + }); + + it('successor market not in continuous mode', () => { + mockDataSuccessorMarket = { + ...mockDataSuccessorMarket, + tradingMode: Types.MarketTradingMode.TRADING_MODE_NO_TRADING, + }; + const { container } = render(, { + wrapper: MockedProvider, + }); + expect(container).toBeEmptyDOMElement(); + expect(dataProviders.useDataProvider).lastCalledWith( + expect.objectContaining({ + variables: { marketId: 'successorMarketID' }, + skip: false, + }) + ); + expect(allUtils.getMarketExpiryDate).toHaveBeenCalled(); + }); + + it('successor market is not active', () => { + mockDataSuccessorMarket = { + ...mockDataSuccessorMarket, + state: Types.MarketState.STATE_PENDING, + }; + const { container } = render(, { + wrapper: MockedProvider, + }); + expect(container).toBeEmptyDOMElement(); + expect(dataProviders.useDataProvider).lastCalledWith( + expect.objectContaining({ + variables: { marketId: 'successorMarketID' }, + skip: false, + }) + ); + expect(allUtils.getMarketExpiryDate).toHaveBeenCalled(); + }); + }); + + describe('should be displayed', () => { + it('should be rendered', () => { + render(, { + wrapper: MockedProvider, + }); + expect( + screen.getByText('This market has been succeeded') + ).toBeInTheDocument(); + expect( + screen.getByRole('link', { name: 'Successor Market Name' }) + ).toHaveAttribute('href', '/#/markets/successorMarketID'); + }); + + it('should display optionally successor volume', () => { + mockDataSuccessorMarket = { + ...mockDataSuccessorMarket, + positionDecimalPlaces: 3, + }; + mockCandles = { + oneDayCandles: [ + { volume: 123 }, + { volume: 456 }, + { volume: 789 }, + { volume: 99999 }, + ], + }; + + render(, { + wrapper: MockedProvider, + }); + expect(screen.getByText('has 101.367 24h vol.')).toBeInTheDocument(); + }); + + it('should display optionally duration', () => { + jest + .spyOn(allUtils, 'getMarketExpiryDate') + .mockReturnValue( + new Date(Date.now() + 24 * 60 * 60 * 1000 + 60 * 1000) + ); + render(, { + wrapper: MockedProvider, + }); + expect( + screen.getByText(/^This market expires in 1 day/) + ).toBeInTheDocument(); + }); + }); +}); diff --git a/apps/trading/components/market-banner/market-successor-banner.tsx b/apps/trading/components/market-banner/market-successor-banner.tsx new file mode 100644 index 000000000..1ea870a1f --- /dev/null +++ b/apps/trading/components/market-banner/market-successor-banner.tsx @@ -0,0 +1,115 @@ +import { useState } from 'react'; +import { isBefore, formatDuration, intervalToDuration } from 'date-fns'; +import { useDataProvider } from '@vegaprotocol/data-provider'; +import type { Market } from '@vegaprotocol/markets'; +import { + calcCandleVolume, + marketProvider, + useCandles, +} from '@vegaprotocol/markets'; +import { + ExternalLink, + Intent, + NotificationBanner, +} from '@vegaprotocol/ui-toolkit'; +import { + addDecimalsFormatNumber, + getMarketExpiryDate, + isNumeric, +} from '@vegaprotocol/utils'; +import { t } from '@vegaprotocol/i18n'; +import * as Types from '@vegaprotocol/types'; + +const getExpiryDate = (tags: string[], close?: string): Date | null => { + const expiryDate = getMarketExpiryDate(tags); + return expiryDate || (close && new Date(close)) || null; +}; + +export const MarketSuccessorBanner = ({ + market, +}: { + market: Market | null; +}) => { + const { data: successorData } = useDataProvider({ + dataProvider: marketProvider, + variables: { + marketId: market?.successorMarketID || '', + }, + skip: !market?.successorMarketID, + }); + const [visible, setVisible] = useState(true); + + const expiry = market + ? getExpiryDate( + market.tradableInstrument.instrument.metadata.tags || [], + market.marketTimestamps.close + ) + : null; + + const duration = + expiry && isBefore(new Date(), expiry) + ? intervalToDuration({ start: new Date(), end: expiry }) + : null; + + const isInContinuesMode = + successorData?.state === Types.MarketState.STATE_ACTIVE && + successorData?.tradingMode === + Types.MarketTradingMode.TRADING_MODE_CONTINUOUS; + + const { oneDayCandles } = useCandles({ + marketId: successorData?.id, + }); + + const candleVolume = oneDayCandles?.length + ? calcCandleVolume(oneDayCandles) + : null; + + const successorVolume = + candleVolume && isNumeric(successorData?.positionDecimalPlaces) + ? addDecimalsFormatNumber( + candleVolume, + successorData?.positionDecimalPlaces as number + ) + : null; + + if (isInContinuesMode && visible) { + return ( + { + setVisible(false); + }} + > +
+ {t('This market has been succeeded')} +
+
+ {duration && ( + + {t('This market expires in %s.', [ + formatDuration(duration, { + format: [ + 'years', + 'months', + 'weeks', + 'days', + 'hours', + 'minutes', + ], + }), + ])} + + )}{' '} + {t('The successor market')}{' '} + + {successorData?.tradableInstrument.instrument.name} + + {successorVolume && ( + {t('has %s 24h vol.', [successorVolume])} + )} +
+
+ ); + } + return null; +}; diff --git a/libs/liquidity/src/lib/__generated__/MarketLiquidity.ts b/libs/liquidity/src/lib/__generated__/MarketLiquidity.ts index e8d67a088..143a5badd 100644 --- a/libs/liquidity/src/lib/__generated__/MarketLiquidity.ts +++ b/libs/liquidity/src/lib/__generated__/MarketLiquidity.ts @@ -180,4 +180,4 @@ export function useLiquidityProviderFeeShareLazyQuery(baseOptions?: Apollo.LazyQ } export type LiquidityProviderFeeShareQueryHookResult = ReturnType; export type LiquidityProviderFeeShareLazyQueryHookResult = ReturnType; -export type LiquidityProviderFeeShareQueryResult = Apollo.QueryResult; \ No newline at end of file +export type LiquidityProviderFeeShareQueryResult = Apollo.QueryResult; diff --git a/libs/markets/src/lib/__generated__/markets.ts b/libs/markets/src/lib/__generated__/markets.ts index addf669a7..5d5653db7 100644 --- a/libs/markets/src/lib/__generated__/markets.ts +++ b/libs/markets/src/lib/__generated__/markets.ts @@ -7,12 +7,12 @@ export type DataSourceFilterFragment = { __typename?: 'Filter', key: { __typenam export type DataSourceSpecFragment = { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } }; -export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number, quantum: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; +export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, successorMarketID?: string | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number, quantum: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; export type MarketsQueryVariables = Types.Exact<{ [key: string]: never; }>; -export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number, quantum: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; +export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, successorMarketID?: string | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number, quantum: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; export const DataSourceFilterFragmentDoc = gql` fragment DataSourceFilter on Filter { @@ -104,6 +104,7 @@ export const MarketFieldsFragmentDoc = gql` open close } + successorMarketID } ${DataSourceSpecFragmentDoc}`; export const MarketsDocument = gql` diff --git a/libs/markets/src/lib/components/market-info/MarketInfo.graphql b/libs/markets/src/lib/components/market-info/MarketInfo.graphql index 7ea10700e..4b6c56fb2 100644 --- a/libs/markets/src/lib/components/market-info/MarketInfo.graphql +++ b/libs/markets/src/lib/components/market-info/MarketInfo.graphql @@ -142,5 +142,6 @@ query MarketInfo($marketId: ID!) { } } } + parentMarketID } } diff --git a/libs/markets/src/lib/components/market-info/__generated__/MarketInfo.ts b/libs/markets/src/lib/components/market-info/__generated__/MarketInfo.ts index d7f227c23..7f7b039c8 100644 --- a/libs/markets/src/lib/components/market-info/__generated__/MarketInfo.ts +++ b/libs/markets/src/lib/components/market-info/__generated__/MarketInfo.ts @@ -10,7 +10,7 @@ export type MarketInfoQueryVariables = Types.Exact<{ }>; -export type MarketInfoQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, lpPriceRange: string, proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, riskFactors?: { __typename?: 'RiskFactor', market: string, short: string, long: string } | null, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: string, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } }, marginCalculator?: { __typename?: 'MarginCalculator', scalingFactors: { __typename?: 'ScalingFactors', searchLevel: number, initialMargin: number, collateralRelease: number } } | null } } | null }; +export type MarketInfoQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, lpPriceRange: string, parentMarketID?: string | null, proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, riskFactors?: { __typename?: 'RiskFactor', market: string, short: string, long: string } | null, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: string, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } } | { __typename?: 'DataSourceDefinitionInternal' } } }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } }, marginCalculator?: { __typename?: 'MarginCalculator', scalingFactors: { __typename?: 'ScalingFactors', searchLevel: number, initialMargin: number, collateralRelease: number } } | null } } | null }; export const DataSourceFragmentDoc = gql` fragment DataSource on DataSourceDefinition { @@ -158,6 +158,7 @@ export const MarketInfoDocument = gql` } } } + parentMarketID } } ${DataSourceFragmentDoc}`; 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 6fb4af889..92e4cd255 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 @@ -144,6 +144,7 @@ export const KeyDetailsInfoPanel = ({ market }: MarketInfoProps) => { data={{ name: market.tradableInstrument.instrument.name, marketID: market.id, + parentMarketID: market.parentMarketID, tradingMode: market.tradingMode && MarketTradingModeMapping[market.tradingMode], marketDecimalPlaces: market.decimalPlaces, diff --git a/libs/markets/src/lib/components/market-info/market-info.mock.ts b/libs/markets/src/lib/components/market-info/market-info.mock.ts index 8004daa3a..d951c1a73 100644 --- a/libs/markets/src/lib/components/market-info/market-info.mock.ts +++ b/libs/markets/src/lib/components/market-info/market-info.mock.ts @@ -191,6 +191,7 @@ export const marketInfoQuery = ( }, }, }, + parentMarketID: 'market-1', }, }; 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 eb539dd75..6c44f10f8 100644 --- a/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx +++ b/libs/markets/src/lib/components/market-info/tooltip-mapping.tsx @@ -102,4 +102,5 @@ 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'), }; diff --git a/libs/markets/src/lib/markets.graphql b/libs/markets/src/lib/markets.graphql index 84e25a6e2..799ef906d 100644 --- a/libs/markets/src/lib/markets.graphql +++ b/libs/markets/src/lib/markets.graphql @@ -85,6 +85,7 @@ fragment MarketFields on Market { open close } + successorMarketID } query Markets { diff --git a/libs/types/src/__generated__/types.ts b/libs/types/src/__generated__/types.ts index cc785d575..450f81545 100644 --- a/libs/types/src/__generated__/types.ts +++ b/libs/types/src/__generated__/types.ts @@ -356,6 +356,13 @@ export enum BusEventType { Withdrawal = 'Withdrawal' } +/** Allows for cancellation of an existing governance transfer */ +export type CancelTransfer = { + __typename?: 'CancelTransfer'; + /** The governance transfer to cancel */ + transferId: Scalars['ID']; +}; + /** Candle stick representation of trading */ export type Candle = { __typename?: 'Candle'; @@ -367,6 +374,8 @@ export type Candle = { lastUpdateInPeriod: Scalars['Timestamp']; /** Low price (uint64) */ low: Scalars['String']; + /** Total notional value of trades (uint64) */ + notional: Scalars['String']; /** Open price (uint64) */ open: Scalars['String']; /** RFC3339Nano formatted date and time for the candle start time */ @@ -1123,6 +1132,17 @@ export type FutureProduct = { settlementAsset: Asset; }; +export type GovernanceTransferKind = OneOffGovernanceTransfer | RecurringGovernanceTransfer; + +export enum GovernanceTransferType { + /** Transfers the specified amount or does not transfer anything */ + GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING = 'GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING', + /** Transfers the specified amount or the max allowable amount if this is less than the specified amount */ + GOVERNANCE_TRANSFER_TYPE_BEST_EFFORT = 'GOVERNANCE_TRANSFER_TYPE_BEST_EFFORT', + /** Default value, always invalid */ + GOVERNANCE_TRANSFER_TYPE_UNSPECIFIED = 'GOVERNANCE_TRANSFER_TYPE_UNSPECIFIED' +} + /** A segment of data node history */ export type HistorySegment = { __typename?: 'HistorySegment'; @@ -1134,6 +1154,17 @@ export type HistorySegment = { toHeight: Scalars['Int']; }; +/** Details of the iceberg order */ +export type IcebergOrder = { + __typename?: 'IcebergOrder'; + /** If the visible size of the order falls below this value, it will be replenished back to the peak size using the reserved amount */ + minimumVisibleSize: Scalars['String']; + /** Size of the order that will be made visible if the iceberg order is replenished after trading */ + peakSize: Scalars['String']; + /** Size of the order that is reserved and used to restore the iceberg's peak when it is refreshed */ + reservedRemaining: Scalars['String']; +}; + /** Describes something that can be traded on Vega */ export type Instrument = { __typename?: 'Instrument'; @@ -1305,10 +1336,12 @@ export type LiquidityProviderFeeShare = { averageEntryValuation: Scalars['String']; /** The average liquidity score */ averageScore: Scalars['String']; - /** The share owned by this liquidity provider (float) */ + /** The share owned by this liquidity provider */ equityLikeShare: Scalars['String']; /** The liquidity provider party ID */ party: Party; + /** The virtual stake for this liquidity provider */ + virtualStake: Scalars['String']; }; /** The command to be sent to the chain for a liquidity provision submission */ @@ -1323,7 +1356,7 @@ export type LiquidityProvision = { /** Nominated liquidity fee factor, which is an input to the calculation of liquidity fees on the market, as per setting fees and rewarding liquidity providers. */ fee: Scalars['String']; /** Unique identifier for the order (set by the system after consensus) */ - id?: Maybe; + id: Scalars['ID']; /** Market for the order */ market: Market; /** The party making this commitment */ @@ -1372,7 +1405,7 @@ export type LiquidityProvisionUpdate = { /** Nominated liquidity fee factor, which is an input to the calculation of liquidity fees on the market, as per setting fees and rewarding liquidity providers. */ fee: Scalars['String']; /** Unique identifier for the order (set by the system after consensus) */ - id?: Maybe; + id: Scalars['ID']; /** Market for the order */ marketID: Scalars['ID']; /** The party making this commitment */ @@ -1546,6 +1579,8 @@ export type Market = { fees: Fees; /** Market ID */ id: Scalars['ID']; + /** Optional: When a successor market is created, a fraction of the parent market's insurance pool can be transferred to the successor market */ + insurancePoolFraction?: Maybe; /** Linear slippage factor is used to cap the slippage component of maintainence margin - it is applied to the slippage volume */ linearSlippageFactor: Scalars['String']; /** Liquidity monitoring parameters for the market */ @@ -1563,6 +1598,11 @@ export type Market = { openingAuction: AuctionDuration; /** Orders on a market */ ordersConnection?: Maybe; + /** + * Optional: Parent market ID. A market can be a successor to another market. If this market is a successor to a previous market, + * this field will be populated with the ID of the previous market. + */ + parentMarketID?: Maybe; /** * The number of decimal places that an integer must be shifted in order to get a correct size (uint64). * i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes. @@ -1580,6 +1620,8 @@ export type Market = { riskFactors?: Maybe; /** Current state of the market */ state: MarketState; + /** Optional: Market ID of the successor to this market if one exists */ + successorMarketID?: Maybe; /** An instance of, or reference to, a tradable instrument. */ tradableInstrument: TradableInstrument; /** @deprecated Simplify and consolidate trades query and remove nesting. Use trades query instead */ @@ -1672,12 +1714,16 @@ export type MarketData = { indicativePrice: Scalars['String']; /** Indicative volume if the auction ended now, 0 if not in auction mode */ indicativeVolume: Scalars['String']; + /** The last traded price (an unsigned integer) */ + lastTradedPrice: Scalars['String']; /** The equity like share of liquidity fee for each liquidity provider */ liquidityProviderFeeShare?: Maybe>; /** The mark price (an unsigned integer) */ markPrice: Scalars['String']; /** Market of the associated mark price */ market: Market; + /** The market growth factor for the last market time window */ + marketGrowth: Scalars['String']; /** Current state of the market */ marketState: MarketState; /** What mode the market is in (auction, continuous, etc) */ @@ -1775,7 +1821,7 @@ export type MarketDepthUpdate = { sequenceNumber: Scalars['String']; }; -/** Edge type containing the order and cursor information returned by a OrderConnection */ +/** Edge type containing the market and cursor information returned by a MarketConnection */ export type MarketEdge = { __typename?: 'MarketEdge'; /** The cursor for this market */ @@ -1932,7 +1978,7 @@ export type NewMarket = { decimalPlaces: Scalars['Int']; /** New market instrument configuration */ instrument: InstrumentConfiguration; - /** Linear slippage factor is used to cap the slippage component of maintainence margin - it is applied to the slippage volume */ + /** Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume */ linearSlippageFactor: Scalars['String']; /** Liquidity monitoring parameters */ liquidityMonitoringParameters: LiquidityMonitoringParameters; @@ -1944,10 +1990,34 @@ export type NewMarket = { positionDecimalPlaces: Scalars['Int']; /** Price monitoring parameters */ priceMonitoringParameters: PriceMonitoringParameters; - /** Quadratic slippage factor is used to cap the slippage component of maintainence margin - it is applied to the square of the slippage volume */ + /** Quadratic slippage factor is used to cap the slippage component of maintenance margin - it is applied to the square of the slippage volume */ quadraticSlippageFactor: Scalars['String']; /** New market risk configuration */ riskParameters: RiskModel; + /** Successor market configuration. If this proposed market is meant to succeed a given market, then this needs to be set. */ + successorConfiguration?: Maybe; +}; + +export type NewTransfer = { + __typename?: 'NewTransfer'; + /** The maximum amount to be transferred */ + amount: Scalars['String']; + /** The asset to transfer */ + asset: Asset; + /** The destination account */ + destination: Scalars['String']; + /** The type of destination account */ + destinationType: AccountType; + /** The fraction of the balance to be transferred */ + fraction_of_balance: Scalars['String']; + /** The type of governance transfer being made, i.e. a one-off or recurring transfer */ + kind: GovernanceTransferKind; + /** The source account */ + source: Scalars['String']; + /** The type of source account */ + sourceType: AccountType; + /** The type of the governance transfer */ + transferType: GovernanceTransferType; }; /** Information available for a node */ @@ -2161,10 +2231,14 @@ export type ObservableMarketData = { indicativePrice: Scalars['String']; /** Indicative volume if the auction ended now, 0 if not in auction mode */ indicativeVolume: Scalars['String']; + /** The last traded price (an unsigned integer) */ + lastTradedPrice: Scalars['String']; /** The equity like share of liquidity fee for each liquidity provider */ liquidityProviderFeeShare?: Maybe>; /** The mark price (an unsigned integer) */ markPrice: Scalars['String']; + /** The market growth factor for the last market time window */ + marketGrowth: Scalars['String']; /** Market ID of the associated mark price */ marketId: Scalars['ID']; /** Current state of the market */ @@ -2229,6 +2303,13 @@ export type ObservableMarketDepthUpdate = { sequenceNumber: Scalars['String']; }; +/** The specific details for a one-off governance transfer */ +export type OneOffGovernanceTransfer = { + __typename?: 'OneOffGovernanceTransfer'; + /** An optional time when the transfer should be delivered */ + deliverOn?: Maybe; +}; + /** The specific details for a one-off transfer */ export type OneOffTransfer = { __typename?: 'OneOffTransfer'; @@ -2293,6 +2374,8 @@ export type Order = { createdAt: Scalars['Timestamp']; /** Expiration time of this order (ISO-8601 RFC3339+Nano formatted date) */ expiresAt?: Maybe; + /** Details of an iceberg order */ + icebergOrder?: Maybe; /** Hash of the order data */ id: Scalars['ID']; /** The liquidity provision this order was created from */ @@ -2537,6 +2620,35 @@ export enum OrderStatus { STATUS_STOPPED = 'STATUS_STOPPED' } +/** Details of the order that will be submitted when the stop order is triggered. */ +export type OrderSubmission = { + __typename?: 'OrderSubmission'; + /** Expiration time of this order (ISO-8601 RFC3339+Nano formatted date) */ + expiresAt: Scalars['Timestamp']; + /** Details of an iceberg order */ + icebergOrder?: Maybe; + /** Market the order is for. */ + marketId: Scalars['ID']; + /** PeggedOrder contains the details about a pegged order */ + peggedOrder?: Maybe; + /** Is this a post only order */ + postOnly?: Maybe; + /** The worst price the order will trade at (e.g. buy for price or less, sell for price or more) (uint64) */ + price: Scalars['String']; + /** Is this a reduce only order */ + reduceOnly?: Maybe; + /** The external reference (if available) for the order */ + reference?: Maybe; + /** Whether the order is to buy or sell */ + side: Side; + /** Total number of units that may be bought or sold (immutable) (uint64) */ + size: Scalars['String']; + /** The timeInForce of order (determines how and if it executes, and whether it persists on the book) */ + timeInForce: OrderTimeInForce; + /** The order type */ + type: OrderType; +}; + /** Valid order types, these determine what happens when an order is added to the book */ export enum OrderTimeInForce { /** Fill or Kill: The order either trades completely (remainingSize == 0 after adding) or not at all, does not remain on the book if it doesn't trade */ @@ -2576,6 +2688,8 @@ export type OrderUpdate = { createdAt: Scalars['Timestamp']; /** Expiration time of this order (ISO-8601 RFC3339+Nano formatted date) */ expiresAt?: Maybe; + /** Details of an iceberg order */ + icebergOrder?: Maybe; /** Hash of the order data */ id: Scalars['ID']; /** The liquidity provision this order was created from */ @@ -3089,7 +3203,7 @@ export type Proposal = { votes: ProposalVotes; }; -export type ProposalChange = NewAsset | NewFreeform | NewMarket | UpdateAsset | UpdateMarket | UpdateNetworkParameter; +export type ProposalChange = CancelTransfer | NewAsset | NewFreeform | NewMarket | NewTransfer | UpdateAsset | UpdateMarket | UpdateNetworkParameter; export type ProposalDetail = { __typename?: 'ProposalDetail'; @@ -3160,6 +3274,12 @@ export enum ProposalRejectionReason { PROPOSAL_ERROR_ENACT_TIME_TOO_SOON = 'PROPOSAL_ERROR_ENACT_TIME_TOO_SOON', /** The ERC-20 address specified by this proposal is already in use by another asset */ PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE = 'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE', + /** The proposal for cancellation of an active governance transfer has failed */ + PROPOSAL_ERROR_GOVERNANCE_CANCEL_TRANSFER_PROPOSAL_INVALID = 'PROPOSAL_ERROR_GOVERNANCE_CANCEL_TRANSFER_PROPOSAL_INVALID', + /** The governance transfer proposal has failed */ + PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_FAILED = 'PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_FAILED', + /** The governance transfer proposal is invalid */ + 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 */ @@ -3184,6 +3304,10 @@ export enum ProposalRejectionReason { PROPOSAL_ERROR_INVALID_RISK_PARAMETER = 'PROPOSAL_ERROR_INVALID_RISK_PARAMETER', /** Market proposal has one or more invalid liquidity shapes */ PROPOSAL_ERROR_INVALID_SHAPE = 'PROPOSAL_ERROR_INVALID_SHAPE', + /** Validation of spot market proposal failed */ + PROPOSAL_ERROR_INVALID_SPOT = 'PROPOSAL_ERROR_INVALID_SPOT', + /** Validation of successor market has failed */ + PROPOSAL_ERROR_INVALID_SUCCESSOR_MARKET = 'PROPOSAL_ERROR_INVALID_SUCCESSOR_MARKET', /** Proposal declined because the majority threshold was not reached */ PROPOSAL_ERROR_MAJORITY_THRESHOLD_NOT_REACHED = 'PROPOSAL_ERROR_MAJORITY_THRESHOLD_NOT_REACHED', /** Market proposal is missing a liquidity commitment */ @@ -3499,6 +3623,12 @@ export type Query = { protocolUpgradeStatus?: Maybe; /** Get statistics about the Vega node */ statistics: Statistics; + /** Get stop order by ID */ + stopOrder?: Maybe; + /** Get a list of stop orders. If provided, the filter will be applied to the list of stop orders to restrict the results. */ + stopOrders?: Maybe; + /** List markets in a succession line */ + successorMarkets?: Maybe; /** Get a list of all trades and apply any given filters to the results */ trades?: Maybe; /** Get a list of all transfers for a public key */ @@ -3558,6 +3688,7 @@ export type QueryentitiesArgs = { /** Queries allow a caller to read data and filter data via GraphQL. */ export type QueryepochArgs = { + block?: InputMaybe; id?: InputMaybe; }; @@ -3803,6 +3934,27 @@ export type QueryprotocolUpgradeProposalsArgs = { }; +/** Queries allow a caller to read data and filter data via GraphQL. */ +export type QuerystopOrderArgs = { + id: Scalars['ID']; +}; + + +/** Queries allow a caller to read data and filter data via GraphQL. */ +export type QuerystopOrdersArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; +}; + + +/** Queries allow a caller to read data and filter data via GraphQL. */ +export type QuerysuccessorMarketsArgs = { + fullHistory?: InputMaybe; + marketId: Scalars['ID']; + pagination?: InputMaybe; +}; + + /** Queries allow a caller to read data and filter data via GraphQL. */ export type QuerytradesArgs = { dateRange?: InputMaybe; @@ -3847,6 +3999,15 @@ export type RankingScore = { votingPower: Scalars['String']; }; +/** The specific details for a recurring governance transfer */ +export type RecurringGovernanceTransfer = { + __typename?: 'RecurringGovernanceTransfer'; + /** An optional epoch at which this transfer will stop */ + endEpoch?: Maybe; + /** The epoch at which this recurring transfer will start */ + startEpoch: Scalars['Int']; +}; + /** The specific details for a recurring transfer */ export type RecurringTransfer = { __typename?: 'RecurringTransfer'; @@ -4182,6 +4343,117 @@ export type Statistics = { vegaTime: Scalars['Timestamp']; }; +/** A stop order in Vega */ +export type StopOrder = { + __typename?: 'StopOrder'; + /** Time the stop order was created. */ + createdAt: Scalars['Timestamp']; + /** Time at which the order will expire if an expiry time is set. */ + expiresAt?: Maybe; + /** If an expiry is set, what should the stop order do when it expires. */ + expiryStrategy?: Maybe; + /** Hash of the stop order data */ + id: Scalars['ID']; + /** Market the stop order is for. */ + marketId: Scalars['ID']; + /** If OCO (one-cancels-other) order, the ID of the associated order. */ + ocoLinkId?: Maybe; + /** Party that submitted the stop order. */ + partyId: Scalars['ID']; + /** Status of the stop order */ + status: StopOrderStatus; + /** Order to submit when the stop order is triggered. */ + submission: OrderSubmission; + /** Price movement that will trigger the stop order */ + trigger?: Maybe; + /** Direction the price is moving to trigger the stop order. */ + triggerDirection: StopOrderTriggerDirection; + /** Time the stop order was last updated. */ + updatedAt?: Maybe; +}; + +/** Connection type for retrieving cursory-based paginated stop order information */ +export type StopOrderConnection = { + __typename?: 'StopOrderConnection'; + /** The stop orders in this connection */ + edges?: Maybe>; + /** The pagination information */ + pageInfo?: Maybe; +}; + +/** Edge type containing the stop order and cursor information returned by a StopOrderConnection */ +export type StopOrderEdge = { + __typename?: 'StopOrderEdge'; + /** The cursor for this stop order */ + cursor?: Maybe; + /** The stop order */ + node?: Maybe; +}; + +/** Valid stop order expiry strategies. The expiry strategy determines what happens to a stop order when it expires. */ +export enum StopOrderExpiryStrategy { + /** The stop order will be cancelled when it expires. */ + EXPIRY_STRATEGY_CANCELS = 'EXPIRY_STRATEGY_CANCELS', + /** The stop order will be submitted when the expiry time is reached. */ + EXPIRY_STRATEGY_SUBMIT = 'EXPIRY_STRATEGY_SUBMIT', + /** The stop order expiry strategy has not been specified by the trader. */ + EXPIRY_STRATEGY_UNSPECIFIED = 'EXPIRY_STRATEGY_UNSPECIFIED' +} + +/** Filter to be applied when querying a list of stop orders. If multiple criteria are specified, e.g. parties and markets, then the filter is applied as an AND. */ +export type StopOrderFilter = { + /** Date range to retrieve order from/to. Start and end time should be expressed as an integer value of nano-seconds past the Unix epoch */ + dateRange?: InputMaybe; + /** Zero or more expiry strategies to filter by */ + expiryStrategy?: InputMaybe>; + /** Zero or more market IDs to filter by */ + markets?: InputMaybe>; + /** Zero or more party IDs to filter by */ + parties?: InputMaybe>; + /** Zero or more order status to filter by */ + status?: InputMaybe>; +}; + +/** Price at which a stop order will trigger */ +export type StopOrderPrice = { + __typename?: 'StopOrderPrice'; + price: Scalars['String']; +}; + +/** Valid stop order statuses, these determine several states for a stop order that cannot be expressed with other fields in StopOrder. */ +export enum StopOrderStatus { + /** Stop order has been cancelled. This could be by the trader or by the network. */ + STATUS_CANCELLED = 'STATUS_CANCELLED', + /** Stop order has expired. This means the trigger conditions have not been met and the stop order has expired. */ + STATUS_EXPIRED = 'STATUS_EXPIRED', + /** Stop order is pending. This means the stop order has been accepted in the network, but the trigger conditions have not been met. */ + STATUS_PENDING = 'STATUS_PENDING', + /** Stop order has been rejected. This means the stop order was not accepted by the network. */ + STATUS_REJECTED = 'STATUS_REJECTED', + /** Stop order has been stopped. This means the trigger conditions have been met, but the stop order was not executed, and stopped. */ + STATUS_STOPPED = 'STATUS_STOPPED', + /** Stop order has been triggered. This means the trigger conditions have been met, and the stop order was executed. */ + STATUS_TRIGGERED = 'STATUS_TRIGGERED', + /** Stop order has been submitted to the network but does not have a status yet */ + STATUS_UNSPECIFIED = 'STATUS_UNSPECIFIED' +} + +/** Percentage movement in the price at which a stop order will trigger. */ +export type StopOrderTrailingPercentOffset = { + __typename?: 'StopOrderTrailingPercentOffset'; + trailingPercentOffset: Scalars['String']; +}; + +export type StopOrderTrigger = StopOrderPrice | StopOrderTrailingPercentOffset; + +/** Valid stop order trigger direction. The trigger direction determines whether the price should rise above or fall below the stop order trigger. */ +export enum StopOrderTriggerDirection { + /** The price should fall below the trigger. */ + TRIGGER_DIRECTION_FALLS_BELOW = 'TRIGGER_DIRECTION_FALLS_BELOW', + /** The price should rise above the trigger. */ + TRIGGER_DIRECTION_RISES_ABOVE = 'TRIGGER_DIRECTION_RISES_ABOVE' +} + /** Subscriptions allow a caller to receive new information as it is available from the Vega network. */ export type Subscription = { __typename?: 'Subscription'; @@ -4314,6 +4586,40 @@ export type SubscriptionvotesArgs = { proposalId?: InputMaybe; }; +export type SuccessorConfiguration = { + __typename?: 'SuccessorConfiguration'; + /** Decimal value between 0 and 1, specifying the fraction of the insurance pool balance is carried over from the parent market to the successor. */ + insurancePoolFraction: Scalars['String']; + /** ID of the market this proposal will succeed */ + parentMarketId: Scalars['String']; +}; + +export type SuccessorMarket = { + __typename?: 'SuccessorMarket'; + /** The market */ + market: Market; + /** Proposals for child markets */ + proposals?: Maybe>>; +}; + +/** Connection type for retrieving cursor-based paginated market information */ +export type SuccessorMarketConnection = { + __typename?: 'SuccessorMarketConnection'; + /** The markets in this connection */ + edges: Array; + /** The pagination information */ + pageInfo: PageInfo; +}; + +/** Edge type containing the market and cursor information returned by a MarketConnection */ +export type SuccessorMarketEdge = { + __typename?: 'SuccessorMarketEdge'; + /** The cursor for this market */ + cursor: Scalars['String']; + /** The market */ + node: SuccessorMarket; +}; + /** TargetStakeParameters contains parameters used in target stake calculation */ export type TargetStakeParameters = { __typename?: 'TargetStakeParameters'; @@ -4546,7 +4852,7 @@ export type TransferEdge = { node: Transfer; }; -export type TransferKind = OneOffTransfer | RecurringTransfer; +export type TransferKind = OneOffGovernanceTransfer | OneOffTransfer | RecurringGovernanceTransfer | RecurringTransfer; export type TransferResponse = { __typename?: 'TransferResponse'; @@ -4593,6 +4899,10 @@ export enum TransferType { TRANSFER_TYPE_CLEAR_ACCOUNT = 'TRANSFER_TYPE_CLEAR_ACCOUNT', /** Funds deposited to general account */ TRANSFER_TYPE_DEPOSIT = 'TRANSFER_TYPE_DEPOSIT', + /** An internal instruction to transfer a quantity corresponding to an active spot order from a general account into a party holding account */ + TRANSFER_TYPE_HOLDING_LOCK = 'TRANSFER_TYPE_HOLDING_LOCK', + /** An internal instruction to transfer an excess quantity corresponding to an active spot order from a holding account into a party general account */ + TRANSFER_TYPE_HOLDING_RELEASE = 'TRANSFER_TYPE_HOLDING_RELEASE', /** Infrastructure fee received into general account */ TRANSFER_TYPE_INFRASTRUCTURE_FEE_DISTRIBUTE = 'TRANSFER_TYPE_INFRASTRUCTURE_FEE_DISTRIBUTE', /** Infrastructure fee paid from general account */ @@ -4619,6 +4929,8 @@ export enum TransferType { TRANSFER_TYPE_MTM_WIN = 'TRANSFER_TYPE_MTM_WIN', /** Reward payout received */ TRANSFER_TYPE_REWARD_PAYOUT = 'TRANSFER_TYPE_REWARD_PAYOUT', + /** Spot trade delivery */ + TRANSFER_TYPE_SPOT = 'TRANSFER_TYPE_SPOT', /** A network internal instruction for the collateral engine to move funds from the pending transfers pool account into the destination account */ TRANSFER_TYPE_TRANSFER_FUNDS_DISTRIBUTE = 'TRANSFER_TYPE_TRANSFER_FUNDS_DISTRIBUTE', /** A network internal instruction for the collateral engine to move funds from a user's general account into the pending transfers pool */ diff --git a/libs/types/src/global-types-mappings.ts b/libs/types/src/global-types-mappings.ts index 159d43f8f..bcd4d441d 100644 --- a/libs/types/src/global-types-mappings.ts +++ b/libs/types/src/global-types-mappings.ts @@ -321,6 +321,15 @@ export const ProposalRejectionReasonMapping: { PROPOSAL_ERROR_UNSUPPORTED_TRADING_MODE: 'Unsupported trading mode', PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE: 'ERC20 address already in use by an existing asset', + PROPOSAL_ERROR_GOVERNANCE_CANCEL_TRANSFER_PROPOSAL_INVALID: + 'PROPOSAL_ERROR_GOVERNANCE_CANCEL_TRANSFER_PROPOSAL_INVALID', + PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_FAILED: + 'PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_FAILED', + PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_INVALID: + 'PROPOSAL_ERROR_GOVERNANCE_TRANSFER_PROPOSAL_INVALID', + PROPOSAL_ERROR_INVALID_SPOT: 'PROPOSAL_ERROR_INVALID_SPOT', + PROPOSAL_ERROR_INVALID_SUCCESSOR_MARKET: + 'PROPOSAL_ERROR_INVALID_SUCCESSOR_MARKET', }; /** @@ -419,6 +428,9 @@ export const TransferTypeMapping: TransferTypeMap = { TRANSFER_TYPE_TRANSFER_FUNDS_DISTRIBUTE: 'Transfer received', TRANSFER_TYPE_CLEAR_ACCOUNT: 'Market accounts cleared', TRANSFER_TYPE_CHECKPOINT_BALANCE_RESTORE: 'Balances restored', + TRANSFER_TYPE_HOLDING_LOCK: 'TRANSFER_TYPE_HOLDING_LOCK', + TRANSFER_TYPE_HOLDING_RELEASE: 'TRANSFER_TYPE_HOLDING_RELEASE', + TRANSFER_TYPE_SPOT: 'TRANSFER_TYPE_SPOT', }; export const DescriptionTransferTypeMapping: TransferTypeMap = { @@ -446,6 +458,9 @@ export const DescriptionTransferTypeMapping: TransferTypeMap = { TRANSFER_TYPE_CLEAR_ACCOUNT: `Market-related accounts emptied, and balances moved, because the market has closed`, TRANSFER_TYPE_UNSPECIFIED: 'Default value, always invalid', TRANSFER_TYPE_CHECKPOINT_BALANCE_RESTORE: `Balances are being restored to the user's account following a checkpoint restart of the network`, + TRANSFER_TYPE_HOLDING_LOCK: '-', + TRANSFER_TYPE_HOLDING_RELEASE: '-', + TRANSFER_TYPE_SPOT: '-', }; type DispatchMetricLabel = {