From 64c8b107a4283036a219b820f7f56abc5fd9dbf5 Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Wed, 3 Jan 2018 19:34:22 -0800 Subject: [PATCH 1/6] add dropdown to select mining key, add limits --- src/components/BallotKeysMetadata.jsx | 12 +++++-- src/components/NewBallot.jsx | 18 +++++----- src/contracts/VotingToChangeKeys.contract.js | 14 ++++++++ .../VotingToChangeMinThreshold.contract.js | 14 ++++++++ src/contracts/VotingToChangeProxy.contract.js | 14 ++++++++ src/index.js | 6 ++-- src/stores/BallotStore.js | 14 +++++--- src/stores/ContractsStore.js | 34 +++++++++++++++---- 8 files changed, 102 insertions(+), 24 deletions(-) diff --git a/src/components/BallotKeysMetadata.jsx b/src/components/BallotKeysMetadata.jsx index 0fdf94d..2438ff2 100644 --- a/src/components/BallotKeysMetadata.jsx +++ b/src/components/BallotKeysMetadata.jsx @@ -1,10 +1,13 @@ import React from 'react'; import { inject, observer } from "mobx-react"; +import Select from 'react-select'; +import 'react-select/dist/react-select.css'; -@inject("ballotStore") +@inject("ballotStore", "contractsStore") @observer export class BallotKeysMetadata extends React.Component { render() { + const options = this.props.contractsStore.validatorsMetadata.slice(); const { ballotStore } = this.props; return (
@@ -24,9 +27,12 @@ export class BallotKeysMetadata extends React.Component {
- ballotStore.changeBallotMetadata(e, "miningKey", "ballotKeys")} + onChange={ballotStore.setMiningKey} + options={options} />

Mining key address of validator to vote for. Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee. diff --git a/src/components/NewBallot.jsx b/src/components/NewBallot.jsx index 8a52aef..82a804a 100644 --- a/src/components/NewBallot.jsx +++ b/src/components/NewBallot.jsx @@ -53,7 +53,6 @@ export class NewBallot extends React.Component { commonStore.hideLoading(); return false; } - let isMiningKeyAddress = contractsStore.web3Instance.isAddress(ballotStore.ballotKeys.miningKey); if (!isMiningKeyAddress) { @@ -102,10 +101,9 @@ export class NewBallot extends React.Component { ballotStore.ballotKeys.affectedKey, ballotStore.ballotKeys.keyType, ballotStore.ballotKeys.miningKey, - ballotStore.ballotType, + ballotStore.ballotKeys.keysBallotType, contractsStore.votingKey ]; - console.log(inputToMethod) let method = contractsStore.votingToChangeKeys.createVotingForKeys( ...inputToMethod ); @@ -120,7 +118,6 @@ export class NewBallot extends React.Component { ballotStore.ballotMinThreshold.proposedValue, contractsStore.votingKey ]; - console.log(inputToMethod) let method = contractsStore.votingToChangeMinThreshold.createBallotToChangeThreshold( ...inputToMethod ); @@ -189,7 +186,7 @@ export class NewBallot extends React.Component { let validator = ballotStore.isNewValidatorPersonalData ? : ""; let keysTypes = ballotStore.isBallotForKey ? : ""; let metadata - let minThreshold + let minThreshold = 0; switch (ballotStore.ballotType) { case ballotStore.BallotType.keys: metadata = ; @@ -218,7 +215,7 @@ export class NewBallot extends React.Component { checked={ballotStore.isBallotForKey} onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.keys)} /> - +

Ballot to add, remove or swap any type of key for existing or new validators.

@@ -231,7 +228,7 @@ export class NewBallot extends React.Component { checked={ballotStore.isBallotForMinThreshold} onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.minThreshold)} /> - +

Ballot to change the minimum threshold for consensus to vote for keys.

@@ -244,7 +241,7 @@ export class NewBallot extends React.Component { checked={ballotStore.isBallotForProxy} onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.proxy)} /> - +

Ballot to change one of the proxy contracts.

@@ -257,7 +254,10 @@ export class NewBallot extends React.Component { {metadata}
- Minimum {minThreshold} from {contractsStore.validatorsLength} validators required to pass the proposal + Minimum {minThreshold} from {contractsStore.validatorsLength} validators required to pass the proposal
+ You can create {contractsStore.validatorLimits.keys} ballot for keys
+ You can create {contractsStore.validatorLimits.minThreshold} ballot for consensus
+ You can create {contractsStore.validatorLimits.proxy} ballot for proxy
diff --git a/src/contracts/VotingToChangeKeys.contract.js b/src/contracts/VotingToChangeKeys.contract.js index 9aee8da..62cfd6c 100644 --- a/src/contracts/VotingToChangeKeys.contract.js +++ b/src/contracts/VotingToChangeKeys.contract.js @@ -68,4 +68,18 @@ export default class VotingToChangeKeys { getAffectedKey(_id) { return this.votingToChangeKeysInstance.methods.getAffectedKey(_id).call(); } + + getMiningByVotingKey(_votingKey) { + return this.votingToChangeKeysInstance.methods.getMiningByVotingKey(_votingKey).call(); + } + + async getValidatorActiveBallots(_votingKey) { + const miningKey = await this.getMiningByVotingKey(_votingKey); + return await this.votingToChangeKeysInstance.methods.validatorActiveBallots(miningKey).call(); + } + + async getBallotLimit(_votingKey) { + const currentLimit = await this.votingToChangeKeysInstance.methods.getBallotLimitPerValidator().call(); + return currentLimit - await this.getValidatorActiveBallots(_votingKey) + } } diff --git a/src/contracts/VotingToChangeMinThreshold.contract.js b/src/contracts/VotingToChangeMinThreshold.contract.js index 738199f..4742b21 100644 --- a/src/contracts/VotingToChangeMinThreshold.contract.js +++ b/src/contracts/VotingToChangeMinThreshold.contract.js @@ -60,4 +60,18 @@ export default class VotingToChangeMinThreshold { getProposedValue(_id) { return this.votingToChangeMinThresholdInstance.methods.getProposedValue(_id).call(); } + + getMiningByVotingKey(_votingKey) { + return this.votingToChangeMinThresholdInstance.methods.getMiningByVotingKey(_votingKey).call(); + } + + async getValidatorActiveBallots(_votingKey) { + const miningKey = await this.getMiningByVotingKey(_votingKey); + return await this.votingToChangeMinThresholdInstance.methods.validatorActiveBallots(miningKey).call(); + } + + async getBallotLimit(_votingKey) { + const currentLimit = await this.votingToChangeMinThresholdInstance.methods.getBallotLimitPerValidator().call(); + return currentLimit - await this.getValidatorActiveBallots(_votingKey) + } } diff --git a/src/contracts/VotingToChangeProxy.contract.js b/src/contracts/VotingToChangeProxy.contract.js index f6e21c2..f8cdbff 100644 --- a/src/contracts/VotingToChangeProxy.contract.js +++ b/src/contracts/VotingToChangeProxy.contract.js @@ -64,4 +64,18 @@ export default class VotingToChangeProxy { getContractType(_id) { return this.votingToChangeProxyInstance.methods.getContractType(_id).call(); } + + getMiningByVotingKey(_votingKey) { + return this.votingToChangeProxyInstance.methods.getMiningByVotingKey(_votingKey).call(); + } + + async getValidatorActiveBallots(_votingKey) { + const miningKey = await this.getMiningByVotingKey(_votingKey); + return await this.votingToChangeProxyInstance.methods.validatorActiveBallots(miningKey).call(); + } + + async getBallotLimit(_votingKey) { + const currentLimit = await this.votingToChangeProxyInstance.methods.getBallotLimitPerValidator().call(); + return currentLimit - await this.getValidatorActiveBallots(_votingKey) + } } \ No newline at end of file diff --git a/src/index.js b/src/index.js index 4f55981..37ac1f0 100644 --- a/src/index.js +++ b/src/index.js @@ -28,10 +28,10 @@ class AppMainRouter extends Component { getWeb3().then(async (web3Config) => { contractsStore.setWeb3Instance(web3Config); - await contractsStore.setPoaConsensus(web3Config); + contractsStore.setPoaConsensus(web3Config); contractsStore.setBallotsStorage(web3Config); contractsStore.getValidatorsLength(); - await contractsStore.getKeysBallotThreshold(); + contractsStore.getKeysBallotThreshold(); contractsStore.getMinThresholdBallotThreshold(); contractsStore.getProxyBallotThreshold(); contractsStore.setVotingToChangeKeys(web3Config); @@ -43,6 +43,8 @@ class AppMainRouter extends Component { contractsStore.getAllMinThresholdBallots(); contractsStore.getAllProxyBallots(); await contractsStore.setMiningKey(web3Config); + contractsStore.getValidatorActiveBallots(); + contractsStore.getAllValidatorMetadata() console.log("votingKey", contractsStore.votingKey) console.log("miningKey", contractsStore.miningKey) }).catch((error) => { diff --git a/src/stores/BallotStore.js b/src/stores/BallotStore.js index fa74247..5942f81 100644 --- a/src/stores/BallotStore.js +++ b/src/stores/BallotStore.js @@ -1,4 +1,4 @@ -import { observable, computed, action } from 'mobx'; +import { observable, computed, action, toJS } from 'mobx'; import moment from 'moment'; class BallotStore { @@ -25,6 +25,7 @@ class BallotStore { 5: 'BallotsStorage' } @observable ballotType; + @observable keysBallotType; @observable endTime; @observable ballotKeys; @@ -33,12 +34,12 @@ class BallotStore { constructor() { - this.ballotType = this.BallotType.keys; + this.ballotType = null; this.endTime = ""; this.ballotKeys = { - keyType: this.KeyType.mining, - keysBallotType: this.KeysBallotType.add, + keyType: null, + keysBallotType: null, //memo: "", affectedKey: "", miningKey: "" @@ -128,6 +129,11 @@ class BallotStore { this[field] = newVal; console.log("ballot metadata", field, parent?this[parent][field]:this[field]) } + @action("change ballot metadata") + setMiningKey = (value) => { + this.ballotKeys.miningKey = value; + console.log("ballot mining key", toJS(value)) + } } const ballotStore = new BallotStore(); diff --git a/src/stores/ContractsStore.js b/src/stores/ContractsStore.js index a793e6b..4a6ed05 100644 --- a/src/stores/ContractsStore.js +++ b/src/stores/ContractsStore.js @@ -19,7 +19,7 @@ import "babel-polyfill"; class ContractsStore { @observable activeKeysBallotsIDs; - + @observable validatorLimits; @observable poaConsensus; @observable ballotsStorage; @observable votingToChangeKeys; @@ -33,15 +33,18 @@ class ContractsStore { @observable keysBallotThreshold; @observable minThresholdBallotThreshold; @observable proxyBallotThreshold; + @observable validatorLimits; + @observable validatorsMetadata; constructor() { this.votingKey = null; this.miningKey = null; this.activeKeysBallotsIDs = []; - + this.validatorsMetadata = []; + this.validatorLimits = {keys: null, minThreshold: null, proxy: null}; getWeb3().then(async (web3Config) => { - contractsStore.setWeb3Instance(web3Config); - }) + contractsStore.setWeb3Instance(web3Config); + }) } @computed get isValidVotingKey() { @@ -55,8 +58,8 @@ class ContractsStore { } @action("Get min threshold ballot threshold") - getMinThresholdBallotThreshold() { - this.minThresholdBallotThreshold = this.keysBallotThreshold; + async getMinThresholdBallotThreshold() { + this.minThresholdBallotThreshold = await this.ballotsStorage.ballotsStorageInstance.methods.getBallotThreshold(1).call(); } @action("get proxy ballot threshold") @@ -173,6 +176,25 @@ class ContractsStore { commonStore.hideLoading(); } } + @action + async getValidatorActiveBallots() { + if(this.web3Instance){ + await this.setVotingToChangeKeys({web3Instance: this.web3Instance}) + await this.setVotingToChangeMinThreshold({web3Instance: this.web3Instance}) + await this.setVotingToChangeProxy({web3Instance: this.web3Instance}) + this.validatorLimits.keys = await this.votingToChangeKeys.getBallotLimit(this.web3Instance.eth.defaultAccount); + this.validatorLimits.minThreshold = await this.votingToChangeMinThreshold.getBallotLimit(this.web3Instance.eth.defaultAccount); + this.validatorLimits.proxy = await this.votingToChangeProxy.getBallotLimit(this.web3Instance.eth.defaultAccount); + } + } + @action + async getAllValidatorMetadata() { + const keys = await this.poaConsensus.getValidators(); + keys.forEach(async (key) => { + const metadata = await this.validatorMetadata.getValidatorData({miningKey: key}) + this.validatorsMetadata.push({label: `${key} ${metadata.lastName}`, value: key}) + }) + } } const contractsStore = new ContractsStore(); From e47c4ec16d8fee3f9818f68a127e51401152eb36 Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Wed, 3 Jan 2018 20:51:10 -0800 Subject: [PATCH 2/6] (ESlint) fix styling issues --- src/components/BallotKeysMetadata.jsx | 6 +++--- src/contracts/VotingToChangeKeys.contract.js | 2 +- src/contracts/VotingToChangeMinThreshold.contract.js | 2 +- src/contracts/VotingToChangeProxy.contract.js | 2 +- src/index.js | 6 +++--- src/stores/BallotStore.js | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/BallotKeysMetadata.jsx b/src/components/BallotKeysMetadata.jsx index 2438ff2..9468d19 100644 --- a/src/components/BallotKeysMetadata.jsx +++ b/src/components/BallotKeysMetadata.jsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React from "react"; import { inject, observer } from "mobx-react"; -import Select from 'react-select'; -import 'react-select/dist/react-select.css'; +import Select from "react-select"; +import "react-select/dist/react-select.css"; @inject("ballotStore", "contractsStore") @observer diff --git a/src/contracts/VotingToChangeKeys.contract.js b/src/contracts/VotingToChangeKeys.contract.js index 62cfd6c..1cea1a4 100644 --- a/src/contracts/VotingToChangeKeys.contract.js +++ b/src/contracts/VotingToChangeKeys.contract.js @@ -80,6 +80,6 @@ export default class VotingToChangeKeys { async getBallotLimit(_votingKey) { const currentLimit = await this.votingToChangeKeysInstance.methods.getBallotLimitPerValidator().call(); - return currentLimit - await this.getValidatorActiveBallots(_votingKey) + return currentLimit - await this.getValidatorActiveBallots(_votingKey); } } diff --git a/src/contracts/VotingToChangeMinThreshold.contract.js b/src/contracts/VotingToChangeMinThreshold.contract.js index 4742b21..acf8fe3 100644 --- a/src/contracts/VotingToChangeMinThreshold.contract.js +++ b/src/contracts/VotingToChangeMinThreshold.contract.js @@ -72,6 +72,6 @@ export default class VotingToChangeMinThreshold { async getBallotLimit(_votingKey) { const currentLimit = await this.votingToChangeMinThresholdInstance.methods.getBallotLimitPerValidator().call(); - return currentLimit - await this.getValidatorActiveBallots(_votingKey) + return currentLimit - await this.getValidatorActiveBallots(_votingKey); } } diff --git a/src/contracts/VotingToChangeProxy.contract.js b/src/contracts/VotingToChangeProxy.contract.js index f8cdbff..d022ce2 100644 --- a/src/contracts/VotingToChangeProxy.contract.js +++ b/src/contracts/VotingToChangeProxy.contract.js @@ -76,6 +76,6 @@ export default class VotingToChangeProxy { async getBallotLimit(_votingKey) { const currentLimit = await this.votingToChangeProxyInstance.methods.getBallotLimitPerValidator().call(); - return currentLimit - await this.getValidatorActiveBallots(_votingKey) + return currentLimit - await this.getValidatorActiveBallots(_votingKey); } } \ No newline at end of file diff --git a/src/index.js b/src/index.js index 37ac1f0..9a0f247 100644 --- a/src/index.js +++ b/src/index.js @@ -44,9 +44,9 @@ class AppMainRouter extends Component { contractsStore.getAllProxyBallots(); await contractsStore.setMiningKey(web3Config); contractsStore.getValidatorActiveBallots(); - contractsStore.getAllValidatorMetadata() - console.log("votingKey", contractsStore.votingKey) - console.log("miningKey", contractsStore.miningKey) + contractsStore.getAllValidatorMetadata(); + console.log("votingKey", contractsStore.votingKey); + console.log("miningKey", contractsStore.miningKey); }).catch((error) => { commonStore.hideLoading(); swal({ diff --git a/src/stores/BallotStore.js b/src/stores/BallotStore.js index 5942f81..ccf7e33 100644 --- a/src/stores/BallotStore.js +++ b/src/stores/BallotStore.js @@ -127,12 +127,12 @@ class BallotStore { this[parent][field] = newVal; else this[field] = newVal; - console.log("ballot metadata", field, parent?this[parent][field]:this[field]) + console.log("ballot metadata", field, parent?this[parent][field]:this[field]); } @action("change ballot metadata") setMiningKey = (value) => { this.ballotKeys.miningKey = value; - console.log("ballot mining key", toJS(value)) + console.log("ballot mining key", toJS(value)); } } From eaf6aad01d67d0e57b7b42cbf82757fbece1b34b Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Thu, 4 Jan 2018 13:12:23 -0800 Subject: [PATCH 3/6] (Fix) #51. Load Addresses dynamically based on Chain Id --- src/contracts/BallotsStorage.contract.js | 11 +++--- src/contracts/PoaConsensus.contract.js | 13 +++---- src/contracts/ValidatorMetadata.contract.js | 14 +++---- src/contracts/VotingToChangeKeys.contract.js | 15 ++++---- .../VotingToChangeMinThreshold.contract.js | 13 +++---- src/contracts/VotingToChangeProxy.contract.js | 13 +++---- src/contracts/addresses.js | 38 +++++++++++++++++-- src/getWeb3.js | 1 + src/index.js | 16 ++++---- src/stores/ContractsStore.js | 27 ++++++++----- 10 files changed, 97 insertions(+), 64 deletions(-) diff --git a/src/contracts/BallotsStorage.contract.js b/src/contracts/BallotsStorage.contract.js index 61832ba..c4fe799 100644 --- a/src/contracts/BallotsStorage.contract.js +++ b/src/contracts/BallotsStorage.contract.js @@ -1,13 +1,12 @@ import ballotsStorageAbi from './ballotsStorage.abi.json' import Web3 from 'web3'; -import {BALLOTS_STORAGE_ADDRESS} from './addresses'; +import networkAddresses from './addresses'; -console.log('Ballots Storage Address ' , BALLOTS_STORAGE_ADDRESS) export default class POAConsensus { - constructor(){ - if(window.web3.currentProvider){ - let web3_10 = new Web3(window.web3.currentProvider); + constructor({web3, netId}){ + const {BALLOTS_STORAGE_ADDRESS} = networkAddresses(netId); + console.log('Ballots Storage Address ' , BALLOTS_STORAGE_ADDRESS); + let web3_10 = new Web3(web3.currentProvider); this.ballotsStorageInstance = new web3_10.eth.Contract(ballotsStorageAbi, BALLOTS_STORAGE_ADDRESS); - } } } \ No newline at end of file diff --git a/src/contracts/PoaConsensus.contract.js b/src/contracts/PoaConsensus.contract.js index 3316336..ec67642 100644 --- a/src/contracts/PoaConsensus.contract.js +++ b/src/contracts/PoaConsensus.contract.js @@ -1,14 +1,13 @@ import poaConsensusAbi from './poaConsensus.abi.json' import Web3 from 'web3'; -import {POA_ADDRESS} from './addresses'; +import networkAddresses from './addresses'; -console.log('POA Address ' , POA_ADDRESS) export default class POAConsensus { - constructor(){ - if(window.web3.currentProvider){ - let web3_10 = new Web3(window.web3.currentProvider); - this.poaInstance = new web3_10.eth.Contract(poaConsensusAbi, POA_ADDRESS); - } + constructor({web3, netId}){ + const {POA_ADDRESS} = networkAddresses(netId); + console.log('POA Address ' , POA_ADDRESS) + let web3_10 = new Web3(web3.currentProvider); + this.poaInstance = new web3_10.eth.Contract(poaConsensusAbi, POA_ADDRESS); } async getValidators(){ return await this.poaInstance.methods.getValidators().call(); diff --git a/src/contracts/ValidatorMetadata.contract.js b/src/contracts/ValidatorMetadata.contract.js index 271cfba..941daef 100644 --- a/src/contracts/ValidatorMetadata.contract.js +++ b/src/contracts/ValidatorMetadata.contract.js @@ -1,7 +1,7 @@ import MetadataAbi from './validatorMetadata.abi.json' import Web3 from 'web3'; import moment from 'moment'; -import {METADATA_ADDRESS} from './addresses'; +import networkAddresses from './addresses'; var toAscii = function(hex) { var str = '', i = 0, @@ -17,13 +17,13 @@ var toAscii = function(hex) { return str; }; -console.log('Metadata contract:', METADATA_ADDRESS) + export default class Metadata { - constructor(){ - if(window.web3.currentProvider){ - this.web3_10 = new Web3(window.web3.currentProvider); - this.metadataInstance = new this.web3_10.eth.Contract(MetadataAbi, METADATA_ADDRESS); - } + constructor({web3, netId}){ + const {METADATA_ADDRESS} = networkAddresses(netId); + console.log('Metadata contract:', METADATA_ADDRESS) + this.web3_10 = new Web3(web3.currentProvider); + this.metadataInstance = new this.web3_10.eth.Contract(MetadataAbi, METADATA_ADDRESS); } async getValidatorData({votingKey, miningKey}){ diff --git a/src/contracts/VotingToChangeKeys.contract.js b/src/contracts/VotingToChangeKeys.contract.js index 1cea1a4..6573d22 100644 --- a/src/contracts/VotingToChangeKeys.contract.js +++ b/src/contracts/VotingToChangeKeys.contract.js @@ -1,14 +1,13 @@ import votingToChangeKeysABI from './votingToChangeKeys.abi.json' import Web3 from 'web3'; -import {VOTING_TO_CHANGE_KEYS_ADDRESS} from './addresses' - -console.log('VotingToChangeKeys ', VOTING_TO_CHANGE_KEYS_ADDRESS) +import networkAddresses from './addresses'; + export default class VotingToChangeKeys { - constructor(){ - if(window.web3.currentProvider){ - let web3_10 = new Web3(window.web3.currentProvider); - this.votingToChangeKeysInstance = new web3_10.eth.Contract(votingToChangeKeysABI, VOTING_TO_CHANGE_KEYS_ADDRESS); - } + constructor({web3, netId}){ + const {VOTING_TO_CHANGE_KEYS_ADDRESS} = networkAddresses(netId); + console.log('VotingToChangeKeys ', VOTING_TO_CHANGE_KEYS_ADDRESS); + let web3_10 = new Web3(web3.currentProvider); + this.votingToChangeKeysInstance = new web3_10.eth.Contract(votingToChangeKeysABI, VOTING_TO_CHANGE_KEYS_ADDRESS); } //setters diff --git a/src/contracts/VotingToChangeMinThreshold.contract.js b/src/contracts/VotingToChangeMinThreshold.contract.js index acf8fe3..b850668 100644 --- a/src/contracts/VotingToChangeMinThreshold.contract.js +++ b/src/contracts/VotingToChangeMinThreshold.contract.js @@ -1,14 +1,13 @@ import votingToChangeMinThresholdABI from './votingToChangeMinThreshold.abi.json' import Web3 from 'web3'; -import {VOTING_TO_CHANGE_MIN_THRESHOLD} from './addresses' +import networkAddresses from './addresses'; -console.log('VotingToChangeMinThreshold ', VOTING_TO_CHANGE_MIN_THRESHOLD) export default class VotingToChangeMinThreshold { - constructor(){ - if(window.web3.currentProvider){ - let web3_10 = new Web3(window.web3.currentProvider); - this.votingToChangeMinThresholdInstance = new web3_10.eth.Contract(votingToChangeMinThresholdABI, VOTING_TO_CHANGE_MIN_THRESHOLD); - } + constructor({web3, netId}){ + const {VOTING_TO_CHANGE_MIN_THRESHOLD} = networkAddresses(netId); + let web3_10 = new Web3(web3.currentProvider); + console.log('VotingToChangeMinThreshold ', VOTING_TO_CHANGE_MIN_THRESHOLD) + this.votingToChangeMinThresholdInstance = new web3_10.eth.Contract(votingToChangeMinThresholdABI, VOTING_TO_CHANGE_MIN_THRESHOLD); } //setters diff --git a/src/contracts/VotingToChangeProxy.contract.js b/src/contracts/VotingToChangeProxy.contract.js index d022ce2..4d335d6 100644 --- a/src/contracts/VotingToChangeProxy.contract.js +++ b/src/contracts/VotingToChangeProxy.contract.js @@ -1,14 +1,13 @@ import votingToChangeProxyABI from './votingToChangeProxy.abi.json' import Web3 from 'web3'; -import {VOTING_TO_CHANGE_PROXY} from './addresses' +import networkAddresses from './addresses'; -console.log('VotingToChangeProxy ', VOTING_TO_CHANGE_PROXY) export default class VotingToChangeProxy { - constructor(){ - if(window.web3.currentProvider){ - let web3_10 = new Web3(window.web3.currentProvider); - this.votingToChangeProxyInstance = new web3_10.eth.Contract(votingToChangeProxyABI, VOTING_TO_CHANGE_PROXY); - } + constructor({web3, netId}){ + const {VOTING_TO_CHANGE_PROXY} = networkAddresses(netId); + console.log('VotingToChangeProxy ', VOTING_TO_CHANGE_PROXY) + let web3_10 = new Web3(web3.currentProvider); + this.votingToChangeProxyInstance = new web3_10.eth.Contract(votingToChangeProxyABI, VOTING_TO_CHANGE_PROXY); } //setters diff --git a/src/contracts/addresses.js b/src/contracts/addresses.js index 4998436..e753870 100644 --- a/src/contracts/addresses.js +++ b/src/contracts/addresses.js @@ -1,8 +1,38 @@ -module.exports = { - VOTING_TO_CHANGE_KEYS_ADDRESS: '0x49df4ec19243263e5db22da5865b4f482b8323a0', +const local = { + VOTING_TO_CHANGE_KEYS_ADDRESS: '0x758492834ed6454f41d6d3d6b73d6e46d4555429', + VOTING_TO_CHANGE_MIN_THRESHOLD: '0xcbf043db3498b5064bd62341be0c0e3fb0344b1b', + VOTING_TO_CHANGE_PROXY: '0xcb3f870269a3f7215eb87d9548ee5b7eff6396dd', + BALLOTS_STORAGE_ADDRESS: '0x144947d78b932ea0dff14d75e1f7cd1b2f131426', + METADATA_ADDRESS: '0x3111c94b9243a8a99d5a867e00609900e437e2c0', + POA_ADDRESS: '0xf472e0e43570b9afaab67089615080cf7c20018d', +} + +const CORE_ADDRESSES = { + VOTING_TO_CHANGE_KEYS_ADDRESS: '0x49df4ec19243263e5db22da5865b4f482b8323a0', VOTING_TO_CHANGE_MIN_THRESHOLD: '0x8829ebe113535826e8af17ed51f83755f675789a', VOTING_TO_CHANGE_PROXY: '0x6b728399b41a38d4109f7af2213d4cc31ca87812', + BALLOTS_STORAGE_ADDRESS: '0x0d7590c7aedf1e7e85fc9a1ee88f6f17d3ba762f', METADATA_ADDRESS: '0xcBB2912666c7e8023B7ec78B6842702eB26336aC', POA_ADDRESS: '0x8bf38d4764929064f2d4d3a56520a76ab3df415b', - BALLOTS_STORAGE_ADDRESS: '0x0d7590c7aedf1e7e85fc9a1ee88f6f17d3ba762f' -} \ No newline at end of file +} + +const SOKOL_ADDRESSES = { + VOTING_TO_CHANGE_KEYS_ADDRESS: '0x145a3d3bd5db8a0ad863b4949b6088d133726cdb', + VOTING_TO_CHANGE_MIN_THRESHOLD: '0xad623f870298774765bc5e56ebeafac721028867', + VOTING_TO_CHANGE_PROXY: '0x6fb85b2030a68a76ab237d2392b09e28e6f03fa9', + BALLOTS_STORAGE_ADDRESS: '0x1e0eaa06d02f965be2dfe0bc9ff52b2d82133461', + METADATA_ADDRESS: '0xce9ff1123223d13672cce06dd073d3749764daa6', + POA_ADDRESS: '0x8bf38d4764929064f2d4d3a56520a76ab3df415b', +} + +module.exports = (netId) => { + switch (netId) { + case '77': + return SOKOL_ADDRESSES + case '99': + return local + default: + return local + } +} + diff --git a/src/getWeb3.js b/src/getWeb3.js index 836a0d2..fef21e1 100644 --- a/src/getWeb3.js +++ b/src/getWeb3.js @@ -29,6 +29,7 @@ let getWeb3 = () => { errorMsg = constants.WRONG_NETWORK_MSG console.log('This is an unknown network.', netId) } + document.title = `${netIdName} - POA governance dApp` var defaultAccount = web3.eth.defaultAccount || null; if(defaultAccount === null){ reject({message: constants.NO_METAMASK_MSG}) diff --git a/src/index.js b/src/index.js index 9a0f247..a1a7752 100644 --- a/src/index.js +++ b/src/index.js @@ -27,21 +27,21 @@ class AppMainRouter extends Component { commonStore.showLoading(); getWeb3().then(async (web3Config) => { - contractsStore.setWeb3Instance(web3Config); - contractsStore.setPoaConsensus(web3Config); - contractsStore.setBallotsStorage(web3Config); + await contractsStore.setWeb3Instance(web3Config); + await contractsStore.setPoaConsensus(web3Config); + await contractsStore.setBallotsStorage(web3Config); + await contractsStore.setVotingToChangeKeys(web3Config); + await contractsStore.setVotingToChangeMinThreshold(web3Config); + await contractsStore.setVotingToChangeProxy(web3Config); + await contractsStore.setValidatorMetadata(web3Config); contractsStore.getValidatorsLength(); contractsStore.getKeysBallotThreshold(); contractsStore.getMinThresholdBallotThreshold(); contractsStore.getProxyBallotThreshold(); - contractsStore.setVotingToChangeKeys(web3Config); - contractsStore.setVotingToChangeMinThreshold(web3Config); - contractsStore.setVotingToChangeProxy(web3Config); - contractsStore.setValidatorMetadata(web3Config); - contractsStore.setVotingKey(web3Config); contractsStore.getAllKeysBallots(); contractsStore.getAllMinThresholdBallots(); contractsStore.getAllProxyBallots(); + contractsStore.setVotingKey(web3Config); await contractsStore.setMiningKey(web3Config); contractsStore.getValidatorActiveBallots(); contractsStore.getAllValidatorMetadata(); diff --git a/src/stores/ContractsStore.js b/src/stores/ContractsStore.js index 4a6ed05..f5dc67c 100644 --- a/src/stores/ContractsStore.js +++ b/src/stores/ContractsStore.js @@ -70,47 +70,54 @@ class ContractsStore { @action("Set web3Instance") setWeb3Instance = (web3Config) => { this.web3Instance = web3Config.web3Instance; + this.netId = web3Config.netId; } @action("Set PoA Consensus contract") setPoaConsensus = (web3Config) => { this.poaConsensus = new PoaConsensus({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @action("Set Ballots Storage contract") setBallotsStorage = (web3Config) => { this.ballotsStorage = new BallotsStorage({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @action("Set VotingToChangeKeys contract") setVotingToChangeKeys = (web3Config) => { this.votingToChangeKeys = new VotingToChangeKeys({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @action("Set VotingToChangeMinThreshold contract") setVotingToChangeMinThreshold = (web3Config) => { this.votingToChangeMinThreshold = new VotingToChangeMinThreshold({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @action("Set VotingToChangeProxy contract") setVotingToChangeProxy = (web3Config) => { this.votingToChangeProxy = new VotingToChangeProxy({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @action("Set ValidatorMetadata contract") setValidatorMetadata = (web3Config) => { this.validatorMetadata = new ValidatorMetadata({ - web3: web3Config.web3Instance + web3: web3Config.web3Instance, + netId: web3Config.netId }); } @@ -178,10 +185,10 @@ class ContractsStore { } @action async getValidatorActiveBallots() { - if(this.web3Instance){ - await this.setVotingToChangeKeys({web3Instance: this.web3Instance}) - await this.setVotingToChangeMinThreshold({web3Instance: this.web3Instance}) - await this.setVotingToChangeProxy({web3Instance: this.web3Instance}) + if(this.web3Instance && this.netId){ + await this.setVotingToChangeKeys({web3Instance: this.web3Instance, netId: this.netId}) + await this.setVotingToChangeMinThreshold({web3Instance: this.web3Instance, netId: this.netId}) + await this.setVotingToChangeProxy({web3Instance: this.web3Instance, netId: this.netId}) this.validatorLimits.keys = await this.votingToChangeKeys.getBallotLimit(this.web3Instance.eth.defaultAccount); this.validatorLimits.minThreshold = await this.votingToChangeMinThreshold.getBallotLimit(this.web3Instance.eth.defaultAccount); this.validatorLimits.proxy = await this.votingToChangeProxy.getBallotLimit(this.web3Instance.eth.defaultAccount); From 2d7990e39e7dbcbf14fb8e4b24a65a29763eec7f Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Fri, 5 Jan 2018 12:36:25 -0800 Subject: [PATCH 4/6] Add card id + have live clockwatch --- jsconfig.json | 5 ++++ package-lock.json | 30 +++++++++++----------- src/App.js | 8 +++--- src/assets/App.css | 6 ++++- src/assets/stylesheets/ballots/footer.scss | 5 ++++ src/components/BallotKeysCard.jsx | 18 ++++++++++--- src/contracts/addresses.js | 20 +++++++-------- src/getWeb3.js | 2 +- src/stores/ContractsStore.js | 1 - 9 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 jsconfig.json diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..904df79 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "experimentalDecorators": true + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index df869e5..33e64fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4588,6 +4588,13 @@ } } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "string-width": { "version": "1.0.2", "bundled": true, @@ -4597,13 +4604,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -10293,6 +10293,14 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -10335,14 +10343,6 @@ "function-bind": "1.1.1" } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/src/App.js b/src/App.js index c9c5e63..2f2dd8a 100644 --- a/src/App.js +++ b/src/App.js @@ -38,9 +38,10 @@ class App extends Component { const { commonStore } = this.props; const currentPath = this.props.location.pathname; let showNavPan = - currentPath == `${commonStore.rootPath}` - || currentPath == `${commonStore.rootPath}/` - || currentPath == `${commonStore.rootPath}/active`; + currentPath === `${commonStore.rootPath}` + || currentPath === "/" + || currentPath === `${commonStore.rootPath}/` + || currentPath === `${commonStore.rootPath}/active`; return showNavPan; } @@ -61,6 +62,7 @@ class App extends Component { {loading}
{nav} + diff --git a/src/assets/App.css b/src/assets/App.css index e0c1473..ca1c1f7 100644 --- a/src/assets/App.css +++ b/src/assets/App.css @@ -772,7 +772,11 @@ button { .ballots-footer { display: flex; - align-items: center; } + align-items: center; + justify-content: space-between; } + .ballots-footer-left { + display: inline-flex; + align-items: center; } @media screen and (max-width: 768px) { .ballots-footer { padding-top: 20px; } } diff --git a/src/assets/stylesheets/ballots/footer.scss b/src/assets/stylesheets/ballots/footer.scss index 5832ddf..79fba9b 100644 --- a/src/assets/stylesheets/ballots/footer.scss +++ b/src/assets/stylesheets/ballots/footer.scss @@ -1,7 +1,12 @@ .ballots-footer { display: flex; align-items: center; + justify-content: space-between; + &-left { + display: inline-flex; + align-items: center; + } @media screen and (max-width: $tablet-width) { padding-top: $tablet-indent; } diff --git a/src/components/BallotKeysCard.jsx b/src/components/BallotKeysCard.jsx index dcf1b35..f81f1f3 100644 --- a/src/components/BallotKeysCard.jsx +++ b/src/components/BallotKeysCard.jsx @@ -1,6 +1,6 @@ import React from 'react'; import moment from 'moment'; -import { observable, action, computed } from "mobx"; +import { observable, action, computed, autorun } from "mobx"; import { inject, observer } from "mobx-react"; import { toAscii } from "../helpers"; import { constants } from "../constants"; @@ -265,6 +265,15 @@ export class BallotKeysCard extends React.Component { this.getProgress(); this.getIsFinalized(); } + componentDidMount() { + this.interval = setInterval(() => { + this.calcTimeToFinish() + }, 1000) + } + + componentWillUnmount() { + window.clearInterval(this.interval); + } hideCard = () => { let { commonStore } = this.props; @@ -360,8 +369,11 @@ export class BallotKeysCard extends React.Component {

- -

{constants.CARD_FINALIZE_DESCRIPTION}

+
+ +

{constants.CARD_FINALIZE_DESCRIPTION}

+
+
Ballot ID: {this.props.id}
); diff --git a/src/contracts/addresses.js b/src/contracts/addresses.js index e753870..91499bf 100644 --- a/src/contracts/addresses.js +++ b/src/contracts/addresses.js @@ -1,11 +1,11 @@ -const local = { - VOTING_TO_CHANGE_KEYS_ADDRESS: '0x758492834ed6454f41d6d3d6b73d6e46d4555429', - VOTING_TO_CHANGE_MIN_THRESHOLD: '0xcbf043db3498b5064bd62341be0c0e3fb0344b1b', - VOTING_TO_CHANGE_PROXY: '0xcb3f870269a3f7215eb87d9548ee5b7eff6396dd', - BALLOTS_STORAGE_ADDRESS: '0x144947d78b932ea0dff14d75e1f7cd1b2f131426', - METADATA_ADDRESS: '0x3111c94b9243a8a99d5a867e00609900e437e2c0', - POA_ADDRESS: '0xf472e0e43570b9afaab67089615080cf7c20018d', -} +// const local = { +// VOTING_TO_CHANGE_KEYS_ADDRESS: '0x758492834ed6454f41d6d3d6b73d6e46d4555429', +// VOTING_TO_CHANGE_MIN_THRESHOLD: '0xcbf043db3498b5064bd62341be0c0e3fb0344b1b', +// VOTING_TO_CHANGE_PROXY: '0xcb3f870269a3f7215eb87d9548ee5b7eff6396dd', +// BALLOTS_STORAGE_ADDRESS: '0x144947d78b932ea0dff14d75e1f7cd1b2f131426', +// METADATA_ADDRESS: '0x3111c94b9243a8a99d5a867e00609900e437e2c0', +// POA_ADDRESS: '0xf472e0e43570b9afaab67089615080cf7c20018d', +// } const CORE_ADDRESSES = { VOTING_TO_CHANGE_KEYS_ADDRESS: '0x49df4ec19243263e5db22da5865b4f482b8323a0', @@ -30,9 +30,9 @@ module.exports = (netId) => { case '77': return SOKOL_ADDRESSES case '99': - return local + return CORE_ADDRESSES default: - return local + return CORE_ADDRESSES } } diff --git a/src/getWeb3.js b/src/getWeb3.js index fef21e1..e899f40 100644 --- a/src/getWeb3.js +++ b/src/getWeb3.js @@ -29,7 +29,7 @@ let getWeb3 = () => { errorMsg = constants.WRONG_NETWORK_MSG console.log('This is an unknown network.', netId) } - document.title = `${netIdName} - POA governance dApp` + document.title = `${netIdName} - POA Network Governance DApp` var defaultAccount = web3.eth.defaultAccount || null; if(defaultAccount === null){ reject({message: constants.NO_METAMASK_MSG}) diff --git a/src/stores/ContractsStore.js b/src/stores/ContractsStore.js index f5dc67c..615e39f 100644 --- a/src/stores/ContractsStore.js +++ b/src/stores/ContractsStore.js @@ -19,7 +19,6 @@ import "babel-polyfill"; class ContractsStore { @observable activeKeysBallotsIDs; - @observable validatorLimits; @observable poaConsensus; @observable ballotsStorage; @observable votingToChangeKeys; From 8dacc1d7f64f8801b9737f94743583ece85ed470 Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Fri, 5 Jan 2018 13:10:19 -0800 Subject: [PATCH 5/6] fix the rest of card with correct passing of decision --- src/components/BallotKeysCard.jsx | 2 +- src/components/BallotMinThresholdCard.jsx | 39 +++++++++++++---------- src/components/BallotProxyCard.jsx | 39 +++++++++++++---------- src/index.js | 1 + 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/components/BallotKeysCard.jsx b/src/components/BallotKeysCard.jsx index f81f1f3..f7d92b1 100644 --- a/src/components/BallotKeysCard.jsx +++ b/src/components/BallotKeysCard.jsx @@ -373,7 +373,7 @@ export class BallotKeysCard extends React.Component {

{constants.CARD_FINALIZE_DESCRIPTION}

-
Ballot ID: {this.props.id}
+
Keys Ballot ID: {this.props.id}
); diff --git a/src/components/BallotMinThresholdCard.jsx b/src/components/BallotMinThresholdCard.jsx index 3c9ff0e..4a0848a 100644 --- a/src/components/BallotMinThresholdCard.jsx +++ b/src/components/BallotMinThresholdCard.jsx @@ -6,6 +6,8 @@ import { toAscii } from "../helpers"; import { constants } from "../constants"; import swal from 'sweetalert2'; +const ACCEPT = 1; +const REJECT = 2; @inject("commonStore", "contractsStore", "routing") @observer export class BallotMinThresholdCard extends React.Component { @@ -132,7 +134,7 @@ export class BallotMinThresholdCard extends React.Component { return isActive; } - vote = async (e, _type) => { + vote = async ({choice}) => { const { commonStore, contractsStore, id } = this.props; const { push } = this.props.routing; if (!contractsStore.isValidVotingKey) { @@ -146,7 +148,7 @@ export class BallotMinThresholdCard extends React.Component { swal("Warning!", constants.INVALID_VOTE_MSG, "warning"); return; } - contractsStore.votingToChangeMinThreshold.vote(id, _type, contractsStore.votingKey) + contractsStore.votingToChangeMinThreshold.vote(id, choice, contractsStore.votingKey) .on("receipt", () => { commonStore.hideLoading(); swal("Congratulations!", constants.VOTED_SUCCESS_MSG, "success").then((result) => { @@ -249,26 +251,26 @@ export class BallotMinThresholdCard extends React.Component {
- -
-

Yes

-

Votes: {this.votesForNumber}

-

{this.votesForPercents}%

-
-
-
-
-
-
+

No

Votes: {this.votesAgainstNumber}

{this.votesAgainstPercents}%

-
+
- +
+
+
+

Yes

+

Votes: {this.votesForNumber}

+

{this.votesForPercents}%

+
+
+
+
+
@@ -276,8 +278,11 @@ export class BallotMinThresholdCard extends React.Component {

- -

{constants.CARD_FINALIZE_DESCRIPTION}

+
+ +

{constants.CARD_FINALIZE_DESCRIPTION}

+
+
Consensus Ballot ID: {this.props.id}
); diff --git a/src/components/BallotProxyCard.jsx b/src/components/BallotProxyCard.jsx index 515d693..f0b959b 100644 --- a/src/components/BallotProxyCard.jsx +++ b/src/components/BallotProxyCard.jsx @@ -6,6 +6,8 @@ import { toAscii } from "../helpers"; import { constants } from "../constants"; import swal from 'sweetalert2'; +const ACCEPT = 1; +const REJECT = 2; @inject("commonStore", "contractsStore", "ballotStore", "routing") @observer export class BallotProxyCard extends React.Component { @@ -140,7 +142,7 @@ export class BallotProxyCard extends React.Component { return isActive; } - vote = async (e, _type) => { + vote = async ({choice}) => { const { commonStore, contractsStore, id } = this.props; const { push } = this.props.routing; if (!contractsStore.isValidVotingKey) { @@ -154,7 +156,7 @@ export class BallotProxyCard extends React.Component { swal("Warning!", constants.INVALID_VOTE_MSG, "warning"); return; } - contractsStore.votingToChangeProxy.vote(id, _type, contractsStore.votingKey) + contractsStore.votingToChangeProxy.vote(id, choice, contractsStore.votingKey) .on("receipt", () => { commonStore.hideLoading(); swal("Congratulations!", constants.VOTED_SUCCESS_MSG, "success").then((result) => { @@ -267,26 +269,26 @@ export class BallotProxyCard extends React.Component {
- -
-

Yes

-

Votes: {this.votesForNumber}

-

{this.votesForPercents}%

-
-
-
-
-
-
+

No

Votes: {this.votesAgainstNumber}

{this.votesAgainstPercents}%

-
+
- +
+
+
+

Yes

+

Votes: {this.votesForNumber}

+

{this.votesForPercents}%

+
+
+
+
+
@@ -294,8 +296,11 @@ export class BallotProxyCard extends React.Component {

- -

{constants.CARD_FINALIZE_DESCRIPTION}

+
+ +

{constants.CARD_FINALIZE_DESCRIPTION}

+
+
Proxy Ballot ID: {this.props.id}
); diff --git a/src/index.js b/src/index.js index a1a7752..c1ebccb 100644 --- a/src/index.js +++ b/src/index.js @@ -47,6 +47,7 @@ class AppMainRouter extends Component { contractsStore.getAllValidatorMetadata(); console.log("votingKey", contractsStore.votingKey); console.log("miningKey", contractsStore.miningKey); + commonStore.hideLoading(); }).catch((error) => { commonStore.hideLoading(); swal({ From 754c7ae9ee5647bdaa2086aefda4c19be2a195ed Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Fri, 5 Jan 2018 13:20:32 -0800 Subject: [PATCH 6/6] fix for netlify deployment --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2baa388..6603601 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "poa-dapps-voting", "version": "0.1.0", "private": true, - "homepage": "https://poanetwork.github.io/poa-dapps-voting", + "homepage": "https://poanetwork.github.io/", "dependencies": { "autoprefixer": "7.1.6", "babel-core": "6.26.0",