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/Footer/index.tsx b/packages/bridge/src/components/Footer/index.tsx index a03939b..50410cf 100644 --- a/packages/bridge/src/components/Footer/index.tsx +++ b/packages/bridge/src/components/Footer/index.tsx @@ -11,15 +11,17 @@ export const Footer = () => { - + > + ); }; diff --git a/packages/bridge/src/components/Layout/index.tsx b/packages/bridge/src/components/Layout/index.tsx index c1dac07..6c4fcaf 100644 --- a/packages/bridge/src/components/Layout/index.tsx +++ b/packages/bridge/src/components/Layout/index.tsx @@ -6,20 +6,16 @@ import { Link, useLocation } from 'react-router-dom'; import metamaskIcon from '../../assets/metamask.svg'; import { LABELS } from '../../constants'; -import { contexts, AppBar, shortenAddress, useWallet } from '@oyster/common'; +import { AppBar } from '@oyster/common'; import Wormhole from '../Wormhole'; -import { useEthereum } from '../../contexts'; -import { useCorrectNetwork } from '../../hooks/useCorrectNetwork'; import { Footer as AppFooter } from './../Footer'; +import { EthereumConnect } from '../EthereumConnect'; const { Header, Content, Footer } = Layout; -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', @@ -46,32 +42,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 8456896..3670076 100644 --- a/packages/bridge/src/components/SecurityAuditButton/index.tsx +++ b/packages/bridge/src/components/SecurityAuditButton/index.tsx @@ -5,8 +5,11 @@ import './index.less'; export const SecurityAuditButton = () => { return ( - ); diff --git a/packages/bridge/src/components/Transfer/index.tsx b/packages/bridge/src/components/Transfer/index.tsx index 224b84f..dc79dc7 100644 --- a/packages/bridge/src/components/Transfer/index.tsx +++ b/packages/bridge/src/components/Transfer/index.tsx @@ -5,7 +5,12 @@ import { Input } from '../Input'; import './style.less'; import { ASSET_CHAIN, chainToName } from '../../utils/assets'; -import { fromSolana, ProgressUpdate, toSolana, TransferRequest } from '../../models/bridge'; +import { + fromSolana, + ProgressUpdate, + toSolana, + TransferRequest, +} from '../../models/bridge'; import { useEthereum } from '../../contexts'; import { TokenDisplay } from '../TokenDisplay'; import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory'; @@ -89,8 +94,7 @@ export const Transfer = () => { return; } try { - - if(request.from === ASSET_CHAIN.Solana) { + if (request.from === ASSET_CHAIN.Solana) { const bridgeAddress = programIds().wormhole.bridge; let signer = provider.getSigner(); @@ -235,7 +239,7 @@ export const Transfer = () => { (async () => { let steps: ProgressUpdate[] = []; try { - if(request.from === ASSET_CHAIN.Solana) { + if (request.from === ASSET_CHAIN.Solana) { debugger; await fromSolana( connection, diff --git a/packages/bridge/src/components/Wormhole/WormholeCanvas.tsx b/packages/bridge/src/components/Wormhole/WormholeCanvas.tsx index 987608a..f8e0666 100644 --- a/packages/bridge/src/components/Wormhole/WormholeCanvas.tsx +++ b/packages/bridge/src/components/Wormhole/WormholeCanvas.tsx @@ -20,7 +20,7 @@ const WormholeCanvas = ({ - + ); 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 }; };