diff --git a/apps/explorer/.env b/apps/explorer/.env index 455137895..9fdd36c08 100644 --- a/apps/explorer/.env +++ b/apps/explorer/.env @@ -3,7 +3,6 @@ NX_TENDERMINT_URL=http://localhost:26617 NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket NX_VEGA_URL=http://localhost:3028/query NX_VEGA_ENV=CUSTOM -NX_VEGA_REST=http://localhost:3029 NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm @@ -12,7 +11,6 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json NX_VEGA_URL=https://n01.stagnet3.vega.xyz/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=STAGNET3 -NX_VEGA_REST=https://n01.stagnet3.vega.xyz/datanode/rest NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions # App flags diff --git a/apps/explorer/.env.capsule b/apps/explorer/.env.capsule index 302407622..f360272cc 100644 --- a/apps/explorer/.env.capsule +++ b/apps/explorer/.env.capsule @@ -5,7 +5,6 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket NX_VEGA_URL=http://localhost:3028/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=CUSTOM -NX_VEGA_REST=http://localhost:3029 NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions # App flags diff --git a/apps/explorer/.env.devnet b/apps/explorer/.env.devnet index 738e500ad..e8a1dc521 100644 --- a/apps/explorer/.env.devnet +++ b/apps/explorer/.env.devnet @@ -6,5 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json NX_VEGA_URL=https://n04.d.vega.xyz/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=DEVNET -NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/.env.mainnet b/apps/explorer/.env.mainnet index bdfcded65..c5768f82d 100644 --- a/apps/explorer/.env.mainnet +++ b/apps/explorer/.env.mainnet @@ -6,5 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json NX_VEGA_URL=https://api.token.vega.xyz/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=MAINNET -NX_VEGA_REST=https://api.token.vega.xyz/ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/.env.stagnet1 b/apps/explorer/.env.stagnet1 index 164257d9c..723adaf10 100644 --- a/apps/explorer/.env.stagnet1 +++ b/apps/explorer/.env.stagnet1 @@ -6,5 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json NX_VEGA_URL=https://n03.s.vega.xyz/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=STAGNET -NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/.env.stagnet3 b/apps/explorer/.env.stagnet3 index b955fba9c..12dec4d38 100644 --- a/apps/explorer/.env.stagnet3 +++ b/apps/explorer/.env.stagnet3 @@ -6,5 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json NX_VEGA_URL=https://n01.stagnet3.vega.xyz/query NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=STAGNET3 -NX_VEGA_REST=https://n01.stagnet3.vega.xyz/datanode/rest NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/.env.testnet b/apps/explorer/.env.testnet index e162d687f..f6b1c2d67 100644 --- a/apps/explorer/.env.testnet +++ b/apps/explorer/.env.testnet @@ -6,5 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}' NX_VEGA_ENV=TESTNET -NX_VEGA_REST=https://api.n11.testnet.vega.xyz NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/.env.vegacapsule b/apps/explorer/.env.vegacapsule index 348f7604d..cc49be5cb 100644 --- a/apps/explorer/.env.vegacapsule +++ b/apps/explorer/.env.vegacapsule @@ -4,5 +4,4 @@ NX_TENDERMINT_URL=http://localhost:26607/ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket NX_VEGA_URL=http://localhost:3003/query NX_VEGA_ENV=CUSTOM -NX_VEGA_REST=http://localhost:3029/rest NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/explorer/README.md b/apps/explorer/README.md index 5969e2b64..792c49464 100644 --- a/apps/explorer/README.md +++ b/apps/explorer/README.md @@ -47,13 +47,12 @@ yarn nx run explorer:serve --env={env} # e.g. stagnet1 There are a few different configuration options offered for this app: | **Flag** | **Purpose** | -| -------------------------------- | ---------------------------------------------------------------------------------------------------- | +| -------------------------------- | ---------------------------------------------------------------------------------------------------- | --- | | `NX_CHAIN_EXPLORER_URL` | The URL of the chain explorer service for decoding transactions | | `NX_TENDERMINT_URL` | The Tendermint REST URL for the Vega consesus engine | | `NX_TENDERMINT_WEBSOCKET_URL` | The Tendermint Websocket URL for the Vega consensus engine | | `NX_VEGA_URL` | The GraphQl query endpoint of a [Vega data node](https://github.com/vegaprotocol/networks#data-node) | -| `NX_VEGA_ENV` | The name of the currently connected vega environment | -| `NX_VEGA_REST` | The REST URL for the Vega Data Node | +| `NX_VEGA_ENV` | The name of the currently connected vega environment | | | `NX_EXPLORER_ASSETS` | Enable the assets page for the explorer | | `NX_EXPLORER_GENESIS` | Enable the genesis page for the explorer | | `NX_EXPLORER_GOVERNANCE` | Enable the governance page for the explorer | diff --git a/apps/explorer/src/app/app.tsx b/apps/explorer/src/app/app.tsx index da2cd690c..5757c81fe 100644 --- a/apps/explorer/src/app/app.tsx +++ b/apps/explorer/src/app/app.tsx @@ -1,15 +1,23 @@ import { useState, useEffect } from 'react'; +import * as Sentry from '@sentry/react'; +import { BrowserTracing } from '@sentry/tracing'; import { useLocation } from 'react-router-dom'; import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers'; -import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment'; +import { + EnvironmentProvider, + NetworkLoader, + useEnvironment, +} from '@vegaprotocol/environment'; import { NetworkInfo } from '@vegaprotocol/network-info'; import { createClient } from './lib/apollo-client'; import { Nav } from './components/nav'; import { Header } from './components/header'; import { Main } from './components/main'; import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider'; +import { ENV } from './config/env'; function App() { + const { VEGA_ENV } = useEnvironment(); const [theme, toggleTheme] = useThemeSwitcher(); const [menuOpen, setMenuOpen] = useState(false); @@ -19,34 +27,49 @@ function App() { setMenuOpen(false); }, [location]); + useEffect(() => { + Sentry.init({ + dsn: ENV.dsn, + integrations: [new BrowserTracing()], + tracesSampleRate: 1, + environment: VEGA_ENV, + }); + }, [VEGA_ENV]); + return ( - - - - -
-
-
-
+ + + +
+
+
+
- - - - +
+
+
+
); } -export default App; +const Wrapper = () => { + return ( + + + + ); +}; + +export default Wrapper; diff --git a/apps/explorer/src/app/config/env.ts b/apps/explorer/src/app/config/env.ts index c59d53168..c0682bac1 100644 --- a/apps/explorer/src/app/config/env.ts +++ b/apps/explorer/src/app/config/env.ts @@ -11,13 +11,10 @@ export const ENV = { // Data sources // Environment dsn: windowOrDefault('NX_EXPLORER_SENTRY_DSN'), - envName: windowOrDefault('NX_VEGA_ENV'), dataSources: { chainExplorerUrl: windowOrDefault('NX_CHAIN_EXPLORER_URL'), tendermintUrl: windowOrDefault('NX_TENDERMINT_URL'), tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'), - dataNodeUrl: windowOrDefault('NX_VEGA_URL'), - restEndpoint: windowOrDefault('NX_VEGA_REST'), }, flags: { assets: truthy.includes(windowOrDefault('NX_EXPLORER_ASSETS')), diff --git a/apps/explorer/src/app/routes/home/index.tsx b/apps/explorer/src/app/routes/home/index.tsx index 609531cc4..0027053ee 100644 --- a/apps/explorer/src/app/routes/home/index.tsx +++ b/apps/explorer/src/app/routes/home/index.tsx @@ -1,21 +1,10 @@ -import { DATA_SOURCES } from '../../config'; import { StatsManager } from '@vegaprotocol/network-stats'; -import { ENV } from '../../config/env'; - -const envName = ENV.envName; -const restEndpoint = DATA_SOURCES.restEndpoint; -const statsEndpoint = `${restEndpoint}/statistics`; -const nodesEndpoint = `${restEndpoint}/nodes-data`; const Home = () => { + const classnames = 'mt-12 grid grid-cols-1 lg:grid-cols-2 lg:gap-16'; return (
- +
); }; diff --git a/apps/explorer/src/main.tsx b/apps/explorer/src/main.tsx index f2b613fee..8bde8044c 100644 --- a/apps/explorer/src/main.tsx +++ b/apps/explorer/src/main.tsx @@ -1,24 +1,10 @@ -import * as Sentry from '@sentry/react'; -import { BrowserTracing } from '@sentry/tracing'; import { createRoot } from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import './styles.css'; import App from './app/app'; -import { ENV } from './app/config/env'; import { StrictMode } from 'react'; -const { dsn } = ENV; - -/* istanbul ignore next */ -if (dsn) { - Sentry.init({ - dsn, - integrations: [new BrowserTracing()], - tracesSampleRate: 1, - environment: ENV.envName, - }); -} const rootElement = document.getElementById('root'); const root = rootElement && createRoot(rootElement); diff --git a/apps/stats/.env b/apps/stats/.env index 7f77c5f27..4172029d5 100644 --- a/apps/stats/.env +++ b/apps/stats/.env @@ -1,3 +1,3 @@ # App configuration variables NX_VEGA_ENV=MAINNET -NX_VEGA_REST=https://api.token.vega.xyz/ +NX_VEGA_URL=https://api.token.vega.xyz/query diff --git a/apps/stats/.env.devnet b/apps/stats/.env.devnet index 73841c33a..6a83c6fb7 100644 --- a/apps/stats/.env.devnet +++ b/apps/stats/.env.devnet @@ -1,3 +1,3 @@ # App configuration variables NX_VEGA_ENV=DEVNET -NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest +NX_VEGA_URL=https://n04.d.vega.xyz/query diff --git a/apps/stats/.env.mainnet b/apps/stats/.env.mainnet index 4c06a7948..6ece2f727 100644 --- a/apps/stats/.env.mainnet +++ b/apps/stats/.env.mainnet @@ -1,3 +1,3 @@ # App configuration variables. No overrides for default urls NX_VEGA_ENV=MAINNET -NX_VEGA_REST=https://api.token.vega.xyz/ +NX_VEGA_URL=https://api.token.vega.xyz/query diff --git a/apps/stats/.env.stagnet1 b/apps/stats/.env.stagnet1 index 22086bd03..677035096 100644 --- a/apps/stats/.env.stagnet1 +++ b/apps/stats/.env.stagnet1 @@ -1,3 +1,3 @@ # App configuration variables NX_VEGA_ENV=STAGNET1; -NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest; +NX_VEGA_URL=https://n03.s.vega.xyz/query; diff --git a/apps/stats/.env.stagnet3 b/apps/stats/.env.stagnet3 index 225a0073a..94a4feb03 100644 --- a/apps/stats/.env.stagnet3 +++ b/apps/stats/.env.stagnet3 @@ -1,3 +1,3 @@ # App configuration variables -NX_VEGA_REST=https://n01.stagnet3.vega.xyz/datanode/rest; +NX_VEGA_URL=https://n01.stagnet3.vega.xyz/query; NX_VEGA_ENV=STAGNET3; diff --git a/apps/stats/.env.testnet b/apps/stats/.env.testnet index b5296c3b5..af17e43cf 100644 --- a/apps/stats/.env.testnet +++ b/apps/stats/.env.testnet @@ -1,3 +1,3 @@ # App configuration variables NX_VEGA_ENV=TESTNET -NX_VEGA_REST=https://api.n11.testnet.vega.xyz +NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql diff --git a/apps/stats/src/app.tsx b/apps/stats/src/app.tsx index 8fbdfafa5..1c5034756 100644 --- a/apps/stats/src/app.tsx +++ b/apps/stats/src/app.tsx @@ -1,33 +1,33 @@ -import React from 'react'; -import { DATA_SOURCES } from './config'; +import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment'; import { Header } from './components/header'; import { StatsManager } from '@vegaprotocol/network-stats'; import { ThemeContext } from '@vegaprotocol/react-helpers'; import { useThemeSwitcher } from '@vegaprotocol/react-helpers'; - -const envName = DATA_SOURCES.envName; -const restEndpoint = DATA_SOURCES.restEndpoint; -const statsEndpoint = `${restEndpoint}/statistics`; -const nodesEndpoint = `${restEndpoint}/nodes-data`; +import { createClient } from './lib/apollo-client'; function App() { const [theme, toggleTheme] = useThemeSwitcher(); return ( -
-
-
- + +
+
+
+ +
-
+ ); } -export default App; +const Wrapper = () => { + return ( + + + + ); +}; + +export default Wrapper; diff --git a/apps/stats/src/config/index.tsx b/apps/stats/src/config/index.tsx deleted file mode 100644 index 7aaf89475..000000000 --- a/apps/stats/src/config/index.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export const DATA_SOURCES = { - envName: process.env['NX_VEGA_ENV'] as string, - restEndpoint: process.env['NX_VEGA_REST'] as string, -}; diff --git a/apps/stats/src/lib/apollo-client.tsx b/apps/stats/src/lib/apollo-client.tsx new file mode 100644 index 000000000..d5de5e727 --- /dev/null +++ b/apps/stats/src/lib/apollo-client.tsx @@ -0,0 +1,52 @@ +import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client'; +import { onError } from '@apollo/client/link/error'; +import { RetryLink } from '@apollo/client/link/retry'; + +export function createClient(base?: string) { + if (!base) { + throw new Error('Base must be passed into createClient!'); + } + const urlHTTP = new URL(base); + const urlWS = new URL(base); + // Replace http with ws, preserving if its a secure connection eg. https => wss + urlWS.protocol = urlWS.protocol.replace('http', 'ws'); + + const cache = new InMemoryCache({ + typePolicies: { + Query: {}, + Account: { + keyFields: false, + fields: { + balanceFormatted: {}, + }, + }, + Node: { + keyFields: false, + }, + }, + }); + + const retryLink = new RetryLink({ + delay: { + initial: 300, + max: 10000, + jitter: true, + }, + }); + + const httpLink = new HttpLink({ + uri: urlHTTP.href, + credentials: 'same-origin', + }); + + const errorLink = onError(({ graphQLErrors, networkError }) => { + console.log(graphQLErrors); + console.log(networkError); + }); + + return new ApolloClient({ + connectToDevTools: process.env['NODE_ENV'] === 'development', + link: from([errorLink, retryLink, httpLink]), + cache, + }); +} diff --git a/libs/environment/src/hooks/use-config.tsx b/libs/environment/src/hooks/use-config.tsx index 1c89e9192..cfc5b29c3 100644 --- a/libs/environment/src/hooks/use-config.tsx +++ b/libs/environment/src/hooks/use-config.tsx @@ -18,7 +18,7 @@ const compileHosts = (hosts: string[], envUrl?: string) => { const getCacheKey = (env: Networks) => `${LOCAL_STORAGE_NETWORK_KEY}-${env}`; -const getCachedConfig = (env: Networks) => { +const getCachedConfig = (env: Networks, envUrl?: string) => { const cacheKey = getCacheKey(env); const value = LocalStorage.getItem(cacheKey); @@ -31,7 +31,10 @@ const getCachedConfig = (env: Networks) => { throw new Error('Invalid configuration found in the storage.'); } - return config; + return { + ...config, + hosts: compileHosts(config.hosts, envUrl), + }; } catch (err) { LocalStorage.removeItem(cacheKey); console.warn( @@ -49,7 +52,7 @@ export const useConfig = ( ) => { const [loading, setLoading] = useState(false); const [config, setConfig] = useState( - getCachedConfig(environment.VEGA_ENV) + getCachedConfig(environment.VEGA_ENV, environment.VEGA_URL) ); useEffect(() => { diff --git a/libs/environment/src/utils/validate-node.tsx b/libs/environment/src/utils/validate-node.tsx index 7f78ee4ff..039b6708c 100644 --- a/libs/environment/src/utils/validate-node.tsx +++ b/libs/environment/src/utils/validate-node.tsx @@ -110,11 +110,10 @@ export const getErrorByType = ( }; export const getErrorType = (env: Networks, data?: NodeData) => { - if (data && !getIsNodeLoading(data) && data.initialized) { + if (data && data.initialized) { if (getIsInvalidUrl(data.url)) { return ErrorType.INVALID_URL; } - if ( data.chain.hasError || data.responseTime.hasError || @@ -123,7 +122,7 @@ export const getErrorType = (env: Networks, data?: NodeData) => { return ErrorType.CONNECTION_ERROR; } - if (getHasInvalidChain(env, data.chain.value)) { + if (!data.chain.isLoading && getHasInvalidChain(env, data.chain.value)) { return ErrorType.INVALID_NETWORK; } diff --git a/libs/network-stats/.eslintrc.json b/libs/network-stats/.eslintrc.json index 734ddacee..db820c5d0 100644 --- a/libs/network-stats/.eslintrc.json +++ b/libs/network-stats/.eslintrc.json @@ -1,6 +1,6 @@ { "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], + "ignorePatterns": ["!**/*", "__generated__"], "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], diff --git a/libs/network-stats/src/components/stats-manager/__generated__/NetworkStats.ts b/libs/network-stats/src/components/stats-manager/__generated__/NetworkStats.ts new file mode 100644 index 000000000..1f4e6990f --- /dev/null +++ b/libs/network-stats/src/components/stats-manager/__generated__/NetworkStats.ts @@ -0,0 +1,95 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: NetworkStats +// ==================================================== + +export interface NetworkStats_nodeData { + __typename: "NodeData"; + /** + * Total staked amount across all nodes + */ + stakedTotal: string; + /** + * Total number of nodes + */ + totalNodes: number; + /** + * Number of inactive nodes + */ + inactiveNodes: number; + /** + * Number of nodes validating + */ + validatingNodes: number; + /** + * Total uptime for all epochs across all nodes. Or specify a number of epochs + */ + uptime: number; +} + +export interface NetworkStats_statistics { + __typename: "Statistics"; + /** + * Status of the Vega application connection with the chain + */ + status: string; + /** + * Current block number + */ + blockHeight: string; + /** + * Duration of the last block, in nanoseconds + */ + blockDuration: string; + /** + * Number of items in the backlog + */ + backlogLength: string; + /** + * Number of transaction processed per block + */ + txPerBlock: string; + /** + * Number of the trades per seconds + */ + tradesPerSecond: string; + /** + * Number of orders per seconds + */ + ordersPerSecond: string; + /** + * Average number of orders added per blocks + */ + averageOrdersPerBlock: string; + /** + * RFC3339Nano current time of the chain (decided through consensus) + */ + vegaTime: string; + /** + * Version of the Vega node (semver) + */ + appVersion: string; + /** + * Version of the chain (semver) + */ + chainVersion: string; + /** + * Current chain ID + */ + chainId: string; +} + +export interface NetworkStats { + /** + * returns information about nodes + */ + nodeData: NetworkStats_nodeData | null; + /** + * get statistics about the Vega node + */ + statistics: NetworkStats_statistics; +} diff --git a/libs/network-stats/src/components/stats-manager/stats-manager.tsx b/libs/network-stats/src/components/stats-manager/stats-manager.tsx index 4e55ac9bf..49d841e2e 100644 --- a/libs/network-stats/src/components/stats-manager/stats-manager.tsx +++ b/libs/network-stats/src/components/stats-manager/stats-manager.tsx @@ -1,5 +1,7 @@ -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import classnames from 'classnames'; +import { useQuery, gql } from '@apollo/client'; +import { useEnvironment } from '@vegaprotocol/environment'; import { statsFields } from '../../config/stats-fields'; import type { Stats as IStats, @@ -9,75 +11,75 @@ import { Table } from '../table'; import { TableRow } from '../table-row'; import { PromotedStats } from '../promoted-stats'; import { PromotedStatsItem } from '../promoted-stats-item'; +import type { NetworkStats } from './__generated__/NetworkStats'; interface StatsManagerProps { - envName: string; - statsEndpoint: string; - nodesEndpoint: string; className?: string; } -export const StatsManager = ({ - envName, - statsEndpoint, - nodesEndpoint, - className, -}: StatsManagerProps) => { - const [data, setData] = useState(null); - const [error, setError] = useState(null); +const STATS_QUERY = gql` + query NetworkStats { + nodeData { + stakedTotal + totalNodes + inactiveNodes + validatingNodes + uptime + } + statistics { + status + blockHeight + blockDuration + backlogLength + txPerBlock + tradesPerSecond + ordersPerSecond + averageOrdersPerBlock + vegaTime + appVersion + chainVersion + chainId + } + } +`; + +const compileData = (data?: NetworkStats) => { + const { nodeData, statistics } = data || {}; + const returned = { ...nodeData, ...statistics }; + + // Loop through the stats fields config, grabbing values from the fetched + // data and building a set of promoted and standard table entries. + return Object.entries(statsFields).reduce( + (acc, [key, value]) => { + const statKey = key as keyof IStats; + const statData = returned[statKey]; + + value.forEach((x) => { + const stat = { + ...x, + value: statData, + }; + + stat.promoted ? acc.promoted.push(stat) : acc.table.push(stat); + }); + + return acc; + }, + { promoted: [], table: [] } as IStructuredStats + ); +}; + +export const StatsManager = ({ className }: StatsManagerProps) => { + const { VEGA_ENV } = useEnvironment(); + const { data, error, startPolling, stopPolling } = + useQuery(STATS_QUERY); useEffect(() => { - async function getStats() { - try { - const [res1, res2] = await Promise.all([ - fetch(statsEndpoint), - fetch(nodesEndpoint), - ]); - const [{ statistics }, { nodeData }] = await Promise.all([ - res1.json(), - res2.json(), - ]); - const returned = { ...nodeData, ...statistics }; + startPolling(1000); + return () => stopPolling(); + }); - if (!statistics || !nodeData) { - throw new Error('Failed to get data from endpoints'); - } - - // Loop through the stats fields config, grabbing values from the fetched - // data and building a set of promoted and standard table entries. - const structured = Object.entries(statsFields).reduce( - (acc, [key, value]) => { - const statKey = key as keyof IStats; - const statData = returned[statKey]; - - value.forEach((x) => { - const stat = { - ...x, - value: statData, - }; - - stat.promoted ? acc.promoted.push(stat) : acc.table.push(stat); - }); - - return acc; - }, - { promoted: [], table: [] } as IStructuredStats - ); - - setData(structured); - setError(null); - } catch (e) { - setData(null); - setError(e as Error); - } - } - - const interval = setInterval(getStats, 1000); - - return () => { - clearInterval(interval); - }; - }, [nodesEndpoint, statsEndpoint]); + const displayData = compileData(data); const classes = classnames( className, @@ -90,12 +92,13 @@ export const StatsManager = ({ data-testid="stats-environment" className="font-alpha uppercase text-h3 pb-16 col-span-full" > - {(error && `/ ${error}`) || (data ? `/ ${envName}` : '/ Connecting...')} + {(error && `/ ${error}`) || + (data ? `/ ${VEGA_ENV}` : '/ Connecting...')} - {data?.promoted ? ( + {displayData?.promoted ? ( - {data.promoted.map((stat, i) => { + {displayData.promoted.map((stat, i) => { return ( - {data?.table - ? data.table.map((stat, i) => { + {displayData?.table + ? displayData.table.map((stat, i) => { return ( diff --git a/libs/network-stats/src/config/types.ts b/libs/network-stats/src/config/types.ts index 2cd040554..eee026171 100644 --- a/libs/network-stats/src/config/types.ts +++ b/libs/network-stats/src/config/types.ts @@ -1,22 +1,10 @@ -export interface Stats { - blockHeight: string; - totalNodes: string; - validatingNodes: string; - inactiveNodes: string; - stakedTotal: string; - backlogLength: string; - tradesPerSecond: string; - averageOrdersPerBlock: string; - ordersPerSecond: string; - txPerBlock: string; - blockDuration: string; - status: string; - vegaTime: string; - appVersion: string; - chainVersion: string; - uptime: string; - chainId: string; -} +import type { + NetworkStats_nodeData, + NetworkStats_statistics, +} from '../components/stats-manager/__generated__/NetworkStats'; + +export type Stats = Omit & + Omit; // eslint-disable-next-line export type value = any;