1
0
Fork 0
blog/src/components/Web3Donation/index.tsx

184 lines
4.1 KiB
TypeScript
Raw Normal View History

2018-10-09 23:48:25 +02:00
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
2018-10-13 20:37:13 +02:00
import InputGroup from './InputGroup'
2018-10-30 18:08:07 +01:00
import Alerts, { alertMessages } from './Alerts'
2018-10-13 20:37:13 +02:00
import styles from './index.module.scss'
2018-10-26 23:47:41 +02:00
import { getWeb3, getAccounts, getNetwork } from './utils'
2018-10-09 23:48:25 +02:00
const ONE_SECOND = 1000
const ONE_MINUTE = ONE_SECOND * 60
2018-10-30 18:08:07 +01:00
const correctNetwork = 1
2018-10-09 23:48:25 +02:00
export default class Web3Donation extends PureComponent {
state = {
2018-10-26 23:47:41 +02:00
netId: 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-30 18:08:07 +01:00
message: null,
inTransaction: false
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()
}
initWeb3 = async () => {
2018-10-30 18:08:07 +01:00
this.setState({ message: { text: 'Checking' } })
2018-10-26 23:47:41 +02:00
try {
this.web3 = await getWeb3()
2018-10-09 23:48:25 +02:00
2018-10-30 18:08:07 +01:00
this.web3
? this.initAllTheTings()
: this.setState({
message: { status: 'error', text: alertMessages().noWeb3 }
})
2018-10-26 23:47:41 +02:00
} catch (error) {
2018-10-30 18:08:07 +01:00
this.setState({ message: { status: 'error', text: error } })
2018-10-13 20:13:50 +02:00
}
2018-10-09 23:48:25 +02:00
}
async initAllTheTings() {
2018-10-30 18:08:07 +01:00
this.fetchAccounts()
this.fetchNetwork()
2018-10-22 19:24:53 +02:00
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 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)
}
}
2018-10-26 23:47:41 +02:00
fetchNetwork = async () => {
2018-10-09 23:48:25 +02:00
const { web3 } = this
2018-10-30 18:08:07 +01:00
const { netId, networkName } = await getNetwork(web3)
2018-10-09 23:48:25 +02:00
2018-10-30 18:08:07 +01:00
if (netId === correctNetwork) {
this.setState({ netId, networkName })
} else {
2018-10-26 23:47:41 +02:00
this.setState({
2018-10-30 18:08:07 +01:00
message: {
status: 'error',
text: alertMessages(networkName).noCorrectNetwork
}
2018-10-09 23:48:25 +02:00
})
2018-10-26 23:47:41 +02:00
}
2018-10-09 23:48:25 +02:00
}
2018-10-26 23:47:41 +02:00
fetchAccounts = async () => {
2018-10-09 23:48:25 +02:00
const { web3 } = this
2018-10-30 18:08:07 +01:00
const accounts = await getAccounts(web3)
2018-10-09 23:48:25 +02:00
2018-10-30 18:08:07 +01:00
if (accounts[0]) {
2018-10-26 23:47:41 +02:00
this.setState({
accounts,
2018-10-30 18:08:07 +01:00
selectedAccount: accounts[0].toLowerCase()
})
} else {
this.setState({
message: { status: 'error', text: alertMessages().noAccount }
2018-10-09 23:48:25 +02:00
})
2018-10-26 23:47:41 +02:00
}
2018-10-09 23:48:25 +02:00
}
2018-10-30 18:08:07 +01:00
sendTransaction = () => {
2018-10-09 23:48:25 +02:00
const { web3 } = this
2018-10-30 18:08:07 +01:00
this.setState({
inTransaction: true,
message: { text: alertMessages().waitingForUser }
})
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,
2018-10-30 18:08:07 +01:00
message: { text: alertMessages().waitingConfirmation }
2018-10-22 21:07:53 +02:00
})
})
2018-10-30 18:08:07 +01:00
.on('error', error =>
this.setState({ message: { status: 'error', text: error } })
)
2018-10-22 21:07:53 +02:00
.then(() => {
2018-10-28 11:16:57 +01:00
this.setState({
2018-10-30 18:08:07 +01:00
message: { status: 'success', text: alertMessages().success }
2018-10-28 11:16:57 +01:00
})
2018-10-22 21:07:53 +02:00
})
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-14 21:48:38 +02:00
const {
selectedAccount,
amount,
2018-10-22 21:07:53 +02:00
transactionHash,
2018-10-28 11:16:57 +01:00
message,
2018-10-30 18:08:07 +01:00
inTransaction
2018-10-14 21:48:38 +02:00
} = this.state
2018-10-22 19:24:53 +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
<div className={styles.web3Row}>
2018-10-30 18:08:07 +01:00
{selectedAccount &&
this.state.netId === correctNetwork &&
!inTransaction ? (
<InputGroup
selectedAccount={selectedAccount}
amount={amount}
onAmountChange={this.onAmountChange}
sendTransaction={this.sendTransaction}
/>
) : (
2018-10-30 18:08:07 +01:00
message && (
<Alerts message={message} transactionHash={transactionHash} />
)
)}
</div>
2018-10-11 20:06:02 +02:00
</div>
)
2018-10-09 23:48:25 +02:00
}
}