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

224 lines
4.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 20:37:13 +02:00
import InputGroup from './InputGroup'
import Alerts from './Alerts'
import styles from './index.module.scss'
2018-10-22 19:24:53 +02:00
import { getNetworkName, Logger } from './utils'
2018-10-09 23:48:25 +02:00
const ONE_SECOND = 1000
const ONE_MINUTE = ONE_SECOND * 60
export default class Web3Donation extends PureComponent {
state = {
web3Connected: false,
networkId: null,
2018-10-13 20:13:50 +02:00
networkName: null,
2018-10-09 23:48:25 +02:00
accounts: [],
selectedAccount: null,
2018-10-14 20:28:35 +02:00
amount: '0.01',
2018-10-11 23:18:03 +02:00
transactionHash: null,
2018-10-22 21:07:53 +02:00
receipt: null,
2018-10-09 23:48:25 +02:00
loading: false,
2018-10-22 21:07:53 +02:00
error: null,
message: 'Hang on...'
2018-10-09 23:48:25 +02:00
}
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-22 19:24:53 +02:00
this.initWeb3()
2018-10-13 20:13:50 +02:00
}
componentWillUnmount() {
this.resetAllTheThings()
}
2018-10-22 19:24:53 +02:00
async initWeb3() {
2018-10-13 20:13:50 +02:00
// Modern dapp browsers...
2018-10-22 19:24:53 +02:00
if (window.ethereum) {
this.web3 = new Web3(window.ethereum)
try {
// Request account access
await window.ethereum.enable()
this.setState({ web3Connected: true })
this.initAllTheTings()
} catch (error) {
// User denied account access...
Logger.error(error)
this.setState({ error })
}
}
2018-10-13 20:13:50 +02:00
// Legacy dapp browsers...
2018-10-22 19:24:53 +02:00
else if (window.web3) {
2018-10-11 23:18:03 +02:00
this.web3 = new Web3(window.web3.currentProvider)
2018-10-09 23:48:25 +02:00
this.setState({ web3Connected: true })
2018-10-22 19:24:53 +02:00
this.initAllTheTings()
2018-10-09 23:48:25 +02:00
}
2018-10-13 20:13:50 +02:00
// Non-dapp browsers...
else {
this.setState({ web3Connected: false })
}
2018-10-09 23:48:25 +02:00
}
2018-10-22 19:24:53 +02:00
initAllTheTings() {
this.fetchAccounts()
this.fetchNetwork()
this.initAccountsPoll()
this.initNetworkPoll()
}
2018-10-13 20:13:50 +02:00
resetAllTheThings() {
2018-10-09 23:48:25 +02:00
clearInterval(this.interval)
clearInterval(this.networkInterval)
2018-10-13 23:35:21 +02:00
this.setState({ web3Connected: false })
2018-10-09 23:48:25 +02:00
}
2018-10-13 20:13:50 +02:00
initAccountsPoll() {
2018-10-09 23:48:25 +02:00
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-22 21:07:53 +02:00
web3.eth.net.getId((err, netId) => {
2018-10-13 23:35:21 +02:00
if (err) this.setState({ error: err })
2018-10-11 20:06:02 +02:00
2018-10-22 21:07:53 +02:00
if (netId !== this.state.networkId) {
2018-10-09 23:48:25 +02:00
this.setState({
2018-10-13 23:35:21 +02:00
error: null,
networkId: netId
})
getNetworkName(netId).then(networkName => {
2018-10-14 21:48:38 +02:00
this.setState({ networkName })
2018-10-09 23:48:25 +02:00
})
}
})
}
fetchAccounts = () => {
const { web3 } = this
web3 &&
web3.eth &&
web3.eth.getAccounts((err, accounts) => {
2018-10-13 23:35:21 +02:00
if (err) this.setState({ error: err })
2018-10-11 20:06:02 +02:00
this.setState({
2018-10-13 23:35:21 +02:00
error: null,
2018-10-11 20:06:02 +02:00
accounts,
2018-10-25 17:08:42 +02:00
selectedAccount: accounts[0].toLowerCase()
2018-10-11 20:06:02 +02:00
})
2018-10-09 23:48:25 +02:00
})
}
2018-10-25 17:08:42 +02:00
sendTransaction() {
2018-10-09 23:48:25 +02:00
const { web3 } = this
2018-10-22 21:07:53 +02:00
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-22 21:07:53 +02:00
})
.once('transactionHash', transactionHash => {
this.setState({
transactionHash,
message: 'Waiting for network confirmation, hang on...'
})
})
.on('error', error => this.setState({ error, loading: false }))
.then(() => {
this.setState({ message: 'Confirmed. You are awesome, thanks!' })
})
2018-10-09 23:48:25 +02:00
}
2018-10-25 17:08:42 +02:00
handleButton = () => {
this.setState({
loading: true,
message: 'Waiting for your confirmation...'
})
this.sendTransaction()
}
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-14 21:48:38 +02:00
const {
networkId,
accounts,
selectedAccount,
web3Connected,
loading,
amount,
networkName,
error,
2018-10-22 21:07:53 +02:00
transactionHash,
confirmationNumber,
message
2018-10-14 21:48:38 +02:00
} = this.state
2018-10-22 19:24:53 +02:00
2018-10-22 21:22:22 +02:00
const hasCorrectNetwork = networkId === 1
2018-10-14 21:48:38 +02:00
const hasAccount = accounts.length !== 0
2018-10-13 23:35:21 +02:00
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
2018-10-14 21:48:38 +02:00
{web3Connected && (
2018-10-13 18:13:36 +02:00
<div className={styles.web3Row}>
2018-10-14 21:48:38 +02:00
{loading ? (
2018-10-22 21:07:53 +02:00
message
2018-10-11 20:06:02 +02:00
) : (
2018-10-13 18:13:36 +02:00
<InputGroup
2018-10-13 23:35:21 +02:00
hasCorrectNetwork={hasCorrectNetwork}
hasAccount={hasAccount}
2018-10-14 22:04:54 +02:00
selectedAccount={selectedAccount}
2018-10-14 21:48:38 +02:00
amount={amount}
2018-10-13 18:13:36 +02:00
onAmountChange={this.onAmountChange}
2018-10-13 23:35:21 +02:00
handleButton={this.handleButton}
2018-10-13 18:13:36 +02:00
/>
2018-10-11 20:06:02 +02:00
)}
</div>
)}
2018-10-13 23:35:21 +02:00
<Alerts
hasCorrectNetwork={hasCorrectNetwork}
hasAccount={hasAccount}
2018-10-14 21:48:38 +02:00
networkName={networkName}
error={error}
transactionHash={transactionHash}
web3Connected={web3Connected}
2018-10-22 21:07:53 +02:00
confirmationNumber={confirmationNumber}
2018-10-13 23:35:21 +02:00
/>
2018-10-11 20:06:02 +02:00
</div>
)
2018-10-09 23:48:25 +02:00
}
}