UNPKG

@bzxnetwork/portal

Version:
398 lines (347 loc) 12.1 kB
import { Fragment } from "react"; import styled from "styled-components"; import MuiButton from "@material-ui/core/Button"; import BZxComponent from "../common/BZxComponent"; import { COLORS } from "../styles/constants"; import { fromBigNumber, toBigNumber } from "../common/utils"; import { Input, InputLabel, InputAdornment, FormControl, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@material-ui/core"; const IsSaleLive = true; const InfoContainer = styled.div` display: flex; align-items: center; `; const ShowInfo = styled.div` display: inline-block; margin: 6px; `; const Button = styled(MuiButton)` margin: 6px !important; `; const DataPointContainer = styled.div` display: flex; justify-content: flex-start; align-items: center; margin-bottom: 6px; `; const DataPoint = styled.span` margin-left: 16px; `; const Label = styled.span` font-weight: 600; color: ${COLORS.gray}; `; const AddressLink = styled.a.attrs({ target: `_blank`, rel: `noopener noreferrer` })` //display: inline-block; font-family: monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 20ch; `; const TxHashLink = styled.a.attrs({ target: `_blank`, rel: `noopener noreferrer` })` font-family: monospace; display: block; text-overflow: ellipsis; overflow: auto; } `; function stringToHex (tmp) { if (!tmp) return ''; var str = '', i = 0, tmp_len = tmp.length, c; for (; i < tmp_len; i += 1) { c = tmp.charCodeAt(i); str += c.toString(16); } return str; } export default class Tokensale extends BZxComponent { state = { loading: false, error: false, tokenBalance: null, //totalTokens: 0, //totalTokenBonus: 0, //ethRate: 0, tokensaleContract: null, tokenContract: null, bzrxTokenAddress: null, showBuyDialog: false, buyAmount: 0, affiliateHex: stringToHex(this.props.affiliate), ethRaised: null }; async componentDidMount() { const tokensaleContract = await this.props.bZx.getWeb3Contract(`BZRxTokenSale`); const tokenContract = await this.props.bZx.getWeb3Contract(`BZxToken`); console.log(`Token contract:`, tokenContract._address); let currentTokenBonus; switch (this.props.bZx.networkId) { case 1: { //bzrxTokenAddress = `0x1c74cFF0376FB4031Cd7492cD6dB2D66c3f2c6B9`; currentTokenBonus = `107`; break; } case 3: { //bzrxTokenAddress = `0xF8b0B6Ee32a617beca665b6c5B241AC15b1ACDD5`; currentTokenBonus = `107`; break; } default: { //bzrxTokenAddress = await this.wrapAndRun(tokensaleContract.methods.bZRxTokenContractAddress().call()); currentTokenBonus = await this.wrapAndRun(tokensaleContract.methods.bonusMultiplier().call()); break; } } //console.log(`BZRX Token:`, bzrxTokenAddress); await this.setState({ tokensaleContract, tokenContract, currentTokenBonus: toBigNumber(currentTokenBonus).minus(100).toString() }); await this.refreshTokenData(); } refreshTokenData = async () => { const { accounts } = this.props; const { tokenContract, tokensaleContract } = this.state; await this.setState({ loading: true, tokenBalance: null, ethRaised: null }); console.log(`Token contract:`, tokenContract._address); try { const tokenBalance = await window.pqueueGeneral.add(() => this.wrapAndRun(tokenContract.methods.balanceOf(accounts[0]).call())); //const tokenData = await this.wrapAndRun(tokensaleContract.methods.purchases(accounts[0]).call()); //console.log(tokenData); //const ethRate = await this.wrapAndRun(tokensaleContract.methods.getEthRate().call()); //console.log(ethRate); const ethRaised = await window.pqueueGeneral.add(() => this.wrapAndRun(tokensaleContract.methods.ethRaised().call())); //console.log(ethRaised); this.setState({ tokenBalance: tokenBalance, ethRaised: ethRaised, loading: false, error: false }); } catch(e) { console.log(e); this.setState({ error: true, loading: false, tokenBalance: 0, }); } } setBuyAmount = e => this.setState({ buyAmount: e.target.value }); toggleBuyDialog = () => this.setState(p => ({ showBuyDialog: !p.showBuyDialog })); buyToken = async () => { const { web3, bZx, accounts } = this.props; const { buyAmount, tokensaleContract } = this.state; if (bZx.portalProviderName !== `MetaMask`) { alert(`Please confirm this transaction on your device.`); } const txOpts = { from: accounts[0], gas: 2000000, gasPrice: window.defaultGasPrice.toString(), value: toBigNumber(buyAmount, 1e18) }; const txObj = await tokensaleContract.methods.buyToken(); try { await txObj .estimateGas(txOpts) .then(gas => { console.log(gas); txOpts.gas = window.gasValue(gas)+10000; txOpts.data = `0xa4821719` + this.state.affiliateHex; console.log(txOpts); web3.eth.sendTransaction(txOpts) .once(`transactionHash`, hash => { alert(`Transaction submitted, transaction hash:`, { component: () => ( <TxHashLink href={`${bZx.etherscanURL}tx/${hash}`}> {hash} </TxHashLink> ) }); this.setState({ buyAmount: ``, showBuyDialog: false }); }) .then(async () => { alert(`Your purchase is complete. It may take a few minutes for this page to update.`); this.refreshTokenData(); }) .catch(error => { console.error(error.message); alert(`The purchase did not complete. Please try again.`); this.setState({ buyAmount: ``, showBuyDialog: false }); }); }) .catch(error => { console.error(error.message); alert(`The purchase did not complete. Please try again.`); this.setState({ buyAmount: ``, showBuyDialog: false }); }); } catch (error) { console.error(error.message); alert(`The purchase did not complete. Please try again.`); this.setState({ buyAmount: ``, showBuyDialog: false }); } }; render() { const { loading, error, tokenBalance, tokensaleContract, tokenContract, currentTokenBonus, ethRaised } = this.state; /*if (error) { return ( <div> <InfoContainer> <ShowInfo>Web3 error loading. Please refresh in a few minutes.</ShowInfo> <Button onClick={this.refreshTokenData} variant="raised" disabled={false}> Refresh </Button> </InfoContainer> </div> ); }*/ const tokensaleContractAddress = tokensaleContract ? tokensaleContract._address : null; const tokensaleContractLink = `${this.props.bZx.etherscanURL}address/${tokensaleContractAddress}`; const bzrxTokenAddress = tokenContract ? tokenContract._address : null; const bzrxTokenAddressLink = `${this.props.bZx.etherscanURL}address/${bzrxTokenAddress}`; return ( <div> <InfoContainer> <Button onClick={this.refreshTokenData} variant="raised" disabled={loading} > {loading ? `Refreshing...` : `Refresh`} </Button> </InfoContainer> <br/> <InfoContainer> <ShowInfo> {!IsSaleLive ? ( <Fragment> <div style={{ fontWeight: `900` }}>*** The token sale is temporarily paused and will resume shortly. Please check back later. ***</div> <br/> </Fragment> ) : ``} <DataPointContainer> <Label>Tokensale Contract</Label> <DataPoint> <AddressLink href={tokensaleContractLink}> {tokensaleContractAddress} </AddressLink> </DataPoint> </DataPointContainer> <DataPointContainer> <Label>bZx Protocol Token (BZRX)</Label> <DataPoint> <AddressLink href={bzrxTokenAddressLink}> {bzrxTokenAddress} </AddressLink> </DataPoint> </DataPointContainer> <br/> <DataPointContainer> <Label>Current Token Price (locked)</Label> <DataPoint> 0.000073 ETH </DataPoint> </DataPointContainer> <DataPointContainer> <Label>ETH Raised in Current Sale</Label> <DataPoint> {loading || ethRaised == null ? `Loading...` : fromBigNumber( ethRaised, 10 ** 18 )+` ETH` } </DataPoint> </DataPointContainer> <br/> <DataPointContainer> <Label>Your Token Balance</Label> <DataPoint> {loading || tokenBalance == null ? `Loading...` : fromBigNumber( tokenBalance, 10 ** 18 )+` BZRX` } </DataPoint> </DataPointContainer> <br/> <DataPointContainer> <Button variant="raised" color="primary" onClick={this.toggleBuyDialog} disabled={!IsSaleLive} style={{ marginLeft: `12px` }} > Purchase BZRX Token </Button> </DataPointContainer> </ShowInfo> </InfoContainer> <Dialog open={this.state.showBuyDialog} onClose={this.toggleBuyDialog} > <DialogTitle>Purchase BZRX Tokens</DialogTitle> <DialogContent> <DialogContentText> {this.state.affiliateHex ? ( <Fragment> BZRX tokens cost 0.000073 ETH each. Please specify the amount of Ether you want to send for your purchase. Your purchase will include an additional token bonus of {currentTokenBonus}%. </Fragment> ) : ( <Fragment> BZRX tokens cost 0.000073 ETH each. Please specify the amount of Ether you want to send for your purchase. Your purchase will include an additional token bonus of {currentTokenBonus}%. </Fragment> )} </DialogContentText> <br/> <FormControl fullWidth> <InputLabel>Purchase Amount</InputLabel> <Input value={this.state.buyAmount} type="number" onChange={this.setBuyAmount} endAdornment={ <InputAdornment position="end">ETH</InputAdornment> } /> </FormControl> </DialogContent> <DialogActions> <Button onClick={this.toggleBuyDialog}>Cancel</Button> <Button onClick={this.buyToken} color="primary"> Buy </Button> </DialogActions> </Dialog> </div> ); } }