Merge pull request #87 from varasev/issue-85

(Fix, Refactor) Add support of a new version of MetaMask
This commit is contained in:
Victor Baranov 2018-10-15 16:37:50 +03:00 committed by GitHub
commit c70a11a24d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 201 additions and 243 deletions

View File

@ -152,7 +152,7 @@ class App extends Component {
const isValid = await this.getKeysManager().isVotingActive(votingKey)
console.log(isValid)
if (isValid) {
// // add loading screen
// add loading screen
await this.sendTxToContract()
} else {
this.setState({ loading: false })
@ -203,7 +203,7 @@ class App extends Component {
}
render() {
const { netId } = this.props.web3Config
const classNameHiddenIfNotCoreNetwork = netId !== constants.NETID_CORE ? 'display-none' : ''
const classNameHiddenIfNotCoreNetwork = netId !== helpers.netIdByName('core') ? 'display-none' : ''
if (!this.isValidVotingKey) {
return null

View File

@ -1,10 +1,10 @@
import React from 'react'
import moment from 'moment'
import Socials from './Socials'
import { isTestnet } from './helpers'
import { constants } from './constants'
const Footer = ({ netId }) => {
const footerClassName = isTestnet(netId) ? 'sokol' : ''
const footerClassName = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET ? 'sokol' : ''
return (
<footer className={`footer ${footerClassName}`}>

View File

@ -9,16 +9,20 @@ import menuOpenIconSokol from './images/icons/icon-close-sokol.svg'
import NavigationLinks from './NavigationLinks'
import MobileMenuLinks from './MobileMenuLinks'
import { constants } from './constants'
import { isTestnet } from './helpers'
const Header = ({ netId, onChange, injectedWeb3, showMobileMenu, onMenuToggle, baseRootPath, navigationData }) => {
const thisIsTestnet = isTestnet(netId)
const thisIsTestnet = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
const headerClassName = thisIsTestnet ? 'sokol' : ''
const logoImageName = thisIsTestnet ? logoSokol : logoBase
const menuIcon = thisIsTestnet ? menuIconSokol : menuIconBase
const menuOpenIcon = thisIsTestnet ? menuOpenIconSokol : menuOpenIconBase
let select
let options = []
for (const _netId in constants.NETWORKS) {
options.push({ value: _netId, label: `Network: ${constants.NETWORKS[_netId].NAME}` })
}
if (!injectedWeb3) {
select = (
@ -33,10 +37,7 @@ const Header = ({ netId, onChange, injectedWeb3, showMobileMenu, onMenuToggle, b
width: '150px'
}}
clearable={false}
options={[
{ value: constants.NETID_SOKOL, label: 'Network: Sokol' },
{ value: constants.NETID_CORE, label: 'Network: Core' }
]}
options={options}
/>
)
}

View File

@ -9,16 +9,11 @@ const styles = netId => {
backgroundColor: 'rgba(47, 109, 99, 0.8)'
}
switch (netId) {
case constants.NETID_SOKOL:
case constants.NETID_DAI_TEST:
return sokol
case constants.NETID_CORE:
case constants.NETID_DAI:
return core
default:
return {}
if (netId in constants.NETWORKS) {
return constants.NETWORKS[netId].TESTNET ? sokol : core
}
return core
}
const Loading = ({ netId }) => (
<div className="loading-container" style={styles(netId)}>

View File

@ -10,10 +10,32 @@ constants.ABIsSources = {
}
constants.userDeniedTransactionPattern = 'User denied transaction'
constants.NETID_SOKOL = '77'
constants.NETID_CORE = '99'
constants.NETID_DAI_TEST = '79'
constants.NETID_DAI = '100'
constants.NETWORKS = {
'77': {
NAME: 'Sokol',
RPC: 'https://sokol.poa.network',
BRANCH: 'sokol',
TESTNET: true
},
'99': {
NAME: 'Core',
RPC: 'https://core.poa.network',
BRANCH: 'core',
TESTNET: false
},
'79': {
NAME: 'Dai-Test',
RPC: 'http://40.112.48.125',
BRANCH: 'dai-test',
TESTNET: true
},
'100': {
NAME: 'Dai',
RPC: 'https://dai.poa.network',
BRANCH: 'dai',
TESTNET: false
}
}
module.exports = {
constants

View File

@ -1,24 +1,22 @@
import Web3 from 'web3'
import { constants } from '../constants'
import helpers from './helpers'
export default class KeysManager {
async init({ web3, netId, addresses }) {
let web3_10 = new Web3(web3.currentProvider)
const { KEYS_MANAGER_ADDRESS } = addresses
console.log('Keys Manager address ', KEYS_MANAGER_ADDRESS)
const branch = helpers.getBranch(netId)
let KeysManagerAbi = await helpers.getABI(branch, 'KeysManager')
const KeysManagerAbi = await helpers.getABI(constants.NETWORKS[netId].BRANCH, 'KeysManager')
this.keysInstance = new web3_10.eth.Contract(KeysManagerAbi, KEYS_MANAGER_ADDRESS)
this.instance = new web3.eth.Contract(KeysManagerAbi, KEYS_MANAGER_ADDRESS)
}
async isVotingActive(votingKey) {
return await this.keysInstance.methods.isVotingActive(votingKey).call()
return await this.instance.methods.isVotingActive(votingKey).call()
}
async miningKeyByVoting(votingKey) {
return await this.keysInstance.methods.miningKeyByVoting(votingKey).call()
return await this.instance.methods.miningKeyByVoting(votingKey).call()
}
async getVotingByMining(miningKey) {
return await this.keysInstance.methods.getVotingByMining(miningKey).call()
return await this.instance.methods.getVotingByMining(miningKey).call()
}
}

View File

@ -1,9 +1,9 @@
import PoaConsensus from './PoaConsensus.contract'
import Web3 from 'web3'
import moment from 'moment'
import helpers from './helpers'
import helpersGlobal from '../helpers'
import { messages } from '../messages'
import { constants } from '../constants'
var toAscii = function(hex) {
var str = '',
@ -22,19 +22,20 @@ var toAscii = function(hex) {
export default class Metadata {
async init({ web3, netId, addresses }) {
this.web3_10 = new Web3(web3.currentProvider)
this.web3 = web3
this.gasPrice = web3.utils.toWei('2', 'gwei')
const { METADATA_ADDRESS, MOC } = addresses
console.log('Metadata contract Address: ', METADATA_ADDRESS)
const branch = helpers.getBranch(netId)
let MetadataAbi = await helpers.getABI(branch, 'ValidatorMetadata')
const MetadataAbi = await helpers.getABI(constants.NETWORKS[netId].BRANCH, 'ValidatorMetadata')
this.metadataInstance = new this.web3_10.eth.Contract(MetadataAbi, METADATA_ADDRESS)
this.metadataInstance = new web3.eth.Contract(MetadataAbi, METADATA_ADDRESS)
this.MOC_ADDRESS = MOC
this.addresses = addresses
const poaInstance = new PoaConsensus()
await poaInstance.init({ web3: this.web3_10, netId, addresses })
await poaInstance.init({ web3, netId, addresses })
this.mocRemoved = await poaInstance.isMasterOfCeremonyRemoved()
this.miningKeys = await poaInstance.getValidators()
}
@ -50,16 +51,15 @@ export default class Metadata {
hasData
}) {
let methodToCall = hasData ? 'changeRequest' : 'createMetadata'
const gasPrice = this.web3_10.utils.toWei('2', 'gwei')
return await this.metadataInstance.methods[methodToCall](
this.web3_10.utils.fromAscii(firstName),
this.web3_10.utils.fromAscii(lastName),
this.web3_10.utils.fromAscii(licenseId),
this.web3.utils.fromAscii(firstName),
this.web3.utils.fromAscii(lastName),
this.web3.utils.fromAscii(licenseId),
fullAddress,
this.web3_10.utils.fromAscii(state),
this.web3_10.utils.fromAscii(zipcode),
this.web3.utils.fromAscii(state),
this.web3.utils.fromAscii(zipcode),
expirationDate
).send({ from: votingKey, gasPrice })
).send({ from: votingKey, gasPrice: this.gasPrice })
}
getMocData() {
@ -180,10 +180,9 @@ export default class Metadata {
Please ask other validators to verify your new information.`
}
}
const gasPrice = this.web3_10.utils.toWei('2', 'gwei')
return await this.metadataInstance.methods
.confirmPendingChange(miningKeyToConfirm)
.send({ from: senderVotingKey, gasPrice })
.send({ from: senderVotingKey, gasPrice: this.gasPrice })
}
async getConfirmations({ miningKey }) {
@ -208,7 +207,8 @@ export default class Metadata {
The minimum threshold to finalize is ${getMinThreshold}.`
}
}
const gasPrice = this.web3_10.utils.toWei('2', 'gwei')
return await this.metadataInstance.methods.finalize(miningKeyToConfirm).send({ from: senderVotingKey, gasPrice })
return await this.metadataInstance.methods
.finalize(miningKeyToConfirm)
.send({ from: senderVotingKey, gasPrice: this.gasPrice })
}
}

View File

@ -1,25 +1,22 @@
import Web3 from 'web3'
import helpers from './helpers'
import { constants } from '../constants'
export default class POAConsensus {
export default class PoaConsensus {
async init({ web3, netId, addresses }) {
let web3_10 = new Web3(web3.currentProvider)
const { POA_ADDRESS } = addresses
console.log('POA Address ', POA_ADDRESS)
const branch = helpers.getBranch(netId)
const poaConsensusAbi = await helpers.getABI(constants.NETWORKS[netId].BRANCH, 'PoaNetworkConsensus')
let poaConsensusAbi = await helpers.getABI(branch, 'PoaNetworkConsensus')
this.poaInstance = new web3_10.eth.Contract(poaConsensusAbi, POA_ADDRESS)
this.instance = new web3.eth.Contract(poaConsensusAbi, POA_ADDRESS)
}
async getValidators() {
console.log(this.poaInstance)
return await this.poaInstance.methods.getValidators().call()
console.log(this.instance)
return await this.instance.methods.getValidators().call()
}
async isMasterOfCeremonyRemoved() {
if (this.poaInstance.methods.isMasterOfCeremonyRemoved) {
return await this.poaInstance.methods.isMasterOfCeremonyRemoved().call()
if (this.instance.methods.isMasterOfCeremonyRemoved) {
return await this.instance.methods.isMasterOfCeremonyRemoved().call()
}
return false
}

View File

@ -1,19 +1,18 @@
import Web3 from 'web3'
import helpers from './helpers'
import { constants } from '../constants'
const REGISTER_ADDRESS_EVENT_NAME = 'LogAddressRegistered'
export default class ProofOfPhysicalAddress {
async init({ web3, netId, addresses }) {
let web3_10 = new Web3(web3.currentProvider)
const { PROOF_OF_PHYSICAL_ADDRESS } = addresses
const branch = helpers.getBranch(netId)
const branch = constants.NETWORKS[netId].BRANCH
if (branch !== 'core') {
throw new Error(`ProofOfPhysicalAddress contract not deployed on network "${branch}"`)
}
let proofOfPhysicalAddressAbi = await helpers.getABI(branch, 'ProofOfPhysicalAddress')
this.instance = new web3_10.eth.Contract(proofOfPhysicalAddressAbi, PROOF_OF_PHYSICAL_ADDRESS)
const proofOfPhysicalAddressAbi = await helpers.getABI(branch, 'ProofOfPhysicalAddress')
this.instance = new web3.eth.Contract(proofOfPhysicalAddressAbi, PROOF_OF_PHYSICAL_ADDRESS)
this.getPhysicalAddressesOfWalletAddress = this.getPhysicalAddressesOfWalletAddress.bind(this)
this.getAllEvents = this.getAllEvents.bind(this)

View File

@ -10,25 +10,7 @@ import messages from '../messages'
}*/
export default web3Config => {
let branch
switch (web3Config.netId) {
case constants.NETID_SOKOL:
branch = 'sokol'
break
case constants.NETID_DAI_TEST:
branch = 'dai-test'
break
case constants.NETID_CORE:
branch = 'core'
break
case constants.NETID_DAI:
branch = 'dai'
break
default:
branch = 'core'
break
}
const branch = constants.NETWORKS[web3Config.netId].BRANCH
return new Promise((resolve, reject) => {
fetch(helpers.addressesURL(branch))
.then(response => {

View File

@ -23,26 +23,10 @@ function getABI(branch, contract) {
})
}
function getBranch(netId) {
switch (netId) {
case constants.NETID_SOKOL:
return 'sokol'
case constants.NETID_DAI_TEST:
return 'dai-test'
case constants.NETID_CORE:
return 'core'
case constants.NETID_DAI:
return 'dai'
default:
return 'core'
}
}
const helpers = {
addressesURL,
ABIURL,
getABI,
getBranch
getABI
}
export default helpers

View File

@ -1,119 +1,94 @@
import Web3 from 'web3'
import { netIdByName } from './helpers'
import { constants } from './constants'
const POA_CORE = { RPC_URL: 'https://core.poa.network', netIdName: 'CORE', netId: constants.NETID_CORE }
const POA_SOKOL = { RPC_URL: 'https://sokol.poa.network', netIdName: 'SOKOL', netId: constants.NETID_SOKOL }
const POA_DAI = { RPC_URL: 'https://dai.poa.network', netIdName: 'DAI', netId: constants.NETID_DAI }
const POA_DAI_TEST = { RPC_URL: 'https://dai-test.poa.network', netIdName: 'DAI-TEST', netId: constants.NETID_DAI_TEST }
let getWeb3 = () => {
return new Promise(function(resolve, reject) {
// Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener('load', function() {
var results
var web3 = window.web3
window.addEventListener('load', async function() {
let web3 = null
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {
// Use Mist/MetaMask's provider.
var errorMsg = null
web3 = new window.Web3(web3.currentProvider)
web3.version.getNetwork((err, netId) => {
let netIdName
console.log('netId', netId)
switch (netId) {
case constants.NETID_DAI:
netIdName = 'Dai'
console.log('This is Dai', netId)
break
case constants.NETID_CORE:
netIdName = 'Core'
console.log('This is Core', netId)
break
case constants.NETID_DAI_TEST:
netIdName = 'Dai-Test'
console.log('This is Dai-Test', netId)
break
case constants.NETID_SOKOL:
netIdName = 'Sokol'
console.log('This is Sokol', netId)
break
default:
netIdName = 'ERROR'
errorMsg = `You aren't connected to POA Network.
Please, switch to POA network and refresh the page.
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.`
console.log('This is an unknown network.', netId)
}
document.title = `${netIdName} - POA Validators dApp`
var defaultAccount = web3.eth.defaultAccount || null
if (errorMsg !== null) {
reject({ message: errorMsg })
}
results = {
web3Instance: web3,
netIdName,
netId,
injectedWeb3: true,
defaultAccount
}
resolve(results)
})
if (window.ethereum) {
web3 = new Web3(window.ethereum)
console.log('Injected web3 detected.')
try {
await window.ethereum.enable()
} catch (e) {
reject({ message: 'You have denied access to your accounts' })
return
}
} else if (window.web3) {
web3 = new Web3(window.web3.currentProvider)
console.log('Injected web3 detected.')
}
let errorMsg = null
let netIdName
let netId
let injectedWeb3 = web3 !== null
let defaultAccount = null
if (web3) {
netId = await web3.eth.net.getId()
console.log('netId', netId)
if (!(netId in constants.NETWORKS)) {
netIdName = 'ERROR'
errorMsg = `You aren't connected to POA Network.
Please, switch to POA Network and refresh the page.
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>Wiki</a> for more info.`
console.log('This is an unknown network.')
} else {
netIdName = constants.NETWORKS[netId].NAME
console.log(`This is ${netIdName}`)
}
const accounts = await web3.eth.getAccounts()
defaultAccount = accounts[0] || null
} else {
// Fallback to localhost if no web3 injection.
let network
if (window.location.host.indexOf('sokol') !== -1) {
network = POA_SOKOL
} else if (window.location.host.indexOf('dai-test') !== -1) {
network = POA_DAI_TEST
} else if (window.location.host.indexOf('dai') !== -1) {
network = POA_DAI
} else {
network = POA_CORE
}
document.title = `${network.netIdName} - POA validators dApp`
const provider = new Web3.providers.HttpProvider(network.RPC_URL)
let web3 = new Web3(provider)
results = {
web3Instance: web3,
netIdName: network.netIdName,
netId: network.netId,
injectedWeb3: false,
defaultAccount: null
}
resolve(results)
console.log('No web3 instance injected, using Local web3.')
console.error('Metamask not found')
if (window.location.host.indexOf('sokol') !== -1) {
netId = netIdByName('sokol')
} else if (window.location.host.indexOf('dai-test') !== -1) {
netId = netIdByName('dai-test')
} else if (window.location.host.indexOf('dai') !== -1) {
netId = netIdByName('dai')
} else {
netId = netIdByName('core')
}
const network = constants.NETWORKS[netId]
web3 = new Web3(new Web3.providers.HttpProvider(network.RPC))
netIdName = network.NAME
}
document.title = `${netIdName} - POA Validators DApp`
if (errorMsg !== null) {
reject({ message: errorMsg })
return
}
resolve({
web3Instance: web3,
netId,
netIdName,
injectedWeb3,
defaultAccount
})
})
})
}
const setWeb3 = netId => {
let network
switch (netId) {
case constants.NETID_SOKOL:
network = POA_SOKOL
break
case constants.NETID_DAI_TEST:
network = POA_DAI_TEST
break
case constants.NETID_CORE:
network = POA_CORE
break
case constants.NETID_DAI:
network = POA_DAI
break
default:
network = POA_CORE
break
}
const provider = new Web3.providers.HttpProvider(network.RPC_URL)
const provider = new Web3.providers.HttpProvider(constants.NETWORKS[netId].RPC)
return new Web3(provider)
}

View File

@ -11,11 +11,17 @@ function generateAlert(icon, title, msg) {
})
}
function isTestnet(netId) {
return netId === constants.NETID_SOKOL || netId === constants.NETID_DAI_TEST
function netIdByName(netName) {
const netNameLowerCase = netName.toLowerCase()
for (let netId in constants.NETWORKS) {
if (constants.NETWORKS[netId].NAME.toLowerCase() === netNameLowerCase) {
return netId
}
}
return null
}
module.exports = {
generateAlert,
isTestnet
netIdByName
}

View File

@ -75,38 +75,15 @@ class AppMainRouter extends Component {
})
.then(async config => {
const { web3Config, addresses } = config
const keysManager = new KeysManager()
await keysManager.init({
await this.initContracts({
web3: web3Config.web3Instance,
netId: web3Config.netId,
addresses
})
const metadataContract = new Metadata()
await metadataContract.init({
web3: web3Config.web3Instance,
netId: web3Config.netId,
addresses
})
let proofOfPhysicalAddressContract = new ProofOfPhysicalAddress()
try {
await proofOfPhysicalAddressContract.init({
web3: web3Config.web3Instance,
netId: web3Config.netId,
addresses
})
} catch (e) {
console.error('Error initializing ProofOfPhysicalAddress', e)
proofOfPhysicalAddressContract = null
}
this.setState({
votingKey: web3Config.defaultAccount,
miningKey: await keysManager.miningKeyByVoting(web3Config.defaultAccount),
keysManager,
metadataContract,
proofOfPhysicalAddressContract,
loading: false,
injectedWeb3: web3Config.injectedWeb3,
netId: web3Config.netId
miningKey: await this.state.keysManager.miningKeyByVoting(web3Config.defaultAccount),
injectedWeb3: web3Config.injectedWeb3
})
})
.catch(error => {
@ -115,6 +92,38 @@ class AppMainRouter extends Component {
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
}
this.setState({
keysManager,
metadataContract,
proofOfPhysicalAddressContract,
loading: false,
netId
})
}
onRouteChange() {
const setMetadata = baseRootPath + '/set'
@ -215,37 +224,27 @@ class AppMainRouter extends Component {
)
}
getNetIdClass() {
const netId = this.state.netId
return netId === constants.NETID_SOKOL || netId === constants.NETID_DAI_TEST ? 'sokol' : ''
const { netId } = this.state
if (netId in constants.NETWORKS) {
return constants.NETWORKS[netId].TESTNET ? 'sokol' : ''
}
return ''
}
onSearch(term) {
this.setState({ searchTerm: term.target.value.toLowerCase() })
}
async onNetworkChange(e) {
this.setState({ loading: true })
const netId = e.value
const web3 = setWeb3(netId)
networkAddresses({ netId }).then(async config => {
const { addresses } = config
const keysManager = new KeysManager()
await keysManager.init({
web3,
netId,
addresses
})
const metadataContract = new Metadata()
await metadataContract.init({
web3,
netId,
addresses
})
this.setState({ netId: e.value, keysManager, metadataContract })
await this.initContracts({ web3, netId, addresses })
})
}
render() {
console.log('v2.09')
const search = this.state.showSearch ? (
<div className={`search-container ${this.getNetIdClass()}`}>
<div className="container">