import AllValidators from './components/AllValidators' import App from './App' import KeysManager from './contracts/KeysManager.contract' import Metadata from './contracts/Metadata.contract' import ProofOfPhysicalAddress from './contracts/ProofOfPhysicalAddress.contract' import React, { Component } from 'react' import ReactDOM from 'react-dom' import createBrowserHistory from 'history/createBrowserHistory' import getWeb3, { enableWallet } from './utils/getWeb3' import helpers from './utils/helpers' import networkAddresses from './contracts/addresses' import registerServiceWorker from './utils/registerServiceWorker' import { BaseLoader } from './components/BaseLoader' import { ButtonConfirm } from './components/ButtonConfirm' import { ButtonFinalize } from './components/ButtonFinalize' import { Footer } from './components/Footer' import { Header } from './components/Header' import { Router, Route, Redirect } from 'react-router-dom' import { SearchBar } from './components/SearchBar' import { Loading } from './components/Loading' import { constants } from './utils/constants' import { getNetworkBranch } from './utils/utils' import messages from './utils/messages' const history = createBrowserHistory() const baseRootPath = '/poa-dapps-validators' const setMetadataPath = `${baseRootPath}/set` const pendingChangesPath = `${baseRootPath}/pending-changes` class AppMainRouter extends Component { constructor(props) { super(props) history.listen(this.onRouteChange.bind(this)) this.onAllValidatorsRender = this.onAllValidatorsRender.bind(this) this.onConfirmPendingChange = this.onConfirmPendingChange.bind(this) this.onFinalize = this.onFinalize.bind(this) this.onNetworkChange = this.onNetworkChange.bind(this) this.onPendingChangesRender = this.onPendingChangesRender.bind(this) this.onSearch = this.onSearch.bind(this) this.onSetRender = this.onSetRender.bind(this) this.toggleMobileMenu = this.toggleMobileMenu.bind(this) this.onAccountChange = this.onAccountChange.bind(this) this.state = { error: false, injectedWeb3: false, networkMatch: false, keysManager: null, loading: true, loadingNetworkBranch: null, metadataContract: null, miningKey: null, netId: '', poaConsensus: null, searchTerm: '', showMobileMenu: false, showSearch: history.location.pathname !== setMetadataPath, votingKey: null, isValidVotingKey: false } window.addEventListener('load', () => this.initChain()) } initChain() { const netId = window.sessionStorage.netId getWeb3(netId, this.onAccountChange) .then(async web3Config => { return networkAddresses(web3Config) }) .then(async config => { const { web3Config, addresses } = config await this.initContracts({ web3: web3Config.web3Instance, netId: web3Config.netId, addresses }) await this.onAccountChange(web3Config.defaultAccount) this.setState({ injectedWeb3: web3Config.injectedWeb3, networkMatch: web3Config.networkMatch }) this.setState({ loading: false, loadingNetworkBranch: null }) this.onRouteChange() if (web3Config.netId === 99) { // if it's POA Core network const currentTimestamp = Math.floor(Date.now() / 1000) helpers.generateAlert( 'warning', 'Attention', currentTimestamp < 1651698000 ? messages.poaGnoMerging : messages.poaGnoMerged ) } }) .catch(error => { console.error(error.message) this.setState({ loading: false, error: true, loadingNetworkBranch: null }) helpers.generateAlert('error', 'Error!', error.message) }) } async initContracts({ web3, netId, addresses }) { const keysManager = new KeysManager() await keysManager.init({ web3, netId, addresses }) const metadataContract = new Metadata() await metadataContract.init({ web3, netId, addresses }) let proofOfPhysicalAddressContract = new ProofOfPhysicalAddress() try { await proofOfPhysicalAddressContract.init({ web3, netId, addresses }) } catch (e) { console.error('Error initializing ProofOfPhysicalAddress', e) proofOfPhysicalAddressContract = null } const newState = { keysManager, metadataContract, proofOfPhysicalAddressContract, netId } this.setState(newState) } async onAccountChange(votingKey) { let miningKey = null if (this.state.votingKey && votingKey && this.state.votingKey.toLowerCase() === votingKey.toLowerCase()) { return } this.setState({ votingKey }) if (votingKey) { miningKey = await this.state.keysManager.miningKeyByVoting(votingKey) } const isValidVotingKey = miningKey !== '0x0000000000000000000000000000000000000000' && miningKey !== '0x00' && miningKey !== '0x0' && miningKey !== '0x' && miningKey this.setState({ isValidVotingKey, miningKey }) console.log(`Accounts set:\nvotingKey = ${votingKey}\nminingKey = ${miningKey}`) } onRouteChange() { if (history.location.pathname === setMetadataPath) { this.setState({ showSearch: false }) if (this.state.injectedWeb3 === false) { helpers.generateAlert('warning', 'Warning!', messages.noMetamaskFound) } else { this.checkForVotingKey(() => {}) } } else { this.setState({ showSearch: true }) } } async checkForVotingKey(cb) { try { await enableWallet(this.onAccountChange) } catch (error) { helpers.generateAlert('error', 'Error!', error.message) return } if (!this.state.votingKey || this.state.loading) { helpers.generateAlert('warning', 'Warning!', messages.noMetamaskAccount) return } if (!this.state.networkMatch) { helpers.generateAlert('warning', 'Warning!', messages.networkMatchError(this.state.netId)) return } if (!this.state.isValidVotingKey) { helpers.generateAlert('warning', 'Warning!', messages.invalidaVotingKey) return } return cb() } toggleMobileMenu = () => { this.setState(prevState => ({ showMobileMenu: !prevState.showMobileMenu })) } async _onBtnClick({ event, methodToCall, successMsg }) { event.preventDefault() this.checkForVotingKey(async () => { this.setState({ loading: true }) const miningKey = event.currentTarget.getAttribute('miningkey') try { let result = await this.state.metadataContract[methodToCall]({ miningKeyToConfirm: miningKey, senderVotingKey: this.state.votingKey, senderMiningKey: this.state.miningKey }) console.log(result) this.setState({ loading: false }) helpers.generateAlert('success', 'Congratulations!', successMsg) } catch (error) { this.setState({ loading: false }) console.error(error.message) helpers.generateAlert('error', 'Error!', error.message) } }) } async onConfirmPendingChange(event) { await this._onBtnClick({ event, methodToCall: 'confirmPendingChange', successMsg: 'You have successfully confirmed the change!' }) } async onFinalize(event) { await this._onBtnClick({ event, methodToCall: 'finalize', successMsg: 'You have successfully finalized the change!' }) } onPendingChangesRender() { const networkBranch = this.getValidatorsNetworkBranch() return this.state.loading || this.state.error ? null : ( ) } onAllValidatorsRender() { const networkBranch = this.getValidatorsNetworkBranch() return this.state.loading || this.state.error ? null : ( ) } onSearch(term) { this.setState({ searchTerm: term.target.value }) } getValidatorsNetworkBranch() { return this.state.netId ? getNetworkBranch(this.state.netId) : null } onSetRender() { const networkBranch = this.getValidatorsNetworkBranch() return !this.state.loading ? : null } onNetworkChange(e) { this.setState({ loading: true, loadingNetworkBranch: getNetworkBranch(e.value), searchTerm: '' }) window.localStorage.netId = e.value window.sessionStorage.netId = e.value this.initChain() } render() { const networkBranch = this.state.loadingNetworkBranch ? this.state.loadingNetworkBranch : this.getValidatorsNetworkBranch() return networkBranch ? (
{this.state.showSearch ? ( ) : null} {this.state.loading ? ReactDOM.createPortal( , document.getElementById('loadingContainer') ) : null}
( )} />
) : ( ) } } ReactDOM.render(, document.getElementById('root')) registerServiceWorker()