1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-06-17 18:13:14 +02:00
blog/src/components/atoms/Web3Donation.jsx

252 lines
5.9 KiB
React
Raw Normal View History

2018-10-09 23:48:25 +02:00
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import Web3 from 'web3'
2018-10-13 15:40:05 +02:00
import Input from '../atoms/Input'
2018-10-09 23:48:25 +02:00
import styles from './Web3Donation.module.scss'
const ONE_SECOND = 1000
const ONE_MINUTE = ONE_SECOND * 60
2018-10-13 18:13:36 +02:00
const InputGroup = ({
networkId,
selectedAccount,
amount,
onAmountChange,
handleWeb3Button
}) => (
<div className={styles.inputGroup}>
<div className={styles.input}>
<Input
type="number"
disabled={!(networkId === '1') || !selectedAccount}
value={amount}
onChange={onAmountChange}
min="0"
step="0.01"
/>
<div className={styles.currency}>
<span>ETH</span>
</div>
</div>
<button
className="btn btn-primary"
onClick={handleWeb3Button}
disabled={!(networkId === '1') || !selectedAccount}
>
Make it rain
</button>
</div>
)
InputGroup.propTypes = {
networkId: PropTypes.string,
selectedAccount: PropTypes.string,
amount: PropTypes.number,
onAmountChange: PropTypes.func,
handleWeb3Button: PropTypes.func
}
const Alerts = ({ accounts, networkId, error, transactionHash }) => {
if (error || accounts.length === 0) {
return (
<div className={styles.alert}>
{accounts.length === 0 &&
'Web3 detected, but no account. Are you logged into your MetaMask account?'}
{networkId !== '1' && 'Please connect to Main network'}
{error && error.message}
</div>
)
}
if (transactionHash) {
return (
<div className={styles.success}>
You are awesome, thanks!
<br />
<a href={`https://etherscan.io/tx/${transactionHash}`}>
See your transaction on etherscan.io.
</a>
</div>
)
}
return null
}
Alerts.propTypes = {
accounts: PropTypes.array,
networkId: PropTypes.string,
error: PropTypes.object,
transactionHash: PropTypes.string
}
2018-10-09 23:48:25 +02:00
export default class Web3Donation extends PureComponent {
state = {
web3Connected: false,
networkError: null,
networkId: null,
accounts: [],
selectedAccount: null,
2018-10-13 15:40:05 +02:00
amount: 0.01,
2018-10-11 23:18:03 +02:00
receipt: null,
transactionHash: null,
2018-10-09 23:48:25 +02:00
loading: false,
error: null
}
static propTypes = {
address: PropTypes.string
}
2018-10-11 20:06:02 +02:00
web3 = null
2018-10-09 23:48:25 +02:00
interval = null
networkInterval = null
componentDidMount() {
2018-10-11 20:06:02 +02:00
if (typeof window.web3 === 'undefined') {
// no web3
this.setState({ web3Connected: false })
} else {
2018-10-11 23:18:03 +02:00
// this.web3 = new Web3(Web3.givenProvider || 'ws://localhost:8546')
this.web3 = new Web3(window.web3.currentProvider)
2018-10-09 23:48:25 +02:00
this.setState({ web3Connected: true })
this.fetchAccounts()
this.fetchNetwork()
this.initPoll()
this.initNetworkPoll()
}
}
componentWillUnmount() {
clearInterval(this.interval)
clearInterval(this.networkInterval)
this.setState({ web3Connected: false })
}
initPoll() {
if (!this.interval) {
this.interval = setInterval(this.fetchAccounts, ONE_SECOND)
}
}
initNetworkPoll() {
if (!this.networkInterval) {
this.networkInterval = setInterval(this.fetchNetwork, ONE_MINUTE)
}
}
fetchNetwork = () => {
const { web3 } = this
web3 &&
web3.eth &&
2018-10-11 23:18:03 +02:00
//web3.eth.net.getId((err, netId) => {
web3.version.getNetwork((err, netId) => {
2018-10-09 23:48:25 +02:00
if (err) {
2018-10-11 20:06:02 +02:00
this.setState({ networkError: err })
}
if (netId != this.state.networkId) {
2018-10-09 23:48:25 +02:00
this.setState({
2018-10-11 20:06:02 +02:00
networkError: null,
networkId: netId
2018-10-09 23:48:25 +02:00
})
}
})
}
fetchAccounts = () => {
const { web3 } = this
web3 &&
web3.eth &&
web3.eth.getAccounts((err, accounts) => {
if (err) {
2018-10-11 20:06:02 +02:00
this.setState({ accountsError: err })
2018-10-09 23:48:25 +02:00
}
2018-10-11 20:06:02 +02:00
this.setState({
accounts,
selectedAccount: accounts[0]
})
2018-10-09 23:48:25 +02:00
})
}
handleWeb3Button = () => {
const { web3 } = this
this.setState({ loading: true })
2018-10-11 23:18:03 +02:00
// web3.eth
// .sendTransaction({
// from: this.state.selectedAccount,
// to: this.props.address,
// value: '10000000000000000'
// })
// .then(receipt => {
// this.setState({ receipt, loading: false })
// })
// .catch(error => {
// this.setState({ error, loading: false })
// })
web3.eth.sendTransaction(
{
2018-10-09 23:48:25 +02:00
from: this.state.selectedAccount,
to: this.props.address,
2018-10-13 15:40:05 +02:00
value: this.state.amount * 1e18 // ETH -> Wei
2018-10-11 23:18:03 +02:00
},
(error, transactionHash) => {
if (error) this.setState({ error, loading: false })
if (!transactionHash) this.setState({ loading: true })
this.setState({ transactionHash, loading: false })
}
)
2018-10-09 23:48:25 +02:00
}
2018-10-13 15:40:05 +02:00
onAmountChange = ({ target }) => {
this.setState({ amount: target.value })
}
2018-10-09 23:48:25 +02:00
render() {
2018-10-11 20:06:02 +02:00
return (
<div className={styles.web3}>
2018-10-13 18:13:36 +02:00
<header>
<h4>web3</h4>
<p>Send Ether with MetaMask, Brave, or Mist.</p>
</header>
2018-10-11 20:06:02 +02:00
{this.state.web3Connected ? (
2018-10-13 18:13:36 +02:00
<div className={styles.web3Row}>
2018-10-11 20:06:02 +02:00
{this.state.loading ? (
'Hang on...'
) : (
2018-10-13 18:13:36 +02:00
<InputGroup
networkId={this.state.networkId}
selectedAccount={this.state.selectedAccount}
amount={this.state.amount}
onAmountChange={this.onAmountChange}
handleWeb3Button={this.handleWeb3Button}
/>
2018-10-11 20:06:02 +02:00
)}
2018-10-13 18:13:36 +02:00
<Alerts
accounts={this.state.accounts}
networkId={this.state.networkId}
error={this.state.error}
transactionHash={this.state.transactionHash}
/>
2018-10-11 20:06:02 +02:00
</div>
) : (
2018-10-13 18:13:36 +02:00
<small>
No Web3 detected. Install <a href="https://metamask.io">MetaMask</a>
, <a href="https://brave.com">Brave</a>, or{' '}
<a href="https://github.com/ethereum/mist">Mist</a>.
</small>
2018-10-11 20:06:02 +02:00
)}
</div>
)
2018-10-09 23:48:25 +02:00
}
}