* feat: unhardcode contract addresses * fix: linting and tests * feat: switch contract usage in token app to use unhardcoded addresses * chore: remove other usage of hard coded contract addresses * feat: convert contracts to classes, update claim contract to fix circular dependency * feat: add hard coded contract addresses to contracts page * fix: misc tidy up * chore: rename ethers big num conversion func * fix: remove pending transactions modal * chore: add single toBigNum function that can accept number string or EthersBignNumber * chore: delete unused tranche helpers and decimals functions from smart contracts lib * feat: add faucetable token class * fix: reset tx state after early exit from approve tx * feat: re add transaction modal using zustand store * fix: loader colors for eth wallet * fix: pass ethereum config to gurantee existence before tx execution * add docker image for building explorer * add arg * env file changes * add docker file to build env file * add requirement for env file in explorer * fix env file syntax * containers functional * default to testnet * make env flag logic consistent in all places * pre populate env file * ensure working for all projects * address PR comment * generalising env for token * invert config dependency from ui toolkit * fix: merge issues * docs: running containers documentation * style: lint * fix: env varibales not being added properly * chore: fix merge issues * chore: fix docker file to support new exectutors * chore: set address on all contracts as a property * feat: pull token from contract rather than relying on env var * chore: fix typing * chore: remove duplicated prop * chore: don't use chainId * style: lint * style: lint * Merge branch 'master' into feat/dockerize-frontends * Merge remote-tracking branch 'origin/master' into feat/dockerize-frontends * test: revert changes to explorer e2e file * fix: creating client without base causing token to error * test: fix tests erroring in before hook due to file not being found * chore: remove node env from configurable flags Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
184 lines
4.9 KiB
TypeScript
184 lines
4.9 KiB
TypeScript
import type { Networks } from '@vegaprotocol/react-helpers';
|
|
import type { ReactNode } from 'react';
|
|
import { useState } from 'react';
|
|
import { createContext, useContext } from 'react';
|
|
|
|
const isBrowser = typeof window !== 'undefined';
|
|
|
|
declare global {
|
|
interface Window {
|
|
_env_?: Record<string, string>;
|
|
}
|
|
}
|
|
interface VegaContracts {
|
|
claimAddress: string;
|
|
lockedAddress: string;
|
|
}
|
|
|
|
export const ContractAddresses: { [key in Networks]: VegaContracts } = {
|
|
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',
|
|
},
|
|
};
|
|
|
|
type EnvironmentProviderProps = {
|
|
definitions?: Partial<RawEnvironment>;
|
|
children?: ReactNode;
|
|
};
|
|
|
|
export const ENV_KEYS = [
|
|
'VEGA_URL',
|
|
'VEGA_ENV',
|
|
'VEGA_NETWORKS',
|
|
'ETHEREUM_CHAIN_ID',
|
|
'ETHEREUM_PROVIDER_URL',
|
|
'ETHERSCAN_URL',
|
|
] as const;
|
|
|
|
type EnvKey = typeof ENV_KEYS[number];
|
|
|
|
type RawEnvironment = Record<EnvKey, string>;
|
|
|
|
export type Environment = {
|
|
VEGA_URL: string;
|
|
VEGA_ENV: Networks;
|
|
VEGA_NETWORKS: Record<Networks, string>;
|
|
ETHEREUM_CHAIN_ID: number;
|
|
ETHEREUM_PROVIDER_URL: string;
|
|
ETHERSCAN_URL: string;
|
|
ADDRESSES: VegaContracts;
|
|
};
|
|
|
|
type EnvironmentState = Environment;
|
|
|
|
const getBundledEnvironmentValue = (key: EnvKey) => {
|
|
switch (key) {
|
|
// need to have these hardcoded so on build time we can insert sensible defaults
|
|
case 'VEGA_URL':
|
|
return process.env['NX_VEGA_URL'];
|
|
case 'VEGA_ENV':
|
|
return process.env['NX_VEGA_ENV'];
|
|
case 'ETHEREUM_CHAIN_ID':
|
|
return process.env['NX_ETHEREUM_CHAIN_ID'];
|
|
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 transformValue = (key: EnvKey, value?: string) => {
|
|
switch (key) {
|
|
case 'VEGA_ENV':
|
|
return value as Networks;
|
|
case 'ETHEREUM_CHAIN_ID':
|
|
return value && Number(value);
|
|
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 undefined;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
default:
|
|
return value;
|
|
}
|
|
};
|
|
|
|
const getValue = (key: EnvKey, definitions: Partial<RawEnvironment> = {}) => {
|
|
if (!isBrowser) {
|
|
return transformValue(
|
|
key,
|
|
definitions[key] ?? getBundledEnvironmentValue(key)
|
|
);
|
|
}
|
|
return transformValue(
|
|
key,
|
|
window._env_?.[key] ?? definitions[key] ?? getBundledEnvironmentValue(key)
|
|
);
|
|
};
|
|
|
|
const compileEnvironment = (
|
|
definitions?: Partial<RawEnvironment>
|
|
): Environment => {
|
|
const environment = ENV_KEYS.reduce(
|
|
(acc, key) => ({
|
|
...acc,
|
|
[key]: getValue(key, definitions),
|
|
}),
|
|
{} as Environment
|
|
);
|
|
|
|
return {
|
|
...environment,
|
|
ADDRESSES: ContractAddresses[environment['VEGA_ENV']],
|
|
VEGA_NETWORKS: {
|
|
[environment.VEGA_ENV]: isBrowser
|
|
? window.location.href
|
|
: environment.VEGA_NETWORKS[environment.VEGA_ENV],
|
|
...environment.VEGA_NETWORKS,
|
|
},
|
|
};
|
|
};
|
|
|
|
const EnvironmentContext = createContext({} as EnvironmentState);
|
|
|
|
export const EnvironmentProvider = ({
|
|
definitions,
|
|
children,
|
|
}: EnvironmentProviderProps) => {
|
|
const [environment] = useState<Environment>(compileEnvironment(definitions));
|
|
|
|
const missingKeys = Object.keys(environment)
|
|
.filter((key) => typeof environment[key as EnvKey] === undefined)
|
|
.map((key) => `"${key}"`)
|
|
.join(', ');
|
|
|
|
if (missingKeys.length) {
|
|
throw new Error(
|
|
`Error setting up the app environment. The following variables are missing from your environment: ${missingKeys}.`
|
|
);
|
|
}
|
|
|
|
return (
|
|
<EnvironmentContext.Provider value={environment}>
|
|
{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;
|
|
};
|