Merge branch 'master' of github.com:vegaprotocol/frontend-monorepo
This commit is contained in:
commit
865666f9e8
@ -2,7 +2,7 @@ NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-exp
|
|||||||
NX_TENDERMINT_URL=http://localhost:26617
|
NX_TENDERMINT_URL=http://localhost:26617
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||||
NX_VEGA_URL=http://localhost:3028/query
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_ENV=LOCAL
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_REST=http://localhost:3029
|
NX_VEGA_REST=http://localhost:3029
|
||||||
|
|
||||||
CYPRESS_VEGA_TENDERMINT_URL=http://localhost:26617
|
CYPRESS_VEGA_TENDERMINT_URL=http://localhost:26617
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"screenshotsFolder": "../../dist/cypress/apps/explorer-e2e/screenshots",
|
"screenshotsFolder": "../../dist/cypress/apps/explorer-e2e/screenshots",
|
||||||
"chromeWebSecurity": false,
|
"chromeWebSecurity": false,
|
||||||
"env": {
|
"env": {
|
||||||
"environment": "local",
|
"environment": "CUSTOM",
|
||||||
"tsConfig": "tsconfig.json",
|
"tsConfig": "tsconfig.json",
|
||||||
"TAGS": "not @todo and not @ignore and not @manual"
|
"TAGS": "not @todo and not @ignore and not @manual"
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-exp
|
|||||||
NX_TENDERMINT_URL=http://localhost:26617
|
NX_TENDERMINT_URL=http://localhost:26617
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||||
NX_VEGA_URL=http://localhost:3028/query
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_ENV=LOCAL
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_REST=http://localhost:3029
|
NX_VEGA_REST=http://localhost:3029
|
||||||
|
|
||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
|
@ -4,7 +4,7 @@ NX_TENDERMINT_URL=http://localhost:26617
|
|||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||||
NX_VEGA_URL=http://localhost:3028/query
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=LOCAL
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_REST=http://localhost:3029
|
NX_VEGA_REST=http://localhost:3029
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
|
NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
||||||
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||||
NX_VEGA_URL=https://api.token.vega.xyz/query
|
NX_VEGA_URL=https://api.token.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://n03.s.vega.xyz/tm
|
NX_TENDERMINT_URL=https://n03.s.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n03.s.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://n03.s.vega.xyz/tm/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json
|
||||||
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=STAGNET
|
NX_VEGA_ENV=STAGNET
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://n03.stagnet2.vega.xyz/tm
|
NX_TENDERMINT_URL=https://n03.stagnet2.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n03.stagnet2.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://n03.stagnet2.vega.xyz/tm/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet2-network.json
|
||||||
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=STAGNET2
|
NX_VEGA_ENV=STAGNET2
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=https://lb.testnet.vega.xyz/tm
|
NX_TENDERMINT_URL=https://lb.testnet.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import { useState, useEffect, useMemo } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { ApolloProvider } from '@apollo/client';
|
|
||||||
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||||
import { EnvironmentProvider } from '@vegaprotocol/network-switcher';
|
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||||
import { createClient } from './lib/apollo-client';
|
import { createClient } from './lib/apollo-client';
|
||||||
import { Nav } from './components/nav';
|
import { Nav } from './components/nav';
|
||||||
import { Header } from './components/header';
|
import { Header } from './components/header';
|
||||||
import { Main } from './components/main';
|
import { Main } from './components/main';
|
||||||
import { DATA_SOURCES } from './config';
|
|
||||||
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -20,13 +18,11 @@ function App() {
|
|||||||
setMenuOpen(false);
|
setMenuOpen(false);
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
const client = useMemo(() => createClient(DATA_SOURCES.dataNodeUrl), []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<EnvironmentProvider>
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<TendermintWebsocketProvider>
|
<TendermintWebsocketProvider>
|
||||||
<ApolloProvider client={client}>
|
<NetworkLoader createClient={createClient}>
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
menuOpen && 'h-[100vh] overflow-hidden'
|
menuOpen && 'h-[100vh] overflow-hidden'
|
||||||
@ -42,7 +38,7 @@ function App() {
|
|||||||
<Main />
|
<Main />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ApolloProvider>
|
</NetworkLoader>
|
||||||
</TendermintWebsocketProvider>
|
</TendermintWebsocketProvider>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</EnvironmentProvider>
|
</EnvironmentProvider>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import routerConfig from '../../routes/router-config';
|
import routerConfig from '../../routes/router-config';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
interface NavProps {
|
interface NavProps {
|
||||||
menuOpen: boolean;
|
menuOpen: boolean;
|
||||||
@ -9,18 +10,29 @@ export const Nav = ({ menuOpen }: NavProps) => {
|
|||||||
return (
|
return (
|
||||||
<nav className="relative">
|
<nav className="relative">
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={classnames(
|
||||||
menuOpen ? 'right-0 h-[100vh]' : 'right-[200vw] h-full'
|
'absolute top-0 z-50 md:static',
|
||||||
} transition-[right] absolute top-0 w-full md:static md:border-r-1 bg-white dark:bg-black p-20`}
|
'w-full p-20 md:border-r-1',
|
||||||
|
'bg-white dark:bg-black',
|
||||||
|
'transition-[right]',
|
||||||
|
{
|
||||||
|
'right-0 h-[100vh]': menuOpen,
|
||||||
|
'right-[200vw] h-full': !menuOpen,
|
||||||
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{routerConfig.map((r) => (
|
{routerConfig.map((r) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
key={r.name}
|
key={r.name}
|
||||||
to={r.path}
|
to={r.path}
|
||||||
className={({ isActive }) =>
|
className={({ isActive }) =>
|
||||||
`text-h5 block mb-8 px-8 hover:bg-vega-yellow hover:text-black ${
|
classnames(
|
||||||
isActive && 'bg-vega-yellow text-black'
|
'block mb-8 px-8',
|
||||||
}`
|
'text-h5 hover:bg-vega-yellow hover:text-black',
|
||||||
|
{
|
||||||
|
'bg-vega-yellow text-black': isActive,
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{r.text}
|
{r.text}
|
||||||
|
@ -17,3 +17,7 @@ NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|||||||
NX_URL=$URL
|
NX_URL=$URL
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
NX_DEPLOY_URL=$DEPLOY_URL
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
||||||
|
|
||||||
|
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/testnet-network.json"
|
||||||
|
NX_VEGA_ENV = 'TESTNET'
|
||||||
|
NX_VEGA_URL="https://lb.testnet.vega.xyz/query"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
||||||
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest
|
NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||||
NX_VEGA_URL=https://api.token.vega.xyz/query
|
NX_VEGA_URL=https://api.token.vega.xyz/query
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
NX_VEGA_REST=https://api.token.vega.xyz/
|
NX_VEGA_REST=https://api.token.vega.xyz/
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json
|
||||||
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
||||||
NX_VEGA_ENV=STAGNET
|
NX_VEGA_ENV=STAGNET
|
||||||
NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest
|
NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet2-network.json
|
||||||
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
||||||
NX_VEGA_ENV=STAGNET2
|
NX_VEGA_ENV=STAGNET2
|
||||||
NX_VEGA_REST=https://n01.stagnet2.vega.xyz/datanode/rest
|
NX_VEGA_REST=https://n01.stagnet2.vega.xyz/datanode/rest
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest
|
NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import React, { useState, useMemo, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { ApolloProvider } from '@apollo/client';
|
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||||
|
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||||
import { createClient } from './lib/apollo-client';
|
import { createClient } from './lib/apollo-client';
|
||||||
import { DATA_SOURCES } from './config';
|
|
||||||
import {
|
import {
|
||||||
VegaConnectDialog,
|
VegaConnectDialog,
|
||||||
VegaManageDialog,
|
VegaManageDialog,
|
||||||
VegaWalletProvider,
|
VegaWalletProvider,
|
||||||
} from '@vegaprotocol/wallet';
|
} from '@vegaprotocol/wallet';
|
||||||
import { EnvironmentProvider } from '@vegaprotocol/network-switcher';
|
|
||||||
import { VegaWalletConnectButton } from './components/vega-wallet-connect-button';
|
import { VegaWalletConnectButton } from './components/vega-wallet-connect-button';
|
||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Connectors } from './lib/vega-connectors';
|
import { Connectors } from './lib/vega-connectors';
|
||||||
@ -26,8 +24,6 @@ function App() {
|
|||||||
manage: false,
|
manage: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const client = useMemo(() => createClient(DATA_SOURCES.dataNodeUrl), []);
|
|
||||||
|
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
const onToggle = () => setMenuOpen(!menuOpen);
|
const onToggle = () => setMenuOpen(!menuOpen);
|
||||||
|
|
||||||
@ -40,7 +36,7 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<EnvironmentProvider>
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<ApolloProvider client={client}>
|
<NetworkLoader createClient={createClient}>
|
||||||
<VegaWalletProvider>
|
<VegaWalletProvider>
|
||||||
<AppLoader>
|
<AppLoader>
|
||||||
<div className="max-h-full min-h-full dark:bg-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
<div className="max-h-full min-h-full dark:bg-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
||||||
@ -82,7 +78,7 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</AppLoader>
|
</AppLoader>
|
||||||
</VegaWalletProvider>
|
</VegaWalletProvider>
|
||||||
</ApolloProvider>
|
</NetworkLoader>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</EnvironmentProvider>
|
</EnvironmentProvider>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
export const DATA_SOURCES = {
|
|
||||||
dataNodeUrl: process.env['NX_VEGA_URL'] as string,
|
|
||||||
envName: process.env['NX_VEGA_ENV'] as string,
|
|
||||||
restEndpoint: process.env['NX_VEGA_REST'] as string,
|
|
||||||
};
|
|
3
apps/static/src/assets/devnet-network.json
Normal file
3
apps/static/src/assets/devnet-network.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"hosts": ["https://n04.d.vega.xyz/query"]
|
||||||
|
}
|
17
apps/static/src/assets/mainnet-network.json
Normal file
17
apps/static/src/assets/mainnet-network.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"hosts": [
|
||||||
|
"https://vega-data-graphql.chorus.one/query",
|
||||||
|
"https://vega.xprv.io/datanode/query",
|
||||||
|
"http://nala.mainnet.vega.community:3008/query",
|
||||||
|
"http://commodum.mainnet.vega.community:3008/query",
|
||||||
|
"http://lovali.mainnet.vega.community:3008/query",
|
||||||
|
"http://b-harvest.mainnet.vega.community:3008/query",
|
||||||
|
"http://staking-facilities.mainnet.vega.community:3008/query",
|
||||||
|
"http://figment.mainnet.vega.community:3008/query",
|
||||||
|
"http://nodes-guru.mainnet.vega.community:3008/query",
|
||||||
|
"http://p2p.mainnet.vega.community:3008/query",
|
||||||
|
"http://rockaway.mainnet.vega.community:3008/query",
|
||||||
|
"http://greenfield-one.mainnet.vega.community:3008/query",
|
||||||
|
"http://ryabina.mainnet.vega.community:3008/query"
|
||||||
|
]
|
||||||
|
}
|
@ -38,7 +38,7 @@
|
|||||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||||
"total_added": "129999.45",
|
"total_added": "129999.45",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "126083.60755114557871263",
|
"locked_amount": "125847.249906896297139465",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "129999.45",
|
"amount": "129999.45",
|
||||||
@ -488,7 +488,7 @@
|
|||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "97499.58",
|
"total_added": "97499.58",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "66898.475411270217320484",
|
"locked_amount": "66666.63057997215661197",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "97499.58",
|
"amount": "97499.58",
|
||||||
@ -521,7 +521,7 @@
|
|||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "135173.4239508",
|
"total_added": "135173.4239508",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "91438.66634724655576238350452",
|
"locked_amount": "91121.77448920241599915064844",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "135173.4239508",
|
"amount": "135173.4239508",
|
||||||
@ -554,7 +554,7 @@
|
|||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "32499.86",
|
"total_added": "32499.86",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "28143.033330644803332098",
|
"locked_amount": "28045.500213863789588014",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "32499.86",
|
"amount": "32499.86",
|
||||||
@ -587,7 +587,7 @@
|
|||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "10833.29",
|
"total_added": "10833.29",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "9160.28425559368165759",
|
"locked_amount": "9128.538172520424723312",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "10833.29",
|
"amount": "10833.29",
|
||||||
@ -675,7 +675,7 @@
|
|||||||
"tranche_end": "2022-11-01T00:00:00.000Z",
|
"tranche_end": "2022-11-01T00:00:00.000Z",
|
||||||
"total_added": "22500",
|
"total_added": "22500",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "16201.60778985507",
|
"locked_amount": "16079.77241847825975",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "15000",
|
"amount": "15000",
|
||||||
@ -761,7 +761,7 @@
|
|||||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||||
"total_added": "1939928.38",
|
"total_added": "1939928.38",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "1836251.953940101595446458",
|
"locked_amount": "1830956.520319353226245706",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1852091.69",
|
"amount": "1852091.69",
|
||||||
@ -1777,7 +1777,7 @@
|
|||||||
"tranche_end": "2022-09-30T00:00:00.000Z",
|
"tranche_end": "2022-09-30T00:00:00.000Z",
|
||||||
"total_added": "60916.66666633337",
|
"total_added": "60916.66666633337",
|
||||||
"total_removed": "18323.723696937179372649",
|
"total_removed": "18323.723696937179372649",
|
||||||
"locked_amount": "15696.6861743364004734599556982002",
|
"locked_amount": "15541.060867673757124652184217191",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "2833.333333",
|
"amount": "2833.333333",
|
||||||
@ -3228,10 +3228,20 @@
|
|||||||
"tranche_id": 10,
|
"tranche_id": 10,
|
||||||
"tranche_start": "2021-07-15T23:37:11.000Z",
|
"tranche_start": "2021-07-15T23:37:11.000Z",
|
||||||
"tranche_end": "2021-07-15T23:37:11.000Z",
|
"tranche_end": "2021-07-15T23:37:11.000Z",
|
||||||
"total_added": "3623768.150000000000000001",
|
"total_added": "3653968.150000000000000001",
|
||||||
"total_removed": "3615578.640000000000000001",
|
"total_removed": "3645778.640000000000000001",
|
||||||
"locked_amount": "0",
|
"locked_amount": "0",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
|
{
|
||||||
|
"amount": "30000",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tx": "0xf366a57fa7a16029a9581c3f8e0ab19eee6f0758b60242fb59000df38a359e51"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amount": "200",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tx": "0x7b0e95e1914579c79eff111dd0df59e767321858e552cbd2a65e5f0ea8c60868"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "40000",
|
"amount": "40000",
|
||||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
@ -3649,6 +3659,16 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "30000",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tx": "0x9ba5590885e34d6a61031167adaaa47a1f0b76d254813f93560d3b31f32b5c21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amount": "200",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tx": "0xc5ad7140387b5c2eeeae5c158d97a8df0d4c0bbae4a61b3c03c784f11272c89a"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "40000",
|
"amount": "40000",
|
||||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
@ -4009,6 +4029,18 @@
|
|||||||
{
|
{
|
||||||
"address": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
"address": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
|
{
|
||||||
|
"amount": "30000",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tranche_id": 10,
|
||||||
|
"tx": "0xf366a57fa7a16029a9581c3f8e0ab19eee6f0758b60242fb59000df38a359e51"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amount": "200",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tranche_id": 10,
|
||||||
|
"tx": "0x7b0e95e1914579c79eff111dd0df59e767321858e552cbd2a65e5f0ea8c60868"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "40000",
|
"amount": "40000",
|
||||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
@ -4083,6 +4115,18 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "30000",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tranche_id": 10,
|
||||||
|
"tx": "0x9ba5590885e34d6a61031167adaaa47a1f0b76d254813f93560d3b31f32b5c21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amount": "200",
|
||||||
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
|
"tranche_id": 10,
|
||||||
|
"tx": "0xc5ad7140387b5c2eeeae5c158d97a8df0d4c0bbae4a61b3c03c784f11272c89a"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "40000",
|
"amount": "40000",
|
||||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||||
@ -4150,8 +4194,8 @@
|
|||||||
"tx": "0xac16a4ce688d40a482a59914d68c3a676592f8804ee8f0781b66a4ba5ccfbdfc"
|
"tx": "0xac16a4ce688d40a482a59914d68c3a676592f8804ee8f0781b66a4ba5ccfbdfc"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "477451",
|
"total_tokens": "507651",
|
||||||
"withdrawn_tokens": "477451",
|
"withdrawn_tokens": "507651",
|
||||||
"remaining_tokens": "0"
|
"remaining_tokens": "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -5151,7 +5195,7 @@
|
|||||||
"tranche_end": "2022-09-03T00:00:00.000Z",
|
"tranche_end": "2022-09-03T00:00:00.000Z",
|
||||||
"total_added": "19455.000000000000000003",
|
"total_added": "19455.000000000000000003",
|
||||||
"total_removed": "5052.45813105178",
|
"total_removed": "5052.45813105178",
|
||||||
"locked_amount": "3917.2854718417039110006040532724505326",
|
"locked_amount": "3864.17904680365295175059586415525114155",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "75",
|
"amount": "75",
|
||||||
@ -14035,7 +14079,7 @@
|
|||||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||||
"total_added": "3732368.4671",
|
"total_added": "3732368.4671",
|
||||||
"total_removed": "74162.9780761646031",
|
"total_removed": "74162.9780761646031",
|
||||||
"locked_amount": "2846181.26290712673207575918",
|
"locked_amount": "2838044.0251062046717742172",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1998.95815",
|
"amount": "1998.95815",
|
||||||
@ -14747,8 +14791,8 @@
|
|||||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||||
"total_added": "15788853.065470999700000001",
|
"total_added": "15788853.065470999700000001",
|
||||||
"total_removed": "5344.1456869113936",
|
"total_removed": "5923.782558947259825",
|
||||||
"locked_amount": "15313261.3529483959820569576103939875696134",
|
"locked_amount": "15284554.9536832239111747473350177541524737",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "16249.93",
|
"amount": "16249.93",
|
||||||
@ -15242,6 +15286,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "579.636872035866225",
|
||||||
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
|
"tx": "0xb11f9f763196e40be412b1c6992f64d3a73b094833f57eb7783a050c64ec159d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "2446.31552516990115",
|
"amount": "2446.31552516990115",
|
||||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
@ -15328,6 +15377,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "579.636872035866225",
|
||||||
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
|
"tranche_id": 2,
|
||||||
|
"tx": "0xb11f9f763196e40be412b1c6992f64d3a73b094833f57eb7783a050c64ec159d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "2446.31552516990115",
|
"amount": "2446.31552516990115",
|
||||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||||
@ -15372,8 +15427,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "194999.1675",
|
"total_tokens": "194999.1675",
|
||||||
"withdrawn_tokens": "5344.1456869113936",
|
"withdrawn_tokens": "5923.782558947259825",
|
||||||
"remaining_tokens": "189655.0218130886064"
|
"remaining_tokens": "189075.384941052740175"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||||
@ -16777,8 +16832,8 @@
|
|||||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||||
"total_added": "14597706.0446472999",
|
"total_added": "14597706.0446472999",
|
||||||
"total_removed": "2067913.758606456406425022",
|
"total_removed": "2068423.077146290360122272",
|
||||||
"locked_amount": "8488409.61145846751607779171034843",
|
"locked_amount": "8461771.6695419306722268828527521",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "129284.449",
|
"amount": "129284.449",
|
||||||
@ -16987,6 +17042,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "509.31853983395369725",
|
||||||
|
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||||
|
"tx": "0xa7bccea82ef34f1943bc5243ef75909d8ae81c45e67862b9c68b0a7532edc833"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "652.48254356494551875",
|
"amount": "652.48254356494551875",
|
||||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||||
@ -18563,6 +18623,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "509.31853983395369725",
|
||||||
|
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||||
|
"tranche_id": 3,
|
||||||
|
"tx": "0xa7bccea82ef34f1943bc5243ef75909d8ae81c45e67862b9c68b0a7532edc833"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "652.48254356494551875",
|
"amount": "652.48254356494551875",
|
||||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||||
@ -19801,8 +19867,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "359123.469575",
|
"total_tokens": "359123.469575",
|
||||||
"withdrawn_tokens": "149880.84354723987146575",
|
"withdrawn_tokens": "150390.162087073825163",
|
||||||
"remaining_tokens": "209242.62602776012853425"
|
"remaining_tokens": "208733.307487926174837"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
|
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
|
||||||
@ -20792,8 +20858,8 @@
|
|||||||
"tranche_start": "2021-10-05T00:00:00.000Z",
|
"tranche_start": "2021-10-05T00:00:00.000Z",
|
||||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||||
"total_added": "5778205.3912159303",
|
"total_added": "5778205.3912159303",
|
||||||
"total_removed": "1386457.324778695108317227",
|
"total_removed": "1390546.591547348229906227",
|
||||||
"locked_amount": "3036918.57142096853937026120833696",
|
"locked_amount": "3026393.75946481397995019109643517",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "552496.6455",
|
"amount": "552496.6455",
|
||||||
@ -20937,6 +21003,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "4089.266768653121589",
|
||||||
|
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
||||||
|
"tx": "0xa6b9993b9288eac739756499b2997155ce8b1bc6e862c1a6569c8e04463bb31f"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "13341.31568777778021",
|
"amount": "13341.31568777778021",
|
||||||
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
||||||
@ -21765,6 +21836,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"withdrawals": [
|
"withdrawals": [
|
||||||
|
{
|
||||||
|
"amount": "4089.266768653121589",
|
||||||
|
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
||||||
|
"tranche_id": 4,
|
||||||
|
"tx": "0xa6b9993b9288eac739756499b2997155ce8b1bc6e862c1a6569c8e04463bb31f"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"amount": "13341.31568777778021",
|
"amount": "13341.31568777778021",
|
||||||
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
|
||||||
@ -21827,8 +21904,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_tokens": "331498.5873",
|
"total_tokens": "331498.5873",
|
||||||
"withdrawn_tokens": "153215.022368261786721",
|
"withdrawn_tokens": "157304.28913691490831",
|
||||||
"remaining_tokens": "178283.564931738213279"
|
"remaining_tokens": "174194.29816308509169"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0x16da609341ed67750A8BCC5AAa2005471006Cd77",
|
"address": "0x16da609341ed67750A8BCC5AAa2005471006Cd77",
|
||||||
@ -21905,7 +21982,7 @@
|
|||||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||||
"total_added": "472355.6199999996",
|
"total_added": "472355.6199999996",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "450993.69057334309059999665956368",
|
"locked_amount": "449704.29872935272705903095281584",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "3000",
|
"amount": "3000",
|
||||||
|
3
apps/static/src/assets/stagnet1-network.json
Normal file
3
apps/static/src/assets/stagnet1-network.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"hosts": ["https://n03.s.vega.xyz/query"]
|
||||||
|
}
|
@ -38,7 +38,7 @@
|
|||||||
"tranche_end": "2022-11-26T13:48:10.000Z",
|
"tranche_end": "2022-11-26T13:48:10.000Z",
|
||||||
"total_added": "100",
|
"total_added": "100",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "43.306395865043124",
|
"locked_amount": "43.033418949771685",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "100",
|
"amount": "100",
|
||||||
@ -242,7 +242,7 @@
|
|||||||
"tranche_end": "2022-10-12T00:53:20.000Z",
|
"tranche_end": "2022-10-12T00:53:20.000Z",
|
||||||
"total_added": "1100",
|
"total_added": "1100",
|
||||||
"total_removed": "673.04388635",
|
"total_removed": "673.04388635",
|
||||||
"locked_amount": "339.13230910705234",
|
"locked_amount": "336.1295630390665",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1000",
|
"amount": "1000",
|
||||||
|
3
apps/static/src/assets/stagnet2-network.json
Normal file
3
apps/static/src/assets/stagnet2-network.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"hosts": ["https://n03.stagnet2.vega.xyz/query"]
|
||||||
|
}
|
3
apps/static/src/assets/testnet-network.json
Normal file
3
apps/static/src/assets/testnet-network.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"hosts": ["https://lb.testnet.vega.xyz/query"]
|
||||||
|
}
|
@ -69,7 +69,7 @@
|
|||||||
"tranche_end": "2022-10-12T00:53:20.000Z",
|
"tranche_end": "2022-10-12T00:53:20.000Z",
|
||||||
"total_added": "1010.000000000000000001",
|
"total_added": "1010.000000000000000001",
|
||||||
"total_removed": "668.4622323651",
|
"total_removed": "668.4622323651",
|
||||||
"locked_amount": "311.3851201801116940003083020991882294",
|
"locked_amount": "308.628053335870150000305572330035515",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1000",
|
"amount": "1000",
|
||||||
|
@ -3,7 +3,6 @@ import { DATA_SOURCES } from './config';
|
|||||||
import { Header } from './components/header';
|
import { Header } from './components/header';
|
||||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||||
import { EnvironmentProvider } from '@vegaprotocol/network-switcher';
|
|
||||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
const envName = DATA_SOURCES.envName;
|
const envName = DATA_SOURCES.envName;
|
||||||
@ -15,7 +14,6 @@ function App() {
|
|||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
const [theme, toggleTheme] = useThemeSwitcher();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-black-95 dark:bg-black dark:text-white-80">
|
<div className="w-screen min-h-screen grid pb-24 bg-white text-black-95 dark:bg-black dark:text-white-80">
|
||||||
<div className="layout-grid w-screen justify-self-center">
|
<div className="layout-grid w-screen justify-self-center">
|
||||||
@ -29,7 +27,6 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</EnvironmentProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ REACT_APP_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
NX_FAIRGROUND=false
|
NX_FAIRGROUND=false
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
NX_VEGA_URL=https://api.token.vega.xyz/query
|
NX_VEGA_URL=https://api.token.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=1
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET
|
NX_VEGA_ENV=STAGNET
|
||||||
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET2
|
NX_VEGA_ENV=STAGNET2
|
||||||
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -20,8 +20,8 @@ REACT_APP_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
NX_FAIRGROUND=false
|
NX_FAIRGROUND=false
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
||||||
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||||
NX_VEGA_URL=https://api.token.vega.xyz/query
|
NX_VEGA_URL=https://api.token.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=1
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET
|
NX_VEGA_ENV=STAGNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json
|
||||||
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET2
|
NX_VEGA_ENV=STAGNET2
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet2-network.json
|
||||||
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -48,13 +48,13 @@ There are a few different configuration options offered for this app:
|
|||||||
| `NX_APP_INFURA_ID` | Infura fallback for if the user does not have a web3 compatible browser |
|
| `NX_APP_INFURA_ID` | Infura fallback for if the user does not have a web3 compatible browser |
|
||||||
| `NX_APP_HOSTED_WALLET_ENABLED` | If the hosted wallet is enabled or not. If so then allow users to login using the hosted wallet |
|
| `NX_APP_HOSTED_WALLET_ENABLED` | If the hosted wallet is enabled or not. If so then allow users to login using the hosted wallet |
|
||||||
| `NX_APP_ENV` | Change network to connect to. When set to CUSTOM use CUSTOM\_\* vars for network parameters |
|
| `NX_APP_ENV` | Change network to connect to. When set to CUSTOM use CUSTOM\_\* vars for network parameters |
|
||||||
| `CUSTOM_URLS` | When NX_APP_ENV=CUSTOM use these Data Node REST URLs, optional if CUSTOM_URLS_WITH_GRAPHQL is used. |
|
| `NX_CUSTOM_URLS` | When NX_APP_ENV=CUSTOM use these Data Node REST URLs, optional if CUSTOM_URLS_WITH_GRAPHQL is used. |
|
||||||
| `CUSTOM_URLS_WITH_GRAPHQL` | When NX_APP_ENV=CUSTOM use these Data Node GraphQL URLs, optional if CUSTOM_URLS is used. |
|
| `NX_CUSTOM_URLS_WITH_GRAPHQL` | When NX_APP_ENV=CUSTOM use these Data Node GraphQL URLs, optional if CUSTOM_URLS is used. |
|
||||||
| `CUSTOM_TOKEN_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega token address. |
|
| `NX_CUSTOM_TOKEN_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega token address. |
|
||||||
| `CUSTOM_CLAIM_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega claim address. |
|
| `NX_CUSTOM_CLAIM_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega claim address. |
|
||||||
| `CUSTOM_LOCKED_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega locked address. |
|
| `NX_CUSTOM_LOCKED_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega locked address. |
|
||||||
| `CUSTOM_VESTING_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega vesting address. |
|
| `NX_CUSTOM_VESTING_ADDRESS` | When NX_APP_ENV=CUSTOM specify Vega vesting address. |
|
||||||
| `CUSTOM_STAKING_BRIDGE` | When NX_APP_ENV=CUSTOM specify Vega staking bridge address. |
|
| `NX_CUSTOM_STAKING_BRIDGE` | When NX_APP_ENV=CUSTOM specify Vega staking bridge address. |
|
||||||
|
|
||||||
## Example configs:
|
## Example configs:
|
||||||
|
|
||||||
|
@ -17,27 +17,31 @@ import { AppRouter } from './routes';
|
|||||||
import { Web3Provider } from '@vegaprotocol/web3';
|
import { Web3Provider } from '@vegaprotocol/web3';
|
||||||
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
|
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
|
||||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||||
import { createConnectors } from './lib/web3-connectors';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { ApolloProvider } from '@apollo/client';
|
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { createClient } from './lib/apollo-client';
|
|
||||||
import {
|
import {
|
||||||
EnvironmentProvider,
|
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
} from '@vegaprotocol/network-switcher';
|
EnvironmentProvider,
|
||||||
|
NetworkLoader,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
|
import { createClient } from './lib/apollo-client';
|
||||||
|
import { createConnectors } from './lib/web3-connectors';
|
||||||
|
|
||||||
const AppContainer = () => {
|
const AppContainer = () => {
|
||||||
const sideBar = React.useMemo(() => [<EthWallet />, <VegaWallet />], []);
|
const sideBar = React.useMemo(() => [<EthWallet />, <VegaWallet />], []);
|
||||||
const { ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID, VEGA_URL } =
|
const { config, loading, error } = useEthereumConfig();
|
||||||
useEnvironment();
|
const { ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||||
const Connectors = useMemo(
|
const Connectors = useMemo(() => {
|
||||||
() => createConnectors(ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID),
|
if (config?.chain_id) {
|
||||||
[ETHEREUM_CHAIN_ID, ETHEREUM_PROVIDER_URL]
|
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config.chain_id));
|
||||||
);
|
}
|
||||||
const client = useMemo(() => createClient(VEGA_URL), [VEGA_URL]);
|
return undefined;
|
||||||
|
}, [config?.chain_id, ETHEREUM_PROVIDER_URL]);
|
||||||
return (
|
return (
|
||||||
<ApolloProvider client={client}>
|
|
||||||
<Router>
|
<Router>
|
||||||
<AppStateProvider>
|
<AppStateProvider>
|
||||||
|
<AsyncRenderer loading={loading} data={config} error={error}>
|
||||||
|
{Connectors && (
|
||||||
<Web3Provider connectors={Connectors}>
|
<Web3Provider connectors={Connectors}>
|
||||||
<Web3Connector>
|
<Web3Connector>
|
||||||
<VegaWalletProvider>
|
<VegaWalletProvider>
|
||||||
@ -61,16 +65,19 @@ const AppContainer = () => {
|
|||||||
</VegaWalletProvider>
|
</VegaWalletProvider>
|
||||||
</Web3Connector>
|
</Web3Connector>
|
||||||
</Web3Provider>
|
</Web3Provider>
|
||||||
|
)}
|
||||||
|
</AsyncRenderer>
|
||||||
</AppStateProvider>
|
</AppStateProvider>
|
||||||
</Router>
|
</Router>
|
||||||
</ApolloProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<EnvironmentProvider>
|
||||||
|
<NetworkLoader createClient={createClient}>
|
||||||
<AppContainer />
|
<AppContainer />
|
||||||
|
</NetworkLoader>
|
||||||
</EnvironmentProvider>
|
</EnvironmentProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
|
||||||
import { useAddAssetSupported } from '../../hooks/use-add-asset-to-wallet';
|
import { useAddAssetSupported } from '../../hooks/use-add-asset-to-wallet';
|
||||||
import vegaVesting from '../../images/vega_vesting.png';
|
import vegaVesting from '../../images/vega_vesting.png';
|
||||||
import { AddTokenButtonLink } from '../add-token-button/add-token-button';
|
import { AddTokenButtonLink } from '../add-token-button/add-token-button';
|
||||||
import { Callout } from '@vegaprotocol/ui-toolkit';
|
import { Callout } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { ENV } from '../../config/env';
|
||||||
|
|
||||||
export const AddLockedTokenAddress = () => {
|
export const AddLockedTokenAddress = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const addSupported = useAddAssetSupported();
|
const addSupported = useAddAssetSupported();
|
||||||
const { ADDRESSES } = useEnvironment();
|
|
||||||
return (
|
return (
|
||||||
<Callout
|
<Callout
|
||||||
title={t(
|
title={t(
|
||||||
@ -20,7 +19,7 @@ export const AddLockedTokenAddress = () => {
|
|||||||
<>
|
<>
|
||||||
<p className="flex justify-center">
|
<p className="flex justify-center">
|
||||||
<AddTokenButtonLink
|
<AddTokenButtonLink
|
||||||
address={ADDRESSES.lockedAddress}
|
address={ENV.addresses.lockedAddress}
|
||||||
symbol="VEGA🔒"
|
symbol="VEGA🔒"
|
||||||
decimals={18}
|
decimals={18}
|
||||||
image={vegaVesting}
|
image={vegaVesting}
|
||||||
@ -36,7 +35,7 @@ export const AddLockedTokenAddress = () => {
|
|||||||
{t(
|
{t(
|
||||||
'The token address is {{address}}. Hit the add token button in your ERC20 wallet and enter this address.',
|
'The token address is {{address}}. Hit the add token button in your ERC20 wallet and enter this address.',
|
||||||
{
|
{
|
||||||
address: ADDRESSES.lockedAddress,
|
address: ENV.addresses.lockedAddress,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
import { Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
|
|
||||||
export const TransactionComplete = ({
|
export const TransactionComplete = ({
|
||||||
|
@ -2,7 +2,7 @@ import { Button, Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
export interface TransactionErrorProps {
|
export interface TransactionErrorProps {
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { Callout, Loader } from '@vegaprotocol/ui-toolkit';
|
import { Callout, Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
export const TransactionPending = ({
|
export const TransactionPending = ({
|
||||||
hash,
|
hash,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Dialog, Link } from '@vegaprotocol/ui-toolkit';
|
import { Dialog, Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||||
|
import { Button, Splash, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Web3ConnectDialog } from '@vegaprotocol/web3';
|
import { Web3ConnectDialog } from '@vegaprotocol/web3';
|
||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
@ -16,30 +17,35 @@ interface Web3ConnectorProps {
|
|||||||
|
|
||||||
export function Web3Connector({ children }: Web3ConnectorProps) {
|
export function Web3Connector({ children }: Web3ConnectorProps) {
|
||||||
const { appState, appDispatch } = useAppState();
|
const { appState, appDispatch } = useAppState();
|
||||||
const { ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID } = useEnvironment();
|
const { ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||||
const Connectors = useMemo(
|
const { config, loading, error } = useEthereumConfig();
|
||||||
() => createConnectors(ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID),
|
const Connectors = useMemo(() => {
|
||||||
[ETHEREUM_CHAIN_ID, ETHEREUM_PROVIDER_URL]
|
if (config?.chain_id) {
|
||||||
);
|
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config.chain_id));
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}, [config?.chain_id, ETHEREUM_PROVIDER_URL]);
|
||||||
const setDialogOpen = useCallback(
|
const setDialogOpen = useCallback(
|
||||||
(isOpen: boolean) => {
|
(isOpen: boolean) => {
|
||||||
appDispatch({ type: AppStateActionType.SET_ETH_WALLET_OVERLAY, isOpen });
|
appDispatch({ type: AppStateActionType.SET_ETH_WALLET_OVERLAY, isOpen });
|
||||||
},
|
},
|
||||||
[appDispatch]
|
[appDispatch]
|
||||||
);
|
);
|
||||||
const appChainId = Number(ETHEREUM_CHAIN_ID);
|
const appChainId = Number(config?.chain_id);
|
||||||
return (
|
return (
|
||||||
<>
|
<AsyncRenderer loading={loading} error={error} data={config}>
|
||||||
<Web3Content appChainId={appChainId} setDialogOpen={setDialogOpen}>
|
<Web3Content appChainId={appChainId} setDialogOpen={setDialogOpen}>
|
||||||
{children}
|
{children}
|
||||||
</Web3Content>
|
</Web3Content>
|
||||||
|
{Connectors && (
|
||||||
<Web3ConnectDialog
|
<Web3ConnectDialog
|
||||||
connectors={Connectors}
|
connectors={Connectors}
|
||||||
dialogOpen={appState.ethConnectOverlay}
|
dialogOpen={appState.ethConnectOverlay}
|
||||||
setDialogOpen={setDialogOpen}
|
setDialogOpen={setDialogOpen}
|
||||||
desiredChainId={appChainId}
|
desiredChainId={appChainId}
|
||||||
/>
|
/>
|
||||||
</>
|
)}
|
||||||
|
</AsyncRenderer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,11 +55,7 @@ interface Web3ContentProps {
|
|||||||
setDialogOpen: (isOpen: boolean) => void;
|
setDialogOpen: (isOpen: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Web3Content = ({
|
export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
||||||
children,
|
|
||||||
appChainId,
|
|
||||||
setDialogOpen,
|
|
||||||
}: Web3ContentProps) => {
|
|
||||||
const { error, connector, chainId } = useWeb3React();
|
const { error, connector, chainId } = useWeb3React();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { Networks } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
const windowOrDefault = (key: string) => {
|
const windowOrDefault = (key: string) => {
|
||||||
if (window._env_ && window._env_[key]) {
|
if (window._env_ && window._env_[key]) {
|
||||||
return window._env_[key];
|
return window._env_[key];
|
||||||
@ -7,10 +9,49 @@ const windowOrDefault = (key: string) => {
|
|||||||
|
|
||||||
const TRUTHY = ['1', 'true'];
|
const TRUTHY = ['1', 'true'];
|
||||||
|
|
||||||
|
interface VegaContracts {
|
||||||
|
claimAddress: string;
|
||||||
|
lockedAddress: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const customClaimAddress = process.env['NX_CUSTOM_CLAIM_ADDRESS'] as string;
|
||||||
|
const customLockedAddress = process.env['NX_CUSTOM_LOCKED_ADDRESS'] as string;
|
||||||
|
|
||||||
|
export const ContractAddresses: {
|
||||||
|
[key in Networks | 'CUSTOM']: VegaContracts;
|
||||||
|
} = {
|
||||||
|
CUSTOM: {
|
||||||
|
claimAddress: customClaimAddress ?? '0x0',
|
||||||
|
lockedAddress: customLockedAddress ?? '0x0',
|
||||||
|
},
|
||||||
|
DEVNET: {
|
||||||
|
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994',
|
||||||
|
lockedAddress: '0x0',
|
||||||
|
},
|
||||||
|
STAGNET: {
|
||||||
|
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
|
||||||
|
lockedAddress: '0x0', // TODO not deployed to this env
|
||||||
|
},
|
||||||
|
STAGNET2: {
|
||||||
|
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
|
||||||
|
lockedAddress: '0x0', // TODO not deployed to this env
|
||||||
|
},
|
||||||
|
TESTNET: {
|
||||||
|
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
|
||||||
|
lockedAddress: '0x0', // TODO not deployed to this env
|
||||||
|
},
|
||||||
|
MAINNET: {
|
||||||
|
claimAddress: '0x0ee1fb382caf98e86e97e51f9f42f8b4654020f3',
|
||||||
|
lockedAddress: '0x78344c7305d73a7a0ac3c94cd9960f4449a1814e',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const envName = windowOrDefault('NX_VEGA_ENV') ?? 'local';
|
||||||
|
|
||||||
export const ENV = {
|
export const ENV = {
|
||||||
// Environment
|
// Environment
|
||||||
dsn: windowOrDefault('NX_SENTRY_DSN'),
|
dsn: windowOrDefault('NX_SENTRY_DSN'),
|
||||||
envName: windowOrDefault('NX_VEGA_ENV'),
|
envName,
|
||||||
commit: windowOrDefault('NX_COMMIT_REF'),
|
commit: windowOrDefault('NX_COMMIT_REF'),
|
||||||
branch: windowOrDefault('NX_BRANCH'),
|
branch: windowOrDefault('NX_BRANCH'),
|
||||||
vegaUrl: windowOrDefault('NX_VEGA_URL'),
|
vegaUrl: windowOrDefault('NX_VEGA_URL'),
|
||||||
@ -26,4 +67,6 @@ export const ENV = {
|
|||||||
process.env['NX_IS_NEW_BRIDGE_CONTRACT'] as string
|
process.env['NX_IS_NEW_BRIDGE_CONTRACT'] as string
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
addresses:
|
||||||
|
ContractAddresses[(envName === 'local' ? 'CUSTOM' : envName) as Networks],
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
export * from './flags';
|
export * from './flags';
|
||||||
export * from './links';
|
export * from './links';
|
||||||
export * from './network-params';
|
export * from './network-params';
|
||||||
export * from './vega';
|
|
||||||
|
@ -1,176 +0,0 @@
|
|||||||
import { Networks } from '@vegaprotocol/react-helpers';
|
|
||||||
|
|
||||||
interface VegaNode {
|
|
||||||
url: string;
|
|
||||||
api: {
|
|
||||||
GraphQL: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
type VegaNets = {
|
|
||||||
[N in Networks]: {
|
|
||||||
nodes: VegaNode[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NetworkConfig = {
|
|
||||||
[N in Networks]: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const VegaNetworks: VegaNets = {
|
|
||||||
[Networks.DEVNET]: {
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
url: 'https://n01.d.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n02.d.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n03.d.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n04.d.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
[Networks.STAGNET]: {
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
url: 'https://n01.s.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n02.s.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n03.s.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n04.s.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n05.s.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
[Networks.STAGNET2]: {
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
url: 'https://n03.stagnet2.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
[Networks.TESTNET]: {
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
url: 'https://lb.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n01.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n02.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n03.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n04.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n05.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n06.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n07.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n08.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://n09.testnet.vega.xyz',
|
|
||||||
api: {
|
|
||||||
GraphQL: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
[Networks.MAINNET]: {
|
|
||||||
nodes: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GraphQLNodes = Object.keys(VegaNetworks).reduce(
|
|
||||||
(obj: Record<string, string[]>, network) => {
|
|
||||||
const rawNodes: VegaNode[] = VegaNetworks[network as Networks].nodes;
|
|
||||||
const nodesWithGraphQL = rawNodes
|
|
||||||
.filter((n) => n.api.GraphQL)
|
|
||||||
.map((n) => n.url);
|
|
||||||
obj[network] = nodesWithGraphQL;
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const EnvironmentNodes = GraphQLNodes[
|
|
||||||
process.env['NX_VEGA_ENV'] as Networks
|
|
||||||
] as string[];
|
|
@ -6,14 +6,15 @@ import {
|
|||||||
} from '@vegaprotocol/smart-contracts';
|
} from '@vegaprotocol/smart-contracts';
|
||||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { SplashLoader } from '../../components/splash-loader';
|
import { SplashLoader } from '../../components/splash-loader';
|
||||||
import type { ContractsContextShape } from './contracts-context';
|
import type { ContractsContextShape } from './contracts-context';
|
||||||
import { ContractsContext } from './contracts-context';
|
import { ContractsContext } from './contracts-context';
|
||||||
import { createDefaultProvider } from '../../lib/web3-connectors';
|
import { createDefaultProvider } from '../../lib/web3-connectors';
|
||||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
import { ENV } from '../../config/env';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides Vega Ethereum contract instances to its children.
|
* Provides Vega Ethereum contract instances to its children.
|
||||||
@ -21,14 +22,9 @@ import { useEnvironment } from '@vegaprotocol/network-switcher';
|
|||||||
export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
||||||
const { provider: activeProvider, account } = useWeb3React();
|
const { provider: activeProvider, account } = useWeb3React();
|
||||||
const { config } = useEthereumConfig();
|
const { config } = useEthereumConfig();
|
||||||
const { VEGA_ENV, ADDRESSES, ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID } =
|
const { VEGA_ENV, ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||||
useEnvironment();
|
|
||||||
const [contracts, setContracts] =
|
const [contracts, setContracts] =
|
||||||
React.useState<ContractsContextShape | null>(null);
|
React.useState<ContractsContextShape | null>(null);
|
||||||
const defaultProvider = useMemo(
|
|
||||||
() => createDefaultProvider(ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID),
|
|
||||||
[ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create instances of contract classes. If we have an account use a signer for the
|
// Create instances of contract classes. If we have an account use a signer for the
|
||||||
// contracts so that we can sign transactions, otherwise use the provider for just
|
// contracts so that we can sign transactions, otherwise use the provider for just
|
||||||
@ -37,6 +33,12 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
const run = async () => {
|
const run = async () => {
|
||||||
let signer = null;
|
let signer = null;
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
const defaultProvider = createDefaultProvider(
|
||||||
|
ETHEREUM_PROVIDER_URL,
|
||||||
|
Number(config.chain_id)
|
||||||
|
);
|
||||||
|
|
||||||
const provider = activeProvider ? activeProvider : defaultProvider;
|
const provider = activeProvider ? activeProvider : defaultProvider;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -64,12 +66,13 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
config.token_vesting_contract.address,
|
config.token_vesting_contract.address,
|
||||||
signer || provider
|
signer || provider
|
||||||
),
|
),
|
||||||
claim: new Claim(ADDRESSES.claimAddress, signer || provider),
|
claim: new Claim(ENV.addresses.claimAddress, signer || provider),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
run();
|
run();
|
||||||
}, [activeProvider, account, config, ADDRESSES, VEGA_ENV, defaultProvider]);
|
}, [activeProvider, account, config, VEGA_ENV, ETHEREUM_PROVIDER_URL]);
|
||||||
|
|
||||||
if (!contracts) {
|
if (!contracts) {
|
||||||
return (
|
return (
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import { Networks } from '@vegaprotocol/react-helpers';
|
import { Networks } from '@vegaprotocol/environment';
|
||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import { MetaMask } from '@web3-react/metamask';
|
import { MetaMask } from '@web3-react/metamask';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
export const useAddAssetSupported = () => {
|
export const useAddAssetSupported = () => {
|
||||||
const { connector } = useWeb3React();
|
const { connector } = useWeb3React();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { Networks } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import type { Tranche } from '@vegaprotocol/smart-contracts';
|
import type { Tranche } from '@vegaprotocol/smart-contracts';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import type { Networks } from '@vegaprotocol/environment';
|
||||||
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
import { BigNumber } from '../lib/bignumber';
|
import { BigNumber } from '../lib/bignumber';
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ const TRANCHES_URLS: { [N in Networks]: string } = {
|
|||||||
STAGNET: 'https://static.vega.xyz/assets/stagnet1-tranches.json',
|
STAGNET: 'https://static.vega.xyz/assets/stagnet1-tranches.json',
|
||||||
STAGNET2: 'https://static.vega.xyz/assets/stagnet2-tranches.json',
|
STAGNET2: 'https://static.vega.xyz/assets/stagnet2-tranches.json',
|
||||||
DEVNET: 'https://static.vega.xyz/assets/devnet-tranches.json',
|
DEVNET: 'https://static.vega.xyz/assets/devnet-tranches.json',
|
||||||
|
CUSTOM: 'https://static.vega.xyz/assets/testnet-tranches.json',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useTranches() {
|
export function useTranches() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Callout, Intent, Link, Button } from '@vegaprotocol/ui-toolkit';
|
import { Callout, Intent, Link, Button } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { Link as RouteLink } from 'react-router-dom';
|
import { Link as RouteLink } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@ import { t } from '@vegaprotocol/react-helpers';
|
|||||||
import { Link, Splash } from '@vegaprotocol/ui-toolkit';
|
import { Link, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { EthereumConfig } from '@vegaprotocol/web3';
|
import type { EthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Heading } from '../../components/heading';
|
import { Heading } from '../../components/heading';
|
||||||
import { SplashLoader } from '../../components/splash-loader';
|
import { SplashLoader } from '../../components/splash-loader';
|
||||||
|
import { ENV } from '../../config/env';
|
||||||
|
|
||||||
const Contracts = () => {
|
const Contracts = () => {
|
||||||
const { config } = useEthereumConfig();
|
const { config } = useEthereumConfig();
|
||||||
const { ADDRESSES, ETHERSCAN_URL } = useEnvironment();
|
const { ETHERSCAN_URL } = useEnvironment();
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return (
|
return (
|
||||||
@ -47,7 +48,7 @@ const Contracts = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{Object.entries(ADDRESSES).map(([key, value]) => (
|
{Object.entries(ENV.addresses).map(([key, value]) => (
|
||||||
<div
|
<div
|
||||||
key={key}
|
key={key}
|
||||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { Callout, Link, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
import { Callout, Link, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranches } from '../../../hooks/use-tranches';
|
import { useTranches } from '../../../hooks/use-tranches';
|
||||||
import type { BigNumber } from '../../../lib/bignumber';
|
import type { BigNumber } from '../../../lib/bignumber';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Button, Callout, Link, Loader } from '@vegaprotocol/ui-toolkit';
|
import { Button, Callout, Link, Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link as RouteLink } from 'react-router-dom';
|
import { Link as RouteLink } from 'react-router-dom';
|
||||||
|
@ -5,7 +5,7 @@ import { Link as RouteLink } from 'react-router-dom';
|
|||||||
|
|
||||||
import { BulletHeader } from '../../components/bullet-header';
|
import { BulletHeader } from '../../components/bullet-header';
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Links } from '../../config';
|
import { Links } from '../../config';
|
||||||
import {
|
import {
|
||||||
AppStateActionType,
|
AppStateActionType,
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||||
import { BigNumber } from '../../lib/bignumber';
|
import { BigNumber } from '../../lib/bignumber';
|
||||||
import { formatNumber } from '../../lib/format-number';
|
import { formatNumber } from '../../lib/format-number';
|
||||||
|
@ -7,7 +7,7 @@ import { useParams } from 'react-router';
|
|||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useOutletContext } from 'react-router-dom';
|
import { useOutletContext } from 'react-router-dom';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { BigNumber } from '../../lib/bignumber';
|
import { BigNumber } from '../../lib/bignumber';
|
||||||
import { formatNumber } from '../../lib/format-number';
|
import { formatNumber } from '../../lib/format-number';
|
||||||
import { TrancheItem } from '../redemption/tranche-item';
|
import { TrancheItem } from '../redemption/tranche-item';
|
||||||
|
@ -5,7 +5,7 @@ import React from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Heading } from '../../components/heading';
|
import { Heading } from '../../components/heading';
|
||||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||||
import { SplashLoader } from '../../components/splash-loader';
|
import { SplashLoader } from '../../components/splash-loader';
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"TRADING_TEST_VEGA_WALLET_NAME": "UI_Trading_Test",
|
"TRADING_TEST_VEGA_WALLET_NAME": "UI_Trading_Test",
|
||||||
"ETHEREUM_PROVIDER_URL": "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8",
|
"ETHEREUM_PROVIDER_URL": "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8",
|
||||||
"ETHEREUM_CHAIN_ID": 3,
|
|
||||||
"VEGA_PUBLIC_KEY": "47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278",
|
"VEGA_PUBLIC_KEY": "47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278",
|
||||||
"VEGA_PUBLIC_KEY2": "1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4",
|
"VEGA_PUBLIC_KEY2": "1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4",
|
||||||
"TRUNCATED_VEGA_PUBLIC_KEY": "47836c…c7d278",
|
"TRUNCATED_VEGA_PUBLIC_KEY": "47836c…c7d278",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\"}
|
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\"}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=DEVNET
|
NX_VEGA_ENV=DEVNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
||||||
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
NX_VEGA_URL=https://n04.d.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\"}
|
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\"}
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=MAINNET
|
NX_VEGA_ENV=MAINNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||||
NX_VEGA_URL=https://api.token.vega.xyz/query
|
NX_VEGA_URL=https://api.token.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=1
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET
|
NX_VEGA_ENV=STAGNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json
|
||||||
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
NX_VEGA_URL=https://n03.s.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=STAGNET2
|
NX_VEGA_ENV=STAGNET2
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet2-network.json
|
||||||
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
NX_VEGA_URL=https://lb.testnet.vega.xyz/query
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
||||||
NX_ETHEREUM_CHAIN_ID=3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||||
|
@ -26,11 +26,13 @@ Example configurations are provided here:
|
|||||||
|
|
||||||
There are a few different configuration options offered for this app:
|
There are a few different configuration options offered for this app:
|
||||||
|
|
||||||
|
The network configuration for the app
|
||||||
|
|
||||||
| **Flag** | **Purpose** |
|
| **Flag** | **Purpose** |
|
||||||
| -------------------------- | -------------------------------------------------------------------------------------------------------- |
|
| -------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||||
| `NX_VEGA_ENV` | The name of the currently connected vega environment |
|
| `NX_VEGA_ENV` | The name of the currently connected vega environment |
|
||||||
|
| `NX_VEGA_CONFIG_URL` | The network configuration for the app |
|
||||||
| `NX_VEGA_URL` | The GraphQL query endpoint of a [Vega data node](https://github.com/vegaprotocol/networks#data-node) |
|
| `NX_VEGA_URL` | The GraphQL query endpoint of a [Vega data node](https://github.com/vegaprotocol/networks#data-node) |
|
||||||
| `NX_ETHEREUM_CHAIN_ID` | The ID of the Ethereum chain the currently connected Vega Network uses. E.g. Ropsten (3) for testnet |
|
|
||||||
| `NX_ETHEREUM_PROVIDER_URL` | The Ethereum Provider URL for getting data from the Ethereum network, for example Infura or a local node |
|
| `NX_ETHEREUM_PROVIDER_URL` | The Ethereum Provider URL for getting data from the Ethereum network, for example Infura or a local node |
|
||||||
| `NX_ETHERSCAN_URL` | The Etherscan URL to link Ethereum transactions to |
|
| `NX_ETHERSCAN_URL` | The Etherscan URL to link Ethereum transactions to |
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { useEagerConnect } from '@vegaprotocol/wallet';
|
|
||||||
import { Connectors } from '../../lib/vega-connectors';
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
import { useEagerConnect } from '@vegaprotocol/wallet';
|
||||||
|
import { NetworkLoader } from '@vegaprotocol/environment';
|
||||||
|
import { Connectors } from '../../lib/vega-connectors';
|
||||||
|
import { createClient } from '../../lib/apollo-client';
|
||||||
|
|
||||||
interface AppLoaderProps {
|
interface AppLoaderProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -14,5 +16,5 @@ export function AppLoader({ children }: AppLoaderProps) {
|
|||||||
// Get keys from vega wallet immediately
|
// Get keys from vega wallet immediately
|
||||||
useEagerConnect(Connectors);
|
useEagerConnect(Connectors);
|
||||||
|
|
||||||
return <>{children}</>;
|
return <NetworkLoader createClient={createClient}>{children}</NetworkLoader>;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { Web3Container } from './web3-container';
|
|||||||
import type { useWeb3React } from '@web3-react/core';
|
import type { useWeb3React } from '@web3-react/core';
|
||||||
import type { NetworkParamsQuery } from '@vegaprotocol/web3';
|
import type { NetworkParamsQuery } from '@vegaprotocol/web3';
|
||||||
import { NETWORK_PARAMS_QUERY } from '@vegaprotocol/web3';
|
import { NETWORK_PARAMS_QUERY } from '@vegaprotocol/web3';
|
||||||
import { EnvironmentProvider } from '@vegaprotocol/network-switcher';
|
import { EnvironmentProvider } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
const defaultHookValue = {
|
const defaultHookValue = {
|
||||||
isActive: false,
|
isActive: false,
|
||||||
|
@ -8,7 +8,7 @@ import { useWeb3React } from '@web3-react/core';
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { useEffect, useState, useMemo } from 'react';
|
import { useEffect, useState, useMemo } from 'react';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { createConnectors } from '../../lib/web3-connectors';
|
import { createConnectors } from '../../lib/web3-connectors';
|
||||||
|
|
||||||
interface Web3ContainerProps {
|
interface Web3ContainerProps {
|
||||||
@ -18,14 +18,15 @@ interface Web3ContainerProps {
|
|||||||
export const Web3Container = ({ children }: Web3ContainerProps) => {
|
export const Web3Container = ({ children }: Web3ContainerProps) => {
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const { config, loading, error } = useEthereumConfig();
|
const { config, loading, error } = useEthereumConfig();
|
||||||
const { ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID } = useEnvironment();
|
const { ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||||
const Connectors = useMemo(
|
const Connectors = useMemo(() => {
|
||||||
() => createConnectors(ETHEREUM_PROVIDER_URL, ETHEREUM_CHAIN_ID),
|
if (config?.chain_id) {
|
||||||
[ETHEREUM_CHAIN_ID, ETHEREUM_PROVIDER_URL]
|
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config?.chain_id));
|
||||||
);
|
}
|
||||||
|
}, [config?.chain_id, ETHEREUM_PROVIDER_URL]);
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer data={config} loading={loading} error={error}>
|
<AsyncRenderer data={config} loading={loading} error={error}>
|
||||||
{config ? (
|
{Connectors && config && (
|
||||||
<Web3Provider connectors={Connectors}>
|
<Web3Provider connectors={Connectors}>
|
||||||
<Web3Content
|
<Web3Content
|
||||||
appChainId={Number(config.chain_id)}
|
appChainId={Number(config.chain_id)}
|
||||||
@ -40,7 +41,7 @@ export const Web3Container = ({ children }: Web3ContainerProps) => {
|
|||||||
desiredChainId={Number(config.chain_id)}
|
desiredChainId={Number(config.chain_id)}
|
||||||
/>
|
/>
|
||||||
</Web3Provider>
|
</Web3Provider>
|
||||||
) : null}
|
)}
|
||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { AppProps } from 'next/app';
|
import type { AppProps } from 'next/app';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import { Navbar } from '../components/navbar';
|
import { Navbar } from '../components/navbar';
|
||||||
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
@ -7,29 +8,27 @@ import {
|
|||||||
VegaManageDialog,
|
VegaManageDialog,
|
||||||
VegaWalletProvider,
|
VegaWalletProvider,
|
||||||
} from '@vegaprotocol/wallet';
|
} from '@vegaprotocol/wallet';
|
||||||
import { NetworkSwitcherDialog } from '@vegaprotocol/network-switcher';
|
import {
|
||||||
|
useEnvironment,
|
||||||
|
EnvironmentProvider,
|
||||||
|
NetworkSwitcherDialog,
|
||||||
|
} from '@vegaprotocol/environment';
|
||||||
import { Connectors } from '../lib/vega-connectors';
|
import { Connectors } from '../lib/vega-connectors';
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { createClient } from '../lib/apollo-client';
|
|
||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||||
import { ApolloProvider } from '@apollo/client';
|
|
||||||
import { AppLoader } from '../components/app-loader';
|
import { AppLoader } from '../components/app-loader';
|
||||||
import { VegaWalletConnectButton } from '../components/vega-wallet-connect-button';
|
import { VegaWalletConnectButton } from '../components/vega-wallet-connect-button';
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { useGlobalStore } from '../stores';
|
import { useGlobalStore } from '../stores';
|
||||||
import { ENV } from '../lib/config/env';
|
|
||||||
import { EnvironmentProvider } from '@vegaprotocol/network-switcher';
|
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
|
||||||
|
|
||||||
function AppBody({ Component, pageProps }: AppProps) {
|
function AppBody({ Component, pageProps }: AppProps) {
|
||||||
|
const { push } = useRouter();
|
||||||
const store = useGlobalStore();
|
const store = useGlobalStore();
|
||||||
const { VEGA_NETWORKS } = useEnvironment();
|
const { VEGA_NETWORKS } = useEnvironment();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const [, toggleTheme] = useThemeSwitcher();
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
|
||||||
<div className="h-full dark:bg-black dark:text-white-60 bg-white relative z-0 text-black-60 grid grid-rows-[min-content,1fr]">
|
<div className="h-full dark:bg-black dark:text-white-60 bg-white relative z-0 text-black-60 grid grid-rows-[min-content,1fr]">
|
||||||
|
<AppLoader>
|
||||||
<div className="flex items-stretch border-b-[7px] border-vega-yellow">
|
<div className="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||||
@ -62,25 +61,22 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
setDialogOpen={(open) => store.setVegaNetworkSwitcherDialog(open)}
|
setDialogOpen={(open) => store.setVegaNetworkSwitcherDialog(open)}
|
||||||
onConnect={({ network }) => {
|
onConnect={({ network }) => {
|
||||||
if (VEGA_NETWORKS[network]) {
|
if (VEGA_NETWORKS[network]) {
|
||||||
window.location.href = VEGA_NETWORKS[network];
|
push(VEGA_NETWORKS[network] ?? '');
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</AppLoader>
|
||||||
</div>
|
</div>
|
||||||
</ThemeContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function VegaTradingApp(props: AppProps) {
|
function VegaTradingApp(props: AppProps) {
|
||||||
const [theme] = useThemeSwitcher();
|
const [theme] = useThemeSwitcher();
|
||||||
const client = useMemo(() => createClient(ENV.vegaUrl), []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<EnvironmentProvider>
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<ApolloProvider client={client}>
|
|
||||||
<VegaWalletProvider>
|
<VegaWalletProvider>
|
||||||
<AppLoader>
|
|
||||||
<Head>
|
<Head>
|
||||||
<link
|
<link
|
||||||
rel="preload"
|
rel="preload"
|
||||||
@ -95,10 +91,7 @@ function VegaTradingApp(props: AppProps) {
|
|||||||
type="image/x-icon"
|
type="image/x-icon"
|
||||||
href="https://static.vega.xyz/favicon.ico"
|
href="https://static.vega.xyz/favicon.ico"
|
||||||
/>
|
/>
|
||||||
<link
|
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||||
rel="stylesheet"
|
|
||||||
href="https://static.vega.xyz/fonts.css"
|
|
||||||
/>
|
|
||||||
{['1', 'true'].includes(
|
{['1', 'true'].includes(
|
||||||
process.env['NX_USE_ENV_OVERRIDES'] || ''
|
process.env['NX_USE_ENV_OVERRIDES'] || ''
|
||||||
) ? (
|
) ? (
|
||||||
@ -107,9 +100,7 @@ function VegaTradingApp(props: AppProps) {
|
|||||||
) : null}
|
) : null}
|
||||||
</Head>
|
</Head>
|
||||||
<AppBody {...props} />
|
<AppBody {...props} />
|
||||||
</AppLoader>
|
|
||||||
</VegaWalletProvider>
|
</VegaWalletProvider>
|
||||||
</ApolloProvider>
|
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</EnvironmentProvider>
|
</EnvironmentProvider>
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,7 @@ import { PageQueryContainer } from '../../../components/page-query-container';
|
|||||||
import type { DepositPage } from './__generated__/DepositPage';
|
import type { DepositPage } from './__generated__/DepositPage';
|
||||||
import { DepositManager } from '@vegaprotocol/deposits';
|
import { DepositManager } from '@vegaprotocol/deposits';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { useEnvironment } from '@vegaprotocol/network-switcher';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { ASSET_FRAGMENT } from '../../../lib/query-fragments';
|
import { ASSET_FRAGMENT } from '../../../lib/query-fragments';
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
KeyValueTable,
|
KeyValueTable,
|
||||||
KeyValueTableRow,
|
KeyValueTableRow,
|
||||||
AccordionPanel,
|
Accordion,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import startCase from 'lodash/startCase';
|
import startCase from 'lodash/startCase';
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
@ -23,14 +23,10 @@ export interface InfoProps {
|
|||||||
export const Info = ({ market }: InfoProps) => {
|
export const Info = ({ market }: InfoProps) => {
|
||||||
const headerClassName =
|
const headerClassName =
|
||||||
'text-h5 font-bold uppercase text-black dark:text-white';
|
'text-h5 font-bold uppercase text-black dark:text-white';
|
||||||
return (
|
const marketDataPanels = [
|
||||||
<div className="p-16 flex flex-col gap-32">
|
{
|
||||||
<div className="flex flex-col gap-12">
|
title: t('Current fees'),
|
||||||
<p className={headerClassName}>{t('Market data')}</p>
|
content: (
|
||||||
<AccordionPanel
|
|
||||||
key="fees"
|
|
||||||
title={t('Current fees')}
|
|
||||||
content={
|
|
||||||
<>
|
<>
|
||||||
<MarketInfoTable data={market.fees.factors} asPercentage={true} />
|
<MarketInfoTable data={market.fees.factors} asPercentage={true} />
|
||||||
<p className="text-ui-small">
|
<p className="text-ui-small">
|
||||||
@ -39,26 +35,22 @@ export const Info = ({ market }: InfoProps) => {
|
|||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
<AccordionPanel
|
{
|
||||||
key="market-data"
|
title: t('Market data'),
|
||||||
title={t('Market data')}
|
content: (
|
||||||
content={
|
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
data={market.data}
|
data={market.data}
|
||||||
decimalPlaces={market.decimalPlaces}
|
decimalPlaces={market.decimalPlaces}
|
||||||
/>
|
/>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
</div>
|
];
|
||||||
|
const marketSpecPanels = [
|
||||||
<div className="flex flex-col gap-12">
|
{
|
||||||
<p className={headerClassName}>{t('Market specification')}</p>
|
title: t('Key details'),
|
||||||
<AccordionPanel
|
content: (
|
||||||
title={t('Key details')}
|
|
||||||
key="details"
|
|
||||||
content={
|
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
data={pick(
|
data={pick(
|
||||||
market,
|
market,
|
||||||
@ -69,51 +61,56 @@ export const Info = ({ market }: InfoProps) => {
|
|||||||
'state'
|
'state'
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
<AccordionPanel
|
{
|
||||||
title={t('Instrument')}
|
title: t('Instrument'),
|
||||||
key="instrument"
|
content: (
|
||||||
content={
|
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
data={{
|
data={{
|
||||||
product: market.tradableInstrument.instrument.product,
|
product: market.tradableInstrument.instrument.product,
|
||||||
...market.tradableInstrument.instrument.product.settlementAsset,
|
...market.tradableInstrument.instrument.product.settlementAsset,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
<AccordionPanel
|
{
|
||||||
title={t('Risk factors')}
|
title: t('Risk factors'),
|
||||||
key="risk-factors"
|
content: (
|
||||||
content={
|
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
data={market.riskFactors}
|
data={market.riskFactors}
|
||||||
unformatted={true}
|
unformatted={true}
|
||||||
omits={['market', '__typename']}
|
omits={['market', '__typename']}
|
||||||
/>
|
/>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
<AccordionPanel
|
{
|
||||||
title={t('Risk model')}
|
title: t('Risk model'),
|
||||||
key="risk-model"
|
content: (
|
||||||
content={
|
|
||||||
<MarketInfoTable
|
<MarketInfoTable
|
||||||
data={market.tradableInstrument.riskModel}
|
data={market.tradableInstrument.riskModel}
|
||||||
unformatted={true}
|
unformatted={true}
|
||||||
omits={[]}
|
omits={[]}
|
||||||
/>
|
/>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
{(market.priceMonitoringSettings?.parameters?.triggers ?? []).map(
|
...(market.priceMonitoringSettings?.parameters?.triggers || []).map(
|
||||||
(trigger, i) => (
|
(trigger, i) => ({
|
||||||
<AccordionPanel
|
title: t(`Price monitoring trigger ${i + 1}`),
|
||||||
key={`trigger-${i}`}
|
content: <MarketInfoTable data={trigger} />,
|
||||||
title={t(`Price monitoring trigger ${i + 1}`)}
|
})
|
||||||
content={<MarketInfoTable data={trigger} />}
|
),
|
||||||
/>
|
];
|
||||||
)
|
|
||||||
)}
|
return (
|
||||||
|
<div className="p-16 flex flex-col gap-32">
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
<p className={headerClassName}>{t('Market data')}</p>
|
||||||
|
<Accordion panels={marketDataPanels} />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
<p className={headerClassName}>{t('Market specification')}</p>
|
||||||
|
<Accordion panels={marketSpecPanels} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
19
libs/environment/README.md
Normal file
19
libs/environment/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# environment
|
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
The environment variables needed to be present for any app consuming this library.
|
||||||
|
|
||||||
|
`NX_VEGA_ENV` is the name of the environment.
|
||||||
|
|
||||||
|
`NX_VEGA_REST` is the REST endpoint for the environment.
|
||||||
|
|
||||||
|
`NX_VEGA_URL` OR `NX_VEGA_CONFIG_URL` - either the network configuration url or a url to a node to directly connect to
|
||||||
|
|
||||||
|
For examples, see Block Explorer's .env files [here](../../apps/explorer)
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `nx test environment` to execute the unit tests via [Jest](https://jestjs.io).
|
@ -1,9 +1,9 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
displayName: 'network-switcher',
|
displayName: 'environment',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../../jest.preset.js',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.[tj]sx?$': 'babel-jest',
|
'^.+\\.[tj]sx?$': 'babel-jest',
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
coverageDirectory: '../../coverage/libs/network-switcher',
|
coverageDirectory: '../../coverage/libs/environment',
|
||||||
};
|
};
|
4
libs/environment/package.json
Normal file
4
libs/environment/package.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "@vegaprotocol/environment",
|
||||||
|
"version": "0.0.1"
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"root": "libs/network-switcher",
|
"root": "libs/environment",
|
||||||
"sourceRoot": "libs/network-switcher/src",
|
"sourceRoot": "libs/environment/src",
|
||||||
"projectType": "library",
|
"projectType": "library",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"targets": {
|
"targets": {
|
||||||
@ -8,16 +8,16 @@
|
|||||||
"executor": "@nrwl/web:rollup",
|
"executor": "@nrwl/web:rollup",
|
||||||
"outputs": ["{options.outputPath}"],
|
"outputs": ["{options.outputPath}"],
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist/libs/network-switcher",
|
"outputPath": "dist/libs/environment",
|
||||||
"tsConfig": "libs/network-switcher/tsconfig.lib.json",
|
"tsConfig": "libs/environment/tsconfig.lib.json",
|
||||||
"project": "libs/network-switcher/package.json",
|
"project": "libs/environment/package.json",
|
||||||
"entryFile": "libs/network-switcher/src/index.ts",
|
"entryFile": "libs/environment/src/index.ts",
|
||||||
"external": ["react/jsx-runtime"],
|
"external": ["react/jsx-runtime"],
|
||||||
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
||||||
"compiler": "babel",
|
"compiler": "babel",
|
||||||
"assets": [
|
"assets": [
|
||||||
{
|
{
|
||||||
"glob": "libs/network-switcher/README.md",
|
"glob": "libs/environment/README.md",
|
||||||
"input": ".",
|
"input": ".",
|
||||||
"output": "."
|
"output": "."
|
||||||
}
|
}
|
||||||
@ -28,14 +28,14 @@
|
|||||||
"executor": "@nrwl/linter:eslint",
|
"executor": "@nrwl/linter:eslint",
|
||||||
"outputs": ["{options.outputFile}"],
|
"outputs": ["{options.outputFile}"],
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["libs/network-switcher/**/*.{ts,tsx,js,jsx}"]
|
"lintFilePatterns": ["libs/environment/**/*.{ts,tsx,js,jsx}"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"executor": "@nrwl/jest:jest",
|
"executor": "@nrwl/jest:jest",
|
||||||
"outputs": ["coverage/libs/network-switcher"],
|
"outputs": ["coverage/libs/environment"],
|
||||||
"options": {
|
"options": {
|
||||||
"jestConfig": "libs/network-switcher/jest.config.js",
|
"jestConfig": "libs/environment/jest.config.js",
|
||||||
"passWithNoTests": true
|
"passWithNoTests": true
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,2 +1,3 @@
|
|||||||
|
export * from './network-loader';
|
||||||
export * from './network-switcher';
|
export * from './network-switcher';
|
||||||
export * from './network-switcher-dialog';
|
export * from './network-switcher-dialog';
|
1
libs/environment/src/components/network-loader/index.ts
Normal file
1
libs/environment/src/components/network-loader/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './network-loader';
|
@ -0,0 +1,162 @@
|
|||||||
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
import type { ApolloClient } from '@apollo/client';
|
||||||
|
import { ApolloProvider } from '@apollo/client';
|
||||||
|
import {
|
||||||
|
Callout,
|
||||||
|
Intent,
|
||||||
|
Button,
|
||||||
|
Icon,
|
||||||
|
Loader,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
import { useEnvironment } from '../../hooks';
|
||||||
|
import type { ConfigStatus } from '../../types';
|
||||||
|
|
||||||
|
type MessageComponentProps = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StatusMessage = ({ children }: MessageComponentProps) => (
|
||||||
|
<div className="flex items-center fixed bottom-0 right-0 px-16 bg-intent-highlight text-black">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
type ErrorComponentProps = MessageComponentProps & {
|
||||||
|
children?: ReactNode;
|
||||||
|
showTryAgain?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Error = ({ children, showTryAgain }: ErrorComponentProps) => (
|
||||||
|
<div>
|
||||||
|
<div className="mb-16">{children}</div>
|
||||||
|
{showTryAgain && (
|
||||||
|
<Button
|
||||||
|
className="mt-8"
|
||||||
|
variant="secondary"
|
||||||
|
onClick={() => window.location.reload()}
|
||||||
|
>
|
||||||
|
{t('Try again')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
type StatusComponentProps = {
|
||||||
|
status: ConfigStatus;
|
||||||
|
children?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StatusComponent = ({ status, children }: StatusComponentProps) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'error-loading-config':
|
||||||
|
return (
|
||||||
|
<Callout
|
||||||
|
title={t('Error')}
|
||||||
|
intent={Intent.Danger}
|
||||||
|
iconName="error"
|
||||||
|
iconDescription={t('Error')}
|
||||||
|
children={
|
||||||
|
<Error>
|
||||||
|
{t('There was an error fetching the network configuration.')}
|
||||||
|
</Error>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 'error-validating-config':
|
||||||
|
return (
|
||||||
|
<Callout
|
||||||
|
title={t('Error')}
|
||||||
|
intent={Intent.Danger}
|
||||||
|
iconName="error"
|
||||||
|
iconDescription={t('Error')}
|
||||||
|
children={
|
||||||
|
<Error>
|
||||||
|
{t('The network configuration for the app is invalid.')}
|
||||||
|
</Error>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 'error-loading-node':
|
||||||
|
return (
|
||||||
|
<Callout
|
||||||
|
title={t('Error')}
|
||||||
|
intent={Intent.Danger}
|
||||||
|
iconName="error"
|
||||||
|
iconDescription={t('Error')}
|
||||||
|
children={
|
||||||
|
<Error showTryAgain>{t('Failed to connect to a data node.')}</Error>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 'idle':
|
||||||
|
case 'loading-config':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children}
|
||||||
|
<StatusMessage>
|
||||||
|
<Loader size="small" forceTheme="light" />
|
||||||
|
<span className="ml-8">{t('Loading configuration...')}</span>
|
||||||
|
</StatusMessage>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
case 'loading-node':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children}
|
||||||
|
<StatusMessage>
|
||||||
|
<Loader size="small" forceTheme="light" />
|
||||||
|
<span className="ml-8">{t('Finding a node...')}</span>
|
||||||
|
</StatusMessage>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
case 'success':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children}
|
||||||
|
<StatusMessage>
|
||||||
|
<Icon name="antenna" />
|
||||||
|
<span className="ml-8">{t("You're connected!")}</span>
|
||||||
|
</StatusMessage>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type NetworkLoaderProps<T> = {
|
||||||
|
children?: ReactNode;
|
||||||
|
skeleton?: ReactNode;
|
||||||
|
createClient: (url: string) => ApolloClient<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function NetworkLoader<T>({
|
||||||
|
skeleton,
|
||||||
|
children,
|
||||||
|
createClient,
|
||||||
|
}: NetworkLoaderProps<T>) {
|
||||||
|
// this is to prevent an error rendering callouts on the server side
|
||||||
|
const [canShowCallout, setShowCallout] = useState(false);
|
||||||
|
const { configStatus, VEGA_URL } = useEnvironment();
|
||||||
|
|
||||||
|
const client = useMemo(() => {
|
||||||
|
if (VEGA_URL) {
|
||||||
|
return createClient(VEGA_URL);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}, [VEGA_URL, createClient]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setShowCallout(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
return canShowCallout ? (
|
||||||
|
<div className="h-full min-h-screen flex items-center justify-center">
|
||||||
|
<StatusComponent status={configStatus}>{skeleton}</StatusComponent>
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ApolloProvider client={client}>{children}</ApolloProvider>;
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { Button, Select } from '@vegaprotocol/ui-toolkit';
|
import { Button, Select } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { Networks } from '@vegaprotocol/react-helpers';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { useEnvironment } from '../../hooks';
|
import { useEnvironment } from '../../hooks';
|
||||||
|
import type { Networks } from '../../types';
|
||||||
|
|
||||||
type NetworkState = {
|
type NetworkState = {
|
||||||
network: Networks;
|
network: Networks;
|
311
libs/environment/src/hooks/use-config.spec.tsx
Normal file
311
libs/environment/src/hooks/use-config.spec.tsx
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
import { renderHook } from '@testing-library/react-hooks';
|
||||||
|
import type { EnvironmentWithOptionalUrl } from './use-config';
|
||||||
|
import { useConfig, LOCAL_STORAGE_NETWORK_KEY } from './use-config';
|
||||||
|
import { Networks } from '../types';
|
||||||
|
|
||||||
|
type HostMapping = Record<string, number | Error>;
|
||||||
|
|
||||||
|
const mockHostsMap: HostMapping = {
|
||||||
|
'https://host1.com': 300,
|
||||||
|
'https://host2.com': 500,
|
||||||
|
'https://host3.com': 100,
|
||||||
|
'https://host4.com': 650,
|
||||||
|
};
|
||||||
|
|
||||||
|
const hostList = Object.keys(mockHostsMap);
|
||||||
|
|
||||||
|
const mockEnvironment: EnvironmentWithOptionalUrl = {
|
||||||
|
VEGA_ENV: Networks.TESTNET,
|
||||||
|
VEGA_CONFIG_URL: 'https://vega.url/config.json',
|
||||||
|
VEGA_NETWORKS: {},
|
||||||
|
ETHEREUM_PROVIDER_URL: 'https://ethereum.provider',
|
||||||
|
ETHERSCAN_URL: 'https://etherscan.url',
|
||||||
|
};
|
||||||
|
|
||||||
|
function setupFetch(configUrl: string, hostMap: HostMapping) {
|
||||||
|
const hostUrls = Object.keys(hostMap);
|
||||||
|
return (url: RequestInfo) => {
|
||||||
|
if (url === configUrl) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve({ hosts: hostUrls }),
|
||||||
|
} as Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostUrls.includes(url as string)) {
|
||||||
|
const value = hostMap[url as string];
|
||||||
|
return new Promise<Response>((resolve, reject) => {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({ ok: true } as Response);
|
||||||
|
}, value);
|
||||||
|
} else {
|
||||||
|
reject(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
} as Response);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
global.fetch = jest.fn();
|
||||||
|
|
||||||
|
const mockUpdate = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
mockUpdate.mockClear();
|
||||||
|
window.localStorage.clear();
|
||||||
|
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockReset();
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockImplementation(
|
||||||
|
setupFetch(mockEnvironment.VEGA_CONFIG_URL ?? '', mockHostsMap)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
// @ts-ignore: typescript doesn't recognise the mocked fetch instance
|
||||||
|
fetch.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('useConfig hook', () => {
|
||||||
|
it('has an initial success state when the environment already has a URL', async () => {
|
||||||
|
const mockEnvWithUrl = {
|
||||||
|
...mockEnvironment,
|
||||||
|
VEGA_URL: 'https://some.url/query',
|
||||||
|
};
|
||||||
|
const { result } = renderHook(() => useConfig(mockEnvWithUrl, mockUpdate));
|
||||||
|
|
||||||
|
expect(fetch).not.toHaveBeenCalled();
|
||||||
|
expect(mockUpdate).not.toHaveBeenCalled();
|
||||||
|
expect(result.current.status).toBe('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates the environment with a host url from the network configuration', async () => {
|
||||||
|
const allowedStatuses = [
|
||||||
|
'idle',
|
||||||
|
'loading-config',
|
||||||
|
'loading-node',
|
||||||
|
'success',
|
||||||
|
];
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('success');
|
||||||
|
result.all.forEach((state) => {
|
||||||
|
expect(allowedStatuses).toContain('status' in state && state.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
// fetches config
|
||||||
|
expect(fetch).toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
// calls each node
|
||||||
|
hostList.forEach((url) => {
|
||||||
|
expect(fetch).toHaveBeenCalledWith(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
// updates the environment
|
||||||
|
expect(hostList).toContain(mockUpdate.mock.calls[0][0]({}).VEGA_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses the host from the configuration which responds first', async () => {
|
||||||
|
const shortestResponseTime = Object.values(mockHostsMap).sort()[0];
|
||||||
|
const expectedHost = hostList.find((url: keyof typeof mockHostsMap) => {
|
||||||
|
return mockHostsMap[url] === shortestResponseTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('success');
|
||||||
|
expect(mockUpdate.mock.calls[0][0]({}).VEGA_URL).toBe(expectedHost);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores failing hosts and uses one which returns a success response', async () => {
|
||||||
|
const mockHostsMapScoped = {
|
||||||
|
'https://host1.com': 350,
|
||||||
|
'https://host2.com': new Error('Server error'),
|
||||||
|
'https://host3.com': 230,
|
||||||
|
'https://host4.com': new Error('Server error'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockImplementation(
|
||||||
|
setupFetch(mockEnvironment.VEGA_CONFIG_URL ?? '', mockHostsMapScoped)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('success');
|
||||||
|
expect(mockUpdate.mock.calls[0][0]({}).VEGA_URL).toBe('https://host3.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct error status for when the config cannot be accessed', async () => {
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockImplementation((url: RequestInfo) => {
|
||||||
|
if (url === mockEnvironment.VEGA_CONFIG_URL) {
|
||||||
|
return Promise.reject(new Error('Server error'));
|
||||||
|
}
|
||||||
|
return Promise.resolve({ ok: true } as Response);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('error-loading-config');
|
||||||
|
expect(mockUpdate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct error status for when the config is not valid', async () => {
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockImplementation((url: RequestInfo) => {
|
||||||
|
if (url === mockEnvironment.VEGA_CONFIG_URL) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve({ some: 'data' }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({ ok: true } as Response);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('error-validating-config');
|
||||||
|
expect(mockUpdate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct error status for when no hosts can be accessed', async () => {
|
||||||
|
const mockHostsMapScoped = {
|
||||||
|
'https://host1.com': new Error('Server error'),
|
||||||
|
'https://host2.com': new Error('Server error'),
|
||||||
|
'https://host3.com': new Error('Server error'),
|
||||||
|
'https://host4.com': new Error('Server error'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
global.fetch.mockImplementation(
|
||||||
|
setupFetch(mockEnvironment.VEGA_CONFIG_URL ?? '', mockHostsMapScoped)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() =>
|
||||||
|
useConfig(mockEnvironment, mockUpdate)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.current.status).toBe('error-loading-node');
|
||||||
|
expect(mockUpdate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('caches the list of networks', async () => {
|
||||||
|
const run1 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run1.result.current.status).toBe('success');
|
||||||
|
expect(fetch).toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
fetch.mockClear();
|
||||||
|
|
||||||
|
const run2 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run2.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run2.result.current.status).toBe('success');
|
||||||
|
expect(fetch).not.toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('caches the list of networks between runs', async () => {
|
||||||
|
const run1 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run1.result.current.status).toBe('success');
|
||||||
|
expect(fetch).toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
|
||||||
|
// @ts-ignore typescript doesn't recognise the mocked instance
|
||||||
|
fetch.mockClear();
|
||||||
|
|
||||||
|
const run2 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run2.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run2.result.current.status).toBe('success');
|
||||||
|
expect(fetch).not.toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refetches the network configuration and resets the cache when malformed data found in the storage', async () => {
|
||||||
|
window.localStorage.setItem(LOCAL_STORAGE_NETWORK_KEY, '{not:{valid:{json');
|
||||||
|
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(noop);
|
||||||
|
|
||||||
|
const run1 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run1.result.current.status).toBe('success');
|
||||||
|
expect(fetch).toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
expect(consoleWarnSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
consoleWarnSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refetches the network configuration and resets the cache when invalid data found in the storage', async () => {
|
||||||
|
window.localStorage.setItem(
|
||||||
|
LOCAL_STORAGE_NETWORK_KEY,
|
||||||
|
JSON.stringify({ invalid: 'data' })
|
||||||
|
);
|
||||||
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(noop);
|
||||||
|
|
||||||
|
const run1 = renderHook(() => useConfig(mockEnvironment, mockUpdate));
|
||||||
|
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await run1.waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(run1.result.current.status).toBe('success');
|
||||||
|
expect(fetch).toHaveBeenCalledWith(mockEnvironment.VEGA_CONFIG_URL);
|
||||||
|
expect(consoleSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
consoleSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
122
libs/environment/src/hooks/use-config.tsx
Normal file
122
libs/environment/src/hooks/use-config.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import type { Dispatch, SetStateAction } from 'react';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
|
import type { Environment, Configuration, ConfigStatus } from '../types';
|
||||||
|
import { validateConfiguration } from '../utils/validate-configuration';
|
||||||
|
import { promiseRaceToSuccess } from '../utils/promise-race-success';
|
||||||
|
|
||||||
|
export const LOCAL_STORAGE_NETWORK_KEY = 'vegaNetworkConfig';
|
||||||
|
|
||||||
|
export type EnvironmentWithOptionalUrl = Partial<Environment> &
|
||||||
|
Omit<Environment, 'VEGA_URL'>;
|
||||||
|
|
||||||
|
const requestToNode = async (url: string, index: number): Promise<number> => {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed connecting to node: ${url}.`);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCachedConfig = () => {
|
||||||
|
const value = LocalStorage.getItem(LOCAL_STORAGE_NETWORK_KEY);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
try {
|
||||||
|
const config = JSON.parse(value) as Configuration;
|
||||||
|
const hasError = validateConfiguration(config);
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
throw new Error('Invalid configuration found in the storage.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
} catch (err) {
|
||||||
|
LocalStorage.removeItem(LOCAL_STORAGE_NETWORK_KEY);
|
||||||
|
console.warn(
|
||||||
|
'Malformed data found for network configuration. Removed and continuing...'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useConfig = (
|
||||||
|
environment: EnvironmentWithOptionalUrl,
|
||||||
|
updateEnvironment: Dispatch<SetStateAction<Environment>>
|
||||||
|
) => {
|
||||||
|
const [config, setConfig] = useState<Configuration | undefined>(
|
||||||
|
getCachedConfig()
|
||||||
|
);
|
||||||
|
const [status, setStatus] = useState<ConfigStatus>(
|
||||||
|
!environment.VEGA_URL ? 'idle' : 'success'
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!config && status === 'idle') {
|
||||||
|
(async () => {
|
||||||
|
setStatus('loading-config');
|
||||||
|
try {
|
||||||
|
const response = await fetch(environment.VEGA_CONFIG_URL ?? '');
|
||||||
|
const configData: Configuration = await response.json();
|
||||||
|
|
||||||
|
if (validateConfiguration(configData)) {
|
||||||
|
setStatus('error-validating-config');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig({ hosts: configData.hosts });
|
||||||
|
LocalStorage.setItem(
|
||||||
|
LOCAL_STORAGE_NETWORK_KEY,
|
||||||
|
JSON.stringify({ hosts: configData.hosts })
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
setStatus('error-loading-config');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
// load config only once per runtime
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [environment.VEGA_CONFIG_URL, !!config, status, setStatus, setConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
config &&
|
||||||
|
!['loading-node', 'success', 'error-loading-node'].includes(status)
|
||||||
|
) {
|
||||||
|
(async () => {
|
||||||
|
setStatus('loading-node');
|
||||||
|
|
||||||
|
// if there's only one configured node to choose from, set is as the env url
|
||||||
|
if (config.hosts.length === 1) {
|
||||||
|
setStatus('success');
|
||||||
|
updateEnvironment((prevEnvironment) => ({
|
||||||
|
...prevEnvironment,
|
||||||
|
VEGA_URL: config.hosts[0],
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when there are multiple possible hosts, set the env url to the node which responds first
|
||||||
|
try {
|
||||||
|
const requests = config.hosts.map(requestToNode);
|
||||||
|
const index = await promiseRaceToSuccess(requests);
|
||||||
|
setStatus('success');
|
||||||
|
updateEnvironment((prevEnvironment) => ({
|
||||||
|
...prevEnvironment,
|
||||||
|
VEGA_URL: config.hosts[index],
|
||||||
|
}));
|
||||||
|
} catch (err) {
|
||||||
|
setStatus('error-loading-node');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
// load config only once per runtime
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [status, !!config, setStatus, updateEnvironment]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
};
|
228
libs/environment/src/hooks/use-environment.spec.tsx
Normal file
228
libs/environment/src/hooks/use-environment.spec.tsx
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
import type { ComponentProps } from 'react';
|
||||||
|
import { renderHook } from '@testing-library/react-hooks';
|
||||||
|
import type { EnvironmentState } from './use-environment';
|
||||||
|
import { useEnvironment, EnvironmentProvider } from './use-environment';
|
||||||
|
import { Networks } from '../types';
|
||||||
|
|
||||||
|
const MockWrapper = (props: ComponentProps<typeof EnvironmentProvider>) => {
|
||||||
|
return <EnvironmentProvider {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MOCK_HOST = 'https://vega.host/query';
|
||||||
|
|
||||||
|
global.fetch = jest.fn();
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
const mockFetch = (url: RequestInfo) => {
|
||||||
|
if (url === mockEnvironmentState.VEGA_CONFIG_URL) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () =>
|
||||||
|
Promise.resolve({
|
||||||
|
hosts: [MOCK_HOST],
|
||||||
|
}),
|
||||||
|
} as Response);
|
||||||
|
}
|
||||||
|
return Promise.resolve({ ok: true } as Response);
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockEnvironmentState: EnvironmentState = {
|
||||||
|
configStatus: 'success',
|
||||||
|
VEGA_URL: 'https://vega.xyz',
|
||||||
|
VEGA_ENV: Networks.TESTNET,
|
||||||
|
VEGA_CONFIG_URL: 'https://vega.xyz/testnet-config.json',
|
||||||
|
VEGA_NETWORKS: {
|
||||||
|
TESTNET: 'https://testnet.url',
|
||||||
|
STAGNET: 'https://stagnet.url',
|
||||||
|
MAINNET: 'https://mainnet.url',
|
||||||
|
},
|
||||||
|
ETHEREUM_PROVIDER_URL: 'https://ether.provider',
|
||||||
|
ETHERSCAN_URL: 'https://etherscan.url',
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// @ts-ignore typscript doesn't recognise the mock implementation
|
||||||
|
global.fetch.mockReset();
|
||||||
|
// @ts-ignore typscript doesn't recognise the mock implementation
|
||||||
|
global.fetch.mockImplementation(mockFetch);
|
||||||
|
|
||||||
|
window.localStorage.clear();
|
||||||
|
|
||||||
|
process.env['NX_VEGA_URL'] = mockEnvironmentState.VEGA_URL;
|
||||||
|
process.env['NX_VEGA_ENV'] = mockEnvironmentState.VEGA_ENV;
|
||||||
|
process.env['NX_VEGA_CONFIG_URL'] = mockEnvironmentState.VEGA_CONFIG_URL;
|
||||||
|
process.env['NX_ETHEREUM_PROVIDER_URL'] =
|
||||||
|
mockEnvironmentState.ETHEREUM_PROVIDER_URL;
|
||||||
|
process.env['NX_ETHERSCAN_URL'] = mockEnvironmentState.ETHERSCAN_URL;
|
||||||
|
process.env['NX_VEGA_NETWORKS'] = JSON.stringify(
|
||||||
|
mockEnvironmentState.VEGA_NETWORKS
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
// @ts-ignore: typescript doesn't recognise the mocked fetch instance
|
||||||
|
fetch.mockRestore();
|
||||||
|
window.localStorage.clear();
|
||||||
|
|
||||||
|
delete process.env['NX_VEGA_URL'];
|
||||||
|
delete process.env['NX_VEGA_ENV'];
|
||||||
|
delete process.env['NX_VEGA_CONFIG_URL'];
|
||||||
|
delete process.env['NX_ETHEREUM_PROVIDER_URL'];
|
||||||
|
delete process.env['NX_ETHERSCAN_URL'];
|
||||||
|
delete process.env['NX_VEGA_NETWORKS'];
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('useEnvironment hook', () => {
|
||||||
|
it('transforms and exposes values from the environment', () => {
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual(mockEnvironmentState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows for the VEGA_CONFIG_URL to be missing when there is a VEGA_URL present', () => {
|
||||||
|
delete process.env['NX_VEGA_CONFIG_URL'];
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
...mockEnvironmentState,
|
||||||
|
VEGA_CONFIG_URL: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows for the VEGA_URL to be missing when there is a VEGA_CONFIG_URL present', async () => {
|
||||||
|
delete process.env['NX_VEGA_URL'];
|
||||||
|
const { result, waitForNextUpdate } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
await waitForNextUpdate();
|
||||||
|
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
...mockEnvironmentState,
|
||||||
|
VEGA_URL: MOCK_HOST,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows for the VEGA_NETWORKS to be missing from the environment', () => {
|
||||||
|
delete process.env['NX_VEGA_NETWORKS'];
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
...mockEnvironmentState,
|
||||||
|
VEGA_NETWORKS: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws a validation error when NX_VEGA_ENV is not found in the environment', async () => {
|
||||||
|
delete process.env['NX_VEGA_ENV'];
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error?.message).toContain(
|
||||||
|
`NX_VEGA_ENV is invalid, received "undefined" instead of: 'CUSTOM' | 'TESTNET' | 'STAGNET' | 'STAGNET2' | 'DEVNET' | 'MAINNET'`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws a validation error when VEGA_ENV is not a valid network', () => {
|
||||||
|
process.env['NX_VEGA_ENV'] = 'SOMETHING';
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).not.toContain(
|
||||||
|
`NX_VEGA_ENV is invalid, received "SOMETHING" instead of: CUSTOM | TESTNET | STAGNET | STAGNET2 | DEVNET | MAINNET`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when VEGA_NETWORKS is not a valid json, prints a warning and continues without using the value from it', () => {
|
||||||
|
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(noop);
|
||||||
|
process.env['NX_VEGA_NETWORKS'] = '{not:{valid:json';
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
...mockEnvironmentState,
|
||||||
|
VEGA_NETWORKS: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(consoleWarnSpy).toHaveBeenCalled();
|
||||||
|
consoleWarnSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws a validation error when VEGA_NETWORKS is has an invalid network as a key', () => {
|
||||||
|
process.env['NX_VEGA_NETWORKS'] = JSON.stringify({
|
||||||
|
NOT_A_NETWORK: 'https://somewhere.url',
|
||||||
|
});
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error?.message).toContain(
|
||||||
|
`All keys in NX_VEGA_NETWORKS must represent a valid environment: CUSTOM | TESTNET | STAGNET | STAGNET2 | DEVNET | MAINNET`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws a validation error when both VEGA_URL and VEGA_CONFIG_URL are missing in the environment', () => {
|
||||||
|
delete process.env['NX_VEGA_URL'];
|
||||||
|
delete process.env['NX_VEGA_CONFIG_URL'];
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error?.message).toContain(
|
||||||
|
`Must provide either NX_VEGA_CONFIG_URL or NX_VEGA_URL in the environment.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each`
|
||||||
|
env | etherscanUrl | providerUrl
|
||||||
|
${Networks.DEVNET} | ${'https://ropsten.etherscan.io'} | ${'https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'}
|
||||||
|
${Networks.TESTNET} | ${'https://ropsten.etherscan.io'} | ${'https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'}
|
||||||
|
${Networks.STAGNET} | ${'https://ropsten.etherscan.io'} | ${'https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'}
|
||||||
|
${Networks.STAGNET2} | ${'https://ropsten.etherscan.io'} | ${'https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'}
|
||||||
|
${Networks.MAINNET} | ${'https://etherscan.io'} | ${'https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'}
|
||||||
|
`(
|
||||||
|
'uses correct default ethereum connection variables in $env',
|
||||||
|
async ({ env, etherscanUrl, providerUrl }) => {
|
||||||
|
process.env['NX_VEGA_ENV'] = env;
|
||||||
|
delete process.env['NX_ETHEREUM_PROVIDER_URL'];
|
||||||
|
delete process.env['NX_ETHERSCAN_URL'];
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error).toBe(undefined);
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
...mockEnvironmentState,
|
||||||
|
VEGA_ENV: env,
|
||||||
|
ETHEREUM_PROVIDER_URL: providerUrl,
|
||||||
|
ETHERSCAN_URL: etherscanUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('throws a validation error when NX_ETHERSCAN_URL is not a valid url', async () => {
|
||||||
|
process.env['NX_ETHERSCAN_URL'] = 'invalid-url';
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error?.message).toContain(
|
||||||
|
`The NX_ETHERSCAN_URL environment variable must be a valid url`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws a validation error when NX_ETHEREUM_PROVIDER_URL is not a valid url', async () => {
|
||||||
|
process.env['NX_ETHEREUM_PROVIDER_URL'] = 'invalid-url';
|
||||||
|
const { result } = renderHook(() => useEnvironment(), {
|
||||||
|
wrapper: MockWrapper,
|
||||||
|
});
|
||||||
|
expect(result.error?.message).toContain(
|
||||||
|
`The NX_ETHEREUM_PROVIDER_URL environment variable must be a valid url`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
50
libs/environment/src/hooks/use-environment.tsx
Normal file
50
libs/environment/src/hooks/use-environment.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import type { ReactNode } from 'react';
|
||||||
|
import { useState, createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
import { useConfig } from './use-config';
|
||||||
|
import { compileEnvironment } from '../utils/compile-environment';
|
||||||
|
import { validateEnvironment } from '../utils/validate-environment';
|
||||||
|
import type { Environment, RawEnvironment, ConfigStatus } from '../types';
|
||||||
|
|
||||||
|
type EnvironmentProviderProps = {
|
||||||
|
definitions?: Partial<RawEnvironment>;
|
||||||
|
children?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EnvironmentState = Environment & {
|
||||||
|
configStatus: ConfigStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
const EnvironmentContext = createContext({} as EnvironmentState);
|
||||||
|
|
||||||
|
export const EnvironmentProvider = ({
|
||||||
|
definitions,
|
||||||
|
children,
|
||||||
|
}: EnvironmentProviderProps) => {
|
||||||
|
const [environment, updateEnvironment] = useState<Environment>(
|
||||||
|
compileEnvironment(definitions)
|
||||||
|
);
|
||||||
|
const { status: configStatus } = useConfig(environment, updateEnvironment);
|
||||||
|
|
||||||
|
const errorMessage = validateEnvironment(environment);
|
||||||
|
|
||||||
|
if (errorMessage) {
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EnvironmentContext.Provider value={{ ...environment, configStatus }}>
|
||||||
|
{children}
|
||||||
|
</EnvironmentContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useEnvironment = () => {
|
||||||
|
const context = useContext(EnvironmentContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
'Error running "useEnvironment". No context found, make sure your component is wrapped in an <EnvironmentProvider />.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
@ -3,3 +3,6 @@ export * from './components';
|
|||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
export * from './hooks';
|
export * from './hooks';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
export * from './types';
|
27
libs/environment/src/types.ts
Normal file
27
libs/environment/src/types.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import type z from 'zod';
|
||||||
|
|
||||||
|
import type { configSchema } from './utils/validate-configuration';
|
||||||
|
import type { envSchema } from './utils/validate-environment';
|
||||||
|
import { Networks, ENV_KEYS } from './utils/validate-environment';
|
||||||
|
|
||||||
|
export { ENV_KEYS, Networks };
|
||||||
|
|
||||||
|
export type Environment = z.infer<typeof envSchema> & {
|
||||||
|
// provide this manually, zod fails to compile the correct type fot VEGA_NETWORKS
|
||||||
|
VEGA_NETWORKS: Partial<Record<Networks, string>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EnvKey = keyof Environment;
|
||||||
|
|
||||||
|
export type RawEnvironment = Record<EnvKey, string>;
|
||||||
|
|
||||||
|
export type Configuration = z.infer<typeof configSchema>;
|
||||||
|
|
||||||
|
export type ConfigStatus =
|
||||||
|
| 'idle'
|
||||||
|
| 'success'
|
||||||
|
| 'loading-config'
|
||||||
|
| 'loading-node'
|
||||||
|
| 'error-loading-config'
|
||||||
|
| 'error-validating-config'
|
||||||
|
| 'error-loading-node';
|
102
libs/environment/src/utils/compile-environment.ts
Normal file
102
libs/environment/src/utils/compile-environment.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import type { RawEnvironment, EnvKey, Environment } from '../types';
|
||||||
|
import { Networks, ENV_KEYS } from '../types';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
_env_?: Record<string, string>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isBrowser = typeof window !== 'undefined';
|
||||||
|
|
||||||
|
const getDefaultEtherumProviderUrl = (env: Networks) => {
|
||||||
|
return env === Networks.MAINNET
|
||||||
|
? 'https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8'
|
||||||
|
: 'https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDefaultEtherscanUrl = (env: Networks) => {
|
||||||
|
return env === Networks.MAINNET
|
||||||
|
? 'https://etherscan.io'
|
||||||
|
: 'https://ropsten.etherscan.io';
|
||||||
|
};
|
||||||
|
|
||||||
|
const transformValue = (key: EnvKey, value?: string) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'VEGA_ENV':
|
||||||
|
return value as Networks;
|
||||||
|
case 'VEGA_NETWORKS': {
|
||||||
|
if (value) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(value);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(
|
||||||
|
'Error parsing the "NX_VEGA_NETWORKS" environment variable. Make sure it has a valid JSON format.'
|
||||||
|
);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBundledEnvironmentValue = (key: EnvKey) => {
|
||||||
|
switch (key) {
|
||||||
|
// need to have these hardcoded so on build time they can be replaced with the relevant environment variable
|
||||||
|
case 'VEGA_URL':
|
||||||
|
return process.env['NX_VEGA_URL'];
|
||||||
|
case 'VEGA_ENV':
|
||||||
|
return process.env['NX_VEGA_ENV'];
|
||||||
|
case 'VEGA_CONFIG_URL':
|
||||||
|
return process.env['NX_VEGA_CONFIG_URL'];
|
||||||
|
case 'ETHEREUM_PROVIDER_URL':
|
||||||
|
return process.env['NX_ETHEREUM_PROVIDER_URL'];
|
||||||
|
case 'ETHERSCAN_URL':
|
||||||
|
return process.env['NX_ETHERSCAN_URL'];
|
||||||
|
case 'VEGA_NETWORKS':
|
||||||
|
return process.env['NX_VEGA_NETWORKS'];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getValue = (key: EnvKey, definitions: Partial<RawEnvironment> = {}) => {
|
||||||
|
if (!isBrowser) {
|
||||||
|
return transformValue(
|
||||||
|
key,
|
||||||
|
definitions[key] ?? getBundledEnvironmentValue(key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return transformValue(
|
||||||
|
key,
|
||||||
|
definitions[key] ?? window._env_?.[key] ?? getBundledEnvironmentValue(key)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const compileEnvironment = (
|
||||||
|
definitions?: Partial<RawEnvironment>
|
||||||
|
): Environment => {
|
||||||
|
const environment = ENV_KEYS.reduce((acc, key) => {
|
||||||
|
const value = getValue(key, definitions);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[key]: value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {} as Environment);
|
||||||
|
|
||||||
|
return {
|
||||||
|
// @ts-ignore enable using default object props
|
||||||
|
ETHERSCAN_URL: getDefaultEtherscanUrl(environment['VEGA_ENV']),
|
||||||
|
// @ts-ignore enable using default object props
|
||||||
|
ETHEREUM_PROVIDER_URL: getDefaultEtherumProviderUrl(
|
||||||
|
environment['VEGA_ENV']
|
||||||
|
),
|
||||||
|
...environment,
|
||||||
|
};
|
||||||
|
};
|
19
libs/environment/src/utils/compile-errors.ts
Normal file
19
libs/environment/src/utils/compile-errors.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import type { ZodIssue } from 'zod';
|
||||||
|
import { ZodError } from 'zod';
|
||||||
|
|
||||||
|
export const compileErrors = (
|
||||||
|
headline: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
error: any,
|
||||||
|
compileIssue?: (issue: ZodIssue) => string
|
||||||
|
) => {
|
||||||
|
if (error instanceof ZodError) {
|
||||||
|
return error.issues.reduce((acc, issue) => {
|
||||||
|
return (
|
||||||
|
acc + `\n - ${compileIssue ? compileIssue(issue) : issue.message}`
|
||||||
|
);
|
||||||
|
}, `${headline}:`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${headline}${error?.message ? `: ${error.message}` : ''}`;
|
||||||
|
};
|
22
libs/environment/src/utils/promise-race-success.ts
Normal file
22
libs/environment/src/utils/promise-race-success.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export function promiseRaceToSuccess<T>(requests: Array<Promise<T>>) {
|
||||||
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
let hasResolved = false;
|
||||||
|
const failures = [];
|
||||||
|
|
||||||
|
requests.forEach((req) => {
|
||||||
|
req
|
||||||
|
.then((res) => {
|
||||||
|
if (!hasResolved) {
|
||||||
|
resolve(res);
|
||||||
|
hasResolved = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
failures.push(err);
|
||||||
|
if (failures.length === requests.length) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
19
libs/environment/src/utils/validate-configuration.ts
Normal file
19
libs/environment/src/utils/validate-configuration.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import z from 'zod';
|
||||||
|
import type { Configuration } from '../types';
|
||||||
|
import { compileErrors } from './compile-errors';
|
||||||
|
|
||||||
|
export const configSchema = z.object({
|
||||||
|
hosts: z.array(z.string()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const validateConfiguration = (
|
||||||
|
config: Configuration
|
||||||
|
): string | undefined => {
|
||||||
|
try {
|
||||||
|
configSchema.parse(config);
|
||||||
|
return undefined;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
} catch (err: any) {
|
||||||
|
return compileErrors('Error processing the vega app configuration', err);
|
||||||
|
}
|
||||||
|
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user