* feat: add enviromnemt provider to the ui-toolkit * chore: replace etherscan links * chore: wrap trading app into environment provider * chore: move env provider to react-helpers and wrap every app * chore: remove more env variables from libs and replace them with the env hook * fix: lint * fix: update readme with correct formatting command * fix: warnings for web3 hook * fix: wrap warning in conditional, print message only when env keys are missing * fix: incorrect condition on deposit manager fauceting param Co-authored-by: Matthew Russell <mattrussell36@gmail.com> * fix: cleanup token app ethereum config * chore: add better error handling to the useEnvironment hook * fix: lint * fix: formatting * fix: more lint * fix: throw error if required env variables are missing * fix: remove default eth chain id * fix: add back etherscan testid to withdrawals links * fix: imports * fix: try using babel jest for smart contracts test transpilation * fix: uniform ts syntax * chore: set resolveJsonModule in base tsconfig * fix: add missing data-ids for etherscan links Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
bf07dac445
commit
3a27172e04
@ -96,7 +96,7 @@ To run tests locally using your own wallets you can add the following environmen
|
||||
In CI linting, formatting and also run. These checks can be seen in the [CI workflow file](.github/workflows//test.yml).
|
||||
|
||||
- To fix linting errors locally run `yarn nx lint --fix`
|
||||
- To fix formatting errors local run `yarn nx format`
|
||||
- To fix formatting errors local run `yarn nx format:write`
|
||||
- For either command you may use `--all` to run across the entire repository
|
||||
|
||||
### Further help with Nx
|
||||
|
@ -10,7 +10,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -2,7 +2,10 @@ import { useState, useEffect, useMemo } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ApolloProvider } from '@apollo/client';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useThemeSwitcher,
|
||||
EnvironmentProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { Nav } from './components/nav';
|
||||
import { Header } from './components/header';
|
||||
@ -23,27 +26,29 @@ function App() {
|
||||
const client = useMemo(() => createClient(DATA_SOURCES.dataNodeUrl), []);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<TendermintWebsocketProvider>
|
||||
<ApolloProvider client={client}>
|
||||
<div
|
||||
className={`${
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||
>
|
||||
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-black dark:border-white lg:border-l-1 lg:border-r-1 mx-auto">
|
||||
<Header
|
||||
toggleTheme={toggleTheme}
|
||||
menuOpen={menuOpen}
|
||||
setMenuOpen={setMenuOpen}
|
||||
/>
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<TendermintWebsocketProvider>
|
||||
<ApolloProvider client={client}>
|
||||
<div
|
||||
className={`${
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||
>
|
||||
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-black dark:border-white lg:border-l-1 lg:border-r-1 mx-auto">
|
||||
<Header
|
||||
toggleTheme={toggleTheme}
|
||||
menuOpen={menuOpen}
|
||||
setMenuOpen={setMenuOpen}
|
||||
/>
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ApolloProvider>
|
||||
</TendermintWebsocketProvider>
|
||||
</ThemeContext.Provider>
|
||||
</ApolloProvider>
|
||||
</TendermintWebsocketProvider>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"lib": ["es5", "es6", "dom", "dom.iterable"],
|
||||
"resolveJsonModule": true
|
||||
"lib": ["es5", "es6", "dom", "dom.iterable"]
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
VegaManageDialog,
|
||||
VegaWalletProvider,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { EnvironmentProvider } from '@vegaprotocol/react-helpers';
|
||||
import { VegaWalletConnectButton } from './components/vega-wallet-connect-button';
|
||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { Connectors } from './lib/vega-connectors';
|
||||
@ -37,51 +38,53 @@ function App() {
|
||||
}, [location]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<ApolloProvider client={client}>
|
||||
<VegaWalletProvider>
|
||||
<AppLoader>
|
||||
<div className="h-full dark:bg-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
||||
<div className="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||
<DrawerToggle
|
||||
onToggle={onToggle}
|
||||
variant={DRAWER_TOGGLE_VARIANTS.OPEN}
|
||||
className="xs:py-32 xs:px-16"
|
||||
/>
|
||||
|
||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
setManageDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<ApolloProvider client={client}>
|
||||
<VegaWalletProvider>
|
||||
<AppLoader>
|
||||
<div className="h-full dark:bg-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
||||
<div className="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||
<DrawerToggle
|
||||
onToggle={onToggle}
|
||||
variant={DRAWER_TOGGLE_VARIANTS.OPEN}
|
||||
className="xs:py-32 xs:px-16"
|
||||
/>
|
||||
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||
|
||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
setManageDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Main isMenuOpen={menuOpen} onToggle={onToggle} />
|
||||
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWallet.connect}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWallet.manage}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Main isMenuOpen={menuOpen} onToggle={onToggle} />
|
||||
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWallet.connect}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWallet.manage}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</VegaWalletProvider>
|
||||
</ApolloProvider>
|
||||
</ThemeContext.Provider>
|
||||
</AppLoader>
|
||||
</VegaWalletProvider>
|
||||
</ApolloProvider>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -3,6 +3,7 @@ import { DATA_SOURCES } from './config';
|
||||
import { Header } from './components/header';
|
||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { EnvironmentProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const envName = DATA_SOURCES.envName;
|
||||
@ -14,19 +15,21 @@ function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
|
||||
return (
|
||||
<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="layout-grid w-screen justify-self-center">
|
||||
<Header toggleTheme={toggleTheme} />
|
||||
<StatsManager
|
||||
envName={envName}
|
||||
statsEndpoint={statsEndpoint}
|
||||
nodesEndpoint={nodesEndpoint}
|
||||
className="max-w-3xl px-24"
|
||||
/>
|
||||
<EnvironmentProvider>
|
||||
<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="layout-grid w-screen justify-self-center">
|
||||
<Header toggleTheme={toggleTheme} />
|
||||
<StatsManager
|
||||
envName={envName}
|
||||
statsEndpoint={statsEndpoint}
|
||||
nodesEndpoint={nodesEndpoint}
|
||||
className="max-w-3xl px-24"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeContext.Provider>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -20,37 +20,40 @@ import { Web3Provider } from '@vegaprotocol/web3';
|
||||
import { Connectors } from './lib/web3-connectors';
|
||||
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
|
||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||
import { EnvironmentProvider } from '@vegaprotocol/react-helpers';
|
||||
|
||||
function App() {
|
||||
const sideBar = React.useMemo(() => [<EthWallet />, <VegaWallet />], []);
|
||||
return (
|
||||
<GraphQlProvider>
|
||||
<Router>
|
||||
<AppStateProvider>
|
||||
<Web3Provider connectors={Connectors}>
|
||||
<Web3Connector>
|
||||
<VegaWalletProvider>
|
||||
<ContractsProvider>
|
||||
<AppLoader>
|
||||
<BalanceManager>
|
||||
<>
|
||||
<div className="app dark max-w-[1300px] mx-auto my-0 grid grid-rows-[min-content_1fr_min-content] min-h-full lg:border-l-1 lg:border-r-1 lg:border-white font-sans text-body lg:text-body-large text-white-80">
|
||||
<AppBanner />
|
||||
<TemplateSidebar sidebar={sideBar}>
|
||||
<AppRouter />
|
||||
</TemplateSidebar>
|
||||
<AppFooter />
|
||||
</div>
|
||||
<VegaWalletDialogs />
|
||||
<TransactionModal />
|
||||
</>
|
||||
</BalanceManager>
|
||||
</AppLoader>
|
||||
</ContractsProvider>
|
||||
</VegaWalletProvider>
|
||||
</Web3Connector>
|
||||
</Web3Provider>
|
||||
</AppStateProvider>
|
||||
<EnvironmentProvider>
|
||||
<AppStateProvider>
|
||||
<Web3Provider connectors={Connectors}>
|
||||
<Web3Connector>
|
||||
<VegaWalletProvider>
|
||||
<ContractsProvider>
|
||||
<AppLoader>
|
||||
<BalanceManager>
|
||||
<>
|
||||
<div className="app dark max-w-[1300px] mx-auto my-0 grid grid-rows-[min-content_1fr_min-content] min-h-full lg:border-l-1 lg:border-r-1 lg:border-white font-sans text-body lg:text-body-large text-white-80">
|
||||
<AppBanner />
|
||||
<TemplateSidebar sidebar={sideBar}>
|
||||
<AppRouter />
|
||||
</TemplateSidebar>
|
||||
<AppFooter />
|
||||
</div>
|
||||
<VegaWalletDialogs />
|
||||
<TransactionModal />
|
||||
</>
|
||||
</BalanceManager>
|
||||
</AppLoader>
|
||||
</ContractsProvider>
|
||||
</VegaWalletProvider>
|
||||
</Web3Connector>
|
||||
</Web3Provider>
|
||||
</AppStateProvider>
|
||||
</EnvironmentProvider>
|
||||
</Router>
|
||||
</GraphQlProvider>
|
||||
);
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { ADDRESSES } from '../../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { useAddAssetSupported } from '../../hooks/use-add-asset-to-wallet';
|
||||
import vegaVesting from '../../images/vega_vesting.png';
|
||||
import { AddTokenButtonLink } from '../add-token-button/add-token-button';
|
||||
import { Callout } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const AddLockedTokenAddress = () => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const addSupported = useAddAssetSupported();
|
||||
return (
|
||||
|
@ -2,7 +2,7 @@ import * as Sentry from '@sentry/react';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import React from 'react';
|
||||
|
||||
import { ADDRESSES } from '../../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@ -17,6 +17,7 @@ interface BalanceManagerProps {
|
||||
}
|
||||
|
||||
export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const contracts = useContracts();
|
||||
const { account } = useWeb3React();
|
||||
const { appDispatch } = useAppState();
|
||||
@ -55,7 +56,13 @@ export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
||||
};
|
||||
|
||||
updateBalances();
|
||||
}, [appDispatch, contracts?.token, contracts?.vesting, account]);
|
||||
}, [
|
||||
appDispatch,
|
||||
contracts?.token,
|
||||
contracts?.vesting,
|
||||
account,
|
||||
ADDRESSES.stakingBridge,
|
||||
]);
|
||||
|
||||
// This use effect hook is very expensive and is kept separate to prevent expensive reloading of data.
|
||||
React.useEffect(() => {
|
||||
|
@ -3,7 +3,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import type { TransactionState } from '../../hooks/transaction-reducer';
|
||||
import { TxState } from '../../hooks/transaction-reducer';
|
||||
import { truncateMiddle } from '../../lib/truncate-middle';
|
||||
import { Button, EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Button, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Error, HandUp, Tick } from '../icons';
|
||||
import { Loader } from '../loader';
|
||||
import { StatefulButton } from '../stateful-button';
|
||||
@ -122,6 +123,7 @@ export const TransactionButtonFooter = ({
|
||||
txHash,
|
||||
message,
|
||||
}: TransactionButtonFooterProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (message) {
|
||||
@ -142,7 +144,12 @@ export const TransactionButtonFooter = ({
|
||||
<div className="transaction-button__footer">
|
||||
<p className="flex justify-between items-start m-0 text-ui">
|
||||
<span>{t('transaction')}</span>
|
||||
<EtherscanLink text={truncateMiddle(txHash)} tx={txHash} />
|
||||
<Link
|
||||
href={`${ETHERSCAN_URL}/tx/${txHash}`}
|
||||
title={t('View on Etherscan')}
|
||||
>
|
||||
{truncateMiddle(txHash)}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
export const TransactionComplete = ({
|
||||
@ -14,6 +15,7 @@ export const TransactionComplete = ({
|
||||
footer?: ReactElement | string;
|
||||
body?: ReactElement | string;
|
||||
}) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Callout
|
||||
@ -23,7 +25,12 @@ export const TransactionComplete = ({
|
||||
>
|
||||
{body && <p data-testid="transaction-complete-body">{body}</p>}
|
||||
<p>
|
||||
<EtherscanLink tx={hash} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${hash}`}
|
||||
>
|
||||
{hash}
|
||||
</Link>
|
||||
</p>
|
||||
{footer && <p data-testid="transaction-complete-footer">{footer}</p>}
|
||||
</Callout>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Button, Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import type { Error } from '../icons';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export interface TransactionErrorProps {
|
||||
error: Error | null;
|
||||
@ -15,6 +15,7 @@ export const TransactionError = ({
|
||||
hash,
|
||||
onActionClick,
|
||||
}: TransactionErrorProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -22,7 +23,12 @@ export const TransactionError = ({
|
||||
<p>{error ? error.message : t('Something went wrong')}</p>
|
||||
{hash ? (
|
||||
<p>
|
||||
<EtherscanLink tx={hash} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${hash}`}
|
||||
>
|
||||
{hash}
|
||||
</Link>
|
||||
</p>
|
||||
) : null}
|
||||
<Button onClick={() => onActionClick()}>{t('Try again')}</Button>
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Callout } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const TransactionPending = ({
|
||||
hash,
|
||||
@ -18,6 +19,7 @@ export const TransactionPending = ({
|
||||
footer?: React.ReactElement | string;
|
||||
body?: React.ReactElement | string;
|
||||
}) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const remainingConfirmations = React.useMemo(() => {
|
||||
if (requiredConfirmations) {
|
||||
@ -38,7 +40,12 @@ export const TransactionPending = ({
|
||||
<Callout iconName="refresh" title={title}>
|
||||
{body && <p data-testid="transaction-pending-body">{body}</p>}
|
||||
<p>
|
||||
<EtherscanLink tx={hash} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${hash}`}
|
||||
>
|
||||
{hash}
|
||||
</Link>
|
||||
</p>
|
||||
{footer && <p data-testid="transaction-pending-footer">{footer}</p>}
|
||||
</Callout>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { TxData } from '@vegaprotocol/smart-contracts';
|
||||
import { Dialog, EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Dialog, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -28,6 +29,7 @@ const TransactionModalStatus = ({
|
||||
}) => <span className="flex gap-4 items-center">{children}</span>;
|
||||
|
||||
export const TransactionModal = () => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const { transactions } = useContracts();
|
||||
const { appState, appDispatch } = useAppState();
|
||||
@ -76,16 +78,20 @@ export const TransactionModal = () => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{transactions.map((t) => {
|
||||
{transactions.map((transaction) => {
|
||||
return (
|
||||
<tr key={t.tx.hash}>
|
||||
<tr key={transaction.tx.hash}>
|
||||
<TransactionModalTd>
|
||||
<EtherscanLink
|
||||
tx={t.tx.hash}
|
||||
text={truncateMiddle(t.tx.hash)}
|
||||
/>
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${transaction.tx.hash}`}
|
||||
>
|
||||
{truncateMiddle(transaction.tx.hash)}
|
||||
</Link>
|
||||
</TransactionModalTd>
|
||||
<TransactionModalTd>
|
||||
{renderStatus(transaction)}
|
||||
</TransactionModalTd>
|
||||
<TransactionModalTd>{renderStatus(t)}</TransactionModalTd>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
|
@ -6,7 +6,6 @@ import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { AccountType } from '../../__generated__/globalTypes';
|
||||
import { ADDRESSES } from '../../config';
|
||||
import noIcon from '../../images/token-no-icon.png';
|
||||
import vegaBlack from '../../images/vega_black.png';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
@ -18,6 +17,7 @@ import type {
|
||||
DelegationsVariables,
|
||||
} from './__generated__/Delegations';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const DELEGATIONS_QUERY = gql`
|
||||
query Delegations($partyId: ID!) {
|
||||
@ -60,6 +60,7 @@ const DELEGATIONS_QUERY = gql`
|
||||
`;
|
||||
|
||||
export const usePollForDelegations = () => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const { keypair } = useVegaWallet();
|
||||
const client = useApolloClient();
|
||||
@ -227,7 +228,7 @@ export const usePollForDelegations = () => {
|
||||
clearInterval(interval);
|
||||
mounted = false;
|
||||
};
|
||||
}, [client, keypair?.pub, t]);
|
||||
}, [client, keypair?.pub, t, ADDRESSES.vegaTokenAddress]);
|
||||
|
||||
return { delegations, currentStakeAvailable, delegatedNodes, accounts };
|
||||
};
|
||||
|
@ -1,30 +0,0 @@
|
||||
import type { EthereumChainId } from '@vegaprotocol/smart-contracts';
|
||||
import {
|
||||
EnvironmentConfig,
|
||||
EthereumChainIds,
|
||||
} from '@vegaprotocol/smart-contracts';
|
||||
|
||||
import type { Networks } from './vega';
|
||||
|
||||
type VegaContracts = typeof EnvironmentConfig[Networks];
|
||||
|
||||
const appChainId = Number(process.env['NX_ETHEREUM_CHAIN_ID'] || 3);
|
||||
|
||||
export const APP_ENV = process.env['NX_VEGA_ENV'] as Networks;
|
||||
|
||||
const Addresses: Record<number, VegaContracts> = {
|
||||
1: EnvironmentConfig.MAINNET,
|
||||
3: EnvironmentConfig[APP_ENV],
|
||||
};
|
||||
|
||||
export type { EthereumChainId };
|
||||
export { EthereumChainIds };
|
||||
|
||||
/** Contract addresses for the different contracts in the VEGA ecosystem */
|
||||
export const ADDRESSES = Addresses[appChainId];
|
||||
|
||||
/**
|
||||
* The Chain ID the environment is configured for.
|
||||
* Normally this is 0x3 (Ropsten) for dev and 0x1 (Mainnet) for prod
|
||||
*/
|
||||
export const APP_CHAIN_ID = appChainId;
|
@ -1,5 +1,4 @@
|
||||
export * from './flags';
|
||||
export * from './ethereum';
|
||||
export * from './links';
|
||||
export * from './network-params';
|
||||
export * from './vega';
|
||||
|
@ -1,11 +1,4 @@
|
||||
export enum Networks {
|
||||
CUSTOM = 'CUSTOM',
|
||||
TESTNET = 'TESTNET',
|
||||
STAGNET = 'STAGNET',
|
||||
STAGNET2 = 'STAGNET2',
|
||||
DEVNET = 'DEVNET',
|
||||
MAINNET = 'MAINNET',
|
||||
}
|
||||
import { Networks } from '@vegaprotocol/smart-contracts';
|
||||
|
||||
interface VegaNode {
|
||||
url: string;
|
||||
|
@ -10,9 +10,9 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
import React from 'react';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
import { SplashLoader } from '../../components/splash-loader';
|
||||
import { ADDRESSES, APP_ENV } from '../../config';
|
||||
import type { ContractsContextShape } from './contracts-context';
|
||||
import { ContractsContext } from './contracts-context';
|
||||
import { defaultProvider } from '../../lib/web3-connectors';
|
||||
@ -21,6 +21,7 @@ import { defaultProvider } from '../../lib/web3-connectors';
|
||||
* Provides Vega Ethereum contract instances to its children.
|
||||
*/
|
||||
export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
||||
const { ADDRESSES, VEGA_ENV } = useEnvironment();
|
||||
const { provider: activeProvider, account } = useWeb3React();
|
||||
const [txs, setTxs] = React.useState<TxData[]>([]);
|
||||
const [contracts, setContracts] = React.useState<Pick<
|
||||
@ -53,20 +54,20 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
||||
signer
|
||||
),
|
||||
// @ts-ignore Cant accept JsonRpcProvider provider
|
||||
staking: new VegaStaking(APP_ENV, provider, signer),
|
||||
staking: new VegaStaking(VEGA_ENV, provider, signer),
|
||||
// @ts-ignore Cant accept JsonRpcProvider provider
|
||||
vesting: new VegaVesting(APP_ENV, provider, signer),
|
||||
vesting: new VegaVesting(VEGA_ENV, provider, signer),
|
||||
// @ts-ignore Cant accept JsonRpcProvider provider
|
||||
claim: new VegaClaim(APP_ENV, provider, signer),
|
||||
claim: new VegaClaim(VEGA_ENV, provider, signer),
|
||||
erc20Bridge: new VegaErc20Bridge(
|
||||
APP_ENV,
|
||||
VEGA_ENV,
|
||||
// @ts-ignore Cant accept JsonRpcProvider provider
|
||||
provider,
|
||||
signer
|
||||
),
|
||||
});
|
||||
}
|
||||
}, [activeProvider, account]);
|
||||
}, [activeProvider, account, ADDRESSES.vegaTokenAddress, VEGA_ENV]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!contracts) return;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import React from 'react';
|
||||
|
||||
import { APP_ENV, Networks } from '../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Networks } from '@vegaprotocol/smart-contracts';
|
||||
|
||||
export const useAddAssetSupported = () => {
|
||||
const { connector } = useWeb3React();
|
||||
@ -19,6 +19,7 @@ export const useAddAssetToWallet = (
|
||||
decimals: number,
|
||||
image: string
|
||||
) => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { provider } = useWeb3React();
|
||||
const addSupported = useAddAssetSupported();
|
||||
const add = React.useCallback(async () => {
|
||||
@ -35,10 +36,10 @@ export const useAddAssetToWallet = (
|
||||
address,
|
||||
symbol: `${symbol}${
|
||||
// Add the environment if not mainnet
|
||||
APP_ENV === Networks.MAINNET
|
||||
VEGA_ENV === Networks.MAINNET
|
||||
? ''
|
||||
: // Remove NET as VEGA(TESTNET) is too long
|
||||
` ${APP_ENV.replace('NET', '')}`
|
||||
` ${VEGA_ENV.replace('NET', '')}`
|
||||
}`,
|
||||
decimals,
|
||||
image,
|
||||
@ -48,7 +49,7 @@ export const useAddAssetToWallet = (
|
||||
} catch (error) {
|
||||
Sentry.captureException(error);
|
||||
}
|
||||
}, [address, decimals, image, provider, symbol]);
|
||||
}, [address, decimals, image, provider, symbol, VEGA_ENV]);
|
||||
|
||||
return React.useMemo(() => {
|
||||
return {
|
||||
|
@ -2,7 +2,7 @@ import * as Sentry from '@sentry/react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import React from 'react';
|
||||
|
||||
import { ADDRESSES } from '../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@ -10,6 +10,7 @@ import {
|
||||
import { useContracts } from '../contexts/contracts/contracts-context';
|
||||
|
||||
export const useRefreshBalances = (address: string) => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const { appDispatch } = useAppState();
|
||||
const { keypair } = useVegaWallet();
|
||||
const { token, staking, vesting } = useContracts();
|
||||
@ -44,5 +45,13 @@ export const useRefreshBalances = (address: string) => {
|
||||
} catch (err) {
|
||||
Sentry.captureException(err);
|
||||
}
|
||||
}, [address, appDispatch, keypair?.pub, staking, token, vesting]);
|
||||
}, [
|
||||
address,
|
||||
appDispatch,
|
||||
keypair?.pub,
|
||||
staking,
|
||||
token,
|
||||
vesting,
|
||||
ADDRESSES.stakingBridge,
|
||||
]);
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||
import type { Networks, Tranche } from '@vegaprotocol/smart-contracts';
|
||||
import React, { useEffect } from 'react';
|
||||
import { APP_ENV } from '../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
import { BigNumber } from '../lib/bignumber';
|
||||
|
||||
@ -15,8 +15,9 @@ const TRANCHES_URLS: { [N in Networks]: string } = {
|
||||
};
|
||||
|
||||
export function useTranches() {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const [tranches, setTranches] = React.useState<Tranche[] | null>(null);
|
||||
const url = React.useMemo(() => TRANCHES_URLS[APP_ENV], []);
|
||||
const url = React.useMemo(() => TRANCHES_URLS[VEGA_ENV], [VEGA_ENV]);
|
||||
const {
|
||||
state: { data, loading, error },
|
||||
} = useFetch<Tranche[] | null>(url);
|
||||
|
@ -1,11 +1,7 @@
|
||||
import {
|
||||
Callout,
|
||||
Intent,
|
||||
EtherscanLink,
|
||||
Button,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Callout, Intent, Link, Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link as RouteLink } from 'react-router-dom';
|
||||
|
||||
import type { BigNumber } from '../../lib/bignumber';
|
||||
import { formatNumber } from '../../lib/format-number';
|
||||
@ -22,6 +18,7 @@ export const Complete = ({
|
||||
commitTxHash: string | null;
|
||||
claimTxHash: string | null;
|
||||
}) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -38,18 +35,28 @@ export const Complete = ({
|
||||
{commitTxHash && (
|
||||
<p style={{ margin: 0 }}>
|
||||
{t('Link transaction')}:{' '}
|
||||
<EtherscanLink tx={commitTxHash} text={commitTxHash} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${commitTxHash}`}
|
||||
>
|
||||
{commitTxHash}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
{claimTxHash && (
|
||||
<p>
|
||||
{t('Claim transaction')}:{' '}
|
||||
<EtherscanLink tx={claimTxHash} text={claimTxHash} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${claimTxHash}`}
|
||||
>
|
||||
{claimTxHash}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
<Link to={Routes.VESTING}>
|
||||
<RouteLink to={Routes.VESTING}>
|
||||
<Button className="fill">{t('Check your vesting VEGA tokens')}</Button>
|
||||
</Link>
|
||||
</RouteLink>
|
||||
</Callout>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Heading } from '../../components/heading';
|
||||
import { ADDRESSES } from '../../config';
|
||||
|
||||
const Contracts = () => {
|
||||
const { ADDRESSES, ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<section>
|
||||
<Heading title={'Contracts'} />
|
||||
@ -10,7 +13,12 @@ const Contracts = () => {
|
||||
{Object.entries(ADDRESSES).map(([key, value]) => (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>{key}:</div>
|
||||
<EtherscanLink address={value as string} text={value as string} />
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/address/${value}`}
|
||||
>
|
||||
{value}
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
@ -1,13 +1,8 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
Callout,
|
||||
EtherscanLink,
|
||||
Intent,
|
||||
Splash,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Callout, Link, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||
import { ADDRESSES } from '../../../config';
|
||||
import { useTranches } from '../../../hooks/use-tranches';
|
||||
import type { BigNumber } from '../../../lib/bignumber';
|
||||
import { formatNumber } from '../../../lib/format-number';
|
||||
@ -21,6 +16,7 @@ export const TokenDetails = ({
|
||||
totalSupply: BigNumber;
|
||||
totalStaked: BigNumber;
|
||||
}) => {
|
||||
const { ADDRESSES, ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { tranches, loading, error } = useTranches();
|
||||
@ -45,21 +41,25 @@ export const TokenDetails = ({
|
||||
<KeyValueTable className={'token-details'}>
|
||||
<KeyValueTableRow>
|
||||
{t('Token address').toUpperCase()}
|
||||
<EtherscanLink
|
||||
<Link
|
||||
data-testid="token-address"
|
||||
address={ADDRESSES.vegaTokenAddress}
|
||||
text={ADDRESSES.vegaTokenAddress}
|
||||
title={t('View address on Etherscan')}
|
||||
className="font-mono"
|
||||
/>
|
||||
href={`${ETHERSCAN_URL}/address/${ADDRESSES.vegaTokenAddress}`}
|
||||
>
|
||||
{ADDRESSES.vegaTokenAddress}
|
||||
</Link>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
{t('Vesting contract'.toUpperCase())}
|
||||
<EtherscanLink
|
||||
<Link
|
||||
data-testid="token-contract"
|
||||
address={ADDRESSES.vestingAddress}
|
||||
text={ADDRESSES.vestingAddress}
|
||||
title={t('View address on Etherscan')}
|
||||
className="font-mono"
|
||||
/>
|
||||
href={`${ETHERSCAN_URL}/address/${ADDRESSES.vestingAddress}`}
|
||||
>
|
||||
{ADDRESSES.vestingAddress}
|
||||
</Link>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
{t('Total supply').toUpperCase()}
|
||||
|
@ -3,7 +3,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Link, useParams, useOutletContext } from 'react-router-dom';
|
||||
|
||||
import { TransactionCallout } from '../../../components/transaction-callout';
|
||||
import { ADDRESSES } from '../../../config';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { useAppState } from '../../../contexts/app-state/app-state-context';
|
||||
import { useContracts } from '../../../contexts/contracts/contracts-context';
|
||||
import {
|
||||
@ -25,6 +25,7 @@ export const RedeemFromTranche = () => {
|
||||
address: string;
|
||||
}>();
|
||||
const { vesting } = useContracts();
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
appState: { lien, totalVestedBalance, trancheBalances, totalLockedBalance },
|
||||
|
@ -1,12 +1,8 @@
|
||||
import {
|
||||
Button,
|
||||
Callout,
|
||||
EtherscanLink,
|
||||
Intent,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Button, Callout, Link, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link as RouteLink } from 'react-router-dom';
|
||||
|
||||
import { TransactionCallout } from '../../../components/transaction-callout';
|
||||
import type {
|
||||
@ -35,6 +31,7 @@ export const AssociateTransaction = ({
|
||||
requiredConfirmations: number;
|
||||
linking: PartyStakeLinkings_party_stake_linkings | null;
|
||||
}) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const remainingConfirmations = React.useMemo(() => {
|
||||
@ -71,7 +68,12 @@ export const AssociateTransaction = ({
|
||||
})}
|
||||
</p>
|
||||
<p>
|
||||
<EtherscanLink tx={state.txData.hash || ''} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${state.txData.hash}`}
|
||||
>
|
||||
{state.txData.hash}
|
||||
</Link>
|
||||
</p>
|
||||
<p data-testid="transaction-pending-footer">
|
||||
{t('pendingAssociationText', {
|
||||
@ -90,11 +92,11 @@ export const AssociateTransaction = ({
|
||||
{ vegaKey }
|
||||
)}
|
||||
completeFooter={
|
||||
<Link to={Routes.STAKING}>
|
||||
<RouteLink to={Routes.STAKING}>
|
||||
<Button className="fill">
|
||||
{t('Nominate Stake to Validator Node')}
|
||||
</Button>
|
||||
</Link>
|
||||
</RouteLink>
|
||||
}
|
||||
pendingHeading={t('Associating Tokens')}
|
||||
pendingBody={t(
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { TokenInput } from '../../../components/token-input';
|
||||
import { ADDRESSES } from '../../../config';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@ -13,6 +12,7 @@ import { useTransaction } from '../../../hooks/use-transaction';
|
||||
import { BigNumber } from '../../../lib/bignumber';
|
||||
import { AssociateInfo } from './associate-info';
|
||||
import type { VegaKeyExtended } from '@vegaprotocol/wallet';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const WalletAssociate = ({
|
||||
perform,
|
||||
@ -27,6 +27,7 @@ export const WalletAssociate = ({
|
||||
vegaKey: VegaKeyExtended;
|
||||
address: string;
|
||||
}) => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
appDispatch,
|
||||
@ -56,7 +57,13 @@ export const WalletAssociate = ({
|
||||
}
|
||||
};
|
||||
run();
|
||||
}, [address, appDispatch, approveState.txState, token]);
|
||||
}, [
|
||||
address,
|
||||
appDispatch,
|
||||
approveState.txState,
|
||||
token,
|
||||
ADDRESSES.stakingBridge,
|
||||
]);
|
||||
|
||||
let pageContent = null;
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { Button, Callout, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link as RouteLink } from 'react-router-dom';
|
||||
|
||||
import { BulletHeader } from '../../components/bullet-header';
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Links } from '../../config';
|
||||
import {
|
||||
AppStateActionType,
|
||||
@ -29,14 +30,9 @@ export const Staking = ({ data }: { data?: StakingQueryResult }) => {
|
||||
<p className="mb-12">{t('stakingDescription3')}</p>
|
||||
<p className="mb-12">{t('stakingDescription4')}</p>
|
||||
<p className="mb-12">
|
||||
<a
|
||||
className="underline"
|
||||
href={Links.STAKING_GUIDE}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Link href={Links.STAKING_GUIDE} target="_blank">
|
||||
{t('readMoreStaking')}
|
||||
</a>
|
||||
</Link>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@ -65,6 +61,7 @@ export const Staking = ({ data }: { data?: StakingQueryResult }) => {
|
||||
};
|
||||
|
||||
export const StakingStepConnectWallets = () => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const { account } = useWeb3React();
|
||||
const { keypair } = useVegaWallet();
|
||||
@ -75,7 +72,12 @@ export const StakingStepConnectWallets = () => {
|
||||
<Callout intent={Intent.Success} iconName="tick" title={'Connected'}>
|
||||
<p>
|
||||
{t('Connected Ethereum address')}
|
||||
<EtherscanLink address={account} text={account} />
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${account}`}
|
||||
>
|
||||
{account}
|
||||
</Link>
|
||||
</p>
|
||||
<p>
|
||||
{t('stakingVegaWalletConnected', {
|
||||
@ -94,7 +96,7 @@ export const StakingStepConnectWallets = () => {
|
||||
components={{
|
||||
vegaWalletLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a href={Links.WALLET_GUIDE} target="_blank" rel="noreferrer" />
|
||||
<Link href={Links.WALLET_GUIDE} target="_blank" />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
@ -171,17 +173,17 @@ export const StakingStepAssociate = ({
|
||||
title={t('stakingHasAssociated', { tokens: formatNumber(associated) })}
|
||||
>
|
||||
<p>
|
||||
<Link to="/staking/associate">
|
||||
<RouteLink to="/staking/associate">
|
||||
<Button data-testid="associate-more-tokens-btn">
|
||||
{t('stakingAssociateMoreButton')}
|
||||
</Button>
|
||||
</Link>
|
||||
</RouteLink>
|
||||
</p>
|
||||
<Link to="/staking/disassociate">
|
||||
<RouteLink to="/staking/disassociate">
|
||||
<Button data-testid="disassociate-tokens-btn">
|
||||
{t('stakingDisassociateButton')}
|
||||
</Button>
|
||||
</Link>
|
||||
</RouteLink>
|
||||
</Callout>
|
||||
);
|
||||
}
|
||||
@ -189,11 +191,11 @@ export const StakingStepAssociate = ({
|
||||
return (
|
||||
<>
|
||||
<p>{t('stakingStep2Text')}</p>
|
||||
<Link to="/staking/associate">
|
||||
<RouteLink to="/staking/associate">
|
||||
<Button data-testid="associate-tokens-btn">
|
||||
{t('associateButton')}
|
||||
</Button>
|
||||
</Link>
|
||||
</RouteLink>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
import { formatNumber } from '../../lib/format-number';
|
||||
@ -22,6 +23,7 @@ export const ValidatorTable = ({
|
||||
stakedTotal,
|
||||
stakeThisEpoch,
|
||||
}: ValidatorTableProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const stakePercentage = React.useMemo(() => {
|
||||
const total = new BigNumber(stakedTotal);
|
||||
@ -56,10 +58,12 @@ export const ValidatorTable = ({
|
||||
<KeyValueTableRow>
|
||||
<span>{t('ETHEREUM ADDRESS')}</span>
|
||||
<span>
|
||||
<EtherscanLink
|
||||
text={node.ethereumAdddress}
|
||||
address={node.ethereumAdddress}
|
||||
/>
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/address/${node.ethereumAdddress}`}
|
||||
>
|
||||
{node.ethereumAdddress}
|
||||
</Link>
|
||||
</span>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
|
@ -1,6 +1,10 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ADDRESSES, EthereumChainIds } from '../../config';
|
||||
import {
|
||||
EthereumChainIds,
|
||||
EnvironmentConfig,
|
||||
Networks,
|
||||
} from '@vegaprotocol/smart-contracts';
|
||||
import type { TrancheLabelProps } from './tranche-label';
|
||||
import { TrancheLabel } from './tranche-label';
|
||||
|
||||
@ -9,7 +13,7 @@ let props: TrancheLabelProps;
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
chainId: EthereumChainIds.Mainnet,
|
||||
contract: ADDRESSES.vestingAddress,
|
||||
contract: EnvironmentConfig[Networks.MAINNET].vestingAddress,
|
||||
id: 5,
|
||||
};
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ADDRESSES, EthereumChainIds } from '../../config';
|
||||
import type { EthereumChainId } from '../../config';
|
||||
import type { EthereumChainId } from '@vegaprotocol/smart-contracts';
|
||||
import { EthereumChainIds } from '@vegaprotocol/smart-contracts';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const TRANCHE_LABELS: Record<number, string[]> = {
|
||||
'5': ['Coinlist Option 1', 'Community Whitelist'],
|
||||
@ -26,6 +27,7 @@ export interface TrancheLabelProps {
|
||||
* @param id The tranche ID on this contract
|
||||
*/
|
||||
export const TrancheLabel = ({ contract, chainId, id }: TrancheLabelProps) => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
// Only mainnet tranches on the known vesting contract have useful name
|
||||
if (
|
||||
chainId &&
|
||||
|
@ -1,4 +1,7 @@
|
||||
import type { Tranche as ITranche } from '@vegaprotocol/smart-contracts';
|
||||
import type {
|
||||
Tranche as ITranche,
|
||||
EthereumChainId,
|
||||
} from '@vegaprotocol/smart-contracts';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -6,9 +9,8 @@ import { useParams } from 'react-router';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import type { EthereumChainId } from '../../config';
|
||||
import { ADDRESSES } from '../../config';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
import { formatNumber } from '../../lib/format-number';
|
||||
import { TrancheItem } from '../redemption/tranche-item';
|
||||
@ -27,6 +29,7 @@ const TrancheProgressContents = ({
|
||||
|
||||
export const Tranche = () => {
|
||||
const tranches = useOutletContext<ITranche[]>();
|
||||
const { ADDRESSES, ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const { trancheId } = useParams<{ trancheId: string }>();
|
||||
const { chainId } = useWeb3React();
|
||||
@ -81,7 +84,12 @@ export const Tranche = () => {
|
||||
const locked = user.remaining_tokens.times(lockedData?.locked || 0);
|
||||
return (
|
||||
<li className="pb-4" key={i}>
|
||||
<EtherscanLink address={user.address} text={user.address} />
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${user.address}`}
|
||||
>
|
||||
{user.address}
|
||||
</Link>
|
||||
<TrancheProgressContents>
|
||||
<span>{t('Locked')}</span>
|
||||
<span>{t('Unlocked')}</span>
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import type { Tranche } from '@vegaprotocol/smart-contracts';
|
||||
import type { Tranche, EthereumChainId } from '@vegaprotocol/smart-contracts';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { EthereumChainId } from '../../config';
|
||||
import { ADDRESSES } from '../../config';
|
||||
import { TrancheItem } from '../redemption/tranche-item';
|
||||
import { TrancheLabel } from './tranche-label';
|
||||
import { VestingChart } from './vesting-chart';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const trancheMinimum = 10;
|
||||
|
||||
@ -17,6 +16,7 @@ const shouldShowTranche = (t: Tranche) =>
|
||||
!t.total_added.isLessThanOrEqualTo(trancheMinimum);
|
||||
|
||||
export const Tranches = () => {
|
||||
const { ADDRESSES } = useEnvironment();
|
||||
const tranches = useOutletContext<Tranche[]>();
|
||||
const [showAll, setShowAll] = React.useState<boolean>(false);
|
||||
const { t } = useTranslation();
|
||||
|
@ -4,7 +4,8 @@ import orderBy from 'lodash/orderBy';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Heading } from '../../components/heading';
|
||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||
import { SplashLoader } from '../../components/splash-loader';
|
||||
@ -99,6 +100,7 @@ interface WithdrawalProps {
|
||||
}
|
||||
|
||||
export const Withdrawal = ({ withdrawal, complete }: WithdrawalProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const renderStatus = ({
|
||||
@ -148,12 +150,12 @@ export const Withdrawal = ({ withdrawal, complete }: WithdrawalProps) => {
|
||||
<KeyValueTableRow>
|
||||
{t('toEthereum')}
|
||||
<span>
|
||||
<EtherscanLink
|
||||
address={withdrawal.details?.receiverAddress as string}
|
||||
text={truncateMiddle(
|
||||
withdrawal.details?.receiverAddress as string
|
||||
)}
|
||||
/>
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${withdrawal.details?.receiverAddress}`}
|
||||
>
|
||||
{truncateMiddle(withdrawal.details?.receiverAddress ?? '')}
|
||||
</Link>
|
||||
</span>
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
@ -169,10 +171,12 @@ export const Withdrawal = ({ withdrawal, complete }: WithdrawalProps) => {
|
||||
{t('withdrawalTransaction', { foreignChain: 'Ethereum' })}
|
||||
<span>
|
||||
{withdrawal.txHash ? (
|
||||
<EtherscanLink
|
||||
tx={withdrawal.txHash}
|
||||
text={truncateMiddle(withdrawal.txHash)}
|
||||
/>
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ETHERSCAN_URL}/tx/${withdrawal.txHash}`}
|
||||
>
|
||||
{truncateMiddle(withdrawal.txHash)}
|
||||
</Link>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
|
@ -10,8 +10,7 @@
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"resolveJsonModule": true
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
|
@ -11,7 +11,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
VegaManageDialog,
|
||||
VegaWalletProvider,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { EnvironmentProvider } from '@vegaprotocol/react-helpers';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { createClient } from '../lib/apollo-client';
|
||||
@ -25,63 +26,68 @@ function VegaTradingApp({ Component, pageProps }: AppProps) {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<ApolloProvider client={client}>
|
||||
<VegaWalletProvider>
|
||||
<AppLoader>
|
||||
<Head>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
<title>{t('Welcome to Vega trading!')}</title>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
</Head>
|
||||
<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="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||
<Navbar />
|
||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
setManageDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<ApolloProvider client={client}>
|
||||
<VegaWalletProvider>
|
||||
<AppLoader>
|
||||
<Head>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
<title>{t('Welcome to Vega trading!')}</title>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://static.vega.xyz/fonts.css"
|
||||
/>
|
||||
</Head>
|
||||
<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="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||
<Navbar />
|
||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
setManageDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||
</div>
|
||||
</div>
|
||||
<main data-testid={pageProps.page}>
|
||||
{/* @ts-ignore conflict between @types/react and nextjs internal types */}
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWallet.connect}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWallet.manage}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<main data-testid={pageProps.page}>
|
||||
{/* @ts-ignore conflict between @types/react and nextjs internal types */}
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWallet.connect}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWallet.manage}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</VegaWalletProvider>
|
||||
</ApolloProvider>
|
||||
</ThemeContext.Provider>
|
||||
</AppLoader>
|
||||
</VegaWalletProvider>
|
||||
</ApolloProvider>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { gql } from '@apollo/client';
|
||||
import { PageQueryContainer } from '../../../components/page-query-container';
|
||||
import type { DepositPage } from './__generated__/DepositPage';
|
||||
import { DepositManager } from '@vegaprotocol/deposits';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { t, useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { ASSET_FRAGMENT } from '../../../lib/query-fragments';
|
||||
|
||||
@ -28,6 +28,8 @@ export const DepositContainer = ({
|
||||
ethereumConfig,
|
||||
assetId,
|
||||
}: DepositContainerProps) => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
|
||||
return (
|
||||
<PageQueryContainer<DepositPage>
|
||||
query={DEPOSIT_PAGE_QUERY}
|
||||
@ -46,6 +48,7 @@ export const DepositContainer = ({
|
||||
requiredConfirmations={ethereumConfig.confirmations}
|
||||
assets={data.assets}
|
||||
initialAssetId={assetId}
|
||||
isFaucetable={VEGA_ENV !== 'MAINNET'}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
|
@ -9,7 +9,6 @@
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"incremental": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -17,7 +17,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -1 +0,0 @@
|
||||
export const FAUCETABLE = process.env['NX_VEGA_ENV'] !== 'MAINNET';
|
@ -41,6 +41,7 @@ beforeEach(() => {
|
||||
max: new BigNumber(20),
|
||||
},
|
||||
allowance: new BigNumber(30),
|
||||
isFaucetable: true,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -24,7 +24,6 @@ import { useMemo } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { DepositLimits } from './deposit-limits';
|
||||
import { FAUCETABLE } from '../config';
|
||||
import type { Asset } from './deposit-manager';
|
||||
|
||||
interface FormFields {
|
||||
@ -51,6 +50,7 @@ export interface DepositFormProps {
|
||||
max: BigNumber;
|
||||
} | null;
|
||||
allowance: BigNumber | undefined;
|
||||
isFaucetable?: boolean;
|
||||
}
|
||||
|
||||
export const DepositForm = ({
|
||||
@ -63,6 +63,7 @@ export const DepositForm = ({
|
||||
requestFaucet,
|
||||
limits,
|
||||
allowance,
|
||||
isFaucetable,
|
||||
}: DepositFormProps) => {
|
||||
const { account } = useWeb3React();
|
||||
const { keypair } = useVegaWallet();
|
||||
@ -166,7 +167,7 @@ export const DepositForm = ({
|
||||
{errors.asset.message}
|
||||
</InputError>
|
||||
)}
|
||||
{FAUCETABLE && selectedAsset && (
|
||||
{isFaucetable && selectedAsset && (
|
||||
<UseButton onClick={requestFaucet}>
|
||||
{t(`Get ${selectedAsset.symbol}`)}
|
||||
</UseButton>
|
||||
|
@ -34,6 +34,7 @@ interface DepositManagerProps {
|
||||
bridgeAddress: string;
|
||||
assets: Asset[];
|
||||
initialAssetId?: string;
|
||||
isFaucetable?: boolean;
|
||||
}
|
||||
|
||||
export const DepositManager = ({
|
||||
@ -41,6 +42,7 @@ export const DepositManager = ({
|
||||
bridgeAddress,
|
||||
assets,
|
||||
initialAssetId,
|
||||
isFaucetable,
|
||||
}: DepositManagerProps) => {
|
||||
const [assetId, setAssetId] = useState<string | undefined>(initialAssetId);
|
||||
|
||||
@ -54,7 +56,7 @@ export const DepositManager = ({
|
||||
asset?.source.__typename === 'ERC20'
|
||||
? asset.source.contractAddress
|
||||
: undefined,
|
||||
process.env['NX_VEGA_ENV'] !== 'MAINNET'
|
||||
isFaucetable
|
||||
);
|
||||
const bridgeContract = useBridgeContract();
|
||||
|
||||
@ -101,6 +103,7 @@ export const DepositManager = ({
|
||||
requestFaucet={faucet.perform}
|
||||
limits={limits}
|
||||
allowance={allowance}
|
||||
isFaucetable={isFaucetable}
|
||||
/>
|
||||
<TransactionDialog {...approve.transaction} name="approve" />
|
||||
<TransactionDialog {...faucet.transaction} name="faucet" />
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -2,3 +2,4 @@ export * from './use-apply-grid-transaction';
|
||||
export * from './use-data-provider';
|
||||
export * from './use-theme-switcher';
|
||||
export * from './use-fetch';
|
||||
export * from './use-environment';
|
||||
|
125
libs/react-helpers/src/hooks/use-environment.tsx
Normal file
125
libs/react-helpers/src/hooks/use-environment.tsx
Normal file
@ -0,0 +1,125 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import type { Networks } from '@vegaprotocol/smart-contracts';
|
||||
import { EnvironmentConfig } from '@vegaprotocol/smart-contracts';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_ENV?: RawEnvironment;
|
||||
}
|
||||
}
|
||||
|
||||
type VegaContracts = typeof EnvironmentConfig[Networks];
|
||||
|
||||
type EnvironmentProviderProps = {
|
||||
definintions?: Partial<RawEnvironment>;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
export const ENV_KEYS = [
|
||||
'VEGA_URL',
|
||||
'VEGA_ENV',
|
||||
'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;
|
||||
ETHEREUM_CHAIN_ID: number;
|
||||
ETHEREUM_PROVIDER_URL: string;
|
||||
ETHERSCAN_URL: string;
|
||||
ADDRESSES: VegaContracts;
|
||||
};
|
||||
|
||||
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'];
|
||||
}
|
||||
};
|
||||
|
||||
const transformValue = (key: EnvKey, value?: string) => {
|
||||
switch (key) {
|
||||
case 'VEGA_ENV':
|
||||
return value as Networks;
|
||||
case 'ETHEREUM_CHAIN_ID':
|
||||
return value && Number(value);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
const getValue = (key: EnvKey, definintions: Partial<RawEnvironment> = {}) => {
|
||||
if (typeof window === 'undefined') {
|
||||
return transformValue(
|
||||
key,
|
||||
definintions[key] ?? getBundledEnvironmentValue(key)
|
||||
);
|
||||
}
|
||||
return transformValue(
|
||||
key,
|
||||
window._ENV?.[key] ?? definintions[key] ?? getBundledEnvironmentValue(key)
|
||||
);
|
||||
};
|
||||
|
||||
const EnvironmentContext = createContext({} as Environment);
|
||||
|
||||
export const EnvironmentProvider = ({
|
||||
definintions,
|
||||
children,
|
||||
}: EnvironmentProviderProps) => {
|
||||
const environment = ENV_KEYS.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: getValue(key, definintions),
|
||||
}),
|
||||
{} as Environment
|
||||
);
|
||||
|
||||
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,
|
||||
ADDRESSES: EnvironmentConfig[environment['VEGA_ENV']],
|
||||
}}
|
||||
>
|
||||
{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;
|
||||
};
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -1,3 +1,12 @@
|
||||
{
|
||||
"presets": ["@babel/preset-typescript"]
|
||||
"presets": [
|
||||
[
|
||||
"@nrwl/react/babel",
|
||||
{
|
||||
"runtime": "automatic",
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
||||
|
@ -1,13 +1,8 @@
|
||||
module.exports = {
|
||||
displayName: 'smart-contracts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': 'ts-jest',
|
||||
'^.+\\.[tj]sx?$': 'babel-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/libs/smart-contracts',
|
||||
|
@ -1,14 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"files": [],
|
||||
|
@ -6,7 +6,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -6,6 +6,5 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/libs/ui-toolkit',
|
||||
setupFiles: ['./src/setup-test-env.ts'],
|
||||
setupFilesAfterEnv: ['./src/setup-tests.ts'],
|
||||
};
|
||||
|
@ -1,35 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { EtherscanLink } from '.';
|
||||
|
||||
it('renders a link with the text', () => {
|
||||
render(<EtherscanLink text="foo" tx="tx" />);
|
||||
expect(screen.getByText('foo')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders a link with the tx hash if no text is provided', () => {
|
||||
render(<EtherscanLink tx="tx" />);
|
||||
expect(screen.getByText('tx')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders a link with the address if no text is provided', () => {
|
||||
render(<EtherscanLink address="address" />);
|
||||
expect(screen.getByText('address')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('links to etherscan address', () => {
|
||||
const hash = 'hash';
|
||||
render(<EtherscanLink address={hash} />);
|
||||
expect(screen.getByTestId('etherscan-link')).toHaveAttribute(
|
||||
'href',
|
||||
`${process.env['NX_ETHERSCAN_URL']}/address/${hash}`
|
||||
);
|
||||
});
|
||||
|
||||
it('links to etherscan transaction', () => {
|
||||
const hash = 'hash';
|
||||
render(<EtherscanLink tx={hash} />);
|
||||
expect(screen.getByTestId('etherscan-link')).toHaveAttribute(
|
||||
'href',
|
||||
`${process.env['NX_ETHERSCAN_URL']}/tx/${hash}`
|
||||
);
|
||||
});
|
@ -1,24 +0,0 @@
|
||||
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import { EtherscanLink } from '.';
|
||||
|
||||
export default {
|
||||
title: 'EtherscanLink',
|
||||
component: EtherscanLink,
|
||||
} as ComponentMeta<typeof EtherscanLink>;
|
||||
|
||||
const Template: ComponentStory<typeof EtherscanLink> = (args) => (
|
||||
<EtherscanLink {...args} />
|
||||
);
|
||||
|
||||
export const Transaction = Template.bind({});
|
||||
Transaction.args = {
|
||||
tx: 'foo',
|
||||
text: 'View transaction on Etherscan',
|
||||
};
|
||||
|
||||
export const Address = Template.bind({});
|
||||
Address.args = {
|
||||
address: 'foo',
|
||||
text: 'View transaction on Etherscan',
|
||||
};
|
@ -1,65 +0,0 @@
|
||||
import classNames from 'classnames';
|
||||
import type { AnchorHTMLAttributes } from 'react';
|
||||
|
||||
const ETHERSCAN_URL = process.env['NX_ETHERSCAN_URL'] as string;
|
||||
|
||||
interface BaseEtherscanLinkProps
|
||||
extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
text?: string;
|
||||
}
|
||||
|
||||
interface EtherscanAddressLinkProps extends BaseEtherscanLinkProps {
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface EtherscanTransactionLinkProps extends BaseEtherscanLinkProps {
|
||||
tx: string;
|
||||
}
|
||||
|
||||
type EtherscanLinkProps =
|
||||
| EtherscanAddressLinkProps
|
||||
| EtherscanTransactionLinkProps;
|
||||
|
||||
/**
|
||||
* Form an HTML link tag pointing to an appropriate Etherscan page
|
||||
*/
|
||||
export const EtherscanLink = ({
|
||||
text,
|
||||
className,
|
||||
...props
|
||||
}: EtherscanLinkProps) => {
|
||||
let hash: string;
|
||||
let txLink: string | null;
|
||||
const anchorClasses = classNames('underline', className);
|
||||
|
||||
if ('tx' in props) {
|
||||
hash = props.tx;
|
||||
txLink = `${ETHERSCAN_URL}/tx/${hash}`;
|
||||
} else if ('address' in props) {
|
||||
hash = props.address;
|
||||
txLink = `${ETHERSCAN_URL}/address/${hash}`;
|
||||
} else {
|
||||
throw new Error('Must provider either "tx" or "address" prop');
|
||||
}
|
||||
|
||||
const linkText = text ? text : hash;
|
||||
|
||||
// Fallback: just render the TX id
|
||||
if (!txLink) {
|
||||
return <span>{hash}</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
data-testid="etherscan-link"
|
||||
href={txLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={anchorClasses}
|
||||
>
|
||||
{linkText}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
EtherscanLink.displayName = 'EtherScanLink';
|
@ -1 +0,0 @@
|
||||
export { EtherscanLink } from './etherscan-link';
|
@ -7,7 +7,7 @@ export * from './card';
|
||||
export * from './copy-with-tooltip';
|
||||
export * from './dialog';
|
||||
export * from './dropdown-menu';
|
||||
export * from './etherscan-link';
|
||||
export * from './link';
|
||||
export * from './form-group';
|
||||
export * from './icon';
|
||||
export * from './indicator';
|
||||
|
1
libs/ui-toolkit/src/components/link/index.ts
Normal file
1
libs/ui-toolkit/src/components/link/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { Link } from './link';
|
34
libs/ui-toolkit/src/components/link/link.spec.tsx
Normal file
34
libs/ui-toolkit/src/components/link/link.spec.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { Link } from '.';
|
||||
|
||||
it('renders a link with a text', () => {
|
||||
render(
|
||||
<Link href="127.0.0.1" title="Link title">
|
||||
Link text
|
||||
</Link>
|
||||
);
|
||||
const link = screen.getByRole('link', { name: 'Link title' });
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link).toHaveAttribute('data-testid', 'link');
|
||||
expect(link).toHaveAttribute('referrerPolicy', 'strict-origin');
|
||||
expect(link).toHaveAttribute('href', '127.0.0.1');
|
||||
expect(link).toHaveAttribute('title', 'Link title');
|
||||
expect(link).toHaveClass('cursor-pointer');
|
||||
expect(link).toHaveClass('underline');
|
||||
});
|
||||
|
||||
it('renders a link with children elements', () => {
|
||||
render(
|
||||
<Link href="127.0.0.1" title="Link title">
|
||||
<span>Link text</span>
|
||||
</Link>
|
||||
);
|
||||
const link = screen.getByRole('link', { name: 'Link title' });
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link).toHaveAttribute('data-testid', 'link');
|
||||
expect(link).toHaveAttribute('referrerPolicy', 'strict-origin');
|
||||
expect(link).toHaveAttribute('href', '127.0.0.1');
|
||||
expect(link).toHaveAttribute('title', 'Link title');
|
||||
expect(link).toHaveClass('cursor-pointer');
|
||||
expect(link).not.toHaveClass('underline');
|
||||
});
|
25
libs/ui-toolkit/src/components/link/link.stories.tsx
Normal file
25
libs/ui-toolkit/src/components/link/link.stories.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import { Link } from '.';
|
||||
import { VegaLogo } from '../vega-logo';
|
||||
|
||||
export default {
|
||||
title: 'Link',
|
||||
component: Link,
|
||||
} as ComponentMeta<typeof Link>;
|
||||
|
||||
const Template: ComponentStory<typeof Link> = (args) => <Link {...args} />;
|
||||
|
||||
export const Text = Template.bind({});
|
||||
Text.args = {
|
||||
title: 'Link title',
|
||||
href: '/',
|
||||
children: 'View link',
|
||||
};
|
||||
|
||||
export const Element = Template.bind({});
|
||||
Element.args = {
|
||||
title: 'Link title',
|
||||
href: '/',
|
||||
children: <VegaLogo />,
|
||||
};
|
29
libs/ui-toolkit/src/components/link/link.tsx
Normal file
29
libs/ui-toolkit/src/components/link/link.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode, AnchorHTMLAttributes } from 'react';
|
||||
|
||||
type LinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Form an HTML link tag
|
||||
*/
|
||||
export const Link = ({ className, children, ...props }: LinkProps) => {
|
||||
const anchorClassName = classNames(className, 'cursor-pointer', {
|
||||
underline: typeof children === 'string',
|
||||
});
|
||||
|
||||
return (
|
||||
<a
|
||||
role="link"
|
||||
data-testid="link"
|
||||
referrerPolicy="strict-origin"
|
||||
className={anchorClassName}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
Link.displayName = 'Link';
|
@ -1 +0,0 @@
|
||||
process.env['NX_ETHERSCAN_URL'] = 'https://etherscan.io';
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { EtherscanLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { EthTxStatus } from '../use-ethereum-transaction';
|
||||
|
||||
const ACTIVE_CLASSES = 'text-black dark:text-white';
|
||||
@ -31,6 +32,8 @@ export const TxRow = ({
|
||||
requiredConfirmations,
|
||||
highlightComplete = true,
|
||||
}: TxRowProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
|
||||
if (status === EthTxStatus.Pending) {
|
||||
return (
|
||||
<p className={`flex justify-between ${ACTIVE_CLASSES}`}>
|
||||
@ -39,11 +42,13 @@ export const TxRow = ({
|
||||
`Awaiting Ethereum transaction ${confirmations}/${requiredConfirmations} confirmations...`
|
||||
)}
|
||||
</span>
|
||||
<EtherscanLink
|
||||
tx={txHash || ''}
|
||||
<Link
|
||||
href={`${ETHERSCAN_URL}/tx/${txHash}`}
|
||||
title={t('View transaction on Etherscan')}
|
||||
className="text-vega-pink dark:text-vega-yellow"
|
||||
text={t('View on Etherscan')}
|
||||
/>
|
||||
>
|
||||
{t('View on Etherscan')}
|
||||
</Link>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
@ -56,11 +61,13 @@ export const TxRow = ({
|
||||
}`}
|
||||
>
|
||||
<span>{t('Ethereum transaction complete')}</span>
|
||||
<EtherscanLink
|
||||
tx={txHash || ''}
|
||||
<Link
|
||||
href={`${ETHERSCAN_URL}/tx/${txHash}`}
|
||||
title={t('View on Etherscan')}
|
||||
className="text-vega-pink dark:text-vega-yellow"
|
||||
text={t('View on Etherscan')}
|
||||
/>
|
||||
>
|
||||
{t('View transaction on Etherscan')}
|
||||
</Link>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ it('Dialog states', () => {
|
||||
expect(
|
||||
screen.getByText('Awaiting Ethereum transaction 0/1 confirmations...')
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByTestId('etherscan-link')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('link')).toBeInTheDocument();
|
||||
|
||||
rerender(generateJsx({ status: EthTxStatus.Complete, confirmations: 1 }));
|
||||
expect(screen.getByText(`${props.name} complete`)).toBeInTheDocument();
|
||||
|
@ -1,21 +1,18 @@
|
||||
import type { Networks } from '@vegaprotocol/smart-contracts';
|
||||
import { VegaErc20Bridge } from '@vegaprotocol/smart-contracts';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import { useMemo } from 'react';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const useBridgeContract = () => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { provider } = useWeb3React();
|
||||
|
||||
const contract = useMemo(() => {
|
||||
if (!provider) {
|
||||
return null;
|
||||
}
|
||||
return new VegaErc20Bridge(
|
||||
process.env['NX_VEGA_ENV'] as Networks,
|
||||
provider,
|
||||
provider?.getSigner()
|
||||
);
|
||||
}, [provider]);
|
||||
return new VegaErc20Bridge(VEGA_ENV, provider, provider?.getSigner());
|
||||
}, [provider, VEGA_ENV]);
|
||||
|
||||
return contract;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
|
@ -1,10 +1,5 @@
|
||||
import {
|
||||
Dialog,
|
||||
EtherscanLink,
|
||||
Icon,
|
||||
Intent,
|
||||
Loader,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Link, Dialog, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import type { VegaTxState } from '@vegaprotocol/wallet';
|
||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import type { ReactNode } from 'react';
|
||||
@ -28,7 +23,8 @@ export const WithdrawDialog = ({
|
||||
dialogOpen,
|
||||
onDialogChange,
|
||||
}: WithdrawDialogProps) => {
|
||||
const { intent, ...props } = getProps(approval, vegaTx, ethTx);
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { intent, ...props } = getProps(approval, vegaTx, ethTx, ETHERSCAN_URL);
|
||||
return (
|
||||
<Dialog open={dialogOpen} intent={intent} onChange={onDialogChange}>
|
||||
<DialogWrapper {...props} />
|
||||
@ -85,7 +81,8 @@ interface DialogProps {
|
||||
const getProps = (
|
||||
approval: Erc20Approval_erc20WithdrawalApproval | null,
|
||||
vegaTx: VegaTxState,
|
||||
ethTx: EthTxState
|
||||
ethTx: EthTxState,
|
||||
ethUrl: string
|
||||
) => {
|
||||
const vegaTxPropsMap: Record<VegaTxStatus, DialogProps> = {
|
||||
[VegaTxStatus.Default]: {
|
||||
@ -156,11 +153,13 @@ const getProps = (
|
||||
`Awaiting Ethereum transaction ${ethTx.confirmations}/1 confirmations...`
|
||||
)}
|
||||
</span>
|
||||
<EtherscanLink
|
||||
tx={ethTx.txHash || ''}
|
||||
<Link
|
||||
href={`${ethUrl}/tx/${ethTx.txHash}`}
|
||||
title={t('View transaction on Etherscan')}
|
||||
className="text-vega-pink dark:text-vega-yellow"
|
||||
text={t('View on Etherscan')}
|
||||
/>
|
||||
>
|
||||
{t('View on Etherscan')}
|
||||
</Link>
|
||||
</Step>
|
||||
),
|
||||
},
|
||||
@ -171,11 +170,13 @@ const getProps = (
|
||||
children: (
|
||||
<Step>
|
||||
<span>{t('Ethereum transaction complete')}</span>
|
||||
<EtherscanLink
|
||||
tx={ethTx.txHash || ''}
|
||||
<Link
|
||||
href={`${ethUrl}/tx/${ethTx.txHash}`}
|
||||
title={t('View transaction on Etherscan')}
|
||||
className="text-vega-pink dark:text-vega-yellow"
|
||||
text={t('View on Etherscan')}
|
||||
/>
|
||||
>
|
||||
{t('View on Etherscan')}
|
||||
</Link>
|
||||
</Step>
|
||||
),
|
||||
},
|
||||
|
@ -10,10 +10,8 @@ import {
|
||||
formatNumber,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { WithdrawalStatus } from '@vegaprotocol/types';
|
||||
import {
|
||||
EtherscanLink,
|
||||
AgGridDynamic as AgGrid,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Link, AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/react-helpers';
|
||||
import { TransactionDialog } from '@vegaprotocol/web3';
|
||||
import { useCompleteWithdraw } from './use-complete-withdraw';
|
||||
import type { Withdrawals_party_withdrawals } from './__generated__/Withdrawals';
|
||||
@ -23,6 +21,7 @@ export interface WithdrawalsTableProps {
|
||||
}
|
||||
|
||||
export const WithdrawalsTable = ({ withdrawals }: WithdrawalsTableProps) => {
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
const { transaction, submit } = useCompleteWithdraw();
|
||||
|
||||
return (
|
||||
@ -47,6 +46,7 @@ export const WithdrawalsTable = ({ withdrawals }: WithdrawalsTableProps) => {
|
||||
headerName="Recipient"
|
||||
field="details.receiverAddress"
|
||||
cellRenderer="RecipientCell"
|
||||
cellRendererParams={{ ethUrl: ETHERSCAN_URL }}
|
||||
valueFormatter={({ value }: ValueFormatterParams) => {
|
||||
return truncateByChars(value);
|
||||
}}
|
||||
@ -62,7 +62,7 @@ export const WithdrawalsTable = ({ withdrawals }: WithdrawalsTableProps) => {
|
||||
headerName="Status"
|
||||
field="status"
|
||||
cellRenderer="StatusCell"
|
||||
cellRendererParams={{ complete: submit }}
|
||||
cellRendererParams={{ complete: submit, ethUrl: ETHERSCAN_URL }}
|
||||
/>
|
||||
</AgGrid>
|
||||
<TransactionDialog name="withdraw" {...transaction} />
|
||||
@ -71,16 +71,28 @@ export const WithdrawalsTable = ({ withdrawals }: WithdrawalsTableProps) => {
|
||||
};
|
||||
|
||||
export interface StatusCellProps extends ICellRendererParams {
|
||||
ethUrl: string;
|
||||
complete: (withdrawalId: string) => void;
|
||||
}
|
||||
|
||||
export const StatusCell = ({ value, data, complete }: StatusCellProps) => {
|
||||
export const StatusCell = ({
|
||||
ethUrl,
|
||||
value,
|
||||
data,
|
||||
complete,
|
||||
}: StatusCellProps) => {
|
||||
if (data.pendingOnForeignChain) {
|
||||
return (
|
||||
<div className="flex justify-between gap-8">
|
||||
{t('Pending')}
|
||||
{data.txHash && (
|
||||
<EtherscanLink tx={data.txHash} text={t('View on Etherscan')} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ethUrl}/tx/${data.txHash}`}
|
||||
data-testid="etherscan-link"
|
||||
>
|
||||
{t('View on Etherscan')}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@ -92,7 +104,13 @@ export const StatusCell = ({ value, data, complete }: StatusCellProps) => {
|
||||
{data.txHash ? (
|
||||
<>
|
||||
{t('Finalized')}
|
||||
<EtherscanLink tx={data.txHash} text={t('View on Etherscan')} />
|
||||
<Link
|
||||
title={t('View transaction on Etherscan')}
|
||||
href={`${ethUrl}/tx/${data.txHash}`}
|
||||
data-testid="etherscan-link"
|
||||
>
|
||||
{t('View on Etherscan')}
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@ -109,6 +127,22 @@ export const StatusCell = ({ value, data, complete }: StatusCellProps) => {
|
||||
return value;
|
||||
};
|
||||
|
||||
const RecipientCell = ({ value, valueFormatted }: ICellRendererParams) => {
|
||||
return <EtherscanLink address={value} text={valueFormatted} />;
|
||||
export interface RecipientCellProps extends ICellRendererParams {
|
||||
ethUrl: string;
|
||||
}
|
||||
|
||||
const RecipientCell = ({
|
||||
ethUrl,
|
||||
value,
|
||||
valueFormatted,
|
||||
}: RecipientCellProps) => {
|
||||
return (
|
||||
<Link
|
||||
title={t('View address on Etherscan')}
|
||||
href={`${ethUrl}/address/${value}`}
|
||||
data-testid="etherscan-link"
|
||||
>
|
||||
{valueFormatted}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
@ -10,7 +10,6 @@
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"files": [],
|
||||
|
@ -14,6 +14,7 @@
|
||||
"skipLibCheck": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"resolveJsonModule": true,
|
||||
"paths": {
|
||||
"@vegaprotocol/accounts": ["libs/accounts/src/index.ts"],
|
||||
"@vegaprotocol/candles-chart": ["libs/candles-chart/src/index.ts"],
|
||||
|
Loading…
Reference in New Issue
Block a user