diff --git a/packages/bridge/src/components/EthereumConnect/index.tsx b/packages/bridge/src/components/EthereumConnect/index.tsx new file mode 100644 index 0000000..d8f651a --- /dev/null +++ b/packages/bridge/src/components/EthereumConnect/index.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { Button } from 'antd'; + +import { useCorrectNetwork } from '../../hooks/useCorrectNetwork'; +import metamaskIcon from '../../assets/metamask.svg'; +import { shortenAddress } from '@oyster/common'; +import { useEthereum } from '../../contexts'; + +export const EthereumConnect = () => { + const { accounts, onConnectEthereum, connected } = useEthereum(); + const { hasCorrespondingNetworks } = useCorrectNetwork(); + + return ( +
+ {connected ? ( + hasCorrespondingNetworks ? ( + <> + {'metamask-icon'} + {shortenAddress(accounts[0], 4)} + + ) : ( + + ) + ) : ( + + )} +
+ ); +}; diff --git a/packages/bridge/src/components/Layout/index.tsx b/packages/bridge/src/components/Layout/index.tsx index 055c73b..4353dd9 100644 --- a/packages/bridge/src/components/Layout/index.tsx +++ b/packages/bridge/src/components/Layout/index.tsx @@ -12,6 +12,7 @@ import { useEthereum } from '../../contexts'; import { useCorrectNetwork } from '../../hooks/useCorrectNetwork'; import { SecurityAuditButton } from '../SecurityAuditButton'; import { Footer } from '../Footer'; +import { EthereumConnect } from '../EthereumConnect'; const { Header, Content } = Layout; const { useConnectionConfig } = contexts.Connection; @@ -19,8 +20,6 @@ const { useConnectionConfig } = contexts.Connection; export const AppLayout = React.memo((props: any) => { const location = useLocation(); const [wormholeReady, setWormholeReady] = useState(false); - const { accounts, provider } = useEthereum(); - const hasCorrespondingNetworks = useCorrectNetwork(); const paths: { [key: string]: string } = { '/faucet': '7', @@ -47,32 +46,7 @@ export const AppLayout = React.memo((props: any) => {

WORMHOLE

- - {accounts[0] && ( -
- {hasCorrespondingNetworks ? ( - <> - {'metamask-icon'} - {shortenAddress(accounts[0], 4)} - - ) : ( - - )} -
- )} - - } - /> + } /> )} diff --git a/packages/bridge/src/components/SecurityAuditButton/index.tsx b/packages/bridge/src/components/SecurityAuditButton/index.tsx index 454781e..3670076 100644 --- a/packages/bridge/src/components/SecurityAuditButton/index.tsx +++ b/packages/bridge/src/components/SecurityAuditButton/index.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Link } from 'react-router-dom'; import { Button } from 'antd'; import './index.less'; diff --git a/packages/bridge/src/contexts/ethereum.tsx b/packages/bridge/src/contexts/ethereum.tsx index 6514ced..0b91cb6 100644 --- a/packages/bridge/src/contexts/ethereum.tsx +++ b/packages/bridge/src/contexts/ethereum.tsx @@ -13,7 +13,6 @@ import { useWallet as useEthereumWallet } from 'use-wallet'; import WalletConnectProvider from '@walletconnect/web3-provider'; // @ts-ignore import Fortmatic from 'fortmatic'; -import Torus from '@toruslabs/torus-embed'; import { useConnectionConfig, useWallet, ENV } from '@oyster/common'; import { TokenList, TokenInfo } from '@uniswap/token-lists'; import { ethers } from 'ethers'; @@ -24,20 +23,27 @@ export interface EthereumContextState { tokens: TokenInfo[]; tokenMap: Map; accounts: string[]; + connected: boolean; + chainId: number; + onConnectEthereum?: () => void; } export const EthereumContext = createContext({ tokens: [], tokenMap: new Map(), accounts: [''], + chainId: 0, + connected: false, }); export const EthereumProvider: FunctionComponent = ({ children }) => { const [accounts, setAccounts] = useState(['']); const [provider, setProvider] = useState(); - const { env } = useConnectionConfig(); - const { connected } = useWallet(); - const wallet = useEthereumWallet(); + const [connected, setConnected] = useState(false); + const [chainId, setChainId] = useState(0); + //const { env } = useConnectionConfig(); + const { connected: walletConnected } = useWallet(); + //const wallet = useEthereumWallet(); const [tokens, setTokens] = useState<{ map: Map; list: TokenInfo[]; @@ -94,26 +100,59 @@ export const EthereumProvider: FunctionComponent = ({ children }) => { })(); }, [setTokens]); + const onConnectEthereum = () => { + // @ts-ignore + window.ethereum.request({ method: 'eth_requestAccounts' }).then(() => { + // @ts-ignore + const provider = new ethers.providers.Web3Provider( + (window as any).ethereum, + ); + const signer = provider.getSigner(); + signer.getAddress().then(account => { + setAccounts([account]); + setConnected(true); + }); + provider.getNetwork().then(network => { + setChainId(network.chainId); + }); + setProvider(provider); + }); + }; + useEffect(() => { if (connected) { // @ts-ignore - window.ethereum.enable().then(() => { - // @ts-ignore - const provider = new ethers.providers.Web3Provider( - (window as any).ethereum, - ); - const signer = provider.getSigner(); - signer.getAddress().then(account => { - setAccounts([account]); - }); - setProvider(provider); + window.ethereum.on('disconnect', error => { + setConnected(false); + }); + // @ts-ignore + window.ethereum.on('accountsChanged', accounts => { + if (!accounts || !accounts[0]) setConnected(false); + }); + // @ts-ignore + window.ethereum.on('chainChanged', (chainId: string) => { + setChainId(parseInt(chainId, 16)); }); } }, [connected]); + useEffect(() => { + if (walletConnected && !connected) { + onConnectEthereum(); + } + }, [walletConnected]); + return ( onConnectEthereum(), + }} > {children} diff --git a/packages/bridge/src/hooks/useCorrectNetwork.tsx b/packages/bridge/src/hooks/useCorrectNetwork.tsx index f3a832f..f0108c6 100644 --- a/packages/bridge/src/hooks/useCorrectNetwork.tsx +++ b/packages/bridge/src/hooks/useCorrectNetwork.tsx @@ -7,22 +7,21 @@ export const useCorrectNetwork = () => { const [hasCorrespondingNetworks, setHasCorrespondingNetworks] = useState( true, ); - const { provider } = useEthereum(); + const { connected, chainId } = useEthereum(); useEffect(() => { - if (provider) { - provider.getNetwork().then(network => { - if (network.chainId === 5) { - setHasCorrespondingNetworks(env === 'testnet'); - } else if (network.chainId === 1) { - setHasCorrespondingNetworks(env === 'mainnet-beta'); - } else { - setHasCorrespondingNetworks(false); - } - }); + if (connected) { + if (chainId === 5) { + setHasCorrespondingNetworks(env === 'testnet'); + } else if (chainId === 1) { + setHasCorrespondingNetworks(env === 'mainnet-beta'); + } else { + setHasCorrespondingNetworks(false); + } + } else { + setHasCorrespondingNetworks(true); } - setHasCorrespondingNetworks(true); - }, [provider, env]); + }, [connected, env, chainId]); - return hasCorrespondingNetworks; + return { hasCorrespondingNetworks }; };