@bzxnetwork/portal
Version:
Frontend demo portal for bZx
299 lines (275 loc) • 8.12 kB
JSX
// /* 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}
/>
);
}
}