|
@ -1,2 +1,3 @@
|
|||
node_modules/
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
build/
|
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Oracles Network
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,396 +0,0 @@
|
|||
function attachToContract(web3, abi, addr) {
|
||||
web3.eth.defaultAccount = web3.eth.accounts[0];
|
||||
console.log("web3.eth.defaultAccount:" + web3.eth.defaultAccount);
|
||||
|
||||
let contractInstance = new web3.eth.Contract(abi, addr);
|
||||
|
||||
return contractInstance;
|
||||
}
|
||||
//check current network page is connected to. Alerts, if not Oracles network
|
||||
async function checkNetworkVersion(web3, cb) {
|
||||
var msgNotOracles = "You aren't connected to Oracles network. Please, switch on Oracles plugin and choose Oracles network. Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.";
|
||||
let config = await getConfig()
|
||||
web3.eth.net.getId().then(function(connectedNetworkID) {
|
||||
console.log("connectedNetworkID: " + connectedNetworkID);
|
||||
connectedNetworkID = parseInt(connectedNetworkID);
|
||||
switch (connectedNetworkID) {
|
||||
case 1: {
|
||||
console.log('This is mainnet');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case 2: {
|
||||
console.log('This is the deprecated Morden test network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case 3: {
|
||||
console.log('This is the ropsten test network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case config.networkID: {
|
||||
console.log('This is Oracles from Metamask');
|
||||
return true;
|
||||
} break;
|
||||
default: {
|
||||
console.log('This is an unknown network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
}
|
||||
})
|
||||
}
|
||||
function formatDate(date, format, utc) {
|
||||
//var MMMM = ["\x00", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
var MMMM = ["\x00", "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"];
|
||||
var MMM = ["\x01", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
var dddd = ["\x02", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
||||
var ddd = ["\x03", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
|
||||
function ii(i, len) {
|
||||
var s = i + "";
|
||||
len = len || 2;
|
||||
while (s.length < len) s = "0" + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
var y = utc ? date.getUTCFullYear() : date.getFullYear();
|
||||
format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
|
||||
format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
|
||||
format = format.replace(/(^|[^\\])y/g, "$1" + y);
|
||||
|
||||
var M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
|
||||
format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
|
||||
format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
|
||||
format = format.replace(/(^|[^\\])MM/g, "$1" + ii(M));
|
||||
format = format.replace(/(^|[^\\])M/g, "$1" + M);
|
||||
|
||||
var d = utc ? date.getUTCDate() : date.getDate();
|
||||
format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
|
||||
format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
|
||||
format = format.replace(/(^|[^\\])dd/g, "$1" + ii(d));
|
||||
format = format.replace(/(^|[^\\])d/g, "$1" + d);
|
||||
|
||||
var H = utc ? date.getUTCHours() : date.getHours();
|
||||
format = format.replace(/(^|[^\\])HH+/g, "$1" + ii(H));
|
||||
format = format.replace(/(^|[^\\])H/g, "$1" + H);
|
||||
|
||||
var h = H > 12 ? H - 12 : H == 0 ? 12 : H;
|
||||
format = format.replace(/(^|[^\\])hh+/g, "$1" + ii(h));
|
||||
format = format.replace(/(^|[^\\])h/g, "$1" + h);
|
||||
|
||||
var m = utc ? date.getUTCMinutes() : date.getMinutes();
|
||||
format = format.replace(/(^|[^\\])mm+/g, "$1" + ii(m));
|
||||
format = format.replace(/(^|[^\\])m/g, "$1" + m);
|
||||
|
||||
var s = utc ? date.getUTCSeconds() : date.getSeconds();
|
||||
format = format.replace(/(^|[^\\])ss+/g, "$1" + ii(s));
|
||||
format = format.replace(/(^|[^\\])s/g, "$1" + s);
|
||||
|
||||
var f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
|
||||
format = format.replace(/(^|[^\\])fff+/g, "$1" + ii(f, 3));
|
||||
f = Math.round(f / 10);
|
||||
format = format.replace(/(^|[^\\])ff/g, "$1" + ii(f));
|
||||
f = Math.round(f / 10);
|
||||
format = format.replace(/(^|[^\\])f/g, "$1" + f);
|
||||
|
||||
var T = H < 12 ? "AM" : "PM";
|
||||
format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
|
||||
format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));
|
||||
|
||||
var t = T.toLowerCase();
|
||||
format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
|
||||
format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));
|
||||
|
||||
var tz = -date.getTimezoneOffset();
|
||||
var K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
|
||||
if (!utc) {
|
||||
tz = Math.abs(tz);
|
||||
var tzHrs = Math.floor(tz / 60);
|
||||
var tzMin = tz % 60;
|
||||
K += ii(tzHrs) + ":" + ii(tzMin);
|
||||
}
|
||||
format = format.replace(/(^|[^\\])K/g, "$1" + K);
|
||||
|
||||
var day = (utc ? date.getUTCDay() : date.getDay()) + 1;
|
||||
format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
|
||||
format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);
|
||||
|
||||
format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
|
||||
format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);
|
||||
|
||||
format = format.replace(/\\(.)/g, "$1");
|
||||
|
||||
return format;
|
||||
};
|
||||
function filterValidators(searchInput, validators) {
|
||||
return validators.map(function(validator, i) {
|
||||
if (validator) {
|
||||
var searchValidated = validateSearch(validator, searchInput.toLowerCase());
|
||||
if (!searchValidated) return null;
|
||||
else return validator;
|
||||
} else return null;
|
||||
})
|
||||
}
|
||||
|
||||
function validateSearch(validator, searchInput) {
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
if (validatorAddress.indexOf(searchInput) > -1) return true;
|
||||
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
if (validatorPropsObj["fullName"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["streetName"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["zip"].toString().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["licenseID"].toString().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["state"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (formatDate(new Date(parseInt(validatorPropsObj["licenseExpiredAt"])*1000), "MM/dd/yyyy h:mmTT").toLowerCase().indexOf(searchInput) > -1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
//gets config file with address of Oracles contract
|
||||
async function getConfig(cb) {
|
||||
let config = await $.getJSON("./assets/javascripts/config.json")
|
||||
let contractAddress = config.Ethereum[config.environment].ValidatorsStorage.addr
|
||||
let abi = config.Ethereum[config.environment].ValidatorsStorage.abi
|
||||
let networkID = config.networkID
|
||||
let configJSON = {
|
||||
contractAddress,
|
||||
networkID,
|
||||
abi
|
||||
}
|
||||
if (cb) cb(configJSON)
|
||||
return configJSON;
|
||||
}
|
||||
function getValidators(web3, contractAddress, abi, disabled, cb) {
|
||||
let ValidatorsStorage = attachToContract(web3, abi, contractAddress)
|
||||
console.log("attach to oracles contract");
|
||||
if (!ValidatorsStorage) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
ValidatorsStorage.methods.getValidators().call(function(err, validatorsArray) {
|
||||
if (validatorsArray.length == 0) {
|
||||
return cb(validatorsArray);
|
||||
}
|
||||
|
||||
var validatorsArrayOut = [];
|
||||
var iasync = 0;
|
||||
var validatorDataCount = 6;
|
||||
if (disabled)
|
||||
validatorDataCount++;
|
||||
|
||||
getValidatorsProperties(web3, validatorsArray, contractAddress, abi, iasync, validatorDataCount, disabled, validatorsArrayOut, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function getValidatorsProperties(web3, validatorsArray, contractAddress, abi, iasync, validatorDataCount, disabled, validatorsArrayOut, cb) {
|
||||
for (var i = 0; i < validatorsArray.length; i++) {
|
||||
var addr = validatorsArray[i]
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorFullName", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("fullName", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorStreetName", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("streetName", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorState", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("state", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorLicenseExpiredAt", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("licenseExpiredAt", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorZip", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("zip", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorLicenseID", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("licenseID", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
if (disabled) {
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorDisablingDate", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("disablingDate", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyCallback(prop, resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb) {
|
||||
if (validatorsArrayOut.length == _i) {
|
||||
var validator = {};
|
||||
validator[validatorsArray[_i]] = {};
|
||||
validator[validatorsArray[_i]][prop] = resp;
|
||||
validatorsArrayOut.push(validator);
|
||||
} else {
|
||||
validatorsArrayOut[_i][validatorsArray[_i]][prop] = resp;
|
||||
}
|
||||
|
||||
return validatorsArrayOut;
|
||||
}
|
||||
|
||||
function finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb) {
|
||||
if (iasync == validatorsArray.length * validatorDataCount) {cb(validatorsArrayOut)};
|
||||
}
|
||||
function callContractMethod(web3, addr, i, contractAddr, abi, method, cb) {
|
||||
let ValidatorsStorage = attachToContract(web3, abi, contractAddr)
|
||||
console.log("attach to oracles contract");
|
||||
if (!ValidatorsStorage) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
ValidatorsStorage.methods[method](addr).call(function(err, res) {
|
||||
cb(i, res);
|
||||
})
|
||||
}
|
||||
function getValidatorView(validatorAddress, validatorPropsObj) {
|
||||
var stateCode = validatorPropsObj["state"].toString();
|
||||
return `<div class="validators-i">
|
||||
<div class="validators-header">
|
||||
0x` + validatorAddress + `
|
||||
</div>
|
||||
<div class="validators-body">
|
||||
<div class="validators-notary left">
|
||||
<p class="validators-title">Notary</p>
|
||||
<div class="validators-table">
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Full Name
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["fullName"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Address
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["streetName"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
State
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + stateCode + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Zip Code
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["zip"] + `
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="validators-license right">
|
||||
<p class="validators-title">Notary license</p>
|
||||
<div class="validators-table">
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
License ID
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["licenseID"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
License Expiration
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + formatDate(new Date(parseInt(validatorPropsObj["licenseExpiredAt"])*1000), "MM/dd/yyyy"/*"MM/dd/yyyy h:mmTT"*/) + `
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
//gets web3 object from MetaMask or Parity
|
||||
function getWeb3(callback) {
|
||||
if (typeof window.web3 === 'undefined') {
|
||||
// no web3, use fallback
|
||||
console.error("Please use a web3 browser");
|
||||
var msgNotEthereum = "You aren't connected to Oracles Network. Please, switch on Oracles plugin and refresh the page. Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.";
|
||||
swal("Warning", msgNotEthereum, "warning");
|
||||
callback(myWeb3, false);
|
||||
} else {
|
||||
// window.web3 == web3 most of the time. Don't override the provided,
|
||||
// web3, just wrap it in your Web3.
|
||||
var myWeb3 = new Web3(window.web3.currentProvider);
|
||||
|
||||
// the default account doesn't seem to be persisted, copy it to our
|
||||
// new instance
|
||||
myWeb3.eth.defaultAccount = window.web3.eth.defaultAccount;
|
||||
|
||||
let isOraclesNetwork = checkNetworkVersion(myWeb3)
|
||||
callback(myWeb3, isOraclesNetwork);
|
||||
}
|
||||
}
|
||||
//launches main application
|
||||
function startDapp(web3, isOraclesNetwork) {
|
||||
if (!isOraclesNetwork) {
|
||||
$(".loading-container").hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
startDappInner(web3);
|
||||
});
|
||||
}
|
||||
|
||||
async function startDappInner(web3) {
|
||||
var validators;
|
||||
let config = await getConfig()
|
||||
getValidators(web3, config.contractAddress, config.abi, false, function(_validatorsArray) {
|
||||
$(".loading-container").hide();
|
||||
validators = _validatorsArray;
|
||||
for(var i = 0; i < _validatorsArray.length; i++) {
|
||||
var validator = _validatorsArray[i];
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
$(".validators").append(getValidatorView(validatorAddress, validatorPropsObj));
|
||||
}
|
||||
|
||||
$(".search-input").on("keyup", function() {
|
||||
var searchInput = $(this).val();
|
||||
var filteredValidators = filterValidators(searchInput, validators);
|
||||
$(".validators").empty();
|
||||
for(var i = 0; i < filteredValidators.length; i++) {
|
||||
var validator = filteredValidators[i];
|
||||
if (validator) {
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
$(".validators").append(getValidatorView(validatorAddress, validatorPropsObj));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
getWeb3(startDapp);
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
function attachToContract(web3, abi, addr) {
|
||||
web3.eth.defaultAccount = web3.eth.accounts[0];
|
||||
console.log("web3.eth.defaultAccount:" + web3.eth.defaultAccount);
|
||||
|
||||
let contractInstance = new web3.eth.Contract(abi, addr);
|
||||
|
||||
return contractInstance;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//check current network page is connected to. Alerts, if not Oracles network
|
||||
async function checkNetworkVersion(web3, cb) {
|
||||
var msgNotOracles = "You aren't connected to Oracles network. Please, switch on Oracles plugin and choose Oracles network. Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.";
|
||||
let config = await getConfig()
|
||||
web3.eth.net.getId().then(function(connectedNetworkID) {
|
||||
console.log("connectedNetworkID: " + connectedNetworkID);
|
||||
connectedNetworkID = parseInt(connectedNetworkID);
|
||||
switch (connectedNetworkID) {
|
||||
case 1: {
|
||||
console.log('This is mainnet');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case 2: {
|
||||
console.log('This is the deprecated Morden test network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case 3: {
|
||||
console.log('This is the ropsten test network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
case config.networkID: {
|
||||
console.log('This is Oracles from Metamask');
|
||||
return true;
|
||||
} break;
|
||||
default: {
|
||||
console.log('This is an unknown network.');
|
||||
swal("Warning", msgNotOracles, "warning");
|
||||
return false;
|
||||
} break;
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
function formatDate(date, format, utc) {
|
||||
//var MMMM = ["\x00", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
var MMMM = ["\x00", "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"];
|
||||
var MMM = ["\x01", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
var dddd = ["\x02", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
||||
var ddd = ["\x03", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
|
||||
function ii(i, len) {
|
||||
var s = i + "";
|
||||
len = len || 2;
|
||||
while (s.length < len) s = "0" + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
var y = utc ? date.getUTCFullYear() : date.getFullYear();
|
||||
format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
|
||||
format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
|
||||
format = format.replace(/(^|[^\\])y/g, "$1" + y);
|
||||
|
||||
var M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
|
||||
format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
|
||||
format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
|
||||
format = format.replace(/(^|[^\\])MM/g, "$1" + ii(M));
|
||||
format = format.replace(/(^|[^\\])M/g, "$1" + M);
|
||||
|
||||
var d = utc ? date.getUTCDate() : date.getDate();
|
||||
format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
|
||||
format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
|
||||
format = format.replace(/(^|[^\\])dd/g, "$1" + ii(d));
|
||||
format = format.replace(/(^|[^\\])d/g, "$1" + d);
|
||||
|
||||
var H = utc ? date.getUTCHours() : date.getHours();
|
||||
format = format.replace(/(^|[^\\])HH+/g, "$1" + ii(H));
|
||||
format = format.replace(/(^|[^\\])H/g, "$1" + H);
|
||||
|
||||
var h = H > 12 ? H - 12 : H == 0 ? 12 : H;
|
||||
format = format.replace(/(^|[^\\])hh+/g, "$1" + ii(h));
|
||||
format = format.replace(/(^|[^\\])h/g, "$1" + h);
|
||||
|
||||
var m = utc ? date.getUTCMinutes() : date.getMinutes();
|
||||
format = format.replace(/(^|[^\\])mm+/g, "$1" + ii(m));
|
||||
format = format.replace(/(^|[^\\])m/g, "$1" + m);
|
||||
|
||||
var s = utc ? date.getUTCSeconds() : date.getSeconds();
|
||||
format = format.replace(/(^|[^\\])ss+/g, "$1" + ii(s));
|
||||
format = format.replace(/(^|[^\\])s/g, "$1" + s);
|
||||
|
||||
var f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
|
||||
format = format.replace(/(^|[^\\])fff+/g, "$1" + ii(f, 3));
|
||||
f = Math.round(f / 10);
|
||||
format = format.replace(/(^|[^\\])ff/g, "$1" + ii(f));
|
||||
f = Math.round(f / 10);
|
||||
format = format.replace(/(^|[^\\])f/g, "$1" + f);
|
||||
|
||||
var T = H < 12 ? "AM" : "PM";
|
||||
format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
|
||||
format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));
|
||||
|
||||
var t = T.toLowerCase();
|
||||
format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
|
||||
format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));
|
||||
|
||||
var tz = -date.getTimezoneOffset();
|
||||
var K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
|
||||
if (!utc) {
|
||||
tz = Math.abs(tz);
|
||||
var tzHrs = Math.floor(tz / 60);
|
||||
var tzMin = tz % 60;
|
||||
K += ii(tzHrs) + ":" + ii(tzMin);
|
||||
}
|
||||
format = format.replace(/(^|[^\\])K/g, "$1" + K);
|
||||
|
||||
var day = (utc ? date.getUTCDay() : date.getDay()) + 1;
|
||||
format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
|
||||
format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);
|
||||
|
||||
format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
|
||||
format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);
|
||||
|
||||
format = format.replace(/\\(.)/g, "$1");
|
||||
|
||||
return format;
|
||||
};
|
|
@ -1,25 +0,0 @@
|
|||
function filterValidators(searchInput, validators) {
|
||||
return validators.map(function(validator, i) {
|
||||
if (validator) {
|
||||
var searchValidated = validateSearch(validator, searchInput.toLowerCase());
|
||||
if (!searchValidated) return null;
|
||||
else return validator;
|
||||
} else return null;
|
||||
})
|
||||
}
|
||||
|
||||
function validateSearch(validator, searchInput) {
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
if (validatorAddress.indexOf(searchInput) > -1) return true;
|
||||
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
if (validatorPropsObj["fullName"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["streetName"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["zip"].toString().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["licenseID"].toString().indexOf(searchInput) > -1) return true;
|
||||
else if (validatorPropsObj["state"].toLowerCase().indexOf(searchInput) > -1) return true;
|
||||
else if (formatDate(new Date(parseInt(validatorPropsObj["licenseExpiredAt"])*1000), "MM/dd/yyyy h:mmTT").toLowerCase().indexOf(searchInput) > -1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
//gets config file with address of Oracles contract
|
||||
async function getConfig(cb) {
|
||||
let config = await $.getJSON("./assets/javascripts/config.json")
|
||||
let contractAddress = config.Ethereum[config.environment].ValidatorsStorage.addr
|
||||
let abi = config.Ethereum[config.environment].ValidatorsStorage.abi
|
||||
let networkID = config.networkID
|
||||
let configJSON = {
|
||||
contractAddress,
|
||||
networkID,
|
||||
abi
|
||||
}
|
||||
if (cb) cb(configJSON)
|
||||
return configJSON;
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
function getValidators(web3, contractAddress, abi, disabled, cb) {
|
||||
let ValidatorsStorage = attachToContract(web3, abi, contractAddress)
|
||||
console.log("attach to oracles contract");
|
||||
if (!ValidatorsStorage) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
ValidatorsStorage.methods.getValidators().call(function(err, validatorsArray) {
|
||||
if (validatorsArray.length == 0) {
|
||||
return cb(validatorsArray);
|
||||
}
|
||||
|
||||
var validatorsArrayOut = [];
|
||||
var iasync = 0;
|
||||
var validatorDataCount = 6;
|
||||
if (disabled)
|
||||
validatorDataCount++;
|
||||
|
||||
getValidatorsProperties(web3, validatorsArray, contractAddress, abi, iasync, validatorDataCount, disabled, validatorsArrayOut, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function getValidatorsProperties(web3, validatorsArray, contractAddress, abi, iasync, validatorDataCount, disabled, validatorsArrayOut, cb) {
|
||||
for (var i = 0; i < validatorsArray.length; i++) {
|
||||
var addr = validatorsArray[i]
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorFullName", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("fullName", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorStreetName", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("streetName", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorState", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("state", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorLicenseExpiredAt", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("licenseExpiredAt", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorZip", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("zip", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorLicenseID", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("licenseID", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
|
||||
if (disabled) {
|
||||
callContractMethod(web3, addr, i, contractAddress, abi, "getValidatorDisablingDate", function(_i, resp) {
|
||||
iasync++;
|
||||
validatorsArrayOut = getPropertyCallback("disablingDate", resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb);
|
||||
finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyCallback(prop, resp, _i, validatorsArray, validatorDataCount, validatorsArrayOut, cb) {
|
||||
if (validatorsArrayOut.length == _i) {
|
||||
var validator = {};
|
||||
validator[validatorsArray[_i]] = {};
|
||||
validator[validatorsArray[_i]][prop] = resp;
|
||||
validatorsArrayOut.push(validator);
|
||||
} else {
|
||||
validatorsArrayOut[_i][validatorsArray[_i]][prop] = resp;
|
||||
}
|
||||
|
||||
return validatorsArrayOut;
|
||||
}
|
||||
|
||||
function finish(iasync, validatorsArray, validatorDataCount, validatorsArrayOut, cb) {
|
||||
if (iasync == validatorsArray.length * validatorDataCount) {cb(validatorsArrayOut)};
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
function callContractMethod(web3, addr, i, contractAddr, abi, method, cb) {
|
||||
let ValidatorsStorage = attachToContract(web3, abi, contractAddr)
|
||||
console.log("attach to oracles contract");
|
||||
if (!ValidatorsStorage) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
ValidatorsStorage.methods[method](addr).call(function(err, res) {
|
||||
cb(i, res);
|
||||
})
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
function getValidatorView(validatorAddress, validatorPropsObj) {
|
||||
var stateCode = validatorPropsObj["state"].toString();
|
||||
return `<div class="validators-i">
|
||||
<div class="validators-header">
|
||||
0x` + validatorAddress + `
|
||||
</div>
|
||||
<div class="validators-body">
|
||||
<div class="validators-notary left">
|
||||
<p class="validators-title">Notary</p>
|
||||
<div class="validators-table">
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Full Name
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["fullName"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Address
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["streetName"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
State
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + stateCode + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
Zip Code
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["zip"] + `
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="validators-license right">
|
||||
<p class="validators-title">Notary license</p>
|
||||
<div class="validators-table">
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
License ID
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + validatorPropsObj["licenseID"] + `
|
||||
</p>
|
||||
</div>
|
||||
<div class="validators-table-tr">
|
||||
<p class="validators-table-td left">
|
||||
License Expiration
|
||||
</p>
|
||||
<p class="validators-table-td right">
|
||||
` + formatDate(new Date(parseInt(validatorPropsObj["licenseExpiredAt"])*1000), "MM/dd/yyyy"/*"MM/dd/yyyy h:mmTT"*/) + `
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
//gets web3 object from MetaMask or Parity
|
||||
function getWeb3(callback) {
|
||||
if (typeof window.web3 === 'undefined') {
|
||||
// no web3, use fallback
|
||||
console.error("Please use a web3 browser");
|
||||
var msgNotEthereum = "You aren't connected to Oracles Network. Please, switch on Oracles plugin and refresh the page. Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.";
|
||||
swal("Warning", msgNotEthereum, "warning");
|
||||
callback(myWeb3, false);
|
||||
} else {
|
||||
// window.web3 == web3 most of the time. Don't override the provided,
|
||||
// web3, just wrap it in your Web3.
|
||||
var myWeb3 = new Web3(window.web3.currentProvider);
|
||||
|
||||
// the default account doesn't seem to be persisted, copy it to our
|
||||
// new instance
|
||||
myWeb3.eth.defaultAccount = window.web3.eth.defaultAccount;
|
||||
|
||||
let isOraclesNetwork = checkNetworkVersion(myWeb3)
|
||||
callback(myWeb3, isOraclesNetwork);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
//launches main application
|
||||
function startDapp(web3, isOraclesNetwork) {
|
||||
if (!isOraclesNetwork) {
|
||||
$(".loading-container").hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
startDappInner(web3);
|
||||
});
|
||||
}
|
||||
|
||||
async function startDappInner(web3) {
|
||||
var validators;
|
||||
let config = await getConfig()
|
||||
getValidators(web3, config.contractAddress, config.abi, false, function(_validatorsArray) {
|
||||
$(".loading-container").hide();
|
||||
validators = _validatorsArray;
|
||||
for(var i = 0; i < _validatorsArray.length; i++) {
|
||||
var validator = _validatorsArray[i];
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
$(".validators").append(getValidatorView(validatorAddress, validatorPropsObj));
|
||||
}
|
||||
|
||||
$(".search-input").on("keyup", function() {
|
||||
var searchInput = $(this).val();
|
||||
var filteredValidators = filterValidators(searchInput, validators);
|
||||
$(".validators").empty();
|
||||
for(var i = 0; i < filteredValidators.length; i++) {
|
||||
var validator = filteredValidators[i];
|
||||
if (validator) {
|
||||
var validatorAddress = Object.keys(validator)[0];
|
||||
var validatorPropsObj = validator[validatorAddress];
|
||||
$(".validators").append(getValidatorView(validatorAddress, validatorPropsObj));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
getWeb3(startDapp);
|
||||
});
|
|
@ -1,613 +0,0 @@
|
|||
{
|
||||
"environment": "live",
|
||||
"networkID": 12648430,
|
||||
"Ethereum": {
|
||||
"live": {
|
||||
"ValidatorsStorage": {
|
||||
"addr": "0xf472e0e43570b9afaab67089615080cf7c20018d",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "fullName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "streetName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "zip",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "licenseID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "licenseExpiredAt",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "disablingDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "disablingTX",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setValidator",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "disableValidator",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "validator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "fullName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "streetName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "zip",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "licenseID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "licenseExpiredAt",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "disablingDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "disablingTX",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getLastBlockHash",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorFullName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "validators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getDisabledValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addValidator",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "toString",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorState",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorStreetName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "ballotsManager",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "keysStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setValidatorsManager",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setBallotsManager",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorLicenseID",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorLicenseExpiredAt",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "disabledValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorDisablingDate",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isMiningKeyDataExists",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "validatorsManager",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "validatorsManagerAddr",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "keysStorageAddr",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "ballotsManagerAddr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getDisabledValidatorsLength",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setkeysStorage",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorZip",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "i",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getValidatorAtPosition",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "i",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getDisabledValidatorAtPosition",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeValidator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getValidatorsLength",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_parent_hash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_new_set",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "InitiateChange",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
@import './index/*';
|
|
@ -1,33 +0,0 @@
|
|||
%stretch-width {
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
%title {
|
||||
color: #333;
|
||||
text-transform: uppercase;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
%description {
|
||||
color: #8197a2;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
%btn {
|
||||
transition: 0.3s background-color;
|
||||
border-radius: 3px;
|
||||
padding: 0 15px 0 32px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 12px 12px;
|
||||
background-position: left 15px center;
|
||||
color: #fff;
|
||||
line-height: 36px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
.header {
|
||||
@extend %stretch-width;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
padding: 18px 10px;
|
||||
background-image: url(../images/bg_header.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
&-logo {
|
||||
@include image-2x('../images/VALIDATORS@2x.png', 149px, 35px);
|
||||
float: left;
|
||||
width: 149px;
|
||||
height: 35px;
|
||||
background-image: url(../images/VALIDATORS.png);
|
||||
background-position: 0 0;
|
||||
}
|
||||
}
|
BIN
docs/index.png
Before Width: | Height: | Size: 144 KiB |
39
gulpfile.js
|
@ -1,39 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const sass = require('gulp-sass');
|
||||
const sassGlob = require('gulp-sass-glob');
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
const uglifycss = require('gulp-uglifycss');
|
||||
const include = require('gulp-include');
|
||||
const addsrc = require('gulp-add-src');
|
||||
const order = require('gulp-order');
|
||||
const concat = require('gulp-concat');
|
||||
const uglify = require('gulp-uglify');
|
||||
const gutil = require('gulp-util');
|
||||
|
||||
gulp.task('sass', function() {
|
||||
return gulp.src(['assets/stylesheets/*.scss'])
|
||||
.pipe(sassGlob())
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(autoprefixer())
|
||||
.pipe(uglifycss())
|
||||
.pipe(gulp.dest('assets/stylesheets/'));
|
||||
});
|
||||
|
||||
gulp.task('javascript', function() {
|
||||
return gulp.src('assets/javascripts/application/*.js')
|
||||
.pipe(order([
|
||||
"assets/javascripts/application/*.js"
|
||||
], {base: '.'}))
|
||||
.pipe(include())
|
||||
.pipe(concat('application.js'))
|
||||
//.pipe(uglify())
|
||||
.on('error', function (err) { gutil.log(gutil.colors.red('[Error]'), err.toString()); })
|
||||
.pipe(gulp.dest('assets/javascripts'));
|
||||
});
|
||||
|
||||
gulp.task('watch', function() {
|
||||
gulp.watch('assets/stylesheets/**/*.scss', ['sass']);
|
||||
gulp.watch('assets/javascripts/application/*.js', ['javascript']);
|
||||
});
|
67
index.html
|
@ -1,67 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="theme-color" content="#6151cc">
|
||||
<meta name="msapplication-config" content="./favicons/browserconfig.xml">
|
||||
|
||||
<meta property="og:title" content="Oracles Network">
|
||||
<meta property="og:description" content="An open network based on Ethereum protocol with Proof of Authority consensus by independent actors. Public notaries with known identity serve as private validators to secure the network.">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://oracles.org">
|
||||
<meta property="og:image" content="https://oracles.org/assets/images/og_image.jpg">
|
||||
<meta property="fb:app_id" content="249580292197732"/>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./assets/stylesheets/index.css">
|
||||
<link rel="apple-touch-icon" href="./favicons/favicon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="./favicons/favicon-192x192.png">
|
||||
<link rel="mask-icon" color="#6151cc" href="./favicons/safari-pinned-tab.svg">
|
||||
<link rel="manifest" href="./favicons/manifest.webmanifest">
|
||||
<link href="./favicons/favicon.ico" rel="icon" type="image/x-icon">
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="container">
|
||||
<a href="#" class="header-logo"></a>
|
||||
</div>
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="search">
|
||||
<div class="container">
|
||||
<p class="search-title">List of active validators</p>
|
||||
<form action="" class="search-form">
|
||||
<input type="text" class="search-input">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container validators">
|
||||
</div>
|
||||
</section>
|
||||
<div class="loading-container">
|
||||
<div class="loading">
|
||||
<div class="loading-i"></div>
|
||||
<div class="loading-i"></div>
|
||||
<div class="loading-i"></div>
|
||||
<div class="loading-i"></div>
|
||||
<div class="loading-i"></div>
|
||||
<div class="loading-i"></div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<a href="#" class="footer-logo"></a>
|
||||
<div class="socials">
|
||||
<a href="#" class="socials-i socials-i_reddit"></a>
|
||||
<a href="https://twitter.com/oraclesorg" class="socials-i socials-i_twitter"></a>
|
||||
<a href="#" class="socials-i socials-i_bitcoin"></a>
|
||||
</div>
|
||||
<p class="footer-rights">2017 Oracles Network. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="./assets/javascripts/modules.js"></script>
|
||||
<script src="./assets/javascripts/application.js?v=1.20"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"id": "ValidatorsList",
|
||||
"name": "Validators list",
|
||||
"description": "Oracles Validators list",
|
||||
"version": "1.0.0",
|
||||
"author": "Oracles",
|
||||
"iconUrl": "./favicons/fav_2.png"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
let jquery = require("jquery");
|
||||
let sweetalert2 = require("sweetalert2");
|
||||
let Web3 = require("web3");
|
||||
|
||||
window.$ = jquery;
|
||||
window.swal = sweetalert2;
|
||||
window.Web3 = Web3;
|
|
@ -1,40 +1,35 @@
|
|||
{
|
||||
"name": "oracles-dapps-validators",
|
||||
"version": "1.0.0",
|
||||
"description": "Oracles network Validators Dapp",
|
||||
"main": "gulpfile.js",
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-add-src": "^0.2.0",
|
||||
"gulp-autoprefixer": "^3.1.1",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-include": "^2.3.1",
|
||||
"gulp-order": "^1.1.1",
|
||||
"gulp-postcss": "^6.2.0",
|
||||
"gulp-sass": "^2.3.2",
|
||||
"gulp-sass-glob": "^1.0.6",
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulp-uglifycss": "^1.0.6",
|
||||
"gulp-util": "^3.0.8",
|
||||
"http-server": "^0.9.0"
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"homepage": "https://rstormsf.github.io/oracles-dapps-validators",
|
||||
"dependencies": {
|
||||
"clipboard": "^1.7.1",
|
||||
"gh-pages": "^1.1.0",
|
||||
"keythereum": "^1.0.2",
|
||||
"moment": "^2.19.3",
|
||||
"node-sass-chokidar": "0.0.3",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"password-generator": "^2.2.0",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-places-autocomplete": "^5.4.3",
|
||||
"react-router": "^4.2.0",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-scripts": "1.0.17",
|
||||
"sweetalert": "^2.0.8",
|
||||
"web3": "^1.0.0-beta.26"
|
||||
},
|
||||
"scripts": {
|
||||
"sass": "gulp sass",
|
||||
"coffee": "gulp javascript",
|
||||
"watch": "gulp watch",
|
||||
"start": "gulp javascript && http-server -a localhost -p 8000"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oraclesorg/oracles-dapps-validators"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "oraclesorg",
|
||||
"license": "MIT",
|
||||
"homepage": "https://oracles.org/",
|
||||
"dependencies": {
|
||||
"jquery": "^3.2.1",
|
||||
"sweetalert2": "^7.0.3",
|
||||
"web3": "^1.0.0-beta.26"
|
||||
"predeploy": "npm run build",
|
||||
"deploy": "gh-pages -d build -o rstorm",
|
||||
"build-css": "node-sass-chokidar src/index/index.scss -o src/index",
|
||||
"watch-css": "npm run build-css && node-sass-chokidar src/index/index.scss -o src/index --watch --recursive",
|
||||
"start-js": "react-scripts start",
|
||||
"start": "npm-run-all -p watch-css start-js",
|
||||
"build-js": "react-scripts build",
|
||||
"build": "npm-run-all build-css build-js",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
|
|
0
favicons/android-chrome-192x192.png → public/favicons/android-chrome-192x192.png
Normal file → Executable file
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
0
favicons/android-chrome-256x256.png → public/favicons/android-chrome-256x256.png
Normal file → Executable file
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
0
favicons/apple-touch-icon.png → public/favicons/apple-touch-icon.png
Normal file → Executable file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicons/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD97qDOBYZ2fH86Wq1vzhDOiSUsZGVqbVQ&libraries=places"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<header class="header">
|
||||
<div class="container">
|
||||
<a href="#" class="header-logo"></a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<a href="#" class="footer-logo"></a>
|
||||
<div class="socials">
|
||||
<a href="#" class="socials-i socials-i_reddit"></a>
|
||||
<a href="https://twitter.com/oraclesorg" class="socials-i socials-i_twitter"></a>
|
||||
<a href="#" class="socials-i socials-i_bitcoin"></a>
|
||||
</div>
|
||||
<p class="footer-rights">2017 Oracles Network. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import React, {Component, Children} from 'react';
|
||||
import Validator from './Validator'
|
||||
|
||||
export default class AllValidators extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.getMetadataContract = this.getMetadataContract.bind(this);
|
||||
this.state = {
|
||||
validators: []
|
||||
}
|
||||
this.getValidatorsData.call(this);
|
||||
}
|
||||
async getValidatorsData() {
|
||||
this.getMetadataContract()[this.props.methodToCall]().then((data) => {
|
||||
this.setState({
|
||||
validators: data
|
||||
})
|
||||
})
|
||||
}
|
||||
getMetadataContract(){
|
||||
return this.props.web3Config.metadataContract;
|
||||
}
|
||||
render() {
|
||||
|
||||
const filtered = this.state.validators.filter((validator, index) => {
|
||||
return Object.values(validator).some( val =>
|
||||
String(val).toLowerCase().includes(this.props.searchTerm)
|
||||
);
|
||||
})
|
||||
let validators = [];
|
||||
let confirmations = [];
|
||||
for(let [index, validator] of filtered.entries()) {
|
||||
let childrenWithProps = React.Children.map(this.props.children, (child) => {
|
||||
return React.cloneElement(child, { miningkey: validator.address });
|
||||
})
|
||||
validators.push(
|
||||
<Validator
|
||||
key={index}
|
||||
address={validator.address}
|
||||
firstName={validator.firstName}
|
||||
lastName={validator.lastName}
|
||||
fullAddress={validator.fullAddress}
|
||||
us_state={validator.us_state}
|
||||
postal_code={validator.postal_code}
|
||||
licenseId={validator.licenseId}
|
||||
expirationDate={validator.expirationDate}
|
||||
createdDate={validator.createdDate}
|
||||
updatedDate={validator.updatedDate}
|
||||
metadataContract={this.props.web3Config.metadataContract}
|
||||
methodToCall={this.props.methodToCall}
|
||||
>{childrenWithProps}</Validator>)
|
||||
|
||||
}
|
||||
return (<div className="container">
|
||||
{validators}
|
||||
</div>)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #222;
|
||||
height: 150px;
|
||||
padding: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-title {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.App-intro {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
import React, { Component } from 'react';
|
||||
import getWeb3 from './getWeb3'
|
||||
import KeysManager from './contracts/KeysManager.contract';
|
||||
import MetadataContract from './contracts/Metadata.contract';
|
||||
import swal from 'sweetalert';
|
||||
import './index/index.css';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PlacesAutocomplete, { geocodeByAddress, geocodeByPlaceId } from 'react-places-autocomplete';
|
||||
import moment from 'moment';
|
||||
import Metadata from './contracts/Metadata.contract';
|
||||
import Loading from './Loading';
|
||||
|
||||
class App extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.checkValidation = this.checkValidation.bind(this)
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.onChangeFormField = this.onChangeFormField.bind(this);
|
||||
this.getKeysManager = this.getKeysManager.bind(this);
|
||||
this.getMetadataContract = this.getMetadataContract.bind(this);
|
||||
this.getVotingKey = this.getVotingKey.bind(this);
|
||||
this.onChangeAutoComplete = ((address) => {
|
||||
const form = this.state.form;
|
||||
form.fullAddress = address;
|
||||
this.setState({form})
|
||||
})
|
||||
this.onSelect = this.onSelectAutocomplete.bind(this)
|
||||
this.state = {
|
||||
web3Config: {},
|
||||
form: {
|
||||
fullAddress: '',
|
||||
expirationDate: '',
|
||||
postal_code: '',
|
||||
us_state: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
licenseId: ''
|
||||
},
|
||||
hasData: false
|
||||
|
||||
}
|
||||
|
||||
this.defaultValues = null;
|
||||
this.setMetadata.call(this);
|
||||
|
||||
}
|
||||
async setMetadata(){
|
||||
const currentData = await this.getMetadataContract().getValidatorData({votingKey: this.getVotingKey()});
|
||||
const hasData = Number(currentData.postal_code) > 0 ? true : false
|
||||
this.defaultValues = currentData;
|
||||
const pendingChange = await this.getMetadataContract().getPendingChange({votingKey: this.getVotingKey()});
|
||||
if(Number(pendingChange.minThreshold) > 0 ) {
|
||||
var content = document.createElement("div");
|
||||
content.innerHTML = `<div>
|
||||
First Name: ${pendingChange.firstName} <br/>
|
||||
Last Name: ${pendingChange.lastName} <br/>
|
||||
Full Address: ${pendingChange.fullAddress} <br/>
|
||||
Expiration Date: ${pendingChange.expirationDate} <br />
|
||||
License ID: ${pendingChange.licenseId} <br/>
|
||||
US state: ${pendingChange.us_state} <br/>
|
||||
Zip Code: ${pendingChange.postal_code} <br/>
|
||||
</div>`;
|
||||
swal({
|
||||
icon: 'warning',
|
||||
title: 'You have pending changes!',
|
||||
content: content
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
form: {
|
||||
fullAddress: currentData.fullAddress,
|
||||
expirationDate: currentData.expirationDate,
|
||||
postal_code: currentData.postal_code,
|
||||
us_state: currentData.us_state,
|
||||
firstName: currentData.firstName,
|
||||
lastName: currentData.lastName,
|
||||
licenseId: currentData.licenseId,
|
||||
},
|
||||
hasData
|
||||
});
|
||||
}
|
||||
getKeysManager(){
|
||||
return this.props.web3Config.keysManager;
|
||||
}
|
||||
getMetadataContract(){
|
||||
return this.props.web3Config.metadataContract;
|
||||
}
|
||||
getVotingKey(){
|
||||
return this.props.web3Config.votingKey;
|
||||
}
|
||||
checkValidation() {
|
||||
const isAfter = moment(this.state.form.expirationDate).isAfter(moment());
|
||||
let keys = Object.keys(this.state.form);
|
||||
keys.forEach((key) => {
|
||||
if(!this.state.form[key]){
|
||||
this.setState({loading: false})
|
||||
swal("Warning!", `${key} cannot be empty`, "warning");
|
||||
return false;
|
||||
}
|
||||
})
|
||||
if(isAfter){
|
||||
} else {
|
||||
this.setState({loading: false})
|
||||
swal("Warning!", "Expiration date should be valid", "warning");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
async onSelectAutocomplete(data) {
|
||||
let place = await geocodeByAddress(data)
|
||||
let address_components = {};
|
||||
for (var i = 0; i < place[0].address_components.length; i++) {
|
||||
var addressType = place[0].address_components[i].types[0];
|
||||
switch(addressType) {
|
||||
case "postal_code":
|
||||
address_components.postal_code = Number(place[0].address_components[i].short_name);
|
||||
break;
|
||||
case "street_number":
|
||||
address_components.street_number = place[0].address_components[i].short_name;
|
||||
break;
|
||||
case "route":
|
||||
address_components.route = place[0].address_components[i].short_name;
|
||||
break;
|
||||
case "locality":
|
||||
address_components.locality = place[0].address_components[i].short_name;
|
||||
break;
|
||||
case "administrative_area_level_1":
|
||||
address_components.administrative_area_level_1 = place[0].address_components[i].short_name;
|
||||
break;
|
||||
}
|
||||
let form = this.state.form;
|
||||
form.fullAddress= `${address_components.street_number} ${address_components.route} ${address_components.locality}`;
|
||||
form.us_state= address_components.administrative_area_level_1;
|
||||
form.postal_code= address_components.postal_code;
|
||||
this.setState({
|
||||
form
|
||||
});
|
||||
}
|
||||
}
|
||||
async onClick() {
|
||||
this.setState({loading:true});
|
||||
const isFormValid = this.checkValidation();
|
||||
if(isFormValid){
|
||||
const votingKey = this.getVotingKey();
|
||||
console.log('voting', votingKey)
|
||||
const isValid = await this.getKeysManager().isVotingActive(votingKey);
|
||||
console.log(isValid);
|
||||
if(isValid){
|
||||
// // add loading screen
|
||||
await this.sendTxToContract()
|
||||
} else {
|
||||
this.setState({loading:false});
|
||||
swal("Warning!", "The key is not valid voting Key! Please make sure you have loaded correct voting key in metamask", "warning");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
async sendTxToContract(){
|
||||
this.getMetadataContract().createMetadata({
|
||||
firstName: this.state.form.firstName,
|
||||
lastName: this.state.form.lastName,
|
||||
licenseId: this.state.form.licenseId,
|
||||
fullAddress: this.state.form.fullAddress,
|
||||
state: this.state.form.us_state,
|
||||
zipcode: this.state.form.postal_code,
|
||||
expirationDate: moment(this.state.form.expirationDate).unix(),
|
||||
votingKey: this.getVotingKey(),
|
||||
hasData: this.state.hasData
|
||||
}).then((receipt) => {
|
||||
console.log(receipt);
|
||||
this.setState({loading: false})
|
||||
swal("Congratulations!", "Your metadata was sent!", "success");
|
||||
}).catch((error) => {
|
||||
console.error(error.message);
|
||||
this.setState({loading: false})
|
||||
var content = document.createElement("div");
|
||||
content.innerHTML = `<div>
|
||||
Something went wrong!<br/><br/>
|
||||
${error.message}
|
||||
</div>`;
|
||||
swal({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: content
|
||||
});
|
||||
})
|
||||
}
|
||||
onChangeFormField(event) {
|
||||
const field = event.target.id;
|
||||
const value = event.target.value;
|
||||
let form = this.state.form;
|
||||
form[field] = value;
|
||||
this.setState({form});
|
||||
}
|
||||
render() {
|
||||
const BtnAction = this.state.hasData ? "Update" : "Set";
|
||||
const AutocompleteItem = ({ formattedSuggestion }) => (
|
||||
<div className="custom-container">
|
||||
<strong>{ formattedSuggestion.mainText }</strong>{' '}
|
||||
<small>{ formattedSuggestion.secondaryText }</small>
|
||||
</div>
|
||||
)
|
||||
|
||||
const inputProps = {
|
||||
value: this.state.form.fullAddress,
|
||||
onChange: this.onChangeAutoComplete,
|
||||
id: 'address'
|
||||
}
|
||||
let loader = this.state.loading ? <Loading /> : '';
|
||||
let createKeyBtn = (<div className="create-keys">
|
||||
<form className="create-keys-inputs">
|
||||
<div className="left">
|
||||
<label htmlFor="first-name">First name </label>
|
||||
<input type="text" id="firstName" value={this.state.form.firstName} onChange={this.onChangeFormField}/>
|
||||
<label htmlFor="last-name">Last name</label>
|
||||
<input type="text" id="lastName" value={this.state.form.lastName} onChange={this.onChangeFormField}/>
|
||||
<label htmlFor="address">Address</label>
|
||||
<PlacesAutocomplete onSelect={this.onSelect} inputProps={inputProps} autocompleteItem={AutocompleteItem} />
|
||||
<label htmlFor="state">State</label>
|
||||
<input type="text" id="us_state" value={this.state.form.us_state} onChange={this.onChangeFormField}/>
|
||||
</div>
|
||||
<div className="right">
|
||||
<label htmlFor="zip">Zip code</label>
|
||||
<input type="number" id="postal_code" value={this.state.form.postal_code} onChange={this.onChangeFormField}/>
|
||||
<label htmlFor="licenseId">License id</label>
|
||||
<input type="text" id="licenseId" value={this.state.form.licenseId} onChange={this.onChangeFormField}/>
|
||||
<label htmlFor="expirationDate">License expiration</label>
|
||||
<input type="date" id="expirationDate" value={this.state.form.expirationDate} onChange={this.onChangeFormField}/>
|
||||
</div>
|
||||
</form>
|
||||
<button onClick={this.onClick} className="create-keys-button set">{BtnAction} Metadata</button>
|
||||
</div>)
|
||||
let content = createKeyBtn;
|
||||
return (
|
||||
<div className="container">
|
||||
{loader}
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
|
@ -0,0 +1,8 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import React, { Component } from 'react';
|
||||
const Loading = () => (
|
||||
<div className="loading-container">
|
||||
<div className="loading">
|
||||
<div className="loading-i"></div>
|
||||
<div className="loading-i"></div>
|
||||
<div className="loading-i"></div>
|
||||
<div className="loading-i"></div>
|
||||
<div className="loading-i"></div>
|
||||
<div className="loading-i"></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
export default Loading;
|
|
@ -0,0 +1,127 @@
|
|||
import React, {Component, Children} from 'react';
|
||||
|
||||
class Validator extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
confirmation: null
|
||||
}
|
||||
this.props.metadataContract.getConfirmations({miningKey: this.props.address}).then((confirmation) => {
|
||||
this.setState({confirmation})
|
||||
})
|
||||
}
|
||||
render(){
|
||||
let {
|
||||
address,
|
||||
firstName,
|
||||
lastName,
|
||||
fullAddress,
|
||||
us_state,
|
||||
postal_code,
|
||||
licenseId,
|
||||
expirationDate,
|
||||
createdDate,
|
||||
updatedDate,
|
||||
children,
|
||||
} = this.props;
|
||||
let confirmations = this.props.methodToCall === 'getAllValidatorsData' ? '' : <div className="confirmations">
|
||||
<div>{this.state.confirmation} confirmations</div>
|
||||
</div>
|
||||
return(
|
||||
<div className="validators-i">
|
||||
<div className="validators-header">
|
||||
<div className="left">
|
||||
<div>
|
||||
{address}
|
||||
</div>
|
||||
{confirmations}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div className="right">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="validators-body">
|
||||
<div className="validators-notary left">
|
||||
<p className="validators-title">Notary</p>
|
||||
<div className="validators-table">
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
Full Name
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{firstName} {lastName}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
Address
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{fullAddress}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
State
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{us_state}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
Zip Code
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{postal_code}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="validators-license right">
|
||||
<p className="validators-title">Notary license</p>
|
||||
<div className="validators-table">
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
License ID
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{licenseId}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
License Expiration
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{expirationDate}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
Miner Creation Date
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{createdDate}
|
||||
</p>
|
||||
</div>
|
||||
<div className="validators-table-tr">
|
||||
<p className="validators-table-td left">
|
||||
Pending Change Requested Date
|
||||
</p>
|
||||
<p className="validators-table-td right">
|
||||
{updatedDate}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Validator;
|
|
@ -0,0 +1,15 @@
|
|||
import KeysManagerAbi from './keysManager.abi.json'
|
||||
import Web3 from 'web3';
|
||||
|
||||
const KEYS_MANAGER_ADDRESS = '0xafb147e450f0375bc3e61709b053238f5804c9a6';
|
||||
export default class KeysManager {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
this.keysInstance = new web3_10.eth.Contract(KeysManagerAbi, KEYS_MANAGER_ADDRESS);
|
||||
}
|
||||
}
|
||||
async isVotingActive(votingKey) {
|
||||
return await this.keysInstance.methods.isVotingActive(votingKey).call();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
import PoaConsensus from './PoaConsensus.contract'
|
||||
import MetadataAbi from './metadata.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import moment from 'moment';
|
||||
var toAscii = function(hex) {
|
||||
var str = '',
|
||||
i = 0,
|
||||
l = hex.length;
|
||||
if (hex.substring(0, 2) === '0x') {
|
||||
i = 2;
|
||||
}
|
||||
for (; i < l; i+=2) {
|
||||
var code = parseInt(hex.substr(i, 2), 16);
|
||||
if (code === 0) continue; // this is added
|
||||
str += String.fromCharCode(code);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
const METADATA_ADDRESS = '0x3111c94b9243a8a99d5a867e00609900e437e2c0';
|
||||
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);
|
||||
}
|
||||
}
|
||||
async createMetadata({
|
||||
firstName,
|
||||
lastName,
|
||||
licenseId,
|
||||
fullAddress,
|
||||
state,
|
||||
zipcode,
|
||||
expirationDate,
|
||||
votingKey,
|
||||
hasData
|
||||
}) {
|
||||
let methodToCall = hasData ? 'changeRequest' : 'createMetadata'
|
||||
return await this.metadataInstance.methods[methodToCall](
|
||||
this.web3_10.utils.fromAscii(firstName),
|
||||
this.web3_10.utils.fromAscii(lastName),
|
||||
this.web3_10.utils.fromAscii(licenseId),
|
||||
fullAddress,
|
||||
this.web3_10.utils.fromAscii(state),
|
||||
zipcode,
|
||||
expirationDate
|
||||
).send({from: votingKey});
|
||||
}
|
||||
|
||||
async getValidatorData({votingKey, miningKey}){
|
||||
miningKey = miningKey || await this.getMiningByVoting(votingKey);
|
||||
let validatorData = await this.metadataInstance.methods.validators(miningKey).call();
|
||||
let createdDate = validatorData.createdDate > 0 ? moment.unix(validatorData.createdDate).format('YYYY-MM-DD') : ''
|
||||
let updatedDate = validatorData.updatedDate > 0 ? moment.unix(validatorData.updatedDate).format('YYYY-MM-DD') : ''
|
||||
let expirationDate = validatorData.expirationDate > 0 ? moment.unix(validatorData.expirationDate).format('YYYY-MM-DD') : ''
|
||||
let postal_code = Number(validatorData.zipcode) || ''
|
||||
return {
|
||||
firstName: toAscii(validatorData.firstName),
|
||||
lastName: toAscii(validatorData.lastName),
|
||||
fullAddress: validatorData.fullAddress,
|
||||
createdDate,
|
||||
updatedDate,
|
||||
expirationDate,
|
||||
licenseId: toAscii(validatorData.licenseId),
|
||||
us_state: toAscii(validatorData.state),
|
||||
postal_code,
|
||||
}
|
||||
}
|
||||
|
||||
async getMiningByVoting(votingKey){
|
||||
return await this.metadataInstance.methods.getMiningByVotingKey(votingKey).call();
|
||||
}
|
||||
|
||||
async getAllValidatorsData(){
|
||||
let all = [];
|
||||
return new Promise(async(resolve, reject) => {
|
||||
const poaInstance = new PoaConsensus({web3: this.web3_10})
|
||||
const keys = await poaInstance.getValidators()
|
||||
for (let key of keys) {
|
||||
let data = await this.getValidatorData({miningKey: key})
|
||||
data.address = key
|
||||
all.push(data)
|
||||
}
|
||||
resolve(all);
|
||||
})
|
||||
}
|
||||
|
||||
async getPendingChange({votingKey, miningKey}){
|
||||
miningKey = miningKey || await this.getMiningByVoting(votingKey);
|
||||
let pendingChanges = await this.metadataInstance.methods.pendingChanges(miningKey).call();
|
||||
let createdDate = pendingChanges.createdDate > 0 ? moment.unix(pendingChanges.createdDate).format('YYYY-MM-DD') : ''
|
||||
let updatedDate = pendingChanges.updatedDate > 0 ? moment.unix(pendingChanges.updatedDate).format('YYYY-MM-DD') : ''
|
||||
let expirationDate = pendingChanges.expirationDate > 0 ? moment.unix(pendingChanges.expirationDate).format('YYYY-MM-DD') : ''
|
||||
let postal_code = Number(pendingChanges.zipcode) || ''
|
||||
return {
|
||||
firstName: toAscii(pendingChanges.firstName),
|
||||
lastName: toAscii(pendingChanges.lastName),
|
||||
fullAddress: pendingChanges.fullAddress,
|
||||
createdDate,
|
||||
updatedDate,
|
||||
expirationDate,
|
||||
licenseId: toAscii(pendingChanges.licenseId),
|
||||
us_state: toAscii(pendingChanges.state),
|
||||
postal_code,
|
||||
minThreshold: pendingChanges.minThreshold
|
||||
}
|
||||
}
|
||||
|
||||
async getAllPendingChanges() {
|
||||
let allChanges = await this.metadataInstance.getPastEvents('ChangeRequestInitiated', {fromBlock: 0});
|
||||
let miningKeys = allChanges.map((event) => event.returnValues.miningKey)
|
||||
let pendingChanges = []
|
||||
for (let key of miningKeys) {
|
||||
let pendingChange = await this.getPendingChange({miningKey: key})
|
||||
pendingChange.address = key;
|
||||
if(pendingChange.postal_code > 0){
|
||||
pendingChanges.push(pendingChange)
|
||||
}
|
||||
}
|
||||
return pendingChanges
|
||||
}
|
||||
|
||||
async confirmPendingChange({miningKeyToConfirm, senderVotingKey}) {
|
||||
// you can't confirm your own
|
||||
// you can't confirm twice
|
||||
//
|
||||
return await this.metadataInstance.methods.confirmPendingChange(miningKeyToConfirm).send({from: senderVotingKey});
|
||||
}
|
||||
|
||||
async getConfirmations({miningKey}) {
|
||||
return await this.metadataInstance.methods.confirmations(miningKey).call();
|
||||
}
|
||||
|
||||
async getMinThreshold({miningKey}) {
|
||||
let validatorData = await this.metadataInstance.methods.validators(miningKey).call();
|
||||
return validatorData.minThreshold;
|
||||
}
|
||||
|
||||
async finalize({miningKeyToConfirm, senderVotingKey}) {
|
||||
return await this.metadataInstance.methods.finalize(miningKeyToConfirm).send({from: senderVotingKey});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import poaConsensusAbi from './poaConsensus.abi.json'
|
||||
import Web3 from 'web3';
|
||||
|
||||
const KEYS_MANAGER_ADDRESS = '0xf472E0e43570B9AfaAB67089615080cF7C20018d';
|
||||
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, KEYS_MANAGER_ADDRESS);
|
||||
}
|
||||
}
|
||||
async getValidators(){
|
||||
return await this.poaInstance.methods.getValidators().call();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,621 @@
|
|||
[
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removePayoutKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeVotingKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getVotingByMining",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMiningKeyByVoting",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addMiningKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "poaNetworkConsensus",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "miningKeyHistory",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getVotingToChangeKeys",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getTime",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "validatorKeys",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "votingKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "payoutKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "isMiningActive",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "isVotingActive",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "isPayoutActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_votingKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isVotingActive",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addPayoutKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "initialKeys",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapPayoutKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getPayoutByMining",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeMiningKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "maxLimitValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_initialKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "initiateKeys",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addVotingKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isMiningActive",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "proxyStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "votingContract",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_votingKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_payoutKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "createKeys",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "initialKeysCount",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapVotingKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_oldMiningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapMiningKey",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "maxNumberOfInitialKeys",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "masterOfCeremony",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isPayoutActive",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_proxyStorage",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_poaConsensus",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_masterOfCeremony",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "action",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "PayoutKeyChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "action",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "VotingKeyChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "key",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "action",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "MiningKeyChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "votingKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "payoutKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ValidatorInitialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "initialKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "time",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "initialKeysCount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "InitialKeyCreated",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,628 @@
|
|||
[
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "pendingChanges",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "expirationDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "createdDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "updatedDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "minThreshold",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getBallotsStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "confirmations",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "count",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "finalize",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_expirationDate",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getTime",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_votingKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMiningByVotingKey",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_expirationDate",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "changeRequest",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"name": "firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "expirationDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "createdDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "updatedDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "minThreshold",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "requestNonce",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getKeysManager",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "confirmPendingChange",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "proxyStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_expirationDate",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getMinThreshold",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_voter",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isAddressAlreadyVoted",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_expirationDate",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "createMetadata",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "cancelPendingChange",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "expirationDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "createdDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "updatedDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "minThreshold",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "requestNonce",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true,
|
||||
"name": "validators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "firstName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "licenseId",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "fullAddress",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "zipcode",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "expirationDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "createdDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "updatedDate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "minThreshold",
|
||||
"type": "uint256"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_proxyStorage",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "MetadataCreated",
|
||||
"type": "constructor",
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "MetadataCreated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ChangeRequestInitiated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "votingSender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "CancelledRequest",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "votingSender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Confirmed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "miningKey",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "FinalizedChange",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,342 @@
|
|||
[
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "pendingList",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_newAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setProxyStorage",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_validator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeValidator",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "currentValidatorsLength",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "validatorsState",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "isValidator",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getPendingList",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getVotingToChangeKeys",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_validator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addValidator",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "finalizeChange",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "currentValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getKeysManager",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "isMasterOfCeremonyInitialized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "proxyStorage",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "finalized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getValidators",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "systemAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "masterOfCeremony",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_someone",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isValidator",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_masterOfCeremony",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "parentHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSet",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "InitiateChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSet",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "ChangeFinalized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "nameOfContract",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ChangeReference",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "proxyStorage",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "MoCInitializedProxyStorage",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,67 @@
|
|||
let errorMsgNoMetamaskAccount = `You haven't chosen any account in MetaMask.
|
||||
Please, choose your initial key in MetaMask and reload the page.
|
||||
Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.`;
|
||||
|
||||
|
||||
function generateElement(msg){
|
||||
let errorNode = document.createElement("div");
|
||||
errorNode.innerHTML = `<div>
|
||||
${msg}
|
||||
</div>`;
|
||||
return errorNode;
|
||||
}
|
||||
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
|
||||
|
||||
// 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;
|
||||
switch (netId) {
|
||||
case "12648430":
|
||||
netIdName = 'Oracles'
|
||||
console.log('This is oracles')
|
||||
break
|
||||
default:
|
||||
netIdName = 'ERROR'
|
||||
errorMsg = `You aren't connected to Oracles Network.
|
||||
Please, switch on Oracles plugin and refresh the page.
|
||||
Check Oracles network <a href='https://github.com/oraclesorg/oracles-wiki' target='blank'>wiki</a> for more info.`
|
||||
console.log('This is an unknown network.')
|
||||
}
|
||||
var defaultAccount = web3.eth.defaultAccount || null;
|
||||
if(defaultAccount === null){
|
||||
reject({msg: errorMsgNoMetamaskAccount, node: generateElement(errorMsgNoMetamaskAccount)})
|
||||
}
|
||||
if(errorMsg !== null){
|
||||
reject({msg: errorMsg, node: generateElement(errorMsg)})
|
||||
}
|
||||
results = {
|
||||
web3Instance: web3,
|
||||
netIdName,
|
||||
netId,
|
||||
injectedWeb3: true,
|
||||
defaultAccount
|
||||
}
|
||||
resolve(results)
|
||||
})
|
||||
|
||||
console.log('Injected web3 detected.');
|
||||
|
||||
} else {
|
||||
reject({msg: errorMsgNoMetamaskAccount, node: generateElement(errorMsgNoMetamaskAccount)})
|
||||
console.error('Metamask not found');
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default getWeb3
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 541 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20"><path fill="#FBFBFB" fill-rule="evenodd" d="M21.377 14.326L14.152 1.82a3.645 3.645 0 0 0-6.312 0L.488 14.54a3.636 3.636 0 0 0 0 3.64A3.645 3.645 0 0 0 3.644 20h14.712A3.643 3.643 0 0 0 22 16.36c0-.753-.23-1.455-.623-2.034zm-8.821 1.217c0 .861-.663 1.519-1.556 1.519s-1.556-.658-1.556-1.519v-.035c0-.857.663-1.519 1.556-1.519s1.556.658 1.556 1.519v.035zm.036-10.238l-.77 6.717c-.052.484-.373.785-.822.785-.449 0-.77-.305-.822-.785l-.77-6.721c-.051-.519.23-.912.715-.912h1.75c.485.004.771.397.719.916z"/></svg>
|
After Width: | Height: | Size: 571 B |
|
@ -0,0 +1,165 @@
|
|||
import React, {Component} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import swal from 'sweetalert';
|
||||
import App from './App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
import KeysManager from './contracts/KeysManager.contract'
|
||||
import Metadata from './contracts/Metadata.contract'
|
||||
import getWeb3 from './getWeb3'
|
||||
import { setTimeout } from 'timers';
|
||||
import {
|
||||
Router,
|
||||
Route,
|
||||
Link,
|
||||
NavLink
|
||||
} from 'react-router-dom'
|
||||
import createBrowserHistory from 'history/createBrowserHistory'
|
||||
import Loading from './Loading'
|
||||
import AllValidators from './AllValidators'
|
||||
|
||||
const history = createBrowserHistory()
|
||||
|
||||
function generateElement(msg){
|
||||
let errorNode = document.createElement("div");
|
||||
errorNode.innerHTML = `<div>
|
||||
${msg}
|
||||
</div>`;
|
||||
return errorNode;
|
||||
}
|
||||
|
||||
class AppMainRouter extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.rootPath = '/oracles-dapps-validators'
|
||||
history.listen(this.onRouteChange.bind(this));
|
||||
this.onSetRender = this.onSetRender.bind(this);
|
||||
this.onPendingChangesRender = this.onPendingChangesRender.bind(this);
|
||||
this.onAllValidatorsRender = this.onAllValidatorsRender.bind(this)
|
||||
this.onConfirmPendingChange = this.onConfirmPendingChange.bind(this);
|
||||
this.onFinalize = this.onFinalize.bind(this);
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
this.state = {
|
||||
showSearch: true,
|
||||
web3loaded: false,
|
||||
keysManager :null,
|
||||
metadataContract: null,
|
||||
poaConsensus: null,
|
||||
votingKey :null,
|
||||
loading: true,
|
||||
searchTerm: ''
|
||||
}
|
||||
getWeb3().then(async (web3Config) => {
|
||||
const keysManager = new KeysManager({
|
||||
web3: web3Config.web3Instance
|
||||
});
|
||||
const metadataContract = new Metadata({
|
||||
web3: web3Config.web3Instance
|
||||
})
|
||||
this.setState({
|
||||
votingKey: web3Config.defaultAccount,
|
||||
keysManager,
|
||||
metadataContract,
|
||||
loading: false,
|
||||
})
|
||||
}).catch((error) => {
|
||||
console.error(error.message);
|
||||
this.setState({loading: false})
|
||||
swal({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: generateElement(error.message)
|
||||
});
|
||||
})
|
||||
}
|
||||
onRouteChange(){
|
||||
const setMetadata = this.rootPath + "/set";
|
||||
if(history.location.pathname === setMetadata){
|
||||
this.setState({showSearch: false})
|
||||
} else {
|
||||
this.setState({showSearch: true})
|
||||
}
|
||||
}
|
||||
onSetRender() {
|
||||
return this.state.votingKey ? <App web3Config={this.state}/> : '';
|
||||
}
|
||||
async _onBtnClick({event, methodToCall, successMsg}){
|
||||
event.preventDefault();
|
||||
this.setState({loading: true})
|
||||
const miningKey = event.currentTarget.getAttribute('miningkey');
|
||||
try{
|
||||
let result = await this.state.metadataContract[methodToCall]({
|
||||
miningKeyToConfirm: miningKey,
|
||||
senderVotingKey: this.state.votingKey
|
||||
});
|
||||
console.log(result);
|
||||
this.setState({loading: false})
|
||||
swal("Congratulations!", successMsg, "success");
|
||||
} catch(error) {
|
||||
this.setState({loading: false})
|
||||
console.error(error.message);
|
||||
swal({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: generateElement(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() {
|
||||
return this.state.votingKey ? <AllValidators
|
||||
methodToCall="getAllPendingChanges"
|
||||
searchTerm={this.state.searchTerm}
|
||||
web3Config={this.state}>
|
||||
<button onClick={this.onFinalize} className="create-keys-button finalize">Finalize</button>
|
||||
<button onClick={this.onConfirmPendingChange} className="create-keys-button">Confirm</button>
|
||||
</AllValidators> : '';
|
||||
}
|
||||
onAllValidatorsRender() {
|
||||
return this.state.votingKey ? <AllValidators searchTerm={this.state.searchTerm} methodToCall="getAllValidatorsData" web3Config={this.state} /> : '';
|
||||
}
|
||||
onSearch(term){
|
||||
this.setState({searchTerm: term.target.value.toLowerCase()})
|
||||
}
|
||||
render(){
|
||||
console.log('v2.03')
|
||||
const search = this.state.showSearch ? <input type="search" className="search-input" onChange={this.onSearch}/> : ''
|
||||
const loading = this.state.loading ? <Loading /> : ''
|
||||
return (
|
||||
<Router history={history}>
|
||||
<section className="content">
|
||||
{loading}
|
||||
<div className="search">
|
||||
<div className="container flex-container">
|
||||
<div className="nav">
|
||||
<NavLink className="nav-i" exact activeClassName="nav-i_active" to={`${this.rootPath}/`}>All</NavLink>
|
||||
<NavLink className="nav-i" activeClassName="nav-i_active" to={`${this.rootPath}/set`}>Set metadata</NavLink>
|
||||
<NavLink className="nav-i" activeClassName="nav-i_active" to={`${this.rootPath}/pending-changes`}>Pending changes</NavLink>
|
||||
</div>
|
||||
{search}
|
||||
</div>
|
||||
</div>
|
||||
<Route exact path={`${this.rootPath}/`} render={this.onAllValidatorsRender} web3Config={this.state}/>
|
||||
<Route path={`${this.rootPath}/set`} render={this.onSetRender} />
|
||||
<Route path={`${this.rootPath}/pending-changes`} render={this.onPendingChangesRender} />
|
||||
</section>
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<AppMainRouter />, document.getElementById('root'));
|
||||
registerServiceWorker();
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
%stretch-width {
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
%btn {
|
||||
cursor: pointer;
|
||||
transition: 0.3s background-color;
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
padding: 0 15px 0 32px;
|
||||
background-color: #08b3f2;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left 15px center;
|
||||
color: #fff;
|
||||
line-height: 36px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
background-color: #20bdf7;
|
||||
}
|
||||
|
||||
&-new {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAOUlEQVR42tXQsQEAIAgDQcAn+4+snRZxAK79KokrIcNBwgYdc0Migwxk8Qsd1TJWDf/KQWobqt+9G4coA99W7as5AAAAAElFTkSuQmCC);
|
||||
background-size: 12px 12px;
|
||||
}
|
||||
|
||||
&-vote {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAASCAMAAAB2Mu6sAAAAgVBMVEX///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+xZKUEAAAAKnRSTlMAAQIDPVBWYmNkZmpxeHp7fIOEhYaHiZeZmp6foKGio6TV2dze5unx9f63Mu9fAAAAgElEQVR4AXXO1w7CMBSD4VM2lFE2lD0I1O//gIBrCUUn/Hf5rCixRI3V695KeLMEcEn4Dp+C9z2+DZ0f6IXz4x8/0Sf63c/P9DEP7fDM5VkpZw8Ao9rX9JnVBWjJNvSlqW7F67GzAZdiS1+QooXNLaqvRe/6ZWquXuVcdW7XPJY3R9MVHwqyyb8AAAAASUVORK5CYII=);
|
||||
background-size: 12px 9px;
|
||||
}
|
||||
}
|
||||
|
||||
%item {
|
||||
margin-bottom: 30px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
}
|
|
@ -3,7 +3,10 @@ body {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#root {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
p, h1, h2, h3, h4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -33,10 +36,21 @@ body {
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
padding: 0px 10px;
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
|
||||
.key-content {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
background-color: #fbfbfb;
|
||||
text-align: center;
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
.hidden {
|
||||
display:none;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
%title {
|
||||
color: #333;
|
||||
text-transform: uppercase;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
%description {
|
||||
color: #8197a2;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.choose-key {
|
||||
@extend %item;
|
||||
padding: 30px;
|
||||
display: inline-block;
|
||||
|
||||
h1 {
|
||||
@extend %title;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@extend %description;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&-button {
|
||||
@extend %btn;
|
||||
display: inline-block;
|
||||
background-color: #08b3f2;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAMLWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjarVdnVBOJFv6mJIEQakIEpATpIIooTaR3QUA6rC0kAQIhxBRU7K7LKrh2sWBFV0VcdS2grAVR17qIvftQF5WVdbF3eT8ScNf3/rxz3j1nZr5z57v3fvfOnDlzAeMhQoVCRpoAxXK1MiUmXJCVnSNgtYEACQ64sBCKVIqw5OQEAOi5/tNeXwUBAJc8hQqFDP+bmYolKhFAJAPIFatExQCxF6CtRAqlGmC0AnCYoFaoAcZLADxlVnYOwNQDwMvXYmsAvFwt9gLAU6alRADMSECPIxQq8wGjZACCUlG+GjBSAPCSi6VywGg9gGBRgVAMGLUB6F9cXCIGjDkAXHP/lif/Hzlze3MKhfm9WNsLAEAvUqpSyIST8P+2Ypmmp0Y/AJwCZWwKAB5AbC0qiU8BwAGIg/LcxCQAZgBxSioGdPhmgSY2XcfvFKkicgDwARJiYWQ8AGuA5GuK0sN02FuoBLR8MlGqjkvT4VxlSYouP1kqlyUm6PLMKZDE9eC1ElVUag8nTxodB8AEIPeWFaRlanWSx0ulGYkAjACyVVWUGq+LvVtWEJHYw1FqUtIBOALkyzxldIqWQ1kUq3r6ogaIhFGpACwAKlRdkBarjaWyJKqshB4NYklklFYDJZbI03XaKLVCHZ6iiy1XyJJ1fGqtRBaTop0ztUtVmtoTe1GtTNPNnLpfKByerNVPvVaok9O02mgaCYhAJATQQIBclKAQ0pbOhk4IdHeiIYQS+ZDAU+fpiciEEErIIUQqyvAn5JBA1RsXDiGUkKAUcnzq9WrPnsiDEEqUQgIVivAQShTTVnQwHUgn0MF0KB1Me9P+dEBPnMC4pyozihnJjGVGM916dYhQAhlKoIT0v/jiIYMEGighgbynhy/5GA8ZFxj3GVcYbYwbyMDvUELawxornaX8SrkAI9AGjW4qEuRCjo4eDu1Me9M+dDgdRAfTARDQfNoKnvQQ2p8Oo0PoQNqHDviHQk2vti+z/LqeBPJ/9KPzG7kb+ehU5PY+mYhe1tdZIv42IzFKEP81k5pD7aFOUkep09RBqgEC6gi1nzpHHaIa/vYm/A4l8nurpUACOYogg7SH41Xn1eH18T+qC3UKlJBABaglE9UAEFGimKSU5heoBWEKhUwiiJOLBvQXeHsN8gWysnME2s/HCz4IAAT/zBff+CYgoAIg8r/4hA7AgYcA9/UXn8NzgLMQONQq0ihLtT4aABhgwxg8WMIWDnCFJ7zhi0CEIgrDkYQ0ZGMMRChAMZSYgCmYiXJUYiGWYRXWYSO24ifsRgMO4ih+xVm04gpuoQ3teIIuvMYHgiBYhCHBJSwJO8KJ8CC8CX8imIgiEogUIpsYR+QTckJDTCG+JSqJxcQqYgNRS/xMHCCOEqeJC8QN4h7RQTwn3pMUySF5pA3pTA4k/ckwMp5MI0eT+eR4soycTc4nV5A15HaynjxKniWvkG3kE/IVBcqA4lP2lCflT0VQSVQOlUcpqWlUBVVF1VA7qEbqJHWJaqM6qXc0k+bSAtqTDqRj6XRaRI+np9Hz6FX0VrqePk5fou/RXfRnhiHDmuHBGMqIY2Qx8hkTGOWMKsZmxj7GCcYVRjvjNZPJ5DNdmH7MWGY2s5A5mTmPuYa5k9nEvMB8wHzFYrEsWR6sIFYSS8hSs8pZK1nbWUdYF1ntrLd6Bnp2et560Xo5enK9WXpVetv0Dutd1Huk90HfRN9Jf6h+kr5Yf5L+Av1N+o365/Xb9T+wTdku7CB2GruQPZO9gr2DfYJ9m/3CwMCgn0GAwUgDqcEMgxUGuwxOGdwzeMcx47hzIjijOBrOfM4WThPnBueFoaGhs2GoYY6h2nC+Ya3hMcO7hm+NuEYDjOKMxEbTjaqN6o0uGj011jd2Mg4zHmNcZlxlvMf4vHGnib6Js0mEidBkmkm1yQGTayavTLmmg0yTTItN55luMz1t+tiMZeZsFmUmNpttttHsmNkDLsV14EZwRdxvuZu4J7jtPCbPhRfHK+RV8n7itfC6zM3Mh5hnmE80rzY/ZN7Gp/jO/Di+jL+Av5t/lf++j02fsD6SPnP77Ohzsc8bi74WoRYSiwqLnRZXLN5bCiyjLIssF1k2WN6xoq3crUZaTbBaa3XCqrMvr29gX1Hfir67+960Jq3drVOsJ1tvtD5n/crG1ibGRmGz0uaYTact3zbUttB2qe1h2w47rl2wndRuqd0Ruz8E5oIwgUywQnBc0GVvbR9rr7HfYN9i/6GfS7/0frP67ex3x4Ht4O+Q57DUodmhy9HOcYTjFMc6x5tO+k7+TgVOy51OOr1xdnHOdP7eucH5sYuFS5xLmUudy21XQ9cQ1/GuNa6X3Zhu/m5FbmvcWt1Jdx/3Avdq9/MepIevh9RjjceF/oz+Af3l/Wv6X/PkeIZ5lnrWed4bwB+QMGDWgIYBTwc6DswZuGjgyYGfvXy8ZF6bvG4NMhs0fNCsQY2Dnnu7e4u8q70vDzYcHD14+uD9g58N8RgiGbJ2yHUfrs8In+99mn0++fr5Kn13+Hb4OfqN81vtd82f55/sP8//VAAjIDxgesDBgHdDfYeqh+4e+legZ2BR4LbAx8NchkmGbRr2IKhfkDBoQ1BbsCB4XPD64LYQ+xBhSE3I/VCHUHHo5tBHYW5hhWHbw56Ge4Urw/eFv4kYGjE1oimSioyJrIhsiTKLSo9aFXU3ul90fnRddFeMT8zkmKZYRmx87KLYa3E2caK42riu4X7Dpw4/Hs+JT41fFX8/wT1BmdA4ghwxfMSSEbcTnRLliQ1JSIpLWpJ0J9kleXzyLyOZI5NHVo98mDIoZUrKyVRu6tjUbamv08LTFqTdSndN16Q3ZxhnjMqozXiTGZm5OLMta2DW1Kyz2VbZ0uz9OaycjJzNOa++ifpm2Tfto3xGlY+6Otpl9MTRp8dYjZGNOTTWeKxw7J5xjHGZ47aN+yhMEtYIX+XG5a7O7RJFiJaLnohDxUvFHZIgyWLJo7ygvMV5j/OD8pfkdxSEFFQVdEojpKukzwpjC9cVvilKKtpS1C3LlO0s1iseV3xAbiYvkh8vsS2ZWHJB4aEoV7SNHzp+2fguZbxys4pQjVbtV/PUCvU5javmO8290uDS6tK3EzIm7JloOlE+8dwk90lzJz0qiy77cTI9WTS5eYr9lJlT7k0Nm7phGjEtd1rzdIfps6e3z4iZsXUme2bRzN9mec1aPOvlt5nfNs62mT1j9oPvYr6rKzcqV5Zf+z7w+3Vz6DnSOS1zB89dOfdzhbjiTKVXZVXlx3mieWd+GPTDih+65+fNb1ngu2DtQuZC+cKri0IWbV1surhs8YMlI5bULxUsrVj6ctnYZaerhlStW85erlnetiJhxf6VjisXrvy4qmDVlerw6p2rrVfPXf1mjXjNxbWha3ess1lXue79eun66xtiNtTXONdUbWRuLN34cFPGppM/+v9Yu9lqc+XmT1vkW9q2pmw9XutXW7vNetuCOrJOU9exfdT21p8if9q/w3PHhp38nZW7sEuz64+fx/18dXf87uY9/nt27HXau3ofd19FPVE/qb6roaChbX/2/gsHhh9obgxs3PfLgF+2HLQ/WH3I/NCCw+zDsw93Hyk78qpJ0dR5NP/og+axzbeOZR27fHzk8ZYT8SdO/Rr967GTYSePnAo6dfD00NMHzvifaTjre7b+nM+5fb/5/Lavxbel/rzf+f2tAa2NF4ZdOHwx5OLRS5GXfr0cd/nslcQrF66mX71+bdS1tuvi649vyG48u1l688OtGbcZtyvumNypumt9t+Zfbv/a2ebbduhe5L1z91Pv33ogevDkd9XvH9tnPzR8WPXI7lHtY+/HBzuiO1r/+OaP9ieKJx86y/80/XP1U9ene/8K/etcV1ZX+zPls+7n815YvtjycsjL5lfJr+6+Ln794U3FW8u3W9/5vzv5PvP9ow8TPrI+rvjk9qnxc/zn293F3d0KoVIIAKAAkHl5wPMtgGE2wG0F2Eba/QsAQGh3RkD7D/LfsXZHAwD4AltCgfQZQEITsLYJcJoBcJqAZABpoSAHD+49dKbKG+ytzcVRAoy33d0vbABWI/BJ2d39YU1396dNAHUDaBqv3fsAgGkCrHcDgJZz7Clf71//BlLWbMT30dyZAAAAIGNIUk0AAG11AABzoAAA/N0AAINkAABw6AAA7GgAADA+AAAQkOTsmeoAAABmSURBVHjalJE5CoBAEARLMV8fZGjok40Uo32NH7AMPBBxVy2YZJiG7ulCJcEELEAHzMeyJM0CNEAPhHOrpqZWoxtRDWpW8ChCHf1OzGV45sVSuFmqfx2/hR7uH1KzPVR7ee21uHUAspX6H0FQzIIAAAAASUVORK5CYII=);
|
||||
|
||||
&:hover {
|
||||
background-color: #079dd4;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
outline: none;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
select {
|
||||
transition: 0.3s border-color;
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eee;
|
||||
|
||||
&:focus {
|
||||
border-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 0 15px;
|
||||
height: 36px;
|
||||
font-size: 11px;
|
||||
background: #fff;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
.create-keys-button-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center
|
||||
}
|
||||
.create-keys {
|
||||
@extend %item;
|
||||
padding: 30px 20px;
|
||||
|
||||
h1 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.set {
|
||||
margin-top: 20px;
|
||||
}
|
||||
&-button {
|
||||
@extend %btn;
|
||||
display: inline-block;
|
||||
background-color: #08b3f2;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAOUlEQVR42tXQsQEAIAgDQcAn+4+snRZxAK79KokrIcNBwgYdc0Migwxk8Qsd1TJWDf/KQWobqt+9G4coA99W7as5AAAAAElFTkSuQmCC);
|
||||
background-size: 12px 12px;
|
||||
|
||||
&[disabled] {
|
||||
background-color: #079dd4;
|
||||
}
|
||||
}
|
||||
|
||||
&-inputs {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.right {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.left,
|
||||
.right {
|
||||
display: table-cell;
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
label {
|
||||
&:not(.radio) {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
textarea {
|
||||
outline: none;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
transition: 0.3s border-color;
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eee;
|
||||
|
||||
&:focus {
|
||||
border-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
padding: 15px;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0 15px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
display: none;
|
||||
|
||||
&:checked + .radio:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
color: #fff;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
background-image: url(../images/bg_footer.png);
|
||||
background-image: url('../images/bg_footer.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
|
@ -17,14 +17,14 @@
|
|||
}
|
||||
|
||||
&-logo {
|
||||
@include image-2x('../images/VALIDATORS_footer@2x.png', 100px, 24px);
|
||||
@include image-2x('../images/CEREMONY_footer@2x.png', 100px, 24px);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
background-image: url(../images/VALIDATORS_footer.png);
|
||||
background-image: url('../images/CEREMONY_footer.png');
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
.header {
|
||||
@extend %stretch-width;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
padding: 18px 10px;
|
||||
background-image: url('../images/bg_header.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
&-settings {
|
||||
float: right;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
line-height: 39px;
|
||||
margin-right: 40px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-logo {
|
||||
@include image-2x('../images/CEREMONY@2x.png', 149px, 35px);
|
||||
float: left;
|
||||
width: 149px;
|
||||
height: 35px;
|
||||
background-image: url('../images/CEREMONY.png');
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
&-new-ballot {
|
||||
@extend %btn;
|
||||
@extend %btn-new;
|
||||
float: right;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,467 @@
|
|||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; }
|
||||
|
||||
html,
|
||||
body {
|
||||
color: #333;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
-webkit-font-smoothing: antialiased; }
|
||||
|
||||
.footer, .footer-rights, .header {
|
||||
left: 0;
|
||||
right: 0; }
|
||||
|
||||
.create-keys-button, .header-new-ballot {
|
||||
cursor: pointer;
|
||||
transition: 0.3s background-color;
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
padding: 0 15px 0 32px;
|
||||
background-color: #08b3f2;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left 15px center;
|
||||
color: #fff;
|
||||
line-height: 36px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold; }
|
||||
.create-keys-button:hover, .header-new-ballot:hover {
|
||||
background-color: #20bdf7; }
|
||||
.header-new-ballot {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAOUlEQVR42tXQsQEAIAgDQcAn+4+snRZxAK79KokrIcNBwgYdc0Migwxk8Qsd1TJWDf/KQWobqt+9G4coA99W7as5AAAAAElFTkSuQmCC);
|
||||
background-size: 12px 12px; }
|
||||
|
||||
.create-keys {
|
||||
margin-bottom: 30px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
color: #333; }
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
#root {
|
||||
display: table;
|
||||
width: 100%; }
|
||||
|
||||
p, h1, h2, h3, h4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Open Sans', sans-serif; }
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
background-position: center center; }
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
display: table;
|
||||
width: 100%;
|
||||
min-width: 960px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 80px 0 60px; }
|
||||
|
||||
.container {
|
||||
max-width: 960px;
|
||||
margin: 0 auto; }
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center; }
|
||||
|
||||
.content {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
background-color: #fbfbfb; }
|
||||
|
||||
.key-content {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
background-color: #fbfbfb;
|
||||
text-align: center; }
|
||||
|
||||
.left {
|
||||
float: left; }
|
||||
|
||||
.right {
|
||||
float: right; }
|
||||
|
||||
.hidden {
|
||||
display: none; }
|
||||
|
||||
button:focus {
|
||||
outline: none; }
|
||||
|
||||
.create-keys-button-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center; }
|
||||
|
||||
.create-keys {
|
||||
padding: 30px 20px; }
|
||||
.create-keys h1 {
|
||||
margin-bottom: 20px; }
|
||||
.create-keys h2 {
|
||||
margin-bottom: 20px; }
|
||||
.create-keys-button {
|
||||
display: inline-block;
|
||||
background-color: #08b3f2;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAOUlEQVR42tXQsQEAIAgDQcAn+4+snRZxAK79KokrIcNBwgYdc0Migwxk8Qsd1TJWDf/KQWobqt+9G4coA99W7as5AAAAAElFTkSuQmCC);
|
||||
background-size: 12px 12px; }
|
||||
.create-keys-button[disabled] {
|
||||
background-color: #079dd4; }
|
||||
.create-keys-inputs {
|
||||
display: table;
|
||||
width: 100%; }
|
||||
.create-keys .left {
|
||||
padding-right: 10px; }
|
||||
.create-keys .right {
|
||||
padding-left: 10px; }
|
||||
.create-keys .left,
|
||||
.create-keys .right {
|
||||
display: table-cell;
|
||||
width: 48%; }
|
||||
.create-keys label:not(.radio) {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold; }
|
||||
.create-keys button,
|
||||
.create-keys input,
|
||||
.create-keys textarea {
|
||||
outline: none;
|
||||
font-family: 'Open Sans', sans-serif; }
|
||||
.create-keys input,
|
||||
.create-keys textarea {
|
||||
transition: 0.3s border-color;
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eee; }
|
||||
.create-keys input:focus,
|
||||
.create-keys textarea:focus {
|
||||
border-color: #08b3f2; }
|
||||
.create-keys textarea {
|
||||
padding: 15px;
|
||||
height: 110px;
|
||||
resize: none; }
|
||||
.create-keys input {
|
||||
padding: 0 15px;
|
||||
height: 36px; }
|
||||
.create-keys input[type="radio"] {
|
||||
display: none; }
|
||||
.create-keys input[type="radio"]:checked + .radio:after {
|
||||
opacity: 1; }
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 0;
|
||||
padding: 15px 10px;
|
||||
color: #fff;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
background-image: url("../images/bg_footer.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; }
|
||||
.footer .container {
|
||||
position: relative;
|
||||
overflow: hidden; }
|
||||
.footer-logo {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
background-image: url("../images/CEREMONY_footer.png");
|
||||
background-position: 0 0; }
|
||||
@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) {
|
||||
.footer-logo {
|
||||
background-image: url("../images/CEREMONY_footer@2x.png");
|
||||
background-size: 100px 24px; } }
|
||||
.footer-rights {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
text-align: center; }
|
||||
|
||||
.header {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
padding: 18px 10px;
|
||||
background-image: url("../images/bg_header.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; }
|
||||
.header-settings {
|
||||
float: right;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
line-height: 39px;
|
||||
margin-right: 40px;
|
||||
font-size: 13px;
|
||||
font-weight: bold; }
|
||||
.header-logo {
|
||||
float: left;
|
||||
width: 149px;
|
||||
height: 35px;
|
||||
background-image: url("../images/CEREMONY.png");
|
||||
background-position: 0 0; }
|
||||
@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) {
|
||||
.header-logo {
|
||||
background-image: url("../images/CEREMONY@2x.png");
|
||||
background-size: 149px 35px; } }
|
||||
.header-new-ballot {
|
||||
float: right;
|
||||
margin-top: 3px; }
|
||||
|
||||
@keyframes fadeOut {
|
||||
0% {
|
||||
opacity: .2; }
|
||||
20% {
|
||||
opacity: 1;
|
||||
transform: scale(1); }
|
||||
100% {
|
||||
opacity: .2;
|
||||
transform: scale(0.3); } }
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 146px;
|
||||
margin: -30px 0 0 -81.5px;
|
||||
padding-top: 50px; }
|
||||
.loading:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 146px;
|
||||
height: 35px;
|
||||
background-image: url("../images/loading.png");
|
||||
background-position: 0 0; }
|
||||
@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) {
|
||||
.loading:before {
|
||||
background-image: url("../images/loading.png");
|
||||
background-size: 100% 100%; } }
|
||||
.loading-container {
|
||||
position: fixed;
|
||||
z-index: 1000000;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(35, 29, 115, 0.8); }
|
||||
.loading-i {
|
||||
animation-duration: 2s;
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: fadeOut;
|
||||
animation-timing-function: linear;
|
||||
opacity: .2;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
background-color: #fff; }
|
||||
.loading-i:nth-child(2) {
|
||||
animation-delay: .1s; }
|
||||
.loading-i:nth-child(3) {
|
||||
animation-delay: .2s; }
|
||||
.loading-i:nth-child(4) {
|
||||
animation-delay: .3s; }
|
||||
.loading-i:nth-child(5) {
|
||||
animation-delay: .4s; }
|
||||
.loading-i:nth-child(6) {
|
||||
animation-delay: .5s; }
|
||||
|
||||
.socials {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
float: right;
|
||||
font-size: 0; }
|
||||
.socials-i {
|
||||
transition: 0.3s background-color;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-left: 10px;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(255, 255, 255, 0.2); }
|
||||
@media screen and (min-width: 768px) {
|
||||
.socials-i:hover {
|
||||
background-color: rgba(255, 255, 255, 0.4); } }
|
||||
.socials-i:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
background-image: url(../images/socials.png); }
|
||||
@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) {
|
||||
.socials-i:before {
|
||||
background-image: url("../images/socials@2x.png");
|
||||
background-size: 15px 40px; } }
|
||||
.socials-i_reddit:before {
|
||||
width: 15px;
|
||||
height: 13px;
|
||||
margin: -6.5px 0 0 -7.5px;
|
||||
background-position: 0 -15px; }
|
||||
.socials-i_twitter:before {
|
||||
width: 15px;
|
||||
height: 12px;
|
||||
margin: -6px 0 0 -7.5px;
|
||||
background-position: 0 -28px; }
|
||||
.socials-i_bitcoin:before {
|
||||
width: 11px;
|
||||
height: 15px;
|
||||
margin: -7.5px 0 0 -5.5px;
|
||||
background-position: 0 0; }
|
||||
|
||||
.validators {
|
||||
text-align: left; }
|
||||
.validators-i {
|
||||
margin-bottom: 30px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
color: #333; }
|
||||
.validators-i .confirmations {
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
padding-top: 5px; }
|
||||
.validators-header {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 25px 20px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center; }
|
||||
.validators-header .left {
|
||||
flex: 1; }
|
||||
.validators-header .finalize {
|
||||
margin-right: 20px; }
|
||||
.validators-body {
|
||||
overflow: hidden;
|
||||
padding: 0 20px 20px; }
|
||||
.validators-notary, .validators-license {
|
||||
width: 48%; }
|
||||
.validators-title {
|
||||
text-transform: uppercase;
|
||||
margin: 20px 0;
|
||||
color: #8197a2;
|
||||
font-size: 12px;
|
||||
font-weight: bold; }
|
||||
.validators-table {
|
||||
border: 1px solid #eee; }
|
||||
.validators-table-tr {
|
||||
overflow: hidden;
|
||||
padding: 0 10px; }
|
||||
.validators-table-tr:not(:last-child) {
|
||||
border-bottom: 1px solid #eee; }
|
||||
.validators-table-td {
|
||||
padding: 10px 0;
|
||||
font-size: 12px; }
|
||||
|
||||
.nav {
|
||||
font-size: 0; }
|
||||
.nav-i {
|
||||
transition: 0.3s color;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 40px;
|
||||
color: #8197a2;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
line-height: normal;
|
||||
font-size: 14px;
|
||||
font-weight: bold; }
|
||||
.nav-i:hover, .nav-i_active {
|
||||
color: #444; }
|
||||
.nav-i_active:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -30px;
|
||||
height: 3px;
|
||||
background-color: #08b3f2; }
|
||||
|
||||
.search {
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
line-height: 80px;
|
||||
text-align: left; }
|
||||
.search .back {
|
||||
transition: 0.3s opacity;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAMAAACgaw2xAAAAjVBMVEUAtfX///8AtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUmVRXZAAAALnRSTlMAAAQKDxAXISIpKzc+P1laYm1vdneQlJWjpKyvs7W2ycrP0NLY3uDh4u3u+f3+FQ2PgAAAAJlJREFUGNOV0ckSgjAQRdEWghMiKiLihBOiIPf/P88FSEEiC98yp6o79VrkG3uZPRYigzrN+zAEChMme6CMDfASoNgoHfwUeAWWdMFa50A6F+mCExXAeSYajA/AO1SigXsFKJPd8dTKdip3fubWD+6lZ5SMquWOvlxEVd/1DBAryIHUN6CuJDcqaUqMVE/txH8cSsRePbPWaT+TOR0SIiH2HAAAAABJRU5ErkJggg==);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
background-size: 12px 10px;
|
||||
padding-left: 20px;
|
||||
color: #08b3f2;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: bold; }
|
||||
.search .back:hover {
|
||||
opacity: 0.8; }
|
||||
.search .container {
|
||||
position: relative; }
|
||||
.search-input {
|
||||
display: block;
|
||||
transition: 0.3s width, 0.3s border-color;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
margin: -20px 0 0;
|
||||
outline: none;
|
||||
border-radius: 5px;
|
||||
border: 1px solid transparent;
|
||||
box-sizing: border-box;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAA6lBMVEWAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6PrSx+9AAAATXRSTlMAAgMGCAkKDA0UFRYXISIjJDM0NTo7PD0/QEFERUlQWVpoaWp0dXaZm5ydnqSlpra4ub/AwcTFxsjKzM3Oz9bX2N3e6ers7fX5+vz9/pKojzsAAAGRSURBVHgBjZRtX4IwFMUXmKaBYmhWauSzEmkl+ZAaaJGo8P2/TnejEGHrt/PqcM9f2cbdRVHJDWPhuK6zMBoyYkrQJp4fyptoAp2rWn5MVpWCpXo+Rb1UnMvNg/eZ3bIkilK5YwarmOdinI2rB105lhT9gGv2CZme4dpGPf21usHVWTpS6uPKaxbFlDVxvR/ZL35+EVFC4jNOwr2ffeC1XCCKMnjt1t95avCwVxFV6h5C7ffhDbyOGBpAOAmsDCfmKSxQwWme2Cb8ZoyYGkPcJM4A12WDXYgN4lbgrtlgBeIlcQ44iQ1KEH8T54IT2aAIscsP8r+abzMr4p7AdXiOh/vA8/9/wgP5hGFTDDiaImizKzpXjLaZYOHuzFAbl0TCyVUY0a7CCCe1Y+GRkIn/zBBOT1xXqxhbXzBj6rQBUDiWCjAAiLY3UfLy3Seo2S7hkVJqmxijkef0IVXfJkhUs+OYDfu9o5CCNvUi2PSBnN9tkgTJreHS2e2c5bBFRjOVpCskK7zkGnGSn4hHlfXX/Q90qIZ+dL9jIAAAAABJRU5ErkJggg==);
|
||||
background-size: 20px 20px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 10px center;
|
||||
color: #333;
|
||||
font-size: 14px; }
|
||||
.search-input:focus {
|
||||
cursor: text;
|
||||
width: 300px;
|
||||
border-color: #eee;
|
||||
padding: 0 40px 0 10px; }
|
|
@ -0,0 +1,15 @@
|
|||
@import './_0_fonts';
|
||||
@import './_1_mixins';
|
||||
@import './_2_placeholders';
|
||||
@import './_3_base';
|
||||
@import './addition';
|
||||
@import './create-keys';
|
||||
@import './footer';
|
||||
@import './header';
|
||||
@import './loading';
|
||||
@import './socials';
|
||||
@import './validators.scss';
|
||||
@import './nav';
|
||||
@import './search';
|
||||
// @import './new-ballot';
|
||||
// @import './vote';
|
|
@ -0,0 +1,124 @@
|
|||
.keys {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 60px;
|
||||
text-align: left;
|
||||
|
||||
$_this: &;
|
||||
|
||||
&-i {
|
||||
position: relative;
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
width: 33.33%;
|
||||
box-sizing: border-box;
|
||||
padding: 0 15px 60px 15px;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-left: 1px solid #e1e1e1;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: 10px;
|
||||
@extend %title;
|
||||
}
|
||||
|
||||
&-hash {
|
||||
height: 30px;
|
||||
color: #6d2eae;
|
||||
line-height: 16px;
|
||||
font-size: 12px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&-hash-container {
|
||||
display: table;
|
||||
}
|
||||
|
||||
&-description {
|
||||
@extend %description;
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
bottom: 0;
|
||||
|
||||
#{$_this}-i:first-child & {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-download,
|
||||
&-read-more {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&-download {
|
||||
@extend %btn;
|
||||
background-color: #6d2eae;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAANlBMVEX///////////////////////////////////////////////////////////////////////8BOg0gAAAAEXRSTlMASUtWV1hZXF1e5ebn6Orr/GN0dVoAAABnSURBVHja1cnJDYBADENRDzBsYYn7bxaCFFmMaADf/B+0YlbwNSPtE3jvv9Ad29DCsB0dVtKnN8xOGowhCdm5o/eUgOw+AktKQPYFkDygLglQhyRAXZLzWV2iLlFvRb2V7O3qeVa9C41xDOyv+UmuAAAAAElFTkSuQmCC);
|
||||
|
||||
&:hover {
|
||||
background-color: #5d2795;
|
||||
}
|
||||
}
|
||||
|
||||
&-read-more {
|
||||
margin-left: 10px;
|
||||
color: #6d2eae;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&-note {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1px solid #6d2eae;
|
||||
border-radius: 5px;
|
||||
padding: 20px 15px 20px 53px;
|
||||
background-color: rgba(109, 46, 174, 0.1);
|
||||
color: #6d2eae;
|
||||
text-align: left;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 42px;
|
||||
background-color: #6d2eae;
|
||||
background-image: url(../images/warning.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: 10px;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,14 +23,14 @@
|
|||
padding-top: 50px;
|
||||
|
||||
&:before {
|
||||
@include image-2x('../images/loading@2x.png');
|
||||
@include image-2x('../images/loading.png');
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 146px;
|
||||
height: 35px;
|
||||
background-image: url(../images/loading.png);
|
||||
background-image: url('../images/loading.png');
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
.nav {
|
||||
font-size: 0;
|
||||
|
||||
&-i {
|
||||
transition: 0.3s color;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 40px;
|
||||
color: #8197a2;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
line-height: normal;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover,
|
||||
&_active {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
&_active {
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -30px;
|
||||
height: 3px;
|
||||
background-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
.new-ballot {
|
||||
@extend %item;
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 30px;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
|
||||
&-inputs {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left,
|
||||
.right {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
label {
|
||||
&:not(.radio) {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
textarea {
|
||||
outline: none;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
transition: 0.3s border-color;
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eee;
|
||||
|
||||
&:focus {
|
||||
border-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
padding: 15px;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0 15px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
display: none;
|
||||
|
||||
&:checked + .radio:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.radio {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
margin-top: 20px;
|
||||
margin-right: 40px;
|
||||
font-size: 12px;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #d8d9db;
|
||||
}
|
||||
|
||||
&:after {
|
||||
transition: 0.3s opacity;
|
||||
opacity: 0;
|
||||
left: 5px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: -5px;
|
||||
background-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
margin-top: 10px;
|
||||
color: #8197a2;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
&-add {
|
||||
@extend %btn;
|
||||
@extend %btn-vote;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
|
@ -5,15 +5,25 @@
|
|||
line-height: 80px;
|
||||
text-align: left;
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: #333;
|
||||
text-transform: uppercase;
|
||||
.back {
|
||||
transition: 0.3s opacity;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAMAAACgaw2xAAAAjVBMVEUAtfX///8AtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUAtfUmVRXZAAAALnRSTlMAAAQKDxAXISIpKzc+P1laYm1vdneQlJWjpKyvs7W2ycrP0NLY3uDh4u3u+f3+FQ2PgAAAAJlJREFUGNOV0ckSgjAQRdEWghMiKiLihBOiIPf/P88FSEEiC98yp6o79VrkG3uZPRYigzrN+zAEChMme6CMDfASoNgoHfwUeAWWdMFa50A6F+mCExXAeSYajA/AO1SigXsFKJPd8dTKdip3fubWD+6lZ5SMquWOvlxEVd/1DBAryIHUN6CuJDcqaUqMVE/txH8cSsRePbPWaT+TOR0SIiH2HAAAAABJRU5ErkJggg==);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
background-size: 12px 10px;
|
||||
padding-left: 20px;
|
||||
color: #08b3f2;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-input {
|
||||
|
@ -25,7 +35,7 @@
|
|||
z-index: 1;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
width: 40px;
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
margin: -20px 0 0;
|
||||
outline: none;
|
|
@ -7,6 +7,12 @@
|
|||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
|
||||
.confirmations {
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
|
@ -14,6 +20,17 @@
|
|||
padding: 25px 20px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
}
|
||||
.finalize {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&-body {
|
||||
|
@ -51,4 +68,4 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
.vote {
|
||||
text-align: left;
|
||||
|
||||
&-i {
|
||||
@extend %item;
|
||||
}
|
||||
|
||||
&-body {
|
||||
display: table;
|
||||
width: 100%;
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 0;
|
||||
|
||||
&-i {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
width: 33.333%;
|
||||
box-sizing: border-box;
|
||||
padding: 30px 20px;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
|
||||
&:nth-child(2n) {
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
%title {
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
color: #8197a2;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-title {
|
||||
@extend %title;
|
||||
|
||||
&-secondary {
|
||||
@extend %title;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
color: #444;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
overflow: hidden;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
&-now {
|
||||
@extend %btn;
|
||||
@extend %btn-vote;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
&-person {
|
||||
position: relative;
|
||||
padding-left: 50px;
|
||||
|
||||
&-img {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
&-name {
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-choose {
|
||||
padding-left: 20px;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAAAw1BMVEWAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6OAl6M9jT1MAAAAQHRSTlMAAQIDBQYHDA0bHB8gISQmJyg+P0BGR0lKU1RZYmNrbHV2iYqLo6Spqqusra7Cw8TFysvM29zk5ufo6/Lz+Pn8DzgVHgAAATNJREFUeNplk+1agkAQhQfRykQTrJTEUjSCvtTQECPk/q+qPQ7LsnR+7DOzL898LiRlOP46zfN0vXQM0tXydkWlndeqs/620LTtK3Z7LBo6OpLd5fDzl6nVubSnIXv3zIY/8N4HVGrwBj8bwjaR77SgmhYn5DWF5eE7ZoribkZkoIeI78ZJMmYrQkcGjZD9mq+SokjY6qKqEfniDIiFYMR6FqZPn+J8+A9dYX5QKs5eBaFz3p4wUkLwizrkvB2UcoZXJUwYHiqIsDclnBzAvicyrFYQpBW0lK0oqVbkEHR1fzEEHl/YhCHG1yKaoYi5zubl4Mn8wsqe6uwRK4tNmHaG717VsiP4mV1uih9G4FrttuUG7GGGTLOioUwyRI51Ftv6o94rtNcfNbCz2uB32KycCv0BfU5XCrQEyKwAAAAASUVORK5CYII=);
|
||||
background-size: 14px 14px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
color: #8197a2;
|
||||
line-height: 14px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&-time {
|
||||
color: #8197a2;
|
||||
|
||||
&-timer {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-to {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&-rating {
|
||||
overflow: hidden;
|
||||
padding: 30px 20px;
|
||||
|
||||
&-i {
|
||||
width: 48%;
|
||||
color: #8197a2;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
|
||||
strong {
|
||||
margin-right: 5px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
&-value,
|
||||
&-got {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&-scale {
|
||||
clear: left;
|
||||
height: 10px;
|
||||
border-radius: 5px;
|
||||
background-color: #efefef;
|
||||
|
||||
$this: &;
|
||||
|
||||
&-active {
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
&_yes {
|
||||
#{$this}-active {
|
||||
background-color: #08b3f2;
|
||||
}
|
||||
}
|
||||
|
||||
&_no {
|
||||
#{$this}-active {
|
||||
background-color: #6d2eae;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-tooltip {
|
||||
transform: translate3d(0,-10px,0);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
transition: opacity 0.3s, transform 0.3s;
|
||||
left: -275px;
|
||||
top: 0;
|
||||
width: 578px;
|
||||
padding-top: 30px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:before {
|
||||
transform: rotate(-45deg);
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 50%;
|
||||
top: 22px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-left: -12px;
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0 20px 0 fade-out(#000, 0.9);
|
||||
}
|
||||
|
||||
$this: &;
|
||||
|
||||
&-text {
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
padding: 25px;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&-shadow {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 30px;
|
||||
bottom: 0;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 20px 40px 0 fade-out(#000, 0.7);
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&-description {
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
text-transform: none;
|
||||
|
||||
a {
|
||||
color: #08b3f2;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-icon {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-top: -6px;
|
||||
border-radius: 50%;
|
||||
background-color: #08b3f2;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAYCAMAAADqO6ysAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAJUlEQVQI12NgZGFhZGBhY2MBEawMTKzMTAzYAEIdGxCQS8DtAABR5AGfy9XNLgAAAABJRU5ErkJggg==);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 2px 12px;
|
||||
}
|
||||
|
||||
&-container {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
float: right;
|
||||
|
||||
&:hover {
|
||||
#{$this} {
|
||||
pointer-events: auto;
|
||||
opacity: 1;
|
||||
transform: translate3d(0,0,0) rotate3d(0,0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vote-rating-yes,
|
||||
.vote-rating-no {
|
||||
@extend %btn;
|
||||
@extend %btn-vote;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.vote-rating-no {
|
||||
background-color: #6d2eae;
|
||||
|
||||
&:hover {
|
||||
background-color: #5d2795;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,108 @@
|
|||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|