UNPKG

@bzxnetwork/portal

Version:
299 lines (275 loc) 8.12 kB
// /* global window */ import { Fragment } from "react"; import styled from "styled-components"; import { BZxJS } from "@bzxnetwork/bzx.js"; // eslint-disable-line import ChooseProviderDialog from "./ChooseProviderDialog"; import getWeb3 from "./getWeb3"; import NoProviderMessage from "./NoProviderMessage"; import getNetworkId from "./getNetworkId"; const LoadingContainer = styled.div` background: white; width: 100%; height: 100%; display: flex; flex-direction: column; jsutify-content: center; align-items: center; `; const CancelButton = styled.a.attrs({ target: `_blank`, rel: `noopener noreferrer` })` text-decoration: none; display: inherit; `; const CancelButtonLabel = styled.div` color: red; `; export default class Web3Container extends React.Component { state = { loading: true, errorMsg: ``, web3: null, tokens: null, bZx: null, accounts: null, oracles: null, networkId: null }; async componentDidMount() { this.setState({ loading: true, errorMsg: `` }); await this.loadWeb3(this.props.providerName); } async componentWillReceiveProps(nextProps) { if (nextProps.getWeb3) { this.setState({ loading: true, errorMsg: `` }); await this.loadWeb3(nextProps.providerName); } } handleClearProvider = event => { event.preventDefault(); this.props.clearProvider(); }; loadWeb3 = async providerName => { const web3 = await getWeb3(providerName); if (!web3) { this.setState({ web3: null, loading: false, errorMsg: `` }); return; } const networkId = await getNetworkId(web3); // Known networks we actively support should be set here. // Currently only Ropsten is supported. const activeNetworkIds = { 1: `Mainnet`, 3: `Ropsten Testnet`, 4: `Rinkeby Testnet`, 42: `Kovan Testnet` }; const displayNetworkError = () => { if (activeNetworkIds[networkId]) { this.setState({ web3: null, loading: false, errorMsg: `We are temporarily unable to connect to ${ activeNetworkIds[networkId] }. Please try again later.` }); } else if (providerName === `MetaMask`) { this.setState({ web3: null, loading: false, errorMsg: ( <Fragment> <div> You may be on the wrong network. Please check that MetaMask is set to Mainnet, Ropsten, Kovan, or Rinkeby. <br /> <br /> <div style={{ display: `inline-block` }}> You can also {` `} <CancelButton href="" onClick={this.handleClearProvider}> <CancelButtonLabel>choose</CancelButtonLabel> </CancelButton> {` `}a different provider. </div> </div> </Fragment> ) }); } else { this.setState({ web3: null, loading: false, errorMsg: `You may be on the wrong network. Please refresh your browser and try again.` }); } }; const bZx = new BZxJS(web3, { networkId }); bZx.portalProviderName = providerName; // setting custom field //const web3Query = await getWeb3ByNetworkId(networkId); //window.bZxQuery = await (new BZxJS(web3Query.currentProvider, { networkId })); //console.log(window.bZxQuery); // Get accounts let accounts; try { accounts = await web3.eth.getAccounts(); if (!accounts[0]) { if (providerName === `MetaMask`) { this.setState({ web3: null, loading: false, errorMsg: ( <Fragment> <div> Please unlock your MetaMask account. <br /> <br /> <div style={{ display: `inline-block` }}> You can also {` `} <CancelButton href="" onClick={this.handleClearProvider}> <CancelButtonLabel>choose</CancelButtonLabel> </CancelButton> {` `}a different provider. </div> </div> </Fragment> ) }); const interval = setInterval(async () => { if ((await web3.eth.getAccounts())[0]) { // window.location.reload(); this.setState({ web3: null, loading: true, errorMsg: `` }); this.loadWeb3(providerName); clearInterval(interval); } }, 500); } else { this.setState({ web3: null, loading: false, errorMsg: `We are having trouble accessing your account. Please refresh your browser and try again.` }); } return; } console.log(`Accounts: ${accounts}`); } catch (e) { console.log(e); this.setState({ web3: null, loading: false, errorMsg: `` }); return; } if (providerName === `MetaMask`) { // Watch for account change const account = accounts[0]; const interval = setInterval(async () => { if ((await web3.eth.getAccounts())[0] !== account) { // window.location.reload(); this.setState({ web3: null, loading: true, errorMsg: `` }); this.loadWeb3(providerName); clearInterval(interval); } }, 500); } // Get oracles let oracles; try { oracles = await window.pqueueGeneral.add(() => bZx.getOracleList()); if (oracles.length === 0) { displayNetworkError(); return; } } catch (err) { console.error(err); displayNetworkError(); return; } // Get tokens from the token registry let tokens; try { tokens = await window.pqueueGeneral.add(() => bZx.getTokenList()); if (tokens.length === 0) { displayNetworkError(); return; } } catch (err) { console.error(err); displayNetworkError(); return; } this.props.web3Received(bZx); this.setState({ loading: false, errorMsg: ``, web3, tokens, accounts, oracles, networkId }); }; render() { const { loading, errorMsg, web3, tokens, accounts, oracles, networkId } = this.state; const { render, providerName, setProvider, clearProvider, toggleProviderDialog, hideChooseProviderDialog, bZx } = this.props; if (!providerName) { if (hideChooseProviderDialog) { return ( <LoadingContainer style={{ display: `inline-block` }}> Please {` `} <a style={{ textDecoration: `none`, display: `inherit` }} href="" onClick={toggleProviderDialog} > <div style={{ color: `red` }}>choose</div> </a> {` `}a Web3 provider. </LoadingContainer> ); } return ( <ChooseProviderDialog open close={toggleProviderDialog} setProvider={setProvider} /> ); } if (loading) { return ( <LoadingContainer> Connecting to {providerName} ... </LoadingContainer> ); } else if (errorMsg) { return <LoadingContainer>{errorMsg}</LoadingContainer>; } return web3 ? ( render({ web3, tokens, bZx, accounts, oracles, networkId }) ) : ( <NoProviderMessage providerName={providerName} clearProvider={clearProvider} /> ); } }