diff --git a/apps/console-lite-e2e/src/integration/market-selector.test.ts b/apps/console-lite-e2e/src/integration/market-selector.test.ts
index be2502964..7b94eacb6 100644
--- a/apps/console-lite-e2e/src/integration/market-selector.test.ts
+++ b/apps/console-lite-e2e/src/integration/market-selector.test.ts
@@ -9,6 +9,7 @@ import { generatePartyBalance } from '../support/mocks/generate-party-balance';
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
import { generateMarketNames } from '../support/mocks/generate-market-names';
+import { generateMarketDepth } from '../support/mocks/generate-market-depth';
describe('market selector', () => {
let markets;
@@ -23,6 +24,7 @@ describe('market selector', () => {
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
aliasQuery(req, 'MarketNames', generateMarketNames());
+ aliasQuery(req, 'MarketDepth', generateMarketDepth());
});
cy.visit('/markets');
diff --git a/apps/console-lite-e2e/src/integration/market-trade.test.ts b/apps/console-lite-e2e/src/integration/market-trade.test.ts
index 6665940bd..0e7cf03a7 100644
--- a/apps/console-lite-e2e/src/integration/market-trade.test.ts
+++ b/apps/console-lite-e2e/src/integration/market-trade.test.ts
@@ -1,5 +1,8 @@
import { aliasQuery } from '@vegaprotocol/cypress';
-import { generateSimpleMarkets } from '../support/mocks/generate-markets';
+import {
+ generateSimpleMarkets,
+ generateMarkets,
+} from '../support/mocks/generate-markets';
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
import { generateMarketTags } from '../support/mocks/generate-market-tags';
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
@@ -14,6 +17,7 @@ describe('Market trade', () => {
let markets;
beforeEach(() => {
cy.mockGQL((req) => {
+ aliasQuery(req, 'Markets', generateMarkets());
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
aliasQuery(req, 'DealTicketQuery', generateDealTicket());
aliasQuery(req, 'MarketTags', generateMarketTags());
diff --git a/apps/console-lite-e2e/src/support/mocks/generate-market-depth.ts b/apps/console-lite-e2e/src/support/mocks/generate-market-depth.ts
index f8c60fead..d0342a6ea 100644
--- a/apps/console-lite-e2e/src/support/mocks/generate-market-depth.ts
+++ b/apps/console-lite-e2e/src/support/mocks/generate-market-depth.ts
@@ -1,24 +1,15 @@
-export const generateMarketDepth = () => {
- return {
+import merge from 'lodash/merge';
+import type { PartialDeep } from 'type-fest';
+// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
+import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
+
+export const generateMarketDepth = (
+ override?: PartialDeep
+): MarketDepth => {
+ const defaultResult: MarketDepth = {
market: {
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
- decimalPlaces: 5,
- positionDecimalPlaces: 0,
- data: {
- staticMidPrice: '9893006',
- marketTradingMode: 'TRADING_MODE_CONTINUOUS',
- indicativeVolume: '0',
- indicativePrice: '0',
- bestStaticBidPrice: '9893006',
- bestStaticOfferPrice: '9893006',
- market: {
- id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
- __typename: 'Market',
- },
- __typename: 'MarketData',
- },
depth: {
- lastTrade: { price: '9893006', __typename: 'Trade' },
sell: [
{
price: '9893007',
@@ -215,4 +206,5 @@ export const generateMarketDepth = () => {
__typename: 'Market',
},
};
+ return merge(defaultResult, override);
};
diff --git a/apps/console-lite-e2e/src/support/mocks/generate-markets.ts b/apps/console-lite-e2e/src/support/mocks/generate-markets.ts
index 18a3cdc42..16d39a83a 100644
--- a/apps/console-lite-e2e/src/support/mocks/generate-markets.ts
+++ b/apps/console-lite-e2e/src/support/mocks/generate-markets.ts
@@ -1,3 +1,5 @@
+import merge from 'lodash/merge';
+import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import { protoMarket } from './commons';
export const generateSimpleMarkets = () => {
@@ -880,3 +882,41 @@ export const generateLongListMarkets = (count: number) => {
}
return { markets };
};
+
+export const generateMarkets = (override?) => {
+ const markets = [
+ {
+ ...protoMarket,
+ decimalPlaces: 5,
+ positionDecimalPlaces: 0,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ state: MarketState.STATE_ACTIVE,
+ marketTimestamps: {
+ __typename: 'MarketTimestamps',
+ close: '',
+ open: '',
+ },
+ fees: {
+ __typename: 'Fees',
+ factors: {
+ __typename: 'FeeFactors',
+ makerFee: '',
+ infrastructureFee: '',
+ liquidityFee: '',
+ },
+ },
+ },
+ ];
+
+ const defaultResult = {
+ marketsConnection: {
+ __typename: 'MarketConnection',
+ edges: markets.map((node) => ({
+ __typename: 'MarketEdge',
+ node,
+ })),
+ },
+ };
+
+ return merge(defaultResult, override);
+};
diff --git a/apps/console-lite/src/app/hooks/use-calculate-slippage.spec.tsx b/apps/console-lite/src/app/hooks/use-calculate-slippage.spec.tsx
index 49b58dfd5..b5706cb88 100644
--- a/apps/console-lite/src/app/hooks/use-calculate-slippage.spec.tsx
+++ b/apps/console-lite/src/app/hooks/use-calculate-slippage.spec.tsx
@@ -64,6 +64,15 @@ jest.mock('@vegaprotocol/market-depth', () => ({
useOrderBookData: jest.fn(() => mockOrderBookData),
}));
+jest.mock('@vegaprotocol/react-helpers', () => ({
+ ...jest.requireActual('@vegaprotocol/react-helpers'),
+ useDataProvider: jest.fn(() => ({
+ data: {
+ marketsConnection: [],
+ },
+ })),
+}));
+
describe('useCalculateSlippage Hook', () => {
describe('calculate proper result', () => {
afterEach(() => {
diff --git a/apps/console-lite/src/app/hooks/use-calculate-slippage.ts b/apps/console-lite/src/app/hooks/use-calculate-slippage.ts
index 13520587a..ccf937a66 100644
--- a/apps/console-lite/src/app/hooks/use-calculate-slippage.ts
+++ b/apps/console-lite/src/app/hooks/use-calculate-slippage.ts
@@ -1,9 +1,15 @@
import { useMemo } from 'react';
import { Side } from '@vegaprotocol/types';
import { useOrderBookData } from '@vegaprotocol/market-depth';
+import { marketProvider } from '@vegaprotocol/market-list';
+import type { Market } from '@vegaprotocol/market-list';
import type { Order } from '@vegaprotocol/orders';
import { BigNumber } from 'bignumber.js';
-import { formatNumber, toBigNum } from '@vegaprotocol/react-helpers';
+import {
+ formatNumber,
+ toBigNum,
+ useDataProvider,
+} from '@vegaprotocol/react-helpers';
interface Props {
marketId: string;
@@ -16,11 +22,16 @@ const useCalculateSlippage = ({ marketId, order }: Props) => {
variables,
throttleMilliseconds: 5000,
});
+ const { data: market } = useDataProvider({
+ dataProvider: marketProvider,
+ noUpdate: true,
+ variables,
+ });
const volPriceArr =
data?.depth[order.side === Side.SIDE_BUY ? 'sell' : 'buy'] || [];
- if (volPriceArr.length) {
- const decimals = data?.decimalPlaces ?? 0;
- const positionDecimals = data?.positionDecimalPlaces ?? 0;
+ if (volPriceArr.length && market) {
+ const decimals = market.decimalPlaces ?? 0;
+ const positionDecimals = market.positionDecimalPlaces ?? 0;
const bestPrice = toBigNum(volPriceArr[0].price, decimals);
const { size } = order;
let descSize = new BigNumber(size);
diff --git a/apps/trading-e2e/src/integration/home.cy.ts b/apps/trading-e2e/src/integration/home.cy.ts
index 996050767..509b020bf 100644
--- a/apps/trading-e2e/src/integration/home.cy.ts
+++ b/apps/trading-e2e/src/integration/home.cy.ts
@@ -55,11 +55,16 @@ describe('home', () => {
it('redirects to a the market list page if no sensible default is found', () => {
// Mock markets query that is triggered by home page to find default market
cy.mockGQL((req) => {
- aliasQuery(req, 'MarketList', { markets: [] });
+ const data = {
+ marketsConnection: {
+ __typename: 'MarketConnection',
+ edges: [],
+ },
+ };
+ aliasQuery(req, 'Markets', data);
});
-
cy.visit('/');
- cy.wait('@MarketList');
+ cy.wait('@Markets');
cy.url().should('eq', Cypress.config().baseUrl + '/markets');
});
});
diff --git a/apps/trading-e2e/src/integration/markets.cy.ts b/apps/trading-e2e/src/integration/markets.cy.ts
index afc4ea06f..fada777dc 100644
--- a/apps/trading-e2e/src/integration/markets.cy.ts
+++ b/apps/trading-e2e/src/integration/markets.cy.ts
@@ -11,7 +11,9 @@ describe('markets table', () => {
it('renders markets correctly', () => {
cy.visit('/');
cy.wait('@Market');
- cy.wait('@MarketList');
+ cy.wait('@Markets');
+ cy.wait('@MarketsDataQuery');
+ cy.wait('@MarketsCandlesQuery');
cy.get('[data-testid^="market-link-"]')
.should('not.be.empty')
.and('have.attr', 'href');
@@ -24,7 +26,9 @@ describe('markets table', () => {
it('renders market list drop down', () => {
cy.visit('/');
- cy.wait('@MarketList');
+ cy.wait('@Markets');
+ cy.wait('@MarketsDataQuery');
+ cy.wait('@MarketsCandlesQuery');
openMarketDropDown();
cy.getByTestId('price').invoke('text').should('not.be.empty');
cy.getByTestId('trading-mode').should('not.be.empty');
@@ -35,7 +39,9 @@ describe('markets table', () => {
it('Able to select market from dropdown', () => {
cy.visit('/');
- cy.wait('@MarketList');
+ cy.wait('@Markets');
+ cy.wait('@MarketsDataQuery');
+ cy.wait('@MarketsCandlesQuery');
openMarketDropDown();
cy.getByTestId('market-link-market-0').should('be.visible').click();
@@ -53,7 +59,9 @@ describe('markets table', () => {
'SOLUSD',
];
cy.visit('/');
- cy.wait('@MarketList');
+ cy.wait('@Markets');
+ cy.wait('@MarketsDataQuery');
+ cy.wait('@MarketsCandlesQuery');
cy.getByTestId('link').should('have.attr', 'href', '/markets').click();
cy.url().should('eq', Cypress.config('baseUrl') + '/markets');
cy.contains('AAPL.MF21').should('be.visible');
diff --git a/apps/trading-e2e/src/support/mocks/generate-market-depth.ts b/apps/trading-e2e/src/support/mocks/generate-market-depth.ts
index d7016fc1c..74012beb1 100644
--- a/apps/trading-e2e/src/support/mocks/generate-market-depth.ts
+++ b/apps/trading-e2e/src/support/mocks/generate-market-depth.ts
@@ -1,5 +1,4 @@
import merge from 'lodash/merge';
-import { MarketTradingMode } from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
@@ -10,26 +9,10 @@ export const generateMarketDepth = (
const defaultResult: MarketDepth = {
market: {
id: 'market-0',
- decimalPlaces: 5,
- positionDecimalPlaces: 0,
- data: {
- marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- staticMidPrice: '0',
- indicativePrice: '0',
- bestStaticBidPrice: '0',
- bestStaticOfferPrice: '0',
- indicativeVolume: '0',
- market: {
- id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
- __typename: 'Market',
- },
- __typename: 'MarketData',
- },
depth: {
__typename: 'MarketDepth',
buy: [],
sell: [],
- lastTrade: null,
sequenceNumber: '',
},
__typename: 'Market',
diff --git a/apps/trading-e2e/src/support/mocks/generate-markets.ts b/apps/trading-e2e/src/support/mocks/generate-markets.ts
index c4724aa7a..f40925d47 100644
--- a/apps/trading-e2e/src/support/mocks/generate-markets.ts
+++ b/apps/trading-e2e/src/support/mocks/generate-markets.ts
@@ -5,12 +5,17 @@ import {
MarketTradingMode,
} from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
-import type { MarketList, MarketList_markets } from '@vegaprotocol/market-list';
+import type {
+ Markets,
+ Markets_marketsConnection_edges_node,
+ MarketsCandlesQuery,
+ MarketsCandlesQuery_marketsConnection_edges_node,
+ MarketsDataQuery,
+ MarketsDataQuery_marketsConnection_edges_node,
+} from '@vegaprotocol/market-list';
-export const generateMarkets = (
- override?: PartialDeep
-): MarketList => {
- const markets: MarketList_markets[] = [
+export const generateMarkets = (override?: PartialDeep): Markets => {
+ const markets: Markets_marketsConnection_edges_node[] = [
{
id: 'market-0',
decimalPlaces: 5,
@@ -22,15 +27,6 @@ export const generateMarkets = (
close: '',
open: '',
},
- candles: [
- {
- __typename: 'Candle',
- open: '100',
- close: '100',
- high: '110',
- low: '90',
- },
- ],
fees: {
__typename: 'Fees',
factors: {
@@ -40,20 +36,6 @@ export const generateMarkets = (
liquidityFee: '',
},
},
- data: {
- market: {
- id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
- state: MarketState.STATE_ACTIVE,
- tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- __typename: 'Market',
- },
- indicativeVolume: '0',
- bestBidPrice: '0',
- bestOfferPrice: '0',
- markPrice: '4612690058',
- trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
- __typename: 'MarketData',
- },
tradableInstrument: {
instrument: {
id: '',
@@ -87,15 +69,6 @@ export const generateMarkets = (
close: '',
open: '',
},
- candles: [
- {
- __typename: 'Candle',
- open: '100',
- close: '100',
- high: '110',
- low: '90',
- },
- ],
fees: {
__typename: 'Fees',
factors: {
@@ -105,20 +78,6 @@ export const generateMarkets = (
liquidityFee: '',
},
},
- data: {
- market: {
- id: '34d95e10faa00c21d19d382d6d7e6fc9722a96985369f0caec041b0f44b775ed',
- state: MarketState.STATE_SUSPENDED,
- tradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
- __typename: 'Market',
- },
- bestBidPrice: '0',
- bestOfferPrice: '0',
- indicativeVolume: '0',
- markPrice: '8441',
- trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
- __typename: 'MarketData',
- },
tradableInstrument: {
instrument: {
id: 'SOLUSD',
@@ -152,15 +111,6 @@ export const generateMarkets = (
close: '2022-08-26T11:36:32.252490405Z',
open: null,
},
- candles: [
- {
- __typename: 'Candle',
- open: '100',
- close: '100',
- high: '110',
- low: '90',
- },
- ],
fees: {
__typename: 'Fees',
factors: {
@@ -170,20 +120,6 @@ export const generateMarkets = (
liquidityFee: '0.001',
},
},
- data: {
- market: {
- id: 'a1c731af07570ca49b22a3cd253cc143dc14068edbec918e1087e69db934af5f',
- state: MarketState.STATE_SUSPENDED,
- tradingMode: MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
- __typename: 'Market',
- },
- indicativeVolume: '0',
- bestBidPrice: '0',
- bestOfferPrice: '0',
- markPrice: '4612690058',
- trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
- __typename: 'MarketData',
- },
tradableInstrument: {
instrument: {
id: '',
@@ -217,15 +153,6 @@ export const generateMarkets = (
close: '2022-08-26T11:36:32.252490405Z',
open: null,
},
- candles: [
- {
- __typename: 'Candle',
- open: '100',
- close: '100',
- high: '110',
- low: '90',
- },
- ],
fees: {
__typename: 'Fees',
factors: {
@@ -235,20 +162,6 @@ export const generateMarkets = (
liquidityFee: '0.001',
},
},
- data: {
- market: {
- id: 'bebea8ec669b913a7d6a704a6d8cede164bc1376229e0d472bc6fdaa976629b2',
- state: MarketState.STATE_ACTIVE,
- tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- __typename: 'Market',
- },
- indicativeVolume: '0',
- bestBidPrice: '0',
- bestOfferPrice: '0',
- markPrice: '4612690058',
- trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
- __typename: 'MarketData',
- },
tradableInstrument: {
instrument: {
id: '',
@@ -272,8 +185,212 @@ export const generateMarkets = (
__typename: 'Market',
},
];
- const defaultResult = {
- markets,
+
+ const defaultResult: Markets = {
+ marketsConnection: {
+ __typename: 'MarketConnection',
+ edges: markets.map((node) => ({
+ __typename: 'MarketEdge',
+ node,
+ })),
+ },
+ };
+
+ return merge(defaultResult, override);
+};
+
+export const generateMarketsData = (
+ override?: PartialDeep
+): MarketsDataQuery => {
+ const markets: MarketsDataQuery_marketsConnection_edges_node[] = [
+ {
+ data: {
+ market: {
+ id: 'market-0',
+ __typename: 'Market',
+ },
+ marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ staticMidPrice: '0',
+ indicativePrice: '0',
+ bestStaticBidPrice: '0',
+ bestStaticOfferPrice: '0',
+ indicativeVolume: '0',
+ bestBidPrice: '0',
+ bestOfferPrice: '0',
+ markPrice: '4612690058',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
+ __typename: 'MarketData',
+ },
+ __typename: 'Market',
+ },
+ {
+ data: {
+ market: {
+ id: 'market-1',
+ __typename: 'Market',
+ },
+ marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ staticMidPrice: '0',
+ indicativePrice: '0',
+ bestStaticBidPrice: '0',
+ bestStaticOfferPrice: '0',
+ indicativeVolume: '0',
+ bestBidPrice: '0',
+ bestOfferPrice: '0',
+ markPrice: '8441',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
+ __typename: 'MarketData',
+ },
+ __typename: 'Market',
+ },
+ {
+ data: {
+ market: {
+ id: 'market-2',
+ __typename: 'Market',
+ },
+ marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ staticMidPrice: '0',
+ indicativePrice: '0',
+ bestStaticBidPrice: '0',
+ bestStaticOfferPrice: '0',
+ indicativeVolume: '0',
+ bestBidPrice: '0',
+ bestOfferPrice: '0',
+ markPrice: '4612690058',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
+ __typename: 'MarketData',
+ },
+ __typename: 'Market',
+ },
+ {
+ data: {
+ market: {
+ id: 'market-3',
+ __typename: 'Market',
+ },
+ marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ staticMidPrice: '0',
+ indicativePrice: '0',
+ bestStaticBidPrice: '0',
+ bestStaticOfferPrice: '0',
+ indicativeVolume: '0',
+ bestBidPrice: '0',
+ bestOfferPrice: '0',
+ markPrice: '4612690058',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
+ __typename: 'MarketData',
+ },
+ __typename: 'Market',
+ },
+ ];
+
+ const defaultResult: MarketsDataQuery = {
+ marketsConnection: {
+ __typename: 'MarketConnection',
+ edges: markets.map((node) => ({
+ __typename: 'MarketEdge',
+ node,
+ })),
+ },
+ };
+
+ return merge(defaultResult, override);
+};
+
+export const generateMarketsCandles = (
+ override?: PartialDeep
+): MarketsCandlesQuery => {
+ const markets: MarketsCandlesQuery_marketsConnection_edges_node[] = [
+ {
+ __typename: 'Market',
+ id: 'market-0',
+ candlesConnection: {
+ __typename: 'CandleDataConnection',
+ edges: [
+ {
+ __typename: 'CandleEdge',
+ node: {
+ __typename: 'CandleNode',
+ open: '100',
+ close: '100',
+ high: '110',
+ low: '90',
+ volume: '1',
+ },
+ },
+ ],
+ },
+ },
+ {
+ __typename: 'Market',
+ id: 'market-1',
+ candlesConnection: {
+ __typename: 'CandleDataConnection',
+ edges: [
+ {
+ __typename: 'CandleEdge',
+ node: {
+ __typename: 'CandleNode',
+ open: '100',
+ close: '100',
+ high: '110',
+ low: '90',
+ volume: '1',
+ },
+ },
+ ],
+ },
+ },
+ {
+ __typename: 'Market',
+ id: 'market-2',
+ candlesConnection: {
+ __typename: 'CandleDataConnection',
+ edges: [
+ {
+ __typename: 'CandleEdge',
+ node: {
+ __typename: 'CandleNode',
+ open: '100',
+ close: '100',
+ high: '110',
+ low: '90',
+ volume: '1',
+ },
+ },
+ ],
+ },
+ },
+ {
+ __typename: 'Market',
+ id: 'market-3',
+ candlesConnection: {
+ __typename: 'CandleDataConnection',
+ edges: [
+ {
+ __typename: 'CandleEdge',
+ node: {
+ __typename: 'CandleNode',
+ open: '100',
+ close: '100',
+ high: '110',
+ low: '90',
+ volume: '1',
+ },
+ },
+ ],
+ },
+ },
+ ];
+ const defaultResult: MarketsCandlesQuery = {
+ marketsConnection: {
+ __typename: 'MarketConnection',
+ edges: markets.map((node) => ({
+ __typename: 'MarketEdge',
+ node,
+ })),
+ },
};
return merge(defaultResult, override);
diff --git a/apps/trading-e2e/src/support/mocks/generate-order-book.ts b/apps/trading-e2e/src/support/mocks/generate-order-book.ts
index 763072179..1529083e2 100644
--- a/apps/trading-e2e/src/support/mocks/generate-order-book.ts
+++ b/apps/trading-e2e/src/support/mocks/generate-order-book.ts
@@ -4,33 +4,13 @@ import type {
MarketDepth,
MarketDepth_market,
} from '@vegaprotocol/market-depth';
-import { MarketTradingMode } from '@vegaprotocol/types';
export const generateOrderBook = (
override?: PartialDeep
): MarketDepth => {
const marketDepth: MarketDepth_market = {
id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
- decimalPlaces: 5,
- positionDecimalPlaces: 0,
- data: {
- staticMidPrice: '826337',
- marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- indicativeVolume: '0',
- indicativePrice: '0',
- bestStaticBidPrice: '826336',
- bestStaticOfferPrice: '826338',
- market: {
- id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
- __typename: 'Market',
- },
- __typename: 'MarketData',
- },
depth: {
- lastTrade: {
- price: '826338',
- __typename: 'Trade',
- },
sell: [
{
price: '826338',
diff --git a/apps/trading-e2e/src/support/trading.ts b/apps/trading-e2e/src/support/trading.ts
index 0b11bfeb1..a63074c0f 100644
--- a/apps/trading-e2e/src/support/trading.ts
+++ b/apps/trading-e2e/src/support/trading.ts
@@ -8,7 +8,11 @@ import { generateDealTicketQuery } from './mocks/generate-deal-ticket-query';
import { generateMarket } from './mocks/generate-market';
import { generateMarketDepth } from './mocks/generate-market-depth';
import { generateMarketInfoQuery } from './mocks/generate-market-info-query';
-import { generateMarkets } from './mocks/generate-markets';
+import {
+ generateMarkets,
+ generateMarketsData,
+ generateMarketsCandles,
+} from './mocks/generate-markets';
import { generateOrders } from './mocks/generate-orders';
import { generatePositions } from './mocks/generate-positions';
import { generateTrades } from './mocks/generate-trades';
@@ -31,7 +35,10 @@ export const mockTradingPage = (
},
})
);
- aliasQuery(req, 'MarketList', generateMarkets());
+ aliasQuery(req, 'Markets', generateMarkets());
+ aliasQuery(req, 'MarketsDataQuery', generateMarketsData());
+ aliasQuery(req, 'MarketsCandlesQuery', generateMarketsCandles());
+
aliasQuery(req, 'MarketDepth', generateMarketDepth());
aliasQuery(req, 'Orders', generateOrders());
aliasQuery(req, 'Accounts', generateAccounts());
diff --git a/apps/trading/pages/index.page.tsx b/apps/trading/pages/index.page.tsx
index 542344bc8..347e2b8ff 100644
--- a/apps/trading/pages/index.page.tsx
+++ b/apps/trading/pages/index.page.tsx
@@ -1,4 +1,5 @@
-import { useMarketList } from '@vegaprotocol/market-list';
+import { activeMarketsProvider } from '@vegaprotocol/market-list';
+import { useDataProvider } from '@vegaprotocol/react-helpers';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
@@ -8,7 +9,10 @@ export function Index() {
const { replace } = useRouter();
// The default market selected in the platform behind the overlay
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
- const { data, error, loading } = useMarketList();
+ const { data, error, loading } = useDataProvider({
+ dataProvider: activeMarketsProvider,
+ noUpdate: true,
+ });
const { riskNoticeDialog, update } = useGlobalStore((store) => ({
riskNoticeDialog: store.riskNoticeDialog,
update: store.update,
diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-container.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-container.tsx
index 62682822f..3282ac731 100644
--- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-container.tsx
+++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-container.tsx
@@ -64,6 +64,7 @@ export const DealTicketContainer = ({
)
) : (
+ {JSON.stringify(data)}
{t('Could not load market')}
)}
diff --git a/libs/market-depth/src/lib/__generated__/MarketDepth.ts b/libs/market-depth/src/lib/__generated__/MarketDepth.ts
index 7b043223b..7de7f05b6 100644
--- a/libs/market-depth/src/lib/__generated__/MarketDepth.ts
+++ b/libs/market-depth/src/lib/__generated__/MarketDepth.ts
@@ -3,60 +3,10 @@
// @generated
// This file was automatically generated and should not be edited.
-import { MarketTradingMode } from "@vegaprotocol/types";
-
// ====================================================
// GraphQL query operation: MarketDepth
// ====================================================
-export interface MarketDepth_market_data_market {
- __typename: "Market";
- /**
- * Market ID
- */
- id: string;
-}
-
-export interface MarketDepth_market_data {
- __typename: "MarketData";
- /**
- * the arithmetic average of the best static bid price and best static offer price
- */
- staticMidPrice: string;
- /**
- * what state the market is in (auction, continuous, etc)
- */
- marketTradingMode: MarketTradingMode;
- /**
- * indicative volume if the auction ended now, 0 if not in auction mode
- */
- indicativeVolume: string;
- /**
- * indicative price if the auction ended now, 0 if not in auction mode
- */
- indicativePrice: string;
- /**
- * the highest price level on an order book for buy orders not including pegged orders.
- */
- bestStaticBidPrice: string;
- /**
- * the lowest price level on an order book for offer orders not including pegged orders.
- */
- bestStaticOfferPrice: string;
- /**
- * market ID of the associated mark price
- */
- market: MarketDepth_market_data_market;
-}
-
-export interface MarketDepth_market_depth_lastTrade {
- __typename: "Trade";
- /**
- * The price of the trade (probably initially the passive order price, other determination algorithms are possible though) (uint64)
- */
- price: string;
-}
-
export interface MarketDepth_market_depth_sell {
__typename: "PriceLevel";
/**
@@ -91,10 +41,6 @@ export interface MarketDepth_market_depth_buy {
export interface MarketDepth_market_depth {
__typename: "MarketDepth";
- /**
- * Last trade for the given market (if available)
- */
- lastTrade: MarketDepth_market_depth_lastTrade | null;
/**
* Sell side price levels (if available)
*/
@@ -115,34 +61,6 @@ export interface MarketDepth_market {
* Market ID
*/
id: string;
- /**
- * decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
- * number denominated in the currency of the market. (uint64)
- *
- * Examples:
- * Currency Balance decimalPlaces Real Balance
- * GBP 100 0 GBP 100
- * GBP 100 2 GBP 1.00
- * GBP 100 4 GBP 0.01
- * GBP 1 4 GBP 0.0001 ( 0.01p )
- *
- * GBX (pence) 100 0 GBP 1.00 (100p )
- * GBX (pence) 100 2 GBP 0.01 ( 1p )
- * GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
- * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
- */
- decimalPlaces: number;
- /**
- * positionDecimalPlaces indicates 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.
- * 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
- * This sets how big the smallest order / position on the market can be.
- */
- positionDecimalPlaces: number;
- /**
- * marketData for the given market
- */
- data: MarketDepth_market_data | null;
/**
* Current depth on the order book for this market
*/
diff --git a/libs/market-depth/src/lib/__generated__/MarketDepthSubscription.ts b/libs/market-depth/src/lib/__generated__/MarketDepthSubscription.ts
index 456b6cc8c..03de5c765 100644
--- a/libs/market-depth/src/lib/__generated__/MarketDepthSubscription.ts
+++ b/libs/market-depth/src/lib/__generated__/MarketDepthSubscription.ts
@@ -3,72 +3,11 @@
// @generated
// This file was automatically generated and should not be edited.
-import { MarketTradingMode } from "@vegaprotocol/types";
-
// ====================================================
// GraphQL subscription operation: MarketDepthSubscription
// ====================================================
-export interface MarketDepthSubscription_marketDepthUpdate_market_data_market {
- __typename: "Market";
- /**
- * Market ID
- */
- id: string;
-}
-
-export interface MarketDepthSubscription_marketDepthUpdate_market_data {
- __typename: "MarketData";
- /**
- * the arithmetic average of the best static bid price and best static offer price
- */
- staticMidPrice: string;
- /**
- * what state the market is in (auction, continuous, etc)
- */
- marketTradingMode: MarketTradingMode;
- /**
- * indicative volume if the auction ended now, 0 if not in auction mode
- */
- indicativeVolume: string;
- /**
- * indicative price if the auction ended now, 0 if not in auction mode
- */
- indicativePrice: string;
- /**
- * the highest price level on an order book for buy orders not including pegged orders.
- */
- bestStaticBidPrice: string;
- /**
- * the lowest price level on an order book for offer orders not including pegged orders.
- */
- bestStaticOfferPrice: string;
- /**
- * market ID of the associated mark price
- */
- market: MarketDepthSubscription_marketDepthUpdate_market_data_market;
-}
-
-export interface MarketDepthSubscription_marketDepthUpdate_market {
- __typename: "Market";
- /**
- * Market ID
- */
- id: string;
- /**
- * positionDecimalPlaces indicates 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.
- * 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
- * This sets how big the smallest order / position on the market can be.
- */
- positionDecimalPlaces: number;
- /**
- * marketData for the given market
- */
- data: MarketDepthSubscription_marketDepthUpdate_market_data | null;
-}
-
-export interface MarketDepthSubscription_marketDepthUpdate_sell {
+export interface MarketDepthSubscription_marketsDepthUpdate_sell {
__typename: "PriceLevel";
/**
* The price of all the orders at this level (uint64)
@@ -84,7 +23,7 @@ export interface MarketDepthSubscription_marketDepthUpdate_sell {
numberOfOrders: string;
}
-export interface MarketDepthSubscription_marketDepthUpdate_buy {
+export interface MarketDepthSubscription_marketsDepthUpdate_buy {
__typename: "PriceLevel";
/**
* The price of all the orders at this level (uint64)
@@ -100,33 +39,37 @@ export interface MarketDepthSubscription_marketDepthUpdate_buy {
numberOfOrders: string;
}
-export interface MarketDepthSubscription_marketDepthUpdate {
- __typename: "MarketDepthUpdate";
+export interface MarketDepthSubscription_marketsDepthUpdate {
+ __typename: "ObservableMarketDepthUpdate";
/**
- * Market
+ * Market ID
*/
- market: MarketDepthSubscription_marketDepthUpdate_market;
+ marketId: string;
/**
* Sell side price levels (if available)
*/
- sell: MarketDepthSubscription_marketDepthUpdate_sell[] | null;
+ sell: MarketDepthSubscription_marketsDepthUpdate_sell[] | null;
/**
* Buy side price levels (if available)
*/
- buy: MarketDepthSubscription_marketDepthUpdate_buy[] | null;
+ buy: MarketDepthSubscription_marketsDepthUpdate_buy[] | null;
/**
* Sequence number for the current snapshot of the market depth. It is always increasing but not monotonic.
*/
sequenceNumber: string;
+ /**
+ * Sequence number of the last update sent; useful for checking that no updates were missed.
+ */
+ previousSequenceNumber: string;
}
export interface MarketDepthSubscription {
/**
* Subscribe to price level market depth updates
*/
- marketDepthUpdate: MarketDepthSubscription_marketDepthUpdate;
+ marketsDepthUpdate: MarketDepthSubscription_marketsDepthUpdate[];
}
export interface MarketDepthSubscriptionVariables {
- marketId: string;
+ id: string;
}
diff --git a/libs/market-depth/src/lib/depth-chart.tsx b/libs/market-depth/src/lib/depth-chart.tsx
index 8b830b49b..87cd59550 100644
--- a/libs/market-depth/src/lib/depth-chart.tsx
+++ b/libs/market-depth/src/lib/depth-chart.tsx
@@ -7,7 +7,7 @@ import {
ThemeContext,
getNumberFormat,
} from '@vegaprotocol/react-helpers';
-import dataProvider from './market-depth-data-provider';
+import dataProvider from './market-depth-provider';
import {
useCallback,
useEffect,
@@ -16,7 +16,13 @@ import {
useState,
useContext,
} from 'react';
-import type { MarketDepthSubscription_marketDepthUpdate } from './__generated__/MarketDepthSubscription';
+import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
+import type { MarketData } from '@vegaprotocol/market-list';
+import type {
+ MarketDepthSubscription_marketsDepthUpdate,
+ MarketDepthSubscription_marketsDepthUpdate_sell,
+ MarketDepthSubscription_marketsDepthUpdate_buy,
+} from './__generated__/MarketDepthSubscription';
import type { DepthChartProps } from 'pennant';
import { parseLevel, updateLevels } from './depth-chart-utils';
@@ -33,46 +39,80 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
const theme = useContext(ThemeContext);
const variables = useMemo(() => ({ marketId }), [marketId]);
const [depthData, setDepthData] = useState(null);
- const [decimalPlaces, setDecimalPlaces] = useState(0);
- const [positionDecimalPlaces, setPositionDecimalPlaces] = useState(0);
const dataRef = useRef(null);
- const setDepthDataThrottledRef = useRef(throttle(setDepthData, 1000));
+ const marketDataRef = useRef(null);
+ const deltaRef = useRef<{
+ sell: MarketDepthSubscription_marketsDepthUpdate_sell[];
+ buy: MarketDepthSubscription_marketsDepthUpdate_buy[];
+ }>({
+ sell: [],
+ buy: [],
+ });
- // Apply updates to the table
- const update = useCallback(
- ({ delta }: { delta: MarketDepthSubscription_marketDepthUpdate }) => {
- if (!dataRef.current) {
- return false;
+ const updateDepthData = useRef(
+ throttle(() => {
+ if (!dataRef.current || !marketDataRef.current || !market) {
+ return;
}
dataRef.current = {
...dataRef.current,
- midPrice: delta.market.data?.staticMidPrice
- ? formatMidPrice(delta.market.data?.staticMidPrice, decimalPlaces)
+ midPrice: marketDataRef.current?.staticMidPrice
+ ? formatMidPrice(
+ marketDataRef.current?.staticMidPrice,
+ market.decimalPlaces
+ )
: undefined,
data: {
- buy: delta.buy
+ buy: deltaRef.current.buy
? updateLevels(
dataRef.current.data.buy,
- delta.buy,
- decimalPlaces,
- positionDecimalPlaces,
+ deltaRef.current.buy,
+ market.decimalPlaces,
+ market.positionDecimalPlaces,
true
)
: dataRef.current.data.buy,
- sell: delta.sell
+ sell: deltaRef.current.sell
? updateLevels(
dataRef.current.data.sell,
- delta.sell,
- decimalPlaces,
- positionDecimalPlaces
+ deltaRef.current.sell,
+ market.decimalPlaces,
+ market.positionDecimalPlaces
)
: dataRef.current.data.sell,
},
};
- setDepthDataThrottledRef.current(dataRef.current);
+ deltaRef.current.buy = [];
+ deltaRef.current.sell = [];
+ setDepthData(dataRef.current);
+ }, 1000)
+ );
+
+ // Apply updates to the table
+ const update = useCallback(
+ ({
+ delta: deltas,
+ }: {
+ delta: MarketDepthSubscription_marketsDepthUpdate[];
+ }) => {
+ if (!dataRef.current) {
+ return false;
+ }
+ for (const delta of deltas) {
+ if (delta.marketId !== marketId) {
+ continue;
+ }
+ if (delta.sell) {
+ deltaRef.current.sell.push(...delta.sell);
+ }
+ if (delta.buy) {
+ deltaRef.current.buy.push(...delta.buy);
+ }
+ updateDepthData.current();
+ }
return true;
},
- [decimalPlaces, positionDecimalPlaces]
+ [marketId, updateDepthData]
);
const { data, error, loading } = useDataProvider({
@@ -81,53 +121,86 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
variables,
});
+ const {
+ data: market,
+ error: marketError,
+ loading: marketLoading,
+ } = useDataProvider({
+ dataProvider: marketProvider,
+ noUpdate: true,
+ variables,
+ });
+
+ const marketDataUpdate = useCallback(({ data }: { data: MarketData }) => {
+ marketDataRef.current = data;
+ return true;
+ }, []);
+
+ const {
+ data: marketData,
+ error: marketDataError,
+ loading: marketDataLoading,
+ } = useDataProvider({
+ dataProvider: marketDataProvider,
+ update: marketDataUpdate,
+ variables,
+ });
+
+ marketDataRef.current = marketData;
+
useEffect(() => {
+ if (!marketData || !market || !data) {
+ return;
+ }
if (!data) {
dataRef.current = null;
setDepthData(dataRef.current);
return;
}
dataRef.current = {
- midPrice: data.data?.staticMidPrice
- ? formatMidPrice(data.data?.staticMidPrice, data.decimalPlaces)
+ midPrice: marketData.staticMidPrice
+ ? formatMidPrice(marketData.staticMidPrice, market.decimalPlaces)
: undefined,
data: {
buy:
data.depth.buy?.map((priceLevel) =>
parseLevel(
priceLevel,
- data.decimalPlaces,
- data.positionDecimalPlaces
+ market.decimalPlaces,
+ market.positionDecimalPlaces
)
) ?? [],
sell:
data.depth.sell?.map((priceLevel) =>
parseLevel(
priceLevel,
- data.decimalPlaces,
- data.positionDecimalPlaces
+ market.decimalPlaces,
+ market.positionDecimalPlaces
)
) ?? [],
},
};
setDepthData(dataRef.current);
- setDecimalPlaces(data.decimalPlaces);
- setPositionDecimalPlaces(data.positionDecimalPlaces);
- }, [data]);
+ }, [data, marketData, market]);
const volumeFormat = useCallback(
(volume: number) =>
- getNumberFormat(data?.positionDecimalPlaces || 0).format(volume),
- [data?.positionDecimalPlaces]
+ getNumberFormat(market?.positionDecimalPlaces || 0).format(volume),
+ [market?.positionDecimalPlaces]
);
const priceFormat = useCallback(
- (price: number) => getNumberFormat(data?.decimalPlaces || 0).format(price),
- [data?.decimalPlaces]
+ (price: number) =>
+ getNumberFormat(market?.decimalPlaces || 0).format(price),
+ [market?.decimalPlaces]
);
return (
-
+
{depthData && (
= {};
-
-const update: Update<
- MarketDepth_market,
- MarketDepthSubscription_marketDepthUpdate
-> = (data, delta, reload) => {
- if (delta.market.id !== data.id) {
- return data;
- }
- const sequenceNumber = Number(delta.sequenceNumber);
- if (sequenceNumber <= sequenceNumbers[delta.market.id]) {
- return data;
- }
- /*
- if (sequenceNumber - 1 !== sequenceNumbers[delta.market.id]) {
- sequenceNumbers[delta.market.id] = 0;
- reload();
- return;
- }
- */
- sequenceNumbers[delta.market.id] = sequenceNumber;
- const updatedData = {
- ...data,
- data: delta.market.data,
- depth: { ...data.depth },
- };
- if (delta.buy) {
- updatedData.depth.buy = updateLevels(data.depth.buy ?? [], delta.buy);
- }
- if (delta.sell) {
- updatedData.depth.sell = updateLevels(data.depth.sell ?? [], delta.sell);
- }
- return updatedData;
-};
-
-const getData = (responseData: MarketDepth) => {
- if (responseData.market?.id) {
- sequenceNumbers[responseData.market.id] = Number(
- responseData.market.depth.sequenceNumber
- );
- }
- return responseData.market;
-};
-const getDelta = (subscriptionData: MarketDepthSubscription) =>
- subscriptionData.marketDepthUpdate;
-
-export const marketDepthDataProvider = makeDataProvider({
- query: MARKET_DEPTH_QUERY,
- subscriptionQuery: MARKET_DEPTH_SUBSCRIPTION_QUERY,
- update,
- getData,
- getDelta,
-});
-
-export default marketDepthDataProvider;
diff --git a/libs/market-depth/src/lib/market-depth-provider.ts b/libs/market-depth/src/lib/market-depth-provider.ts
new file mode 100644
index 000000000..2a5c1dcee
--- /dev/null
+++ b/libs/market-depth/src/lib/market-depth-provider.ts
@@ -0,0 +1,111 @@
+import { gql } from '@apollo/client';
+import { makeDataProvider } from '@vegaprotocol/react-helpers';
+import { updateLevels } from './orderbook-data';
+import type { Update } from '@vegaprotocol/react-helpers';
+import type {
+ MarketDepth,
+ MarketDepth_market,
+} from './__generated__/MarketDepth';
+import type {
+ MarketDepthSubscription,
+ MarketDepthSubscription_marketsDepthUpdate,
+} from './__generated__/MarketDepthSubscription';
+
+const MARKET_DEPTH_QUERY = gql`
+ query MarketDepth($marketId: ID!) {
+ market(id: $marketId) {
+ id
+ depth {
+ sell {
+ price
+ volume
+ numberOfOrders
+ }
+ buy {
+ price
+ volume
+ numberOfOrders
+ }
+ sequenceNumber
+ }
+ }
+ }
+`;
+
+export const MARKET_DEPTH_SUBSCRIPTION_QUERY = gql`
+ subscription MarketDepthSubscription($marketId: ID!) {
+ marketsDepthUpdate(marketIds: [$marketId]) {
+ marketId
+ sell {
+ price
+ volume
+ numberOfOrders
+ }
+ buy {
+ price
+ volume
+ numberOfOrders
+ }
+ sequenceNumber
+ previousSequenceNumber
+ }
+ }
+`;
+
+const sequenceNumbers: Record = {};
+
+const update: Update<
+ MarketDepth_market,
+ MarketDepthSubscription_marketsDepthUpdate[]
+> = (data, deltas, reload) => {
+ for (const delta of deltas) {
+ if (delta.marketId !== data.id) {
+ continue;
+ }
+ const sequenceNumber = Number(delta.sequenceNumber);
+ if (sequenceNumber <= sequenceNumbers[delta.marketId]) {
+ return data;
+ }
+ /*
+ if (sequenceNumber - 1 !== sequenceNumbers[delta.market.id]) {
+ sequenceNumbers[delta.market.id] = 0;
+ reload();
+ return;
+ }
+ */
+ sequenceNumbers[delta.marketId] = sequenceNumber;
+ const updatedData = {
+ ...data,
+ depth: { ...data.depth },
+ };
+ if (delta.buy) {
+ updatedData.depth.buy = updateLevels(data.depth.buy ?? [], delta.buy);
+ }
+ if (delta.sell) {
+ updatedData.depth.sell = updateLevels(data.depth.sell ?? [], delta.sell);
+ }
+ return updatedData;
+ }
+ return data;
+};
+
+const getData = (responseData: MarketDepth) => {
+ if (responseData.market?.id) {
+ sequenceNumbers[responseData.market.id] = Number(
+ responseData.market.depth.sequenceNumber
+ );
+ }
+ return responseData.market;
+};
+const getDelta = (subscriptionData: MarketDepthSubscription) =>
+ subscriptionData.marketsDepthUpdate;
+
+export const marketDepthProvider = makeDataProvider({
+ query: MARKET_DEPTH_QUERY,
+ subscriptionQuery: MARKET_DEPTH_SUBSCRIPTION_QUERY,
+ update,
+ getData,
+ getDelta,
+});
+
+export default marketDepthProvider;
diff --git a/libs/market-depth/src/lib/orderbook-data.ts b/libs/market-depth/src/lib/orderbook-data.ts
index fa515a464..1bb1341e3 100644
--- a/libs/market-depth/src/lib/orderbook-data.ts
+++ b/libs/market-depth/src/lib/orderbook-data.ts
@@ -1,15 +1,14 @@
import groupBy from 'lodash/groupBy';
import { VolumeType } from '@vegaprotocol/react-helpers';
import { MarketTradingMode } from '@vegaprotocol/types';
+import type { MarketData } from '@vegaprotocol/market-list';
import type {
MarketDepth_market_depth_sell,
MarketDepth_market_depth_buy,
- MarketDepth_market_data,
} from './__generated__/MarketDepth';
import type {
- MarketDepthSubscription_marketDepthUpdate_sell,
- MarketDepthSubscription_marketDepthUpdate_buy,
- MarketDepthSubscription_marketDepthUpdate_market_data,
+ MarketDepthSubscription_marketsDepthUpdate_sell,
+ MarketDepthSubscription_marketsDepthUpdate_buy,
} from './__generated__/MarketDepthSubscription';
export interface CumulativeVol {
@@ -33,7 +32,7 @@ export interface OrderbookRowData {
type PartialOrderbookRowData = Pick;
export type OrderbookData = Partial<
- Omit
+ Omit
> & { rows: OrderbookRowData[] | null };
export const getPriceLevel = (price: string | bigint, resolution: number) => {
@@ -105,11 +104,13 @@ export const createRow = (
const mapRawData =
(dataType: VolumeType.ask | VolumeType.bid) =>
(
- data:
+ data: Omit<
| MarketDepth_market_depth_sell
- | MarketDepthSubscription_marketDepthUpdate_sell
+ | MarketDepthSubscription_marketsDepthUpdate_sell
| MarketDepth_market_depth_buy
- | MarketDepthSubscription_marketDepthUpdate_buy
+ | MarketDepthSubscription_marketsDepthUpdate_buy,
+ '__typename'
+ >
): PartialOrderbookRowData =>
createPartialRow(data.price, Number(data.volume), dataType);
@@ -118,16 +119,18 @@ const mapRawData =
*/
export const compactRows = (
sell:
- | (
+ | Omit<
| MarketDepth_market_depth_sell
- | MarketDepthSubscription_marketDepthUpdate_sell
- )[]
+ | MarketDepthSubscription_marketsDepthUpdate_sell,
+ '__typename'
+ >[]
| null,
buy:
- | (
+ | Omit<
| MarketDepth_market_depth_buy
- | MarketDepthSubscription_marketDepthUpdate_buy
- )[]
+ | MarketDepthSubscription_marketsDepthUpdate_buy,
+ '__typename'
+ >[]
| null,
resolution: number
) => {
@@ -199,8 +202,8 @@ const partiallyUpdateCompactedRows = (
dataType: VolumeType,
data: OrderbookRowData[],
delta:
- | MarketDepthSubscription_marketDepthUpdate_sell
- | MarketDepthSubscription_marketDepthUpdate_buy,
+ | MarketDepthSubscription_marketsDepthUpdate_sell
+ | MarketDepthSubscription_marketsDepthUpdate_buy,
resolution: number,
modifiedIndex: number
): [number, OrderbookRowData[]] => {
@@ -255,8 +258,8 @@ const partiallyUpdateCompactedRows = (
*/
export const updateCompactedRows = (
rows: OrderbookRowData[],
- sell: MarketDepthSubscription_marketDepthUpdate_sell[] | null,
- buy: MarketDepthSubscription_marketDepthUpdate_buy[] | null,
+ sell: MarketDepthSubscription_marketsDepthUpdate_sell[] | null,
+ buy: MarketDepthSubscription_marketsDepthUpdate_buy[] | null,
resolution: number
) => {
let sellModifiedIndex = -1;
@@ -320,10 +323,13 @@ export const updateCompactedRows = (
};
export const mapMarketData = (
- data:
- | MarketDepth_market_data
- | MarketDepthSubscription_marketDepthUpdate_market_data
- | null,
+ data: Pick<
+ MarketData,
+ | 'staticMidPrice'
+ | 'bestStaticBidPrice'
+ | 'bestStaticOfferPrice'
+ | 'indicativePrice'
+ > | null,
resolution: number
) => ({
staticMidPrice:
@@ -347,8 +353,8 @@ export const mapMarketData = (
export const updateLevels = (
draft: (MarketDepth_market_depth_buy | MarketDepth_market_depth_sell)[],
updates: (
- | MarketDepthSubscription_marketDepthUpdate_buy
- | MarketDepthSubscription_marketDepthUpdate_sell
+ | MarketDepthSubscription_marketsDepthUpdate_buy
+ | MarketDepthSubscription_marketsDepthUpdate_sell
)[]
) => {
const levels = [...draft];
@@ -399,41 +405,37 @@ export const generateMockData = ({
}: MockDataGeneratorParams) => {
let matrix = new Array(numberOfSellRows).fill(undefined);
let price = midPrice + (numberOfSellRows - Math.ceil(overlap / 2) + 1);
- const sell: MarketDepth_market_depth_sell[] = matrix.map((row, i) => ({
- __typename: 'PriceLevel',
- price: (price -= 1).toString(),
- volume: (numberOfSellRows - i + 1).toString(),
- numberOfOrders: '',
- }));
+ const sell: Omit[] = matrix.map(
+ (row, i) => ({
+ price: (price -= 1).toString(),
+ volume: (numberOfSellRows - i + 1).toString(),
+ numberOfOrders: '',
+ })
+ );
price += overlap;
matrix = new Array(numberOfBuyRows).fill(undefined);
- const buy: MarketDepth_market_depth_buy[] = matrix.map((row, i) => ({
- __typename: 'PriceLevel',
- price: (price -= 1).toString(),
- volume: (i + 2).toString(),
- numberOfOrders: '',
- }));
+ const buy: Omit[] = matrix.map(
+ (row, i) => ({
+ price: (price -= 1).toString(),
+ volume: (i + 2).toString(),
+ numberOfOrders: '',
+ })
+ );
const rows = compactRows(sell, buy, resolution);
return {
rows,
resolution,
indicativeVolume: indicativeVolume?.toString(),
+ marketTradingMode:
+ overlap > 0
+ ? MarketTradingMode.TRADING_MODE_BATCH_AUCTION
+ : MarketTradingMode.TRADING_MODE_CONTINUOUS,
...mapMarketData(
{
- __typename: 'MarketData',
staticMidPrice: '',
- marketTradingMode:
- overlap > 0
- ? MarketTradingMode.TRADING_MODE_BATCH_AUCTION
- : MarketTradingMode.TRADING_MODE_CONTINUOUS,
bestStaticBidPrice: bestStaticBidPrice.toString(),
bestStaticOfferPrice: bestStaticOfferPrice.toString(),
indicativePrice: indicativePrice?.toString() ?? '',
- indicativeVolume: indicativeVolume?.toString() ?? '',
- market: {
- __typename: 'Market',
- id: '',
- },
},
resolution
),
diff --git a/libs/market-depth/src/lib/orderbook-manager.tsx b/libs/market-depth/src/lib/orderbook-manager.tsx
index 0772401cd..e43bd559c 100644
--- a/libs/market-depth/src/lib/orderbook-manager.tsx
+++ b/libs/market-depth/src/lib/orderbook-manager.tsx
@@ -2,9 +2,15 @@ import throttle from 'lodash/throttle';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { Orderbook } from './orderbook';
import { useDataProvider } from '@vegaprotocol/react-helpers';
-import dataProvider from './market-depth-data-provider';
+import marketDepthProvider from './market-depth-provider';
+import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
+import type { MarketData } from '@vegaprotocol/market-list';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import type { MarketDepthSubscription_marketDepthUpdate } from './__generated__/MarketDepthSubscription';
+import type {
+ MarketDepthSubscription_marketsDepthUpdate,
+ MarketDepthSubscription_marketsDepthUpdate_sell,
+ MarketDepthSubscription_marketsDepthUpdate_buy,
+} from './__generated__/MarketDepthSubscription';
import {
compactRows,
updateCompactedRows,
@@ -24,82 +30,116 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
rows: null,
});
const dataRef = useRef({ rows: null });
- const deltaRef = useRef();
+ const marketDataRef = useRef(null);
+ const deltaRef = useRef<{
+ sell: MarketDepthSubscription_marketsDepthUpdate_sell[];
+ buy: MarketDepthSubscription_marketsDepthUpdate_buy[];
+ }>({
+ sell: [],
+ buy: [],
+ });
const updateOrderbookData = useRef(
throttle(() => {
- if (!deltaRef.current) {
- return;
- }
dataRef.current = {
- ...deltaRef.current.market.data,
- ...mapMarketData(deltaRef.current.market.data, resolutionRef.current),
- rows: updateCompactedRows(
- dataRef.current.rows ?? [],
- deltaRef.current.sell,
- deltaRef.current.buy,
- resolutionRef.current
- ),
+ ...marketDataRef.current,
+ ...mapMarketData(marketDataRef.current, resolutionRef.current),
+ rows:
+ deltaRef.current.buy.length || deltaRef.current.sell.length
+ ? updateCompactedRows(
+ dataRef.current.rows ?? [],
+ deltaRef.current.sell,
+ deltaRef.current.buy,
+ resolutionRef.current
+ )
+ : dataRef.current.rows,
};
- deltaRef.current = undefined;
+ deltaRef.current.buy = [];
+ deltaRef.current.sell = [];
setOrderbookData(dataRef.current);
}, 1000)
);
const update = useCallback(
- ({ delta }: { delta: MarketDepthSubscription_marketDepthUpdate }) => {
+ ({
+ delta: deltas,
+ }: {
+ delta: MarketDepthSubscription_marketsDepthUpdate[];
+ }) => {
if (!dataRef.current.rows) {
return false;
}
- if (deltaRef.current) {
- deltaRef.current.market = delta.market;
+ for (const delta of deltas) {
+ if (delta.marketId !== marketId) {
+ continue;
+ }
if (delta.sell) {
- if (deltaRef.current.sell) {
- deltaRef.current.sell.push(...delta.sell);
- } else {
- deltaRef.current.sell = delta.sell;
- }
+ deltaRef.current.sell.push(...delta.sell);
}
if (delta.buy) {
- if (deltaRef.current.buy) {
- deltaRef.current.buy.push(...delta.buy);
- } else {
- deltaRef.current.buy = delta.buy;
- }
+ deltaRef.current.buy.push(...delta.buy);
}
- } else {
- deltaRef.current = delta;
+ updateOrderbookData.current();
}
- updateOrderbookData.current();
return true;
},
- // using resolutionRef.current to avoid using resolution as a dependency - it will cause data provider restart on resolution change
- []
+ [marketId, updateOrderbookData]
);
const { data, error, loading, flush } = useDataProvider({
- dataProvider,
+ dataProvider: marketDepthProvider,
update,
variables,
});
+ const {
+ data: market,
+ error: marketError,
+ loading: marketLoading,
+ } = useDataProvider({
+ dataProvider: marketProvider,
+ noUpdate: true,
+ variables,
+ });
+
+ const marketDataUpdate = useCallback(({ data }: { data: MarketData }) => {
+ marketDataRef.current = data;
+ updateOrderbookData.current();
+ return true;
+ }, []);
+
+ const {
+ data: marketData,
+ error: marketDataError,
+ loading: marketDataLoading,
+ } = useDataProvider({
+ dataProvider: marketDataProvider,
+ update: marketDataUpdate,
+ variables,
+ });
+
+ marketDataRef.current = marketData;
+
useEffect(() => {
const throttleRunnner = updateOrderbookData.current;
+ if (!marketDataRef.current) {
+ return;
+ }
if (!data) {
dataRef.current = { rows: null };
setOrderbookData(dataRef.current);
return;
}
dataRef.current = {
- ...data.data,
+ ...marketDataRef.current,
+ ...mapMarketData(marketDataRef.current, resolution),
rows: compactRows(data.depth.sell, data.depth.buy, resolution),
- ...mapMarketData(data.data, resolution),
};
setOrderbookData(dataRef.current);
return () => {
throttleRunnner.cancel();
};
- }, [data, resolution]);
+ }, [data, marketData, resolution]);
useEffect(() => {
resolutionRef.current = resolution;
@@ -107,11 +147,15 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
}, [resolution, flush]);
return (
-
+
setResolution(resolution)}
/>
diff --git a/libs/market-depth/src/lib/use-orderbook-data.ts b/libs/market-depth/src/lib/use-orderbook-data.ts
index ace259830..c4a007f59 100644
--- a/libs/market-depth/src/lib/use-orderbook-data.ts
+++ b/libs/market-depth/src/lib/use-orderbook-data.ts
@@ -1,8 +1,8 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import throttle from 'lodash/throttle';
import { useDataProvider } from '@vegaprotocol/react-helpers';
-import dataProvider from './market-depth-data-provider';
-import type { MarketDepth_market } from './';
+import dataProvider from './market-depth-provider';
+import type { MarketDepth_market } from './__generated__/MarketDepth';
interface Props {
variables: { marketId: string };
diff --git a/libs/market-list/src/lib/MarketData.graphql b/libs/market-list/src/lib/MarketData.graphql
deleted file mode 100644
index 5bc5f9906..000000000
--- a/libs/market-list/src/lib/MarketData.graphql
+++ /dev/null
@@ -1,75 +0,0 @@
-fragment MarketDataFields on MarketData {
- market {
- id
- state
- tradingMode
- }
- bestBidPrice
- bestOfferPrice
- markPrice
- trigger
- indicativeVolume
-}
-
-query MarketList($interval: Interval!, $since: String!) {
- markets {
- id
- name
- decimalPlaces
- positionDecimalPlaces
- state
- tradingMode
- fees {
- factors {
- makerFee
- infrastructureFee
- liquidityFee
- }
- }
- data {
- market {
- id
- state
- tradingMode
- }
- bestBidPrice
- bestOfferPrice
- markPrice
- trigger
- indicativeVolume
- }
- tradableInstrument {
- instrument {
- id
- name
- code
- metadata {
- tags
- }
- product {
- ... on Future {
- settlementAsset {
- symbol
- }
- }
- }
- }
- }
- marketTimestamps {
- open
- close
- }
- candles(interval: $interval, since: $since) {
- open
- close
- high
- low
- }
- }
-}
-
-subscription MarketDataSub {
- marketData {
- ...MarketDataFields
- }
-}
diff --git a/libs/market-list/src/lib/__generated__/MarketCandlesQuery.ts b/libs/market-list/src/lib/__generated__/MarketCandlesQuery.ts
new file mode 100644
index 000000000..070d3e591
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketCandlesQuery.ts
@@ -0,0 +1,78 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { Interval } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL query operation: MarketCandlesQuery
+// ====================================================
+
+export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node {
+ __typename: "CandleNode";
+ /**
+ * High price (uint64)
+ */
+ high: string;
+ /**
+ * Low price (uint64)
+ */
+ low: string;
+ /**
+ * Open price (uint64)
+ */
+ open: string;
+ /**
+ * Close price (uint64)
+ */
+ close: string;
+ /**
+ * Volume price (uint64)
+ */
+ volume: string;
+}
+
+export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges {
+ __typename: "CandleEdge";
+ node: MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
+}
+
+export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection {
+ __typename: "CandleDataConnection";
+ /**
+ * The candles
+ */
+ edges: (MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges | null)[] | null;
+}
+
+export interface MarketCandlesQuery_marketsConnection_edges_node {
+ __typename: "Market";
+ /**
+ * Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters using cursor based pagination
+ */
+ candlesConnection: MarketCandlesQuery_marketsConnection_edges_node_candlesConnection;
+}
+
+export interface MarketCandlesQuery_marketsConnection_edges {
+ __typename: "MarketEdge";
+ node: MarketCandlesQuery_marketsConnection_edges_node;
+}
+
+export interface MarketCandlesQuery_marketsConnection {
+ __typename: "MarketConnection";
+ /**
+ * The markets in this connection
+ */
+ edges: MarketCandlesQuery_marketsConnection_edges[];
+}
+
+export interface MarketCandlesQuery {
+ marketsConnection: MarketCandlesQuery_marketsConnection;
+}
+
+export interface MarketCandlesQueryVariables {
+ interval: Interval;
+ since: string;
+ marketId: string;
+}
diff --git a/libs/market-list/src/lib/__generated__/MarketCandlesSub.ts b/libs/market-list/src/lib/__generated__/MarketCandlesSub.ts
new file mode 100644
index 000000000..c5a5a4738
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketCandlesSub.ts
@@ -0,0 +1,46 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { Interval } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL subscription operation: MarketCandlesSub
+// ====================================================
+
+export interface MarketCandlesSub_candles {
+ __typename: "Candle";
+ /**
+ * High price (uint64)
+ */
+ high: string;
+ /**
+ * Low price (uint64)
+ */
+ low: string;
+ /**
+ * Open price (uint64)
+ */
+ open: string;
+ /**
+ * Close price (uint64)
+ */
+ close: string;
+ /**
+ * Volume price (uint64)
+ */
+ volume: string;
+}
+
+export interface MarketCandlesSub {
+ /**
+ * Subscribe to the candles updates
+ */
+ candles: MarketCandlesSub_candles;
+}
+
+export interface MarketCandlesSubVariables {
+ marketId: string;
+ interval: Interval;
+}
diff --git a/libs/market-list/src/lib/__generated__/MarketDataFields.ts b/libs/market-list/src/lib/__generated__/MarketDataFields.ts
index 44cdd10ac..d31d4b3c2 100644
--- a/libs/market-list/src/lib/__generated__/MarketDataFields.ts
+++ b/libs/market-list/src/lib/__generated__/MarketDataFields.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
+import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
// ====================================================
// GraphQL fragment: MarketDataFields
@@ -15,20 +15,12 @@ export interface MarketDataFields_market {
* Market ID
*/
id: string;
- /**
- * Current state of the market
- */
- state: MarketState;
- /**
- * Current mode of execution of the market
- */
- tradingMode: MarketTradingMode;
}
export interface MarketDataFields {
__typename: "MarketData";
/**
- * market ID of the associated mark price
+ * market of the associated mark price
*/
market: MarketDataFields_market;
/**
@@ -47,8 +39,28 @@ export interface MarketDataFields {
* what triggered an auction (if an auction was started)
*/
trigger: AuctionTrigger;
+ /**
+ * the arithmetic average of the best static bid price and best static offer price
+ */
+ staticMidPrice: string;
+ /**
+ * what state the market is in (auction, continuous, etc)
+ */
+ marketTradingMode: MarketTradingMode;
/**
* indicative volume if the auction ended now, 0 if not in auction mode
*/
indicativeVolume: string;
+ /**
+ * indicative price if the auction ended now, 0 if not in auction mode
+ */
+ indicativePrice: string;
+ /**
+ * the highest price level on an order book for buy orders not including pegged orders.
+ */
+ bestStaticBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders not including pegged orders.
+ */
+ bestStaticOfferPrice: string;
}
diff --git a/libs/market-list/src/lib/__generated__/MarketDataQuery.ts b/libs/market-list/src/lib/__generated__/MarketDataQuery.ts
new file mode 100644
index 000000000..67b13d022
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketDataQuery.ts
@@ -0,0 +1,95 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL query operation: MarketDataQuery
+// ====================================================
+
+export interface MarketDataQuery_marketsConnection_edges_node_data_market {
+ __typename: "Market";
+ /**
+ * Market ID
+ */
+ id: string;
+}
+
+export interface MarketDataQuery_marketsConnection_edges_node_data {
+ __typename: "MarketData";
+ /**
+ * market of the associated mark price
+ */
+ market: MarketDataQuery_marketsConnection_edges_node_data_market;
+ /**
+ * the highest price level on an order book for buy orders.
+ */
+ bestBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders.
+ */
+ bestOfferPrice: string;
+ /**
+ * the mark price (an unsigned integer)
+ */
+ markPrice: string;
+ /**
+ * what triggered an auction (if an auction was started)
+ */
+ trigger: AuctionTrigger;
+ /**
+ * the arithmetic average of the best static bid price and best static offer price
+ */
+ staticMidPrice: string;
+ /**
+ * what state the market is in (auction, continuous, etc)
+ */
+ marketTradingMode: MarketTradingMode;
+ /**
+ * indicative volume if the auction ended now, 0 if not in auction mode
+ */
+ indicativeVolume: string;
+ /**
+ * indicative price if the auction ended now, 0 if not in auction mode
+ */
+ indicativePrice: string;
+ /**
+ * the highest price level on an order book for buy orders not including pegged orders.
+ */
+ bestStaticBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders not including pegged orders.
+ */
+ bestStaticOfferPrice: string;
+}
+
+export interface MarketDataQuery_marketsConnection_edges_node {
+ __typename: "Market";
+ /**
+ * marketData for the given market
+ */
+ data: MarketDataQuery_marketsConnection_edges_node_data | null;
+}
+
+export interface MarketDataQuery_marketsConnection_edges {
+ __typename: "MarketEdge";
+ node: MarketDataQuery_marketsConnection_edges_node;
+}
+
+export interface MarketDataQuery_marketsConnection {
+ __typename: "MarketConnection";
+ /**
+ * The markets in this connection
+ */
+ edges: MarketDataQuery_marketsConnection_edges[];
+}
+
+export interface MarketDataQuery {
+ marketsConnection: MarketDataQuery_marketsConnection;
+}
+
+export interface MarketDataQueryVariables {
+ id: string;
+}
diff --git a/libs/market-list/src/lib/__generated__/MarketDataSub.ts b/libs/market-list/src/lib/__generated__/MarketDataSub.ts
index c77181ea3..bb78f4ae2 100644
--- a/libs/market-list/src/lib/__generated__/MarketDataSub.ts
+++ b/libs/market-list/src/lib/__generated__/MarketDataSub.ts
@@ -3,34 +3,18 @@
// @generated
// This file was automatically generated and should not be edited.
-import { MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
+import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
// ====================================================
// GraphQL subscription operation: MarketDataSub
// ====================================================
-export interface MarketDataSub_marketData_market {
- __typename: "Market";
- /**
- * Market ID
- */
- id: string;
- /**
- * Current state of the market
- */
- state: MarketState;
- /**
- * Current mode of execution of the market
- */
- tradingMode: MarketTradingMode;
-}
-
-export interface MarketDataSub_marketData {
- __typename: "MarketData";
+export interface MarketDataSub_marketsData {
+ __typename: "ObservableMarketData";
/**
* market ID of the associated mark price
*/
- market: MarketDataSub_marketData_market;
+ marketId: string;
/**
* the highest price level on an order book for buy orders.
*/
@@ -47,15 +31,39 @@ export interface MarketDataSub_marketData {
* what triggered an auction (if an auction was started)
*/
trigger: AuctionTrigger;
+ /**
+ * the arithmetic average of the best static bid price and best static offer price
+ */
+ staticMidPrice: string;
+ /**
+ * what state the market is in (auction, continuous etc)
+ */
+ marketTradingMode: MarketTradingMode;
/**
* indicative volume if the auction ended now, 0 if not in auction mode
*/
indicativeVolume: string;
+ /**
+ * indicative price if the auction ended now, 0 if not in auction mode
+ */
+ indicativePrice: string;
+ /**
+ * the highest price level on an order book for buy orders not including pegged orders.
+ */
+ bestStaticBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders not including pegged orders
+ */
+ bestStaticOfferPrice: string;
}
export interface MarketDataSub {
/**
* Subscribe to the mark price changes
*/
- marketData: MarketDataSub_marketData;
+ marketsData: MarketDataSub_marketsData[];
+}
+
+export interface MarketDataSubVariables {
+ id: string;
}
diff --git a/libs/market-list/src/lib/__generated__/MarketFields.ts b/libs/market-list/src/lib/__generated__/MarketFields.ts
new file mode 100644
index 000000000..29c9cca7e
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketFields.ts
@@ -0,0 +1,154 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL fragment: MarketFields
+// ====================================================
+
+export interface MarketFields_fees_factors {
+ __typename: "FeeFactors";
+ /**
+ * The factor applied to calculate MakerFees, a non-negative float
+ */
+ makerFee: string;
+ /**
+ * The factor applied to calculate InfrastructureFees, a non-negative float
+ */
+ infrastructureFee: string;
+ /**
+ * The factor applied to calculate LiquidityFees, a non-negative float
+ */
+ liquidityFee: string;
+}
+
+export interface MarketFields_fees {
+ __typename: "Fees";
+ /**
+ * The factors used to calculate the different fees
+ */
+ factors: MarketFields_fees_factors;
+}
+
+export interface MarketFields_tradableInstrument_instrument_metadata {
+ __typename: "InstrumentMetadata";
+ /**
+ * An arbitrary list of tags to associated to associate to the Instrument (string list)
+ */
+ tags: string[] | null;
+}
+
+export interface MarketFields_tradableInstrument_instrument_product_settlementAsset {
+ __typename: "Asset";
+ /**
+ * The symbol of the asset (e.g: GBP)
+ */
+ symbol: string;
+}
+
+export interface MarketFields_tradableInstrument_instrument_product {
+ __typename: "Future";
+ /**
+ * The name of the asset (string)
+ */
+ settlementAsset: MarketFields_tradableInstrument_instrument_product_settlementAsset;
+}
+
+export interface MarketFields_tradableInstrument_instrument {
+ __typename: "Instrument";
+ /**
+ * Uniquely identify an instrument across all instruments available on Vega (string)
+ */
+ id: string;
+ /**
+ * Full and fairly descriptive name for the instrument
+ */
+ name: string;
+ /**
+ * A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string)
+ */
+ code: string;
+ /**
+ * Metadata for this instrument
+ */
+ metadata: MarketFields_tradableInstrument_instrument_metadata;
+ /**
+ * A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
+ */
+ product: MarketFields_tradableInstrument_instrument_product;
+}
+
+export interface MarketFields_tradableInstrument {
+ __typename: "TradableInstrument";
+ /**
+ * An instance of, or reference to, a fully specified instrument.
+ */
+ instrument: MarketFields_tradableInstrument_instrument;
+}
+
+export interface MarketFields_marketTimestamps {
+ __typename: "MarketTimestamps";
+ /**
+ * Time when the market is open and ready to accept trades
+ */
+ open: string | null;
+ /**
+ * Time when the market is closed
+ */
+ close: string | null;
+}
+
+export interface MarketFields {
+ __typename: "Market";
+ /**
+ * Market ID
+ */
+ id: string;
+ /**
+ * decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
+ * number denominated in the currency of the market. (uint64)
+ *
+ * Examples:
+ * Currency Balance decimalPlaces Real Balance
+ * GBP 100 0 GBP 100
+ * GBP 100 2 GBP 1.00
+ * GBP 100 4 GBP 0.01
+ * GBP 1 4 GBP 0.0001 ( 0.01p )
+ *
+ * GBX (pence) 100 0 GBP 1.00 (100p )
+ * GBX (pence) 100 2 GBP 0.01 ( 1p )
+ * GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
+ * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
+ */
+ decimalPlaces: number;
+ /**
+ * positionDecimalPlaces indicates 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.
+ * 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
+ * This sets how big the smallest order / position on the market can be.
+ */
+ positionDecimalPlaces: number;
+ /**
+ * Current state of the market
+ */
+ state: MarketState;
+ /**
+ * Current mode of execution of the market
+ */
+ tradingMode: MarketTradingMode;
+ /**
+ * Fees related data
+ */
+ fees: MarketFields_fees;
+ /**
+ * An instance of, or reference to, a tradable instrument.
+ */
+ tradableInstrument: MarketFields_tradableInstrument;
+ /**
+ * timestamps for state changes in the market
+ */
+ marketTimestamps: MarketFields_marketTimestamps;
+}
diff --git a/libs/market-list/src/lib/__generated__/MarketList.ts b/libs/market-list/src/lib/__generated__/Markets.ts
similarity index 55%
rename from libs/market-list/src/lib/__generated__/MarketList.ts
rename to libs/market-list/src/lib/__generated__/Markets.ts
index f147b3498..c155703fa 100644
--- a/libs/market-list/src/lib/__generated__/MarketList.ts
+++ b/libs/market-list/src/lib/__generated__/Markets.ts
@@ -3,13 +3,13 @@
// @generated
// This file was automatically generated and should not be edited.
-import { Interval, MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
+import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
// ====================================================
-// GraphQL query operation: MarketList
+// GraphQL query operation: Markets
// ====================================================
-export interface MarketList_markets_fees_factors {
+export interface Markets_marketsConnection_edges_node_fees_factors {
__typename: "FeeFactors";
/**
* The factor applied to calculate MakerFees, a non-negative float
@@ -25,59 +25,15 @@ export interface MarketList_markets_fees_factors {
liquidityFee: string;
}
-export interface MarketList_markets_fees {
+export interface Markets_marketsConnection_edges_node_fees {
__typename: "Fees";
/**
* The factors used to calculate the different fees
*/
- factors: MarketList_markets_fees_factors;
+ factors: Markets_marketsConnection_edges_node_fees_factors;
}
-export interface MarketList_markets_data_market {
- __typename: "Market";
- /**
- * Market ID
- */
- id: string;
- /**
- * Current state of the market
- */
- state: MarketState;
- /**
- * Current mode of execution of the market
- */
- tradingMode: MarketTradingMode;
-}
-
-export interface MarketList_markets_data {
- __typename: "MarketData";
- /**
- * market ID of the associated mark price
- */
- market: MarketList_markets_data_market;
- /**
- * the highest price level on an order book for buy orders.
- */
- bestBidPrice: string;
- /**
- * the lowest price level on an order book for offer orders.
- */
- bestOfferPrice: string;
- /**
- * the mark price (an unsigned integer)
- */
- markPrice: string;
- /**
- * what triggered an auction (if an auction was started)
- */
- trigger: AuctionTrigger;
- /**
- * indicative volume if the auction ended now, 0 if not in auction mode
- */
- indicativeVolume: string;
-}
-
-export interface MarketList_markets_tradableInstrument_instrument_metadata {
+export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_metadata {
__typename: "InstrumentMetadata";
/**
* An arbitrary list of tags to associated to associate to the Instrument (string list)
@@ -85,7 +41,7 @@ export interface MarketList_markets_tradableInstrument_instrument_metadata {
tags: string[] | null;
}
-export interface MarketList_markets_tradableInstrument_instrument_product_settlementAsset {
+export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_product_settlementAsset {
__typename: "Asset";
/**
* The symbol of the asset (e.g: GBP)
@@ -93,15 +49,15 @@ export interface MarketList_markets_tradableInstrument_instrument_product_settle
symbol: string;
}
-export interface MarketList_markets_tradableInstrument_instrument_product {
+export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_product {
__typename: "Future";
/**
* The name of the asset (string)
*/
- settlementAsset: MarketList_markets_tradableInstrument_instrument_product_settlementAsset;
+ settlementAsset: Markets_marketsConnection_edges_node_tradableInstrument_instrument_product_settlementAsset;
}
-export interface MarketList_markets_tradableInstrument_instrument {
+export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument {
__typename: "Instrument";
/**
* Uniquely identify an instrument across all instruments available on Vega (string)
@@ -118,22 +74,22 @@ export interface MarketList_markets_tradableInstrument_instrument {
/**
* Metadata for this instrument
*/
- metadata: MarketList_markets_tradableInstrument_instrument_metadata;
+ metadata: Markets_marketsConnection_edges_node_tradableInstrument_instrument_metadata;
/**
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
*/
- product: MarketList_markets_tradableInstrument_instrument_product;
+ product: Markets_marketsConnection_edges_node_tradableInstrument_instrument_product;
}
-export interface MarketList_markets_tradableInstrument {
+export interface Markets_marketsConnection_edges_node_tradableInstrument {
__typename: "TradableInstrument";
/**
* An instance of, or reference to, a fully specified instrument.
*/
- instrument: MarketList_markets_tradableInstrument_instrument;
+ instrument: Markets_marketsConnection_edges_node_tradableInstrument_instrument;
}
-export interface MarketList_markets_marketTimestamps {
+export interface Markets_marketsConnection_edges_node_marketTimestamps {
__typename: "MarketTimestamps";
/**
* Time when the market is open and ready to accept trades
@@ -145,27 +101,7 @@ export interface MarketList_markets_marketTimestamps {
close: string | null;
}
-export interface MarketList_markets_candles {
- __typename: "Candle";
- /**
- * Open price (uint64)
- */
- open: string;
- /**
- * Close price (uint64)
- */
- close: string;
- /**
- * High price (uint64)
- */
- high: string;
- /**
- * Low price (uint64)
- */
- low: string;
-}
-
-export interface MarketList_markets {
+export interface Markets_marketsConnection_edges_node {
__typename: "Market";
/**
* Market ID
@@ -206,33 +142,30 @@ export interface MarketList_markets {
/**
* Fees related data
*/
- fees: MarketList_markets_fees;
- /**
- * marketData for the given market
- */
- data: MarketList_markets_data | null;
+ fees: Markets_marketsConnection_edges_node_fees;
/**
* An instance of, or reference to, a tradable instrument.
*/
- tradableInstrument: MarketList_markets_tradableInstrument;
+ tradableInstrument: Markets_marketsConnection_edges_node_tradableInstrument;
/**
* timestamps for state changes in the market
*/
- marketTimestamps: MarketList_markets_marketTimestamps;
- /**
- * Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters
- */
- candles: (MarketList_markets_candles | null)[] | null;
+ marketTimestamps: Markets_marketsConnection_edges_node_marketTimestamps;
}
-export interface MarketList {
- /**
- * One or more instruments that are trading on the VEGA network
- */
- markets: MarketList_markets[] | null;
+export interface Markets_marketsConnection_edges {
+ __typename: "MarketEdge";
+ node: Markets_marketsConnection_edges_node;
}
-export interface MarketListVariables {
- interval: Interval;
- since: string;
+export interface Markets_marketsConnection {
+ __typename: "MarketConnection";
+ /**
+ * The markets in this connection
+ */
+ edges: Markets_marketsConnection_edges[];
+}
+
+export interface Markets {
+ marketsConnection: Markets_marketsConnection;
}
diff --git a/libs/market-list/src/lib/__generated__/MarketsCandlesQuery.ts b/libs/market-list/src/lib/__generated__/MarketsCandlesQuery.ts
new file mode 100644
index 000000000..03eb6cc86
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketsCandlesQuery.ts
@@ -0,0 +1,81 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { Interval } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL query operation: MarketsCandlesQuery
+// ====================================================
+
+export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node {
+ __typename: "CandleNode";
+ /**
+ * High price (uint64)
+ */
+ high: string;
+ /**
+ * Low price (uint64)
+ */
+ low: string;
+ /**
+ * Open price (uint64)
+ */
+ open: string;
+ /**
+ * Close price (uint64)
+ */
+ close: string;
+ /**
+ * Volume price (uint64)
+ */
+ volume: string;
+}
+
+export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges {
+ __typename: "CandleEdge";
+ node: MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
+}
+
+export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection {
+ __typename: "CandleDataConnection";
+ /**
+ * The candles
+ */
+ edges: (MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges | null)[] | null;
+}
+
+export interface MarketsCandlesQuery_marketsConnection_edges_node {
+ __typename: "Market";
+ /**
+ * Market ID
+ */
+ id: string;
+ /**
+ * Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters using cursor based pagination
+ */
+ candlesConnection: MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection;
+}
+
+export interface MarketsCandlesQuery_marketsConnection_edges {
+ __typename: "MarketEdge";
+ node: MarketsCandlesQuery_marketsConnection_edges_node;
+}
+
+export interface MarketsCandlesQuery_marketsConnection {
+ __typename: "MarketConnection";
+ /**
+ * The markets in this connection
+ */
+ edges: MarketsCandlesQuery_marketsConnection_edges[];
+}
+
+export interface MarketsCandlesQuery {
+ marketsConnection: MarketsCandlesQuery_marketsConnection;
+}
+
+export interface MarketsCandlesQueryVariables {
+ interval: Interval;
+ since: string;
+}
diff --git a/libs/market-list/src/lib/__generated__/MarketsDataQuery.ts b/libs/market-list/src/lib/__generated__/MarketsDataQuery.ts
new file mode 100644
index 000000000..8a69a3b44
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/MarketsDataQuery.ts
@@ -0,0 +1,91 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
+
+// ====================================================
+// GraphQL query operation: MarketsDataQuery
+// ====================================================
+
+export interface MarketsDataQuery_marketsConnection_edges_node_data_market {
+ __typename: "Market";
+ /**
+ * Market ID
+ */
+ id: string;
+}
+
+export interface MarketsDataQuery_marketsConnection_edges_node_data {
+ __typename: "MarketData";
+ /**
+ * market of the associated mark price
+ */
+ market: MarketsDataQuery_marketsConnection_edges_node_data_market;
+ /**
+ * the highest price level on an order book for buy orders.
+ */
+ bestBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders.
+ */
+ bestOfferPrice: string;
+ /**
+ * the mark price (an unsigned integer)
+ */
+ markPrice: string;
+ /**
+ * what triggered an auction (if an auction was started)
+ */
+ trigger: AuctionTrigger;
+ /**
+ * the arithmetic average of the best static bid price and best static offer price
+ */
+ staticMidPrice: string;
+ /**
+ * what state the market is in (auction, continuous, etc)
+ */
+ marketTradingMode: MarketTradingMode;
+ /**
+ * indicative volume if the auction ended now, 0 if not in auction mode
+ */
+ indicativeVolume: string;
+ /**
+ * indicative price if the auction ended now, 0 if not in auction mode
+ */
+ indicativePrice: string;
+ /**
+ * the highest price level on an order book for buy orders not including pegged orders.
+ */
+ bestStaticBidPrice: string;
+ /**
+ * the lowest price level on an order book for offer orders not including pegged orders.
+ */
+ bestStaticOfferPrice: string;
+}
+
+export interface MarketsDataQuery_marketsConnection_edges_node {
+ __typename: "Market";
+ /**
+ * marketData for the given market
+ */
+ data: MarketsDataQuery_marketsConnection_edges_node_data | null;
+}
+
+export interface MarketsDataQuery_marketsConnection_edges {
+ __typename: "MarketEdge";
+ node: MarketsDataQuery_marketsConnection_edges_node;
+}
+
+export interface MarketsDataQuery_marketsConnection {
+ __typename: "MarketConnection";
+ /**
+ * The markets in this connection
+ */
+ edges: MarketsDataQuery_marketsConnection_edges[];
+}
+
+export interface MarketsDataQuery {
+ marketsConnection: MarketsDataQuery_marketsConnection;
+}
diff --git a/libs/market-list/src/lib/__generated__/index.ts b/libs/market-list/src/lib/__generated__/index.ts
new file mode 100644
index 000000000..c60e2b138
--- /dev/null
+++ b/libs/market-list/src/lib/__generated__/index.ts
@@ -0,0 +1,9 @@
+export * from './MarketCandlesQuery';
+export * from './MarketCandlesSub';
+export * from './MarketDataFields';
+export * from './MarketDataQuery';
+export * from './MarketDataSub';
+export * from './MarketFields';
+export * from './Markets';
+export * from './MarketsCandlesQuery';
+export * from './MarketsDataQuery';
diff --git a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx
index e19f2dfdd..9c44b0c92 100644
--- a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx
+++ b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx
@@ -22,7 +22,7 @@ import {
MarketTradingModeMapping,
AuctionTriggerMapping,
} from '@vegaprotocol/types';
-import type { MarketList_markets } from '../../';
+import type { MarketWithData } from '../../';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
type Props = AgGridReactProps | AgReactUiProps;
@@ -31,7 +31,7 @@ type MarketListTableValueFormatterParams = Omit<
ValueFormatterParams,
'data' | 'value'
> & {
- data: MarketList_markets;
+ data: MarketWithData;
};
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
@@ -83,17 +83,17 @@ export const MarketListTable = forwardRef((props, ref) => {
headerName={t('Trading mode')}
field="data"
minWidth={170}
- valueGetter={({ data }: { data?: MarketList_markets }) => {
+ valueGetter={({ data }: { data?: MarketWithData }) => {
if (!data?.data) return undefined;
- const { market, trigger } = data.data;
- return market &&
- market.tradingMode ===
- MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
+ const { trigger } = data.data;
+ const { tradingMode } = data;
+ return tradingMode ===
+ MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
trigger &&
trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
- ? `${MarketTradingModeMapping[market.tradingMode]}
+ ? `${MarketTradingModeMapping[tradingMode]}
- ${AuctionTriggerMapping[trigger]}`
- : MarketTradingModeMapping[market.tradingMode];
+ : MarketTradingModeMapping[tradingMode];
}}
/>
((props, ref) => {
type="rightAligned"
cellRenderer="PriceFlashCell"
filter="agNumberColumnFilter"
- valueGetter={({ data }: { data?: MarketList_markets }) => {
+ valueGetter={({ data }: { data?: MarketWithData }) => {
return data?.data?.bestBidPrice === undefined
? undefined
: toBigNum(data?.data?.bestBidPrice, data.decimalPlaces).toNumber();
@@ -122,7 +122,7 @@ export const MarketListTable = forwardRef((props, ref) => {
type="rightAligned"
cellRenderer="PriceFlashCell"
filter="agNumberColumnFilter"
- valueGetter={({ data }: { data?: MarketList_markets }) => {
+ valueGetter={({ data }: { data?: MarketWithData }) => {
return data?.data?.bestOfferPrice === undefined
? undefined
: toBigNum(
@@ -145,7 +145,7 @@ export const MarketListTable = forwardRef((props, ref) => {
type="rightAligned"
cellRenderer="PriceFlashCell"
filter="agNumberColumnFilter"
- valueGetter={({ data }: { data?: MarketList_markets }) => {
+ valueGetter={({ data }: { data?: MarketWithData }) => {
return data?.data?.markPrice === undefined
? undefined
: toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber();
diff --git a/libs/market-list/src/lib/components/markets-container/markets-container.tsx b/libs/market-list/src/lib/components/markets-container/markets-container.tsx
index 98c8e3508..bcbbdc9ab 100644
--- a/libs/market-list/src/lib/components/markets-container/markets-container.tsx
+++ b/libs/market-list/src/lib/components/markets-container/markets-container.tsx
@@ -1,89 +1,29 @@
-import { useRef, useCallback, useMemo } from 'react';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
-import { MarketListTable, getRowId } from './market-list-table';
+import { MarketListTable } from './market-list-table';
import { useDataProvider } from '@vegaprotocol/react-helpers';
-import type { AgGridReact } from 'ag-grid-react';
import type { RowClickedEvent } from 'ag-grid-community';
-import { produce } from 'immer';
-import merge from 'lodash/merge';
-import type {
- MarketList_markets,
- MarketList_markets_data,
- MarketDataSub_marketData,
-} from '../../';
-import { marketsDataProvider as dataProvider } from '../../markets-data-provider';
-import { Interval, MarketState } from '@vegaprotocol/types';
-
+import { marketsWithDataProvider as dataProvider } from '../../markets-provider';
+import type { MarketWithData } from '../../markets-provider';
interface MarketsContainerProps {
onSelect: (marketId: string) => void;
}
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
- const gridRef = useRef(null);
-
- const yTimestamp = useMemo(() => {
- const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
- return new Date(yesterday * 1000).toISOString();
- }, []);
- const variables = useMemo(
- () => ({ interval: Interval.INTERVAL_I1H, since: yTimestamp }),
- [yTimestamp]
- );
-
- const update = useCallback(
- ({ delta }: { delta: MarketDataSub_marketData }) => {
- const update: MarketList_markets[] = [];
- const add: MarketList_markets[] = [];
- const remove: MarketList_markets[] = [];
- if (!gridRef.current?.api) {
- return false;
- }
- const rowNode = gridRef.current.api.getRowNode(
- getRowId({ data: delta.market })
- );
- if (rowNode) {
- const updatedData = produce(
- rowNode.data.data,
- (draft: MarketList_markets) => merge(draft, delta)
- );
- if (updatedData !== rowNode.data.data) {
- update.push({ ...rowNode.data, data: updatedData });
- }
- }
- // @TODO - else add new market
- if (update.length || add.length || remove.length) {
- gridRef.current.api.applyTransactionAsync({
- update,
- add,
- addIndex: 0,
- });
- }
- return true;
- },
- [gridRef]
- );
-
- const { data, error, loading } = useDataProvider<
- MarketList_markets[],
- MarketList_markets_data
- >({ dataProvider, update, variables });
+ const { data, error, loading } = useDataProvider({
+ dataProvider,
+ noUpdate: true,
+ });
return (
m.data?.market.state !== MarketState.STATE_REJECTED
- )
- }
- ref={gridRef}
+ rowData={data}
onRowClicked={(rowEvent: RowClickedEvent) => {
const { data, event } = rowEvent;
// filters out clicks on the symbol column because it should display asset details
if ((event?.target as HTMLElement).tagName.toUpperCase() === 'BUTTON')
return;
- onSelect((data as MarketList_markets).id);
+ onSelect((data as MarketWithData).id);
}}
/>
diff --git a/libs/market-list/src/lib/components/select-market-columns.tsx b/libs/market-list/src/lib/components/select-market-columns.tsx
index 1db863775..130c0f2bb 100644
--- a/libs/market-list/src/lib/components/select-market-columns.tsx
+++ b/libs/market-list/src/lib/components/select-market-columns.tsx
@@ -3,6 +3,7 @@ import {
addDecimalsFormatNumber,
formatNumberPercentage,
PriceCell,
+ signedNumberCssClass,
t,
} from '@vegaprotocol/react-helpers';
import {
@@ -18,10 +19,7 @@ import Link from 'next/link';
import { calcCandleHigh, calcCandleLow, totalFees } from '../utils';
import type { CandleClose } from '@vegaprotocol/types';
-import type {
- MarketList_markets,
- MarketList_markets_fees_factors,
-} from '../__generated__/MarketList';
+import type { Market, MarketData, Candle } from '../';
import isNil from 'lodash/isNil';
export const cellClassNames = 'py-1 first:text-left text-right';
@@ -171,10 +169,12 @@ export const columnHeaders: Column[] = [
];
export const columns = (
- market: MarketList_markets,
+ market: Market,
+ marketData: MarketData | undefined,
+ candles: Candle[] | undefined,
onSelect: (id: string) => void
) => {
- const candlesClose = market.candles
+ const candlesClose = candles
?.map((candle) => candle?.close)
.filter((c: string | undefined): c is CandleClose => !isNil(c));
const handleKeyPress = (
@@ -185,8 +185,8 @@ export const columns = (
return onSelect(id);
}
};
- const candleLow = calcCandleLow(market);
- const candleHigh = calcCandleHigh(market);
+ const candleLow = candles && calcCandleLow(candles);
+ const candleHigh = candles && calcCandleHigh(candles);
const selectMarketColumns: Column[] = [
{
value: (
@@ -207,11 +207,11 @@ export const columns = (
onlyOnDetailed: false,
},
{
- value: market.data?.markPrice ? (
+ value: marketData?.markPrice ? (
void
+ market: Market,
+ marketData: MarketData | undefined,
+ candles: Candle[] | undefined,
+ onSelect: (id: string) => void,
+ openVolume?: string
) => {
- const candlesClose = market.candles
+ const candlesClose = candles
?.map((candle) => candle?.close)
.filter((c: string | undefined): c is CandleClose => !isNil(c));
- const candleLow = calcCandleLow(market);
- const candleHigh = calcCandleHigh(market);
+ const candleLow = candles && calcCandleLow(candles);
+ const candleHigh = candles && calcCandleHigh(candles);
const handleKeyPress = (
event: React.KeyboardEvent,
id: string
@@ -361,11 +364,11 @@ export const columnsPositionMarkets = (
onlyOnDetailed: false,
},
{
- value: market.data?.markPrice ? (
+ value: marketData?.markPrice ? (
- {market.openVolume}
-
+ {openVolume}
),
className: `${cellClassNames} hidden xxl:table-cell font-mono`,
onlyOnDetailed: true,
@@ -489,7 +482,7 @@ export const columnsPositionMarkets = (
const FeesCell = ({
feeFactors,
}: {
- feeFactors: MarketList_markets_fees_factors;
+ feeFactors: Market['fees']['factors'];
}) => (
}>
{totalFees(feeFactors) ?? '-'}
@@ -499,7 +492,7 @@ const FeesCell = ({
export const FeesBreakdown = ({
feeFactors,
}: {
- feeFactors?: MarketList_markets_fees_factors;
+ feeFactors?: Market['fees']['factors'];
}) => {
if (!feeFactors) return null;
return (
diff --git a/libs/market-list/src/lib/components/select-market.spec.tsx b/libs/market-list/src/lib/components/select-market.spec.tsx
index e467ce59b..15fabbe13 100644
--- a/libs/market-list/src/lib/components/select-market.spec.tsx
+++ b/libs/market-list/src/lib/components/select-market.spec.tsx
@@ -1,8 +1,10 @@
import { fireEvent, render, screen } from '@testing-library/react';
-import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
+import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
import type { ReactNode } from 'react';
-import type { MarketList_markets } from '../__generated__/MarketList';
+import type { MarketData } from '../market-data-provider';
+import type { MarketCandles } from '../markets-candles-provider';
+import type { Market } from '../markets-provider';
import {
SelectAllMarketsTableBody,
@@ -16,186 +18,173 @@ jest.mock(
children
);
+const MARKET_A: Partial = {
+ __typename: 'Market',
+ id: '1',
+ decimalPlaces: 2,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ tradableInstrument: {
+ __typename: 'TradableInstrument',
+ instrument: {
+ __typename: 'Instrument',
+ id: '1',
+ code: 'ABCDEF',
+ name: 'ABCDEF 1-Day',
+ product: {
+ __typename: 'Future',
+ settlementAsset: {
+ __typename: 'Asset',
+ symbol: 'ABC',
+ },
+ },
+ metadata: {
+ __typename: 'InstrumentMetadata',
+ tags: ['ABC', 'DEF'],
+ },
+ },
+ },
+ fees: {
+ __typename: 'Fees',
+ factors: {
+ __typename: 'FeeFactors',
+ infrastructureFee: '0.01',
+ liquidityFee: '0.01',
+ makerFee: '0.01',
+ },
+ },
+};
+
+const MARKET_B: Partial = {
+ __typename: 'Market',
+ id: '2',
+ decimalPlaces: 2,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+ tradableInstrument: {
+ __typename: 'TradableInstrument',
+ instrument: {
+ __typename: 'Instrument',
+ id: '2',
+ code: 'XYZ',
+ name: 'XYZ 1-Day',
+ product: {
+ __typename: 'Future',
+ settlementAsset: {
+ __typename: 'Asset',
+ symbol: 'XYZ',
+ },
+ },
+ metadata: {
+ __typename: 'InstrumentMetadata',
+ tags: ['XYZ'],
+ },
+ },
+ },
+ fees: {
+ __typename: 'Fees',
+ factors: {
+ __typename: 'FeeFactors',
+ infrastructureFee: '0.01',
+ liquidityFee: '0.01',
+ makerFee: '0.01',
+ },
+ },
+};
+
+const MARKET_DATA_A: Partial = {
+ __typename: 'MarketData',
+ market: {
+ __typename: 'Market',
+ id: '1',
+ },
+ markPrice: '90',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_OPENING,
+ indicativeVolume: '1000',
+};
+
+const MARKET_DATA_B: Partial = {
+ __typename: 'MarketData',
+ market: {
+ __typename: 'Market',
+ id: '2',
+ },
+ markPrice: '123.123',
+ trigger: AuctionTrigger.AUCTION_TRIGGER_OPENING,
+ indicativeVolume: '2000',
+};
+
+const MARKET_CANDLES_A: Partial = {
+ marketId: '1',
+ candles: [
+ {
+ __typename: 'CandleNode',
+ high: '100',
+ low: '10',
+ open: '10',
+ close: '80',
+ volume: '1000',
+ },
+ {
+ __typename: 'CandleNode',
+ high: '10',
+ low: '1',
+ open: '1',
+ close: '100',
+ volume: '1000',
+ },
+ ],
+};
+
+const MARKET_CANDLES_B: Partial = {
+ marketId: '2',
+ candles: [
+ {
+ __typename: 'CandleNode',
+ high: '100',
+ low: '10',
+ open: '10',
+ close: '80',
+ volume: '1000',
+ },
+ ],
+};
+
describe('SelectMarket', () => {
it('should render the SelectAllMarketsTableBody', () => {
const onSelect = jest.fn();
- const expectedMarket = mockData.data.markets[0];
const { container } = render(
);
- expect(screen.getByText('AAPL.MF21')).toBeTruthy();
- expect(screen.getByText('-3.14%')).toBeTruthy();
- expect(container).toHaveTextContent(/141\.75/);
- fireEvent.click(screen.getByTestId(`market-link-${expectedMarket.id}`));
- expect(onSelect).toHaveBeenCalledWith(expectedMarket.id);
+ expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
+ expect(screen.getByText('25.00%')).toBeTruthy(); // price change
+ expect(container).toHaveTextContent(/1,000/); // volume
+ fireEvent.click(screen.getByTestId(`market-link-1`));
+ expect(onSelect).toHaveBeenCalledWith('1');
});
it('should call onSelect callback on SelectMarketLandingTable', () => {
const onSelect = jest.fn();
- const expectedMarket = mockData.data.markets[0];
render(
);
- fireEvent.click(screen.getByTestId(`market-link-${expectedMarket.id}`));
- expect(onSelect).toHaveBeenCalledWith(expectedMarket.id);
+ fireEvent.click(screen.getByTestId(`market-link-1`));
+ expect(onSelect).toHaveBeenCalledWith('1');
+ fireEvent.click(screen.getByTestId(`market-link-2`));
+ expect(onSelect).toHaveBeenCalledWith('2');
});
});
-
-const mockData = {
- data: {
- markets: [
- {
- __typename: 'Market',
- id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
- decimalPlaces: 2,
- name: '',
- positionDecimalPlaces: 4,
- state: MarketState.STATE_ACTIVE,
- tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- data: {
- markPrice: '14175',
- },
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'APEUSD (May 2022)',
- code: 'APEUSD',
- product: {
- __typename: 'Future',
- settlementAsset: {
- __typename: 'Asset',
- symbol: 'USD',
- },
- },
- },
- },
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:08:27.693537312Z',
- close: null,
- },
- fees: {
- __typename: 'Fees',
- factors: {
- __typename: 'FeeFactors',
- infrastructureFee: '0.01',
- makerFee: '0.01',
- liquidityFee: '0.01',
- },
- },
- candles: [
- {
- __typename: 'Candle',
- open: '822',
- close: '798',
- },
- {
- __typename: 'Candle',
- open: '793',
- close: '792',
- },
- {
- __typename: 'Candle',
- open: '794',
- close: '776',
- },
- {
- __typename: 'Candle',
- open: '785',
- close: '786',
- },
- {
- __typename: 'Candle',
- open: '803',
- close: '770',
- },
- {
- __typename: 'Candle',
- open: '785',
- close: '774',
- },
- ],
- } as MarketList_markets,
- {
- __typename: 'Market',
- id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
- decimalPlaces: 5,
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'Apple Monthly (30 Jun 2022)',
- code: 'AAPL.MF21',
- product: {
- __typename: 'Future',
- settlementAsset: {
- __typename: 'Asset',
- symbol: 'USD',
- },
- },
- },
- },
- fees: {
- __typename: 'Fees',
- factors: {
- __typename: 'FeeFactors',
- infrastructureFee: '0.01',
- makerFee: '0.01',
- liquidityFee: '0.01',
- },
- },
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:00:39.328347732Z',
- close: null,
- },
- candles: [
- {
- __typename: 'Candle',
- open: '14707175',
- close: '14633864',
- },
- {
- __typename: 'Candle',
- open: '14658400',
- close: '14550193',
- },
- {
- __typename: 'Candle',
- open: '14550193',
- close: '14373526',
- },
- {
- __typename: 'Candle',
- open: '14307141',
- close: '14339846',
- },
- {
- __typename: 'Candle',
- open: '14357485',
- close: '14179971',
- },
- {
- __typename: 'Candle',
- open: '14179972',
- close: '14174855',
- },
- ],
- name: '',
- positionDecimalPlaces: 4,
- state: MarketState.STATE_ACTIVE,
- tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
- data: {
- markPrice: '14175',
- },
- } as MarketList_markets,
- ],
- },
-};
diff --git a/libs/market-list/src/lib/components/select-market.tsx b/libs/market-list/src/lib/components/select-market.tsx
index 33ebf1df5..77127d0d3 100644
--- a/libs/market-list/src/lib/components/select-market.tsx
+++ b/libs/market-list/src/lib/components/select-market.tsx
@@ -1,5 +1,4 @@
-import { useQuery } from '@apollo/client';
-import { t, volumePrefix } from '@vegaprotocol/react-helpers';
+import { t, useDataProvider } from '@vegaprotocol/react-helpers';
import {
Dialog,
Icon,
@@ -8,6 +7,7 @@ import {
Link,
Popover,
} from '@vegaprotocol/ui-toolkit';
+
import type { ReactNode } from 'react';
import { useMemo, useState } from 'react';
import type { Column } from './select-market-columns';
@@ -17,21 +17,29 @@ import {
} from './select-market-columns';
import { columnHeaders } from './select-market-columns';
import { columns } from './select-market-columns';
-import type { MarketList_markets } from '../';
+import type { Market, MarketData, MarketCandles, Candle } from '../';
import { useVegaWallet } from '@vegaprotocol/wallet';
-import type { Positions } from '@vegaprotocol/positions';
-import { POSITIONS_QUERY } from '@vegaprotocol/positions';
+import type {
+ Positions_party,
+ PositionsSubscription_positions,
+ Positions_party_positionsConnection_edges_node,
+} from '@vegaprotocol/positions';
+import { positionsDataProvider } from '@vegaprotocol/positions';
import {
SelectMarketTableHeader,
SelectMarketTableRow,
} from './select-market-table';
-import { useMarketList } from '../markets-data-provider';
+import { useMarketList } from '../markets-provider';
export const SelectMarketLandingTable = ({
- data,
+ markets,
+ marketsData,
+ marketsCandles,
onSelect,
}: {
- data: MarketList_markets[] | undefined;
+ markets: Market[] | undefined;
+ marketsData: MarketData[] | undefined;
+ marketsCandles: MarketCandles[] | undefined;
onSelect: (id: string) => void;
}) => {
return (
@@ -45,11 +53,20 @@ export const SelectMarketLandingTable = ({
- {data?.map((market, i) => (
+ {markets?.map((market, i) => (
marketData.market.id === market.id
+ ),
+ marketsCandles?.find(
+ (marketCandles) => marketCandles.marketId === market.id
+ )?.candles,
+ onSelect
+ )}
/>
))}
@@ -61,31 +78,52 @@ export const SelectMarketLandingTable = ({
};
export const SelectAllMarketsTableBody = ({
- data,
+ markets,
+ marketsData,
+ marketsCandles,
+ positions,
onSelect,
headers = columnHeaders,
- tableColumns = (market) => columns(market, onSelect),
+ tableColumns = (market, marketData, candles) =>
+ columns(market, marketData, candles, onSelect),
}: {
- data?: MarketList_markets[];
+ markets: Market[] | undefined;
+ marketsData: MarketData[] | undefined;
+ marketsCandles: MarketCandles[] | undefined;
+ positions?: Positions_party_positionsConnection_edges_node[];
title?: string;
onSelect: (id: string) => void;
headers?: Column[];
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- tableColumns?: (market: any) => Column[];
+ tableColumns?: (
+ market: Market,
+ marketData: MarketData | undefined,
+ candles: Candle[] | undefined,
+ openVolume?: string
+ ) => Column[];
}) => {
- if (!data) return null;
+ if (!markets) return null;
return (
<>
- {/* Border styles required to create space between tbody elements margin/padding dont work */}
+ {/* Border styles required to create space between tbody elements margin/padding don't work */}
- {data?.map((market, i) => (
+ {markets?.map((market, i) => (
marketData.market.id === market.id
+ ),
+ marketsCandles?.find(
+ (marketCandles) => marketCandles.marketId === market.id
+ )?.candles,
+ positions &&
+ positions.find((p) => p.market.id === market.id)?.openVolume
+ )}
/>
))}
@@ -106,35 +144,15 @@ export const SelectMarketPopover = ({
const [open, setOpen] = useState(false);
const { data, loading: marketsLoading } = useMarketList();
const variables = useMemo(() => ({ partyId: keypair?.pub }), [keypair?.pub]);
- const { data: marketDataPositions, loading: positionsLoading } =
- useQuery(POSITIONS_QUERY, {
- variables,
- skip: !keypair?.pub,
- });
-
- const positionMarkets = useMemo(
- () => ({
- markets:
- data
- ?.filter((market) =>
- marketDataPositions?.party?.positionsConnection.edges?.find(
- (edge) => edge.node.market.id === market.id
- )
- )
- .map((market) => {
- const position =
- marketDataPositions?.party?.positionsConnection.edges?.find(
- (edge) => edge.node.market.id === market.id
- )?.node;
- return {
- ...market,
- openVolume:
- position?.openVolume && volumePrefix(position.openVolume),
- };
- }) || null,
- }),
- [data, marketDataPositions]
- );
+ const { data: party, loading: positionsLoading } = useDataProvider<
+ Positions_party,
+ PositionsSubscription_positions
+ >({
+ dataProvider: positionsDataProvider,
+ update: () => false,
+ variables,
+ skip: !keypair,
+ });
const onSelectMarket = (marketId: string) => {
onSelect(marketId);
@@ -142,6 +160,15 @@ export const SelectMarketPopover = ({
};
const iconClass = open ? 'rotate-180' : '';
+ const markets = useMemo(
+ () =>
+ data?.markets?.filter((market) =>
+ party?.positionsConnection.edges?.find(
+ (edge) => edge.node.market.id === market.id
+ )
+ ),
+ [data, party]
+ );
return (
) : (
<>
- {keypair &&
- positionMarkets?.markets &&
- positionMarkets.markets.length > 0 && (
-
- {t('My markets')}
-
- columnsPositionMarkets(market, onSelectMarket)
- }
- />
-
- )}
+ {keypair && (party?.positionsConnection.edges?.length ?? 0) > 0 ? (
+
+ {t('My markets')}
+ edge.node)
+ .map((edge) => edge.node)}
+ onSelect={onSelectMarket}
+ headers={columnHeadersPositionMarkets}
+ tableColumns={(market, marketData, candles, openVolume) =>
+ columnsPositionMarkets(
+ market,
+ marketData,
+ candles,
+ onSelectMarket,
+ openVolume
+ )
+ }
+ />
+
+ ) : null}
@@ -256,5 +294,12 @@ const LandingDialogContainer = ({ onSelect }: LandingDialogContainerProps) => {
);
}
- return ;
+ return (
+
+ );
};
diff --git a/libs/market-list/src/lib/index.ts b/libs/market-list/src/lib/index.ts
index 8030e9e48..cc85bd38e 100644
--- a/libs/market-list/src/lib/index.ts
+++ b/libs/market-list/src/lib/index.ts
@@ -1,6 +1,9 @@
-export * from './__generated__/MarketDataFields';
-export * from './__generated__/MarketList';
-export * from './__generated__/MarketDataSub';
+export * from './__generated__';
export * from './components';
export * from './utils';
+export * from './market-candles-provider';
+export * from './market-data-provider';
+export * from './market-provider';
+export * from './markets-candles-provider';
export * from './markets-data-provider';
+export * from './markets-provider';
diff --git a/libs/market-list/src/lib/market-candles-provider.ts b/libs/market-list/src/lib/market-candles-provider.ts
new file mode 100644
index 000000000..a67f975a0
--- /dev/null
+++ b/libs/market-list/src/lib/market-candles-provider.ts
@@ -0,0 +1,83 @@
+import { gql } from '@apollo/client';
+import { makeDataProvider } from '@vegaprotocol/react-helpers';
+import type {
+ MarketCandlesQuery,
+ MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node,
+ MarketCandlesSub,
+ MarketCandlesSub_candles,
+} from './__generated__';
+
+export const MARKET_CANDLES_QUERY = gql`
+ query MarketCandlesQuery(
+ $interval: Interval!
+ $since: String!
+ $marketId: ID!
+ ) {
+ marketsConnection(id: $marketId) {
+ edges {
+ node {
+ candlesConnection(interval: $interval, since: $since) {
+ edges {
+ node {
+ high
+ low
+ open
+ close
+ volume
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+const MARKET_CANDLES_SUB = gql`
+ subscription MarketCandlesSub($marketId: ID!, $interval: Interval!) {
+ candles(interval: $interval, marketId: $marketId) {
+ high
+ low
+ open
+ close
+ volume
+ }
+ }
+`;
+
+export type Candle =
+ MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
+
+const update = (data: Candle[], delta: MarketCandlesSub_candles) => {
+ return data && delta
+ ? [
+ ...data,
+ {
+ ...delta,
+ __typename: 'CandleNode',
+ } as Candle,
+ ]
+ : data;
+};
+
+const getData = (responseData: MarketCandlesQuery): Candle[] | null =>
+ responseData.marketsConnection.edges[0].node.candlesConnection.edges
+ ?.filter((edge) => edge?.node)
+ .map((edge) => edge?.node as Candle) || null;
+
+const getDelta = (
+ subscriptionData: MarketCandlesSub
+): MarketCandlesSub_candles => subscriptionData.candles;
+
+export const marketCandlesProvider = makeDataProvider<
+ MarketCandlesQuery,
+ Candle[],
+ MarketCandlesSub,
+ MarketCandlesSub_candles
+>({
+ query: MARKET_CANDLES_QUERY,
+ subscriptionQuery: MARKET_CANDLES_SUB,
+ update,
+ getData,
+ getDelta,
+});
diff --git a/libs/market-list/src/lib/market-data-provider.ts b/libs/market-list/src/lib/market-data-provider.ts
new file mode 100644
index 000000000..ea0f42e00
--- /dev/null
+++ b/libs/market-list/src/lib/market-data-provider.ts
@@ -0,0 +1,81 @@
+import produce from 'immer';
+import { gql } from '@apollo/client';
+import { makeDataProvider } from '@vegaprotocol/react-helpers';
+import type {
+ MarketDataSub,
+ MarketDataSub_marketsData,
+ MarketDataQuery,
+ MarketDataQuery_marketsConnection_edges_node_data,
+} from './__generated__';
+
+export const MARKET_DATA_QUERY = gql`
+ query MarketDataQuery($marketId: ID!) {
+ marketsConnection(id: $marketId) {
+ edges {
+ node {
+ data {
+ market {
+ id
+ }
+ bestBidPrice
+ bestOfferPrice
+ markPrice
+ trigger
+ staticMidPrice
+ marketTradingMode
+ indicativeVolume
+ indicativePrice
+ bestStaticBidPrice
+ bestStaticOfferPrice
+ }
+ }
+ }
+ }
+ }
+`;
+
+const MARKET_DATA_SUB = gql`
+ subscription MarketDataSub($marketId: ID!) {
+ marketsData(marketIds: [$marketId]) {
+ marketId
+ bestBidPrice
+ bestOfferPrice
+ markPrice
+ trigger
+ staticMidPrice
+ marketTradingMode
+ indicativeVolume
+ indicativePrice
+ bestStaticBidPrice
+ bestStaticOfferPrice
+ }
+ }
+`;
+
+export type MarketData = MarketDataQuery_marketsConnection_edges_node_data;
+
+const update = (data: MarketData, delta: MarketDataSub_marketsData) => {
+ return produce(data, (draft) => {
+ const { marketId, __typename, ...marketData } = delta;
+ Object.assign(draft, marketData);
+ });
+};
+
+const getData = (responseData: MarketDataQuery): MarketData | null =>
+ responseData.marketsConnection.edges[0].node.data || null;
+
+const getDelta = (subscriptionData: MarketDataSub): MarketDataSub_marketsData =>
+ subscriptionData.marketsData[0];
+
+export const marketDataProvider = makeDataProvider<
+ MarketDataQuery,
+ MarketData,
+ MarketDataSub,
+ MarketDataSub_marketsData
+>({
+ query: MARKET_DATA_QUERY,
+ subscriptionQuery: MARKET_DATA_SUB,
+ update,
+ getData,
+ getDelta,
+});
diff --git a/libs/market-list/src/lib/market-provider.ts b/libs/market-list/src/lib/market-provider.ts
new file mode 100644
index 000000000..16f878782
--- /dev/null
+++ b/libs/market-list/src/lib/market-provider.ts
@@ -0,0 +1,19 @@
+import { makeDerivedDataProvider } from '@vegaprotocol/react-helpers';
+
+import type { Market } from './markets-provider';
+import { marketsProvider } from './markets-provider';
+
+export const marketProvider = makeDerivedDataProvider(
+ [(callback, client) => marketsProvider(callback, client)], // omit variables param
+ ([markets], variables) => {
+ if (markets) {
+ const market = (markets as Market[]).find(
+ (market) => market.id === variables?.marketId
+ );
+ if (market) {
+ return market;
+ }
+ }
+ return null;
+ }
+);
diff --git a/libs/market-list/src/lib/markets-candles-provider.ts b/libs/market-list/src/lib/markets-candles-provider.ts
new file mode 100644
index 000000000..22c3db986
--- /dev/null
+++ b/libs/market-list/src/lib/markets-candles-provider.ts
@@ -0,0 +1,53 @@
+import { gql } from '@apollo/client';
+import { makeDataProvider } from '@vegaprotocol/react-helpers';
+import type {
+ MarketsCandlesQuery,
+ MarketsCandlesQuery_marketsConnection_edges_node as Market,
+ MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node as Candle,
+} from './__generated__';
+
+export const MARKETS_CANDLES_QUERY = gql`
+ query MarketsCandlesQuery($interval: Interval!, $since: String!) {
+ marketsConnection {
+ edges {
+ node {
+ id
+ candlesConnection(interval: $interval, since: $since) {
+ edges {
+ node {
+ high
+ low
+ open
+ close
+ volume
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+export interface MarketCandles {
+ marketId: Market['id'];
+ candles: Candle[] | undefined;
+}
+
+const getData = (responseData: MarketsCandlesQuery): MarketCandles[] | null =>
+ responseData.marketsConnection.edges.map((edge) => ({
+ marketId: edge.node.id,
+ candles: edge.node.candlesConnection.edges
+ ?.filter((edge) => edge?.node)
+ .map((edge) => edge?.node as Candle),
+ })) || null;
+
+export const marketsCandlesProvider = makeDataProvider<
+ MarketsCandlesQuery,
+ MarketCandles[],
+ never,
+ never
+>({
+ query: MARKETS_CANDLES_QUERY,
+ getData,
+});
diff --git a/libs/market-list/src/lib/markets-data-provider.ts b/libs/market-list/src/lib/markets-data-provider.ts
index 049521253..0d6602765 100644
--- a/libs/market-list/src/lib/markets-data-provider.ts
+++ b/libs/market-list/src/lib/markets-data-provider.ts
@@ -1,141 +1,45 @@
-import produce from 'immer';
-import { gql, useQuery } from '@apollo/client';
+import { gql } from '@apollo/client';
import { makeDataProvider } from '@vegaprotocol/react-helpers';
-import type {
- MarketDataSub,
- MarketDataSub_marketData,
- MarketList,
- MarketList_markets,
-} from './';
-import { useMemo } from 'react';
-import { Interval } from '@vegaprotocol/types';
-import { mapDataToMarketList } from './utils';
+import type { MarketsDataQuery } from './__generated__/MarketsDataQuery';
+import type { MarketData } from './market-data-provider';
-export const useMarketList = () => {
- const since = useMemo(() => {
- const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
- return new Date(yesterday * 1000).toISOString();
- }, []);
- const { data, loading, error } = useQuery(MARKET_LIST_QUERY, {
- variables: { interval: Interval.INTERVAL_I1H, since },
- });
-
- return {
- data: useMemo(() => data && mapDataToMarketList(data), [data]),
- loading,
- error,
- };
-};
-
-const MARKET_DATA_FRAGMENT = gql`
- fragment MarketDataFields on MarketData {
- market {
- id
- state
- tradingMode
- }
- bestBidPrice
- bestOfferPrice
- markPrice
- trigger
- indicativeVolume
- }
-`;
-
-export const MARKET_LIST_QUERY = gql`
- query MarketList($interval: Interval!, $since: String!) {
- markets {
- id
- decimalPlaces
- positionDecimalPlaces
- state
- tradingMode
- fees {
- factors {
- makerFee
- infrastructureFee
- liquidityFee
- }
- }
- data {
- market {
- id
- state
- tradingMode
- }
- bestBidPrice
- bestOfferPrice
- markPrice
- trigger
- indicativeVolume
- }
- tradableInstrument {
- instrument {
- id
- name
- code
- metadata {
- tags
- }
- product {
- ... on Future {
- settlementAsset {
- symbol
- }
+export const MARKETS_DATA_QUERY = gql`
+ query MarketsDataQuery {
+ marketsConnection {
+ edges {
+ node {
+ data {
+ market {
+ id
}
+ bestBidPrice
+ bestOfferPrice
+ markPrice
+ trigger
+ staticMidPrice
+ marketTradingMode
+ indicativeVolume
+ indicativePrice
+ bestStaticBidPrice
+ bestStaticOfferPrice
}
}
}
- marketTimestamps {
- open
- close
- }
- candles(interval: $interval, since: $since) {
- open
- close
- high
- low
- }
}
}
`;
-const MARKET_DATA_SUB = gql`
- ${MARKET_DATA_FRAGMENT}
- subscription MarketDataSub {
- marketData {
- ...MarketDataFields
- }
- }
-`;
-
-const update = (
- data: MarketList_markets[],
- delta: MarketDataSub_marketData
-) => {
- return produce(data, (draft) => {
- const index = draft.findIndex((m) => m.id === delta.market.id);
- if (index !== -1) {
- draft[index].data = delta;
- }
- // @TODO - else push new market to draft
- });
-};
-
-const getData = (responseData: MarketList): MarketList_markets[] | null =>
- responseData.markets;
-const getDelta = (subscriptionData: MarketDataSub): MarketDataSub_marketData =>
- subscriptionData.marketData;
+const getData = (responseData: MarketsDataQuery): MarketData[] | null =>
+ responseData.marketsConnection.edges
+ .filter((edge) => edge.node.data)
+ .map((edge) => edge.node.data as MarketData) || null;
export const marketsDataProvider = makeDataProvider<
- MarketList,
- MarketList_markets[],
- MarketDataSub,
- MarketDataSub_marketData
+ MarketsDataQuery,
+ MarketData[],
+ never,
+ never
>({
- query: MARKET_LIST_QUERY,
- subscriptionQuery: MARKET_DATA_SUB,
- update,
+ query: MARKETS_DATA_QUERY,
getData,
- getDelta,
});
diff --git a/libs/market-list/src/lib/markets-provider.ts b/libs/market-list/src/lib/markets-provider.ts
new file mode 100644
index 000000000..4f6d4ac7e
--- /dev/null
+++ b/libs/market-list/src/lib/markets-provider.ts
@@ -0,0 +1,144 @@
+import { gql } from '@apollo/client';
+import {
+ makeDataProvider,
+ makeDerivedDataProvider,
+ useDataProvider,
+} from '@vegaprotocol/react-helpers';
+import type {
+ Markets,
+ Markets_marketsConnection_edges_node,
+} from './__generated__';
+import { marketsDataProvider } from './markets-data-provider';
+import { marketsCandlesProvider } from './markets-candles-provider';
+import type { MarketData } from './market-data-provider';
+import type { MarketCandles } from './markets-candles-provider';
+import { useMemo } from 'react';
+import { Interval } from '@vegaprotocol/types';
+import { mapDataToMarketList } from './utils';
+
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export type Market = Markets_marketsConnection_edges_node;
+
+const MARKET_DATA_FRAGMENT = gql`
+ fragment MarketFields on Market {
+ id
+ decimalPlaces
+ positionDecimalPlaces
+ state
+ tradingMode
+ fees {
+ factors {
+ makerFee
+ infrastructureFee
+ liquidityFee
+ }
+ }
+ tradableInstrument {
+ instrument {
+ id
+ name
+ code
+ metadata {
+ tags
+ }
+ product {
+ ... on Future {
+ settlementAsset {
+ symbol
+ }
+ }
+ }
+ }
+ }
+ marketTimestamps {
+ open
+ close
+ }
+ }
+`;
+
+export const MARKET_LIST_QUERY = gql`
+ ${MARKET_DATA_FRAGMENT}
+ query Markets {
+ marketsConnection {
+ edges {
+ node {
+ ...MarketFields
+ }
+ }
+ }
+ }
+`;
+
+const getData = (responseData: Markets): Market[] | null =>
+ responseData.marketsConnection.edges.map((edge) => edge.node);
+
+export const marketsProvider = makeDataProvider<
+ Markets,
+ Market[],
+ never,
+ never
+>({
+ query: MARKET_LIST_QUERY,
+ getData,
+});
+
+export const activeMarketsProvider = makeDerivedDataProvider(
+ [marketsProvider],
+ ([markets]) => mapDataToMarketList(markets)
+);
+
+interface MarketsListData {
+ markets: Market[];
+ marketsData: MarketData[];
+ marketsCandles: MarketCandles[];
+}
+
+export const marketListProvider = makeDerivedDataProvider(
+ [
+ (callback, client) => activeMarketsProvider(callback, client),
+ (callback, client) => marketsDataProvider(callback, client),
+ marketsCandlesProvider,
+ ],
+ (parts) => {
+ return {
+ markets: parts[0] as Market[],
+ marketsData: parts[1] as MarketData[],
+ marketsCandles: parts[2] as MarketCandles[],
+ };
+ }
+);
+
+export type MarketWithData = Market & { data?: MarketData };
+
+export const marketsWithDataProvider = makeDerivedDataProvider<
+ MarketWithData[]
+>([activeMarketsProvider, marketsDataProvider], (parts) =>
+ (parts[0] as Market[]).map((market) => ({
+ ...market,
+ data: (parts[1] as MarketData[]).find(
+ (data) => data.market.id === market.id
+ ),
+ }))
+);
+
+export const useMarketList = () => {
+ const variables = useMemo(() => {
+ const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
+ return {
+ since: new Date(yesterday * 1000).toISOString(),
+ interval: Interval.INTERVAL_I1H,
+ };
+ }, []);
+ const { data, loading, error } = useDataProvider({
+ dataProvider: marketListProvider,
+ variables,
+ noUpdate: true,
+ });
+
+ return {
+ data,
+ loading,
+ error,
+ };
+};
diff --git a/libs/market-list/src/lib/utils/market-utils.spec.tsx b/libs/market-list/src/lib/utils/market-utils.spec.tsx
index 9dc46f140..ade2bc74d 100644
--- a/libs/market-list/src/lib/utils/market-utils.spec.tsx
+++ b/libs/market-list/src/lib/utils/market-utils.spec.tsx
@@ -1,210 +1,59 @@
-import type { MarketList } from '../__generated__/MarketList';
+import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
+import type { Market } from '../markets-provider';
import { mapDataToMarketList } from './market-utils';
+const MARKET_A: Partial = {
+ id: '1',
+ marketTimestamps: {
+ __typename: 'MarketTimestamps',
+ open: '2022-05-18T13:08:27.693537312Z',
+ close: null,
+ },
+ state: MarketState.STATE_ACTIVE,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+};
+
+const MARKET_B: Partial = {
+ id: '2',
+ marketTimestamps: {
+ __typename: 'MarketTimestamps',
+ open: '2022-05-18T13:00:39.328347732Z',
+ close: null,
+ },
+ state: MarketState.STATE_ACTIVE,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+};
+
+const MARKET_C: Partial = {
+ id: '3',
+ marketTimestamps: {
+ __typename: 'MarketTimestamps',
+ open: '2022-05-17T13:00:39.328347732Z',
+ close: null,
+ },
+ state: MarketState.STATE_REJECTED,
+ tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
+};
+
+const MARKET_D: Partial = {
+ id: '4',
+ marketTimestamps: {
+ __typename: 'MarketTimestamps',
+ open: '2022-05-16T13:00:39.328347732Z',
+ close: null,
+ },
+ state: MarketState.STATE_ACTIVE,
+ tradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
+};
+
describe('mapDataToMarketList', () => {
it('should map queried data to market list format', () => {
- const result = mapDataToMarketList(mockData.data as unknown as MarketList);
- expect(result).toEqual(mockList);
+ const result = mapDataToMarketList([
+ MARKET_A,
+ MARKET_B,
+ MARKET_C,
+ MARKET_D,
+ ] as unknown as Market[]);
+ expect(result).toEqual([MARKET_B, MARKET_A]);
});
});
-
-const mockList = [
- {
- __typename: 'Market',
- id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
- decimalPlaces: 5,
- candles: [
- {
- open: '16141155',
- close: '16293551',
- high: '16320190',
- low: '16023805',
- __typename: 'Candle',
- },
- {
- open: '16293548',
- close: '16322118',
- high: '16365861',
- low: '16192970',
- __typename: 'Candle',
- },
- ],
- fees: {
- factors: {
- makerFee: 0.0002,
- infrastructureFee: 0.0005,
- liquidityFee: 0.001,
- },
- },
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'Apple Monthly (30 Jun 2022)',
- code: 'AAPL.MF21',
- product: {
- settlementAsset: { symbol: 'AAPL.MF21', __typename: 'Asset' },
- __typename: 'Future',
- },
- },
- },
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:00:39.328347732Z',
- close: null,
- },
- open: 1652878839328,
- close: null,
- },
- {
- __typename: 'Market',
- id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
- decimalPlaces: 2,
- fees: {
- factors: {
- makerFee: 0.0002,
- infrastructureFee: 0.0005,
- liquidityFee: 0.001,
- },
- },
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'APEUSD (May 2022)',
- code: 'APEUSD',
- product: {
- settlementAsset: { symbol: 'APEUSD', __typename: 'Asset' },
- __typename: 'Future',
- },
- },
- },
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:08:27.693537312Z',
- close: null,
- },
- candles: [
- {
- open: '16141155',
- close: '16293551',
- high: '16320190',
- low: '16023805',
- __typename: 'Candle',
- },
- {
- open: '16293548',
- close: '16322118',
- high: '16365861',
- low: '16192970',
- __typename: 'Candle',
- },
- ],
- open: 1652879307693,
- close: null,
- },
-];
-
-const mockData = {
- data: {
- markets: [
- {
- __typename: 'Market',
- id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
- decimalPlaces: 2,
- fees: {
- factors: {
- makerFee: 0.0002,
- infrastructureFee: 0.0005,
- liquidityFee: 0.001,
- },
- },
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'APEUSD (May 2022)',
- code: 'APEUSD',
- product: {
- settlementAsset: {
- symbol: 'APEUSD',
- __typename: 'Asset',
- },
- __typename: 'Future',
- },
- },
- },
-
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:08:27.693537312Z',
- close: null,
- },
- candles: [
- {
- open: '16141155',
- close: '16293551',
- high: '16320190',
- low: '16023805',
- __typename: 'Candle',
- },
- {
- open: '16293548',
- close: '16322118',
- high: '16365861',
- low: '16192970',
- __typename: 'Candle',
- },
- ],
- },
- {
- __typename: 'Market',
- id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
- decimalPlaces: 5,
- candles: [
- {
- open: '16141155',
- close: '16293551',
- high: '16320190',
- low: '16023805',
- __typename: 'Candle',
- },
- {
- open: '16293548',
- close: '16322118',
- high: '16365861',
- low: '16192970',
- __typename: 'Candle',
- },
- ],
- fees: {
- factors: {
- makerFee: 0.0002,
- infrastructureFee: 0.0005,
- liquidityFee: 0.001,
- },
- },
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- name: 'Apple Monthly (30 Jun 2022)',
- code: 'AAPL.MF21',
- product: {
- settlementAsset: {
- symbol: 'AAPL.MF21',
- __typename: 'Asset',
- },
- __typename: 'Future',
- },
- },
- },
- marketTimestamps: {
- __typename: 'MarketTimestamps',
- open: '2022-05-18T13:00:39.328347732Z',
- close: null,
- },
- },
- ],
- },
-};
diff --git a/libs/market-list/src/lib/utils/market-utils.ts b/libs/market-list/src/lib/utils/market-utils.ts
index 0c5b52f8a..0fdd62839 100644
--- a/libs/market-list/src/lib/utils/market-utils.ts
+++ b/libs/market-list/src/lib/utils/market-utils.ts
@@ -2,13 +2,9 @@ import { formatNumberPercentage } from '@vegaprotocol/react-helpers';
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import BigNumber from 'bignumber.js';
import orderBy from 'lodash/orderBy';
-import type {
- MarketList,
- MarketList_markets,
- MarketList_markets_fees_factors,
-} from '../__generated__/MarketList';
+import type { Market, Candle } from '../';
-export const totalFees = (fees: MarketList_markets_fees_factors) => {
+export const totalFees = (fees: Market['fees']['factors']) => {
if (!fees) {
return undefined;
}
@@ -20,7 +16,7 @@ export const totalFees = (fees: MarketList_markets_fees_factors) => {
);
};
-export const mapDataToMarketList = ({ markets }: MarketList) => {
+export const mapDataToMarketList = (markets: Market[]) => {
const tradingModesOrdering = [
MarketTradingMode.TRADING_MODE_CONTINUOUS,
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
@@ -29,24 +25,12 @@ export const mapDataToMarketList = ({ markets }: MarketList) => {
MarketTradingMode.TRADING_MODE_NO_TRADING,
];
const orderedMarkets = orderBy(
- markets
- ?.filter(
- (m) =>
- m.state !== MarketState.STATE_REJECTED &&
- m.tradingMode !== MarketTradingMode.TRADING_MODE_NO_TRADING
- )
- .map((m) => {
- return {
- ...m,
- open: m.marketTimestamps.open
- ? new Date(m.marketTimestamps.open).getTime()
- : null,
- close: m.marketTimestamps.close
- ? new Date(m.marketTimestamps.close).getTime()
- : null,
- };
- }) || [],
- ['open', 'id'],
+ markets?.filter(
+ (m) =>
+ m.state !== MarketState.STATE_REJECTED &&
+ m.tradingMode !== MarketTradingMode.TRADING_MODE_NO_TRADING
+ ) || [],
+ ['marketTimestamps.open', 'id'],
['asc', 'asc']
);
return orderedMarkets.sort(
@@ -56,8 +40,8 @@ export const mapDataToMarketList = ({ markets }: MarketList) => {
);
};
-export const calcCandleLow = (m: MarketList_markets): string | undefined => {
- return m.candles
+export const calcCandleLow = (candles: Candle[]): string | undefined => {
+ return candles
?.reduce((acc: BigNumber, c) => {
if (c?.low) {
if (acc.isLessThan(new BigNumber(c.low))) {
@@ -66,12 +50,12 @@ export const calcCandleLow = (m: MarketList_markets): string | undefined => {
return new BigNumber(c.low);
}
return acc;
- }, new BigNumber(m.candles?.[0]?.high ?? 0))
+ }, new BigNumber(candles?.[0]?.high ?? 0))
.toString();
};
-export const calcCandleHigh = (m: MarketList_markets): string | undefined => {
- return m.candles
+export const calcCandleHigh = (candles: Candle[]): string | undefined => {
+ return candles
?.reduce((acc: BigNumber, c) => {
if (c?.high) {
if (acc.isGreaterThan(new BigNumber(c.high))) {
diff --git a/libs/positions/src/index.ts b/libs/positions/src/index.ts
index 99df7895b..89483782f 100644
--- a/libs/positions/src/index.ts
+++ b/libs/positions/src/index.ts
@@ -1,4 +1,5 @@
export * from './lib/__generated__/Positions';
+export * from './lib/__generated__/PositionsSubscription';
export * from './lib/positions-container';
export * from './lib/positions-data-providers';
export * from './lib/positions-table';
diff --git a/libs/positions/src/lib/positions-data-providers.ts b/libs/positions/src/lib/positions-data-providers.ts
index 8a93880cd..bcca252e7 100644
--- a/libs/positions/src/lib/positions-data-providers.ts
+++ b/libs/positions/src/lib/positions-data-providers.ts
@@ -252,7 +252,7 @@ export const update = (
});
};
-export const positionDataProvider = makeDataProvider<
+export const positionsDataProvider = makeDataProvider<
Positions,
Positions_party,
PositionsSubscription,
@@ -267,7 +267,7 @@ export const positionDataProvider = makeDataProvider<
});
export const positionsMetricsDataProvider = makeDerivedDataProvider(
- [positionDataProvider, accountsDataProvider],
+ [positionsDataProvider, accountsDataProvider],
([positions, accounts]) => {
return sortBy(
getMetrics(
diff --git a/libs/react-helpers/src/hooks/use-data-provider.ts b/libs/react-helpers/src/hooks/use-data-provider.ts
index 105fed608..486098f18 100644
--- a/libs/react-helpers/src/hooks/use-data-provider.ts
+++ b/libs/react-helpers/src/hooks/use-data-provider.ts
@@ -19,6 +19,8 @@ export function useDataProvider({
update,
insert,
variables,
+ noUpdate,
+ skip,
}: {
dataProvider: Subscribe;
update?: ({ delta, data }: { delta: Delta; data: Data }) => boolean;
@@ -32,11 +34,13 @@ export function useDataProvider({
totalCount?: number;
}) => boolean;
variables?: OperationVariables;
+ noUpdate?: boolean;
+ skip?: boolean;
}) {
const client = useApolloClient();
const [data, setData] = useState(null);
const [totalCount, setTotalCount] = useState();
- const [loading, setLoading] = useState(true);
+ const [loading, setLoading] = useState(!skip);
const [error, setError] = useState(undefined);
const flushRef = useRef<(() => void) | undefined>(undefined);
const reloadRef = useRef<((force?: boolean) => void) | undefined>(undefined);
@@ -75,7 +79,12 @@ export function useDataProvider({
// if update or insert function returns true it means that component handles updates
// component can use flush() which will call callback without delta and cause data state update
if (initialized.current && data) {
- if (isUpdate && update && (!delta || update({ delta, data }))) {
+ if (
+ isUpdate &&
+ !noUpdate &&
+ update &&
+ (!delta || update({ delta, data }))
+ ) {
return;
}
if (
@@ -91,9 +100,12 @@ export function useDataProvider({
setData(data);
}
},
- [update, insert]
+ [update, insert, noUpdate]
);
useEffect(() => {
+ if (skip) {
+ return;
+ }
const { unsubscribe, flush, reload, load } = dataProvider(
callback,
client,
@@ -103,6 +115,6 @@ export function useDataProvider({
reloadRef.current = reload;
loadRef.current = load;
return unsubscribe;
- }, [client, initialized, dataProvider, callback, variables]);
+ }, [client, initialized, dataProvider, callback, variables, skip]);
return { data, loading, error, flush, reload, load, totalCount };
}
diff --git a/libs/react-helpers/src/lib/generic-data-provider.ts b/libs/react-helpers/src/lib/generic-data-provider.ts
index 94b8427e4..f1789c4d7 100644
--- a/libs/react-helpers/src/lib/generic-data-provider.ts
+++ b/libs/react-helpers/src/lib/generic-data-provider.ts
@@ -133,10 +133,10 @@ export function defaultAppend(
interface DataProviderParams {
query: Query;
- subscriptionQuery: Query;
- update: Update;
+ subscriptionQuery?: Query;
+ update?: Update;
getData: GetData;
- getDelta: GetDelta;
+ getDelta?: GetDelta;
pagination?: {
getPageInfo: GetPageInfo;
getTotalCount?: GetTotalCount;
@@ -270,6 +270,7 @@ function makeDataProviderInternal({
? { ...variables, pagination: { first: pagination.first } }
: variables,
fetchPolicy,
+ errorPolicy: 'ignore',
});
data = getData(res.data);
if (data && pagination) {
@@ -291,7 +292,7 @@ function makeDataProviderInternal({
}
}
// if there was some updates received from subscription during initial query loading apply them on just received data
- if (data && updateQueue && updateQueue.length > 0) {
+ if (update && data && updateQueue && updateQueue.length > 0) {
while (updateQueue.length) {
const delta = updateQueue.shift();
if (delta) {
@@ -339,31 +340,33 @@ function makeDataProviderInternal({
if (!client) {
return;
}
- subscription = client
- .subscribe({
- query: subscriptionQuery,
- variables,
- fetchPolicy,
- })
- .subscribe(
- ({ data: subscriptionData }) => {
- if (!subscriptionData) {
- return;
- }
- const delta = getDelta(subscriptionData);
- if (loading || !data) {
- updateQueue.push(delta);
- } else {
- const updatedData = update(data, delta, reload);
- if (updatedData === data) {
+ if (subscriptionQuery && getDelta && update) {
+ subscription = client
+ .subscribe({
+ query: subscriptionQuery,
+ variables,
+ fetchPolicy,
+ })
+ .subscribe(
+ ({ data: subscriptionData }) => {
+ if (!subscriptionData) {
return;
}
- data = updatedData;
- notifyAll({ delta, isUpdate: true });
- }
- },
- () => reload()
- );
+ const delta = getDelta(subscriptionData);
+ if (loading || !data) {
+ updateQueue.push(delta);
+ } else {
+ const updatedData = update(data, delta, reload);
+ if (updatedData === data) {
+ return;
+ }
+ data = updatedData;
+ notifyAll({ delta, isUpdate: true });
+ }
+ },
+ () => reload()
+ );
+ }
await initialFetch();
};
@@ -470,7 +473,8 @@ export function makeDataProvider(
type DependencySubscribe = Subscribe; // eslint-disable-line @typescript-eslint/no-explicit-any
type DependencyUpdateCallback = Parameters['0'];
export type CombineDerivedData = (
- parts: Parameters['0']['data'][]
+ parts: Parameters['0']['data'][],
+ variables?: OperationVariables
) => Data | null;
function makeDerivedDataProviderInternal(
@@ -521,7 +525,10 @@ function makeDerivedDataProviderInternal(
});
const newData = newLoaded
- ? combineData(parts.map((part) => part.data))
+ ? combineData(
+ parts.map((part) => part.data),
+ variables
+ )
: data;
if (
newLoading !== loading ||
diff --git a/libs/types/src/__generated__/globalTypes.ts b/libs/types/src/__generated__/globalTypes.ts
index 25e42c03f..df425d0ab 100644
--- a/libs/types/src/__generated__/globalTypes.ts
+++ b/libs/types/src/__generated__/globalTypes.ts
@@ -10,7 +10,7 @@
/**
* The various account types in Vega (used by collateral)
*/
-export enum AccountType {
+ export enum AccountType {
ACCOUNT_TYPE_BOND = "ACCOUNT_TYPE_BOND",
ACCOUNT_TYPE_EXTERNAL = "ACCOUNT_TYPE_EXTERNAL",
ACCOUNT_TYPE_FEES_INFRASTRUCTURE = "ACCOUNT_TYPE_FEES_INFRASTRUCTURE",
@@ -361,4 +361,4 @@ export interface Pagination {
//==============================================================
// END Enums and Input Objects
-//==============================================================
+//==============================================================
\ No newline at end of file