feat: update lp dashboard and multisigner app

This commit is contained in:
Matthew Russell
2023-02-15 11:48:50 -08:00
parent 2e307b2bb9
commit 8d6ea15b29
10 changed files with 95 additions and 49 deletions
@@ -1,3 +1,5 @@
import type { InMemoryCacheConfig } from '@apollo/client';
import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment';
import { useRoutes } from 'react-router-dom';
import '../styles.scss';
@@ -5,14 +7,40 @@ import { Navbar } from './components/navbar';
import { routerConfig } from './routes/router-config';
const cache: InMemoryCacheConfig = {
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
};
const AppRouter = () => useRoutes(routerConfig);
export function App() {
useInitializeEnv();
return (
<div className="max-h-full min-h-full bg-white">
<Navbar />
<AppRouter />
</div>
<NetworkLoader cache={cache}>
<div className="max-h-full min-h-full bg-white">
<Navbar />
<AppRouter />
</div>
</NetworkLoader>
);
}
@@ -1,44 +1,15 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
import App from './app/app';
import type { InMemoryCacheConfig } from '@apollo/client';
const rootElement = document.getElementById('root');
const root = rootElement && createRoot(rootElement);
const cache: InMemoryCacheConfig = {
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
};
root?.render(
<StrictMode>
<BrowserRouter>
<EnvironmentProvider>
<NetworkLoader cache={cache}>
<App />
</NetworkLoader>
</EnvironmentProvider>
<App />
</BrowserRouter>
</StrictMode>
);
+3
View File
@@ -2,3 +2,6 @@ NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=STAGNET3
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+4
View File
@@ -3,3 +3,7 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=DEVNET
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+2
View File
@@ -3,3 +3,5 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
NX_VEGA_URL=https://api.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=MAINNET
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://etherscan.io
+2
View File
@@ -3,3 +3,5 @@ NX_VEGA_URL=https://api.sandbox.vega.xyz/graphql
NX_VEGA_ENV=SANDBOX
NX_VEGA_NETWORKS={\"DEVNET\":\"https://dev.token.vega.xyz\",\"STAGNET3\":\"https://stagnet3.token.vega.xyz\",\"STAGNET1\":\"https://stagnet1.token.vega.xyz\",\"TESTNET\":\"https://token.fairground.wtf\",\"MAINNET\":\"https://token.vega.xyz\"}
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+2
View File
@@ -3,3 +3,5 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=STAGNET3
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+2
View File
@@ -3,3 +3,5 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=TESTNET
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+6 -6
View File
@@ -3,9 +3,9 @@ import classnames from 'classnames';
import { useEffect, useMemo, useState } from 'react';
import { BrowserTracing } from '@sentry/tracing';
import {
EnvironmentProvider,
NetworkLoader,
useEnvironment,
useInitializeEnv,
} from '@vegaprotocol/environment';
import { AsyncRenderer, Button, Lozenge } from '@vegaprotocol/ui-toolkit';
import type { EthereumConfig } from '@vegaprotocol/web3';
@@ -64,6 +64,7 @@ function App() {
environment: VEGA_ENV,
});
}, [VEGA_ENV]);
const Connectors = useMemo(() => {
if (config?.chain_id) {
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config.chain_id));
@@ -107,12 +108,11 @@ const Wrapper = () => {
},
},
};
useInitializeEnv();
return (
<EnvironmentProvider>
<NetworkLoader cache={cache}>
<App />
</NetworkLoader>
</EnvironmentProvider>
<NetworkLoader cache={cache}>
<App />
</NetworkLoader>
);
};
+41 -9
View File
@@ -44,6 +44,7 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
initialize: async () => {
set({ status: 'pending' });
// validate env vars
try {
const rawVars = compileEnvVars();
const safeVars = envSchema.parse(rawVars);
@@ -70,9 +71,7 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
console.warn(`Could not fetch node config from ${state.VEGA_CONFIG_URL}`);
}
// user has previously loaded the app and found
// a successful node, or chosen one manually - reconnect
// to same node
// Node url found in localStorage, if its valid attempt to connect
if (storedUrl) {
if (isValidUrl(storedUrl)) {
set({ VEGA_URL: storedUrl, status: 'success' });
@@ -82,12 +81,14 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
}
}
// VEGA_URL env var is set no need to find suitable node
// VEGA_URL env var is set and is a valid url no need to proceed
if (state.VEGA_URL) {
set({ status: 'success' });
return;
}
// No url found in env vars or localStorage, AND no nodes were found in
// the config fetched from VEGA_CONFIG_URL, app initialization has failed
if (!nodes || !nodes.length) {
set({
status: 'failed',
@@ -96,7 +97,7 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
return;
}
// create client and store instances
// Create a map of node urls to client instances
const clients: ClientCollection = {};
nodes.forEach((url) => {
clients[url] = createClient({
@@ -107,7 +108,8 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
});
});
// find a suitable node to connected, first one to respond is chosen
// Find a suitable node to connect to by attempting a query and a
// subscription, first to fulfill both will be the resulting url.
const url = await findNode(clients);
if (url !== null) {
@@ -116,7 +118,10 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
VEGA_URL: url,
});
LocalStorage.setItem(STORAGE_KEY, url);
} else {
}
// Every node failed either to make a query or retrieve data from
// a subscription
else {
set({
status: 'failed',
error: t('No node found'),
@@ -126,8 +131,13 @@ export const useEnvironment = create<EnvStore>((set, get) => ({
},
}));
// Use this to fetch node config and find suitable node
// if no NX_VEGA_URL is not provided
/**
* Initialize Vega app to dynamically select a node from the
* VEGA_CONFIG_URL
*
* This can be ommitted if you intend to only use a single node,
* in those cases be sure to set NX_VEGA_URL
*/
export const useInitializeEnv = () => {
const { initialize, status } = useEnvironment((store) => ({
status: store.status,
@@ -141,6 +151,9 @@ export const useInitializeEnv = () => {
}, [status, initialize]);
};
/**
* Fetch and validate a vega node configuration
*/
const fetchConfig = async (url?: string) => {
if (!url) return [];
const res = await fetch(url);
@@ -149,11 +162,18 @@ const fetchConfig = async (url?: string) => {
return result.hosts;
};
/**
* Find a suitable node by running a test query and test
* subscription, against a list of clients, first to resolve wins
*/
const findNode = (clients: ClientCollection): Promise<string | null> => {
const tests = Object.entries(clients).map((args) => testNode(...args));
return Promise.race(tests);
};
/**
* Test a node for suitability for connection
*/
const testNode = async (
url: string,
client: Client
@@ -173,6 +193,9 @@ const testNode = async (
}
};
/**
* Run a test query on a client
*/
const testQuery = async (client: Client) => {
try {
const result = await client.query<StatisticsQuery>({
@@ -187,6 +210,11 @@ const testQuery = async (client: Client) => {
}
};
/**
* Run a test subscription on a client. A subscription
* that takes longer than SUBSCRIPTION_TIMEOUT ms to respond
* is deemed a failure
*/
const testSubscription = (client: Client) => {
return new Promise((resolve) => {
const sub = client
@@ -212,6 +240,10 @@ const testSubscription = (client: Client) => {
});
};
/**
* Retrieve env vars, parsing where needed some type casting is needed
* here to appease the environment store interface
*/
function compileEnvVars() {
const env = {
VEGA_URL: process.env['NX_VEGA_URL'],