diff --git a/.gitignore b/.gitignore index 14dc2ca81..42b904a92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Common +.DS_Store +.idea + # Logs logs *.log @@ -36,6 +40,7 @@ jspm_packages # Optional REPL history .node_repl_history + # local data data/ config.json diff --git a/README.md b/README.md index 91a8a4f97..d005022c4 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,10 @@ -# ETC Explorer - -ETC Explorer logo - -Live Version: [etherhub.io](http://etherhub.io) - -Follow the project progress at: [ETC Block Explorer Development](https://github.com/ethereumclassic/explorer) +# Papyrus Explorer ## Local installation Clone the repo -`git clone https://github.com/ethereumclassic/explorer` +`git clone https://github.com/papyrusglobal/explorer` Download [Nodejs and npm](https://docs.npmjs.com/getting-started/installing-node "Nodejs install") if you don't have them diff --git a/abi/bios.json b/abi/bios.json new file mode 100644 index 000000000..efd707323 --- /dev/null +++ b/abi/bios.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address[]","name":"_sealers","type":"address[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addNewPoll","outputs":[{"internalType":"uint256","name":"closeTime","type":"uint256"},{"internalType":"uint256","name":"votes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorityBlackList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorityBlacklistPoll","outputs":[{"internalType":"uint256","name":"closeTime","type":"uint256"},{"internalType":"uint256","name":"votes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorityStates","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contractStakeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"freeze","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"contract_","type":"address"}],"name":"freezeForContract","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getAddNewPollAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAuthorities","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAuthorityBlacklistPollAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"authority","type":"address"}],"name":"getAuthorityState","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"},{"internalType":"address[7]","name":"","type":"address[7]"},{"internalType":"uint256[7]","name":"","type":"uint256[7]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getFreeMeltingSlots","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMeltingHead","outputs":[{"internalType":"uint224","name":"stake","type":"uint224"},{"internalType":"uint32","name":"timestamp","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMeltingSlots","outputs":[{"internalType":"uint224[]","name":"","type":"uint224[]"},{"internalType":"uint32[]","name":"","type":"uint32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"handleClosedPolls","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint224","name":"val","type":"uint224"}],"name":"melt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint224","name":"val","type":"uint224"}],"name":"meltFromContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"melting","outputs":[{"internalType":"uint8","name":"top","type":"uint8"},{"internalType":"uint8","name":"bottom","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"candidate","type":"address"}],"name":"ownerAddNewAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"candidate","type":"address"}],"name":"ownerBlacklistAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"candidate","type":"address"}],"name":"ownerRemoveFromBlacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"participant","type":"address"}],"name":"proposeBlacklistAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"participant","type":"address"}],"name":"proposeNewAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"neo","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"participant","type":"address"}],"name":"voteForBlackListAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"address","name":"participant","type":"address"}],"name":"voteForNewAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/app.js b/app.js index a0ffb12b7..1c5ccbc3d 100644 --- a/app.js +++ b/app.js @@ -7,19 +7,10 @@ const path = require('path'); const favicon = require('serve-favicon'); const logger = require('morgan'); const bodyParser = require('body-parser'); +const { getConfig } = require('./utils'); -let config = {}; -try { - config = require('./config.json'); -} catch (e) { - if (e.code == 'MODULE_NOT_FOUND') { - console.log('No config file found. Using default configuration... (config.example.json)'); - config = require('./config.example.json'); - } else { - throw e; - process.exit(1); - } -} + +const config = getConfig(); const app = express(); app.set('port', process.env.PORT || 3000); diff --git a/config.example.json b/config.example.json index 347b672a5..fab83a669 100644 --- a/config.example.json +++ b/config.example.json @@ -8,20 +8,15 @@ "patch": true, "patchBlocks": 100, "bulkSize": 100, + "biosAddress": "0x82e3FB6449b7cb18bD9095B963e3E5863d21F8B4", "settings": { - "symbol": "ETC", - "name": "Ethereum Classic", - "title": "Ethereum Classic Block Explorer", + "symbol": "PPR", + "name": "Papyrus", + "title": "Papyrus Explorer", "author": "Elaine, Cody, Hackmod, Bakon", - "contact": "mailto:ethereumclassicanthony@gmail.com", - "about": "This is an open source Blockchain Explorer.", - "rss": "https://ethereumclassic.org", - "reddit": "https://www.reddit.com/r/EthereumClassic", - "twitter": "https://twitter.com/eth_classic", - "linkedin": "https://www.linkedin.com/company/ethereum-classic", - "github": "https://github.com/ethereumclassic", + "about": "This is an open source Blockchain Explorer based on Ethereum Classic Explorer.", "logo": "/img/explorer-logo.png", - "copyright": "2019 © Ethereum Classic.", + "copyright": "Papyrus Explorer", "poweredbyCustom": false, "poweredbyEtcImage": "/img/powered-by-etcexplorer-w.png", "poweredbyEtc": true, @@ -29,29 +24,11 @@ "useRichList": true, "useFiat": true, "miners": { - "0xdf7d7e053933b5cc24372f878c90e62dadad5d42": "EtherMine", - "0xc91716199ccde49dc4fafaeb68925127ac80443f": "F2Pool", - "0x9eab4b0fc468a7f5d46228bf5a76cb52370d068d": "NanoPool", - "0x1C0FA194a9d3B44313DCD849F3C6be6Ad270a0A4": "MiningPoolHub", - "0x4750e296949b747df1585aa67beee8be903dd560": "UUPool", - "0xef224fa5fad302b51f38898f4df499d7af127af0": "91pool", - "0x0073Cf1B9230cF3EE8Cab1971B8DbeF21eA7B595": "2miners", - "0x4c2b4e716883a2c3f6b980b70b577e54b9441060": "ETCPool PL", - "0xd144e30a0571aaf0d0c050070ac435deba461fab": "Clona Network", - "0x568f58bf1667504fdf5aa02d776c156f940178a5": "Whalesburg", - "0x999c2944807874d3677ee3c6065c8a8a92721ac5": "NinjaPool.jp", - "0x39cd14977601184b7da518fd352261aad0cb9fd3": "91pool", - "0xf35074bbd0a9aee46f4ea137971feec024ab704e": "Solo Mining Pools", - "0xa97ed75172773ec705c2c78d999d3203199101bd": "epool", - "0x87cfd09c483fe65352456bb26c784a0e4c4ba389": "ArsMine", - "0x0073cf1b9230cf3ee8cab1971b8dbef21ea7b595": "2miners", - "0x004730417cd2b1d19f6be2679906ded4fa8a64e2": "2miners", - "0x1c0fa194a9d3b44313dcd849f3c6be6ad270a0a4": "MiningPoolHub", - "0x8c5535afdbdeea80adedc955420f684931bf91e0": "MiningPoolHub", - "0xfe0ca4e9d8b83ff2d03ef4f35f0b5f754e81d1fd": "Hiveon Pool", - "0xeda79f0735a56510876a497e1c105916666b0199": "Comining", - "0xd3bfd58a31ddeb2fdd2bc212e38c41725bc93ccd": "EtherDig HVPPS", - "0xf35074bbd0a9aee46f4ea137971feec024ab704e": "solopool.org" - } + "0x21b63aC543f1A418684AbB30307262A13ab4D0E5": "testnet2-head", + "0x743Cf78AdE27abD94C4588eD30CAD1425ECcEfF3": "testnet2-node2", + "0x6a47f2e17ba215f02db9a14a4a3793d0397d35f5": "testnet2-node3", + "0x9d308ffc5cb47378443636774e7f9dc007fc5db3": "testnet2-node4", + "0xe2740ad38baf1f87fb0b97144605b9a6f51bd617": "testnet2-node5" + } } } diff --git a/db.js b/db.js index 46885bb1b..05e705956 100644 --- a/db.js +++ b/db.js @@ -112,6 +112,43 @@ const Market = new Schema( }, { collection: 'Market' }, ); +const Poll = new Schema( + { + address: { type: String, }, + type: { type: Number, default: 0 }, // 0 — authority, 1 - blacklist + closeTime: { type: Number }, + votes: { type: Number, default: 0 }, + isVoted: { type: Boolean, default: false }, + isDisabled: { type: Boolean, default: false } + }, + { collection: 'Poll' } +); + +const AuthoritySlot = new Schema( + { + address: { type: String, default: '0x0000000000000000000000000000000000000000' }, + timestamp: { type: Number, default: 0 } + }, + { _id : false } +); + +const Authority = new Schema( + { + address: { type: String, index: { unique: true } }, + votes: { type: Number, default: 0 }, + slots: [AuthoritySlot] + }, + { collection: 'Authority' } +); + +const Blacklist = new Schema( + { + address: { type: String, index: { unique: true } }, + votes: { type: Number, default: 0 }, + }, + { collection: 'Blacklist' } +) + // create indices Transaction.index({ blockNumber: -1 }); Transaction.index({ from: 1, blockNumber: -1 }); @@ -128,6 +165,10 @@ TokenTransfer.index({ blockNumber: -1 }); TokenTransfer.index({ from: 1, blockNumber: -1 }); TokenTransfer.index({ to: 1, blockNumber: -1 }); TokenTransfer.index({ contract: 1, blockNumber: -1 }); +Poll.index({ address: 1, isDisabled: 1, type: 1 }); +Poll.index({ address: 1, isDisabled: 1, isVoted: 1 }); +Poll.index({ address: 1, isDisabled: 1, isVoted: 1, type: 1, }); +Blacklist.index({ address: 1 }); mongoose.model('BlockStat', BlockStat); mongoose.model('Block', Block); @@ -136,6 +177,10 @@ mongoose.model('Contract', Contract); mongoose.model('Transaction', Transaction); mongoose.model('Market', Market); mongoose.model('TokenTransfer', TokenTransfer); +mongoose.model('Poll', Poll); +mongoose.model('Authority', Authority); +mongoose.model('AuthoritySlot', AuthoritySlot); +mongoose.model('Blacklist', Blacklist); module.exports.BlockStat = mongoose.model('BlockStat'); module.exports.Block = mongoose.model('Block'); module.exports.Contract = mongoose.model('Contract'); @@ -143,6 +188,10 @@ module.exports.Transaction = mongoose.model('Transaction'); module.exports.Account = mongoose.model('Account'); module.exports.Market = mongoose.model('Market'); module.exports.TokenTransfer = mongoose.model('TokenTransfer'); +module.exports.Poll = mongoose.model('Poll'); +module.exports.Authority = mongoose.model('Authority'); +module.exports.AuthoritySlot = mongoose.model('AuthoritySlot'); +module.exports.Blacklist = mongoose.model('Blacklist'); mongoose.Promise = global.Promise; mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost/explorerDB', { @@ -153,4 +202,5 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost/explorerDB', { // pass: 'yourdbpasscode' }); + // mongoose.set('debug', true); diff --git a/docker-compose.yml b/docker-compose.yml index 08df876a1..e5ee3bbd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,14 @@ services: MONGO_URI: 'mongodb://db/explorerDB' depends_on: - db + sync-votes: + build: . + command: ./tools/sync-votes.js + restart: always + environment: + MONGO_URI: 'mongodb://db/explorerDB' + depends_on: + - db stats: build: . command: ./tools/stats.js diff --git a/package-lock.json b/package-lock.json index c4d847dc4..ddff2f88c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,20 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.1.tgz", "integrity": "sha512-Rymt08vh1GaW4vYB6QP61/5m/CFLGnFZP++bJpWbiNxceNa6RBipDmb413jvtSf/R1gg5a/jQVl2jY4XVRscEA==" }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "requires": { + "xtend": "~4.0.0" + } + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -66,6 +80,15 @@ "uri-js": "^4.2.2" } }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -96,6 +119,27 @@ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -183,6 +227,12 @@ "lodash": "^4.14.0" } }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -295,6 +345,12 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz", "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==" }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -303,6 +359,14 @@ "file-uri-to-path": "1.0.0" } }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", @@ -376,6 +440,29 @@ "type-is": "~1.6.16" } }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -577,6 +664,12 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==" }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -628,6 +721,43 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -660,6 +790,12 @@ } } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -761,6 +897,20 @@ "yargs": "^12.0.1" } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", @@ -821,6 +971,15 @@ "elliptic": "^6.0.0" } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -876,6 +1035,12 @@ "randomfill": "^1.0.3" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1017,12 +1182,26 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1132,6 +1311,25 @@ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -1189,6 +1387,14 @@ "once": "^1.4.0" } }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1467,6 +1673,53 @@ "xhr-request-promise": "^0.1.2" } }, + "ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" + }, + "ethereumjs-block": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + }, + "dependencies": { + "ethereum-common": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", + "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" + } + } + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, "ethers": { "version": "4.0.0-beta.1", "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.0-beta.1.tgz", @@ -1537,6 +1790,15 @@ } } }, + "ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, "eventemitter3": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", @@ -2013,6 +2275,554 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, "fstream": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", @@ -2032,8 +2842,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "get-caller-file": { "version": "1.0.3", @@ -2081,6 +2890,16 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", @@ -2090,6 +2909,15 @@ "process": "~0.5.1" } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -2378,6 +3206,17 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" + }, "import-fresh": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", @@ -2396,6 +3235,12 @@ } } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2495,6 +3340,15 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -2506,6 +3360,15 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -2586,11 +3449,27 @@ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -2611,11 +3490,26 @@ } } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -2636,6 +3530,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -2813,6 +3713,15 @@ "graceful-fs": "^4.1.9" } }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -2821,6 +3730,119 @@ "invert-kv": "^2.0.0" } }, + "level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" + }, + "level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + }, + "dependencies": { + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + } + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -2902,6 +3924,11 @@ "yallist": "^2.1.2" } }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -2958,6 +3985,29 @@ "p-is-promise": "^2.0.0" } }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "requires": { + "xtend": "~4.0.0" + } + } + } + }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -2968,6 +4018,28 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -3330,6 +4402,59 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" }, + "nodemon": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", + "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -3341,6 +4466,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -3592,6 +4723,45 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==" }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + } + } + }, "parent-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", @@ -3649,6 +4819,12 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -3839,6 +5015,11 @@ "ipaddr.js": "1.8.0" } }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -3849,6 +5030,12 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "dev": true + }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -3929,6 +5116,26 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "read-pkg": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", @@ -4019,6 +5226,17 @@ "util-deprecate": "~1.0.1" } }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -4040,6 +5258,31 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -4240,6 +5483,28 @@ "pbkdf2": "^3.0.3" } }, + "secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + } + } + }, "seek-bzip": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", @@ -4248,11 +5513,25 @@ "commander": "~2.8.1" } }, + "semaphore": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" + }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", @@ -5048,6 +6327,49 @@ } } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5135,6 +6457,15 @@ "repeat-string": "^1.6.1" } }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -5220,6 +6551,15 @@ "through": "^2.3.8" } }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -5260,6 +6600,15 @@ } } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -5305,6 +6654,36 @@ } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -5638,7 +7017,7 @@ "requires": { "underscore": "1.8.3", "web3-core-helpers": "1.0.0-beta.37", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" + "websocket": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" } }, "web3-shh": { @@ -5705,6 +7084,15 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -5767,6 +7155,17 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", @@ -5777,6 +7176,12 @@ "ultron": "~1.1.0" } }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xhr": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", diff --git a/package.json b/package.json index cf1452920..dcd232efb 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "repository": "https://github.com/ethereumclassic/explorer", "license": "MIT", "scripts": { - "start": "concurrently \"node tools/sync.js \" \"node app.js\" ", + "start": "concurrently \"nodemon tools/sync.js \" \"nodemon tools/sync-votes.js\" \"nodemon app.js\"", "app": "node app.js", "sync": "node tools/sync.js", + "sync-votes": "node tools/sync/votes.js", "stats": "node tools/stats.js", "rich": "node tools/richlist.js", "test": "mocha --exit", @@ -19,6 +20,8 @@ "body-parser": "^1.18.3", "concurrently": "4.1.0", "ejs": "2.6.1", + "ethereumjs-block": "1.7.1", + "ethereumjs-util": "5.2.0", "express": "^4.16.4", "human-standard-token-abi": "^2.0.0", "mongoose": "^4.13.18", @@ -37,6 +40,7 @@ "eslint-plugin-import": "^2.16.0", "html-linter": "^1.1.1", "mocha": "^6.0.2", + "nodemon": "^1.19.1", "request": "^2.88.0" } } diff --git a/public/.DS_Store b/public/.DS_Store new file mode 100644 index 000000000..5008ddfcf Binary files /dev/null and b/public/.DS_Store differ diff --git a/public/css/default.css b/public/css/default.css index 9c6b81281..9961eb73b 100755 --- a/public/css/default.css +++ b/public/css/default.css @@ -75,4 +75,4 @@ a:hover { a.scrollup{ background:#35A49C; -} \ No newline at end of file +} diff --git a/public/css/papyrus-theme.css b/public/css/papyrus-theme.css new file mode 100644 index 000000000..55e559794 --- /dev/null +++ b/public/css/papyrus-theme.css @@ -0,0 +1,494 @@ +@import url('https://fonts.googleapis.com/css?family=Lekton:400,400i,700&display=swap&subset=latin-ext'); + +:root { + --blue: #0500f4; + --orange: #ff7800; + --green: #33c50f; + --red: #ff0808; + --grey: #9DAFBD; + --white: #fff; + --black: #192024; + --light-blue: #3898EC; + + --main-bg: #edeff2; + --blue-bg: #f0f0ff; + --red-bg: rgba(255, 8, 8, .1); + --green-bg: rgba(51, 197, 15, .1); + --dark-blue-bg: #020050; + + --card: #fff; +} + +body { + background-color: var(--main-bg); + color: var(--black); +} + +body, +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: Lekton, "Open Sans", sans-serif; +} + +a { + color: var(--blue); +} + +a:hover { + color: var(--blue); +} + +.primary-link { + color: var(--black) +} + +.primary-link:hover { + color: var(--black) +} + +input[type=text], +input[type=search], +textarea.form-control, +div.dataTables_wrapper div.dataTables_length select { + border: 1px solid #ccc; + color: var(--black); +} + +input[type=text]:focus, +input[type=search]:focus, +textarea.form-control:focus, +div.dataTables_wrapper div.dataTables_length select:focus { + border-color: var(--light-blue); +} + +.papyrus-logo { + width: 176px; + height: 40px; + margin-top: 20px; +} + +.page-on-load { + background-color: var(--main-bg); +} + +.page-spinner-bar { + width: 126px; + height: 126px; + margin-top: -63px; + margin-left: -63px; +} + +.page-spinner-bar img { + width: 100%; + height: 100%; + animation: spin 1.2s infinite ease-in-out; +} + +@keyframes spin { + 0% { + transform:rotate(0deg); + } + 100% { + transform:rotate(360deg); + } +} + +.table td { + word-wrap: break-word; + overflow-wrap: break-word; + word-break: break-word; +} + +.page-header .page-header-menu { + border-bottom: 1px solid rgba(51, 51, 51, .1); +} + +.page-header .page-header-menu .hor-menu .navbar-nav>li>a { + color: var(--black); + text-transform: uppercase; + letter-spacing: 2px; + font-weight: 700; +} + +.page-header .page-header-menu .hor-menu .navbar-nav>li>a:hover { + background-color: transparent; + color: var(--blue); +} + +.page-header .page-header-menu .hor-menu .navbar-nav>li.active>a { + color: var(--blue); +} + +.dashboard-stat2 { + padding: 10px 10px 20px 20px; +} + +.dashboard-stat2 .display .number h3>small, +.dashboard-stat2 .display .number small { + color: var(--grey); + font-weight: 700; +} + +.dashboard-stat2 .display .number small { + letter-spacing: 0.06em; +} + +.portlet.light { + background-color: var(--card); +} + +.portlet.light>.portlet-title>.caption.caption-md>.caption-subject { + font-size: 18px; + letter-spacing: 0.06em; +} + +.portlet.light>.portlet-title>.caption { + color: var(--grey); + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 700; +} + +.portlet.light>.portlet-title>.caption>i { + margin-top: 0; + color: inherit; +} + +.page-head { + background-color: transparent; +} + +.page-head .page-title>h1 { + font-size: 24px; + font-weight: 700; + color: var(--black); +} + +.page-head .page-title>h1>small { + color: var(--grey); +} + +.pagination>li>a, +.pagination>li>span { + color: var(--blue); +} + +.pagination>.active>a, +.pagination>.active>a:hover { + background-color: var(--blue); + border-color: var(--blue); +} + +.todo-tasklist-item { + background-color: var(--blue-bg); +} + +div .todo-tasklist-item:hover { + background-color: var(--blue-bg); +} + +.item-border-green { + border-color: var(--green) +} + +.item-border-blue { + border-color: var(--blue) +} + +.item-border-red { + border-color: var(--red) +} + + +.btn.btn-outline.green-haze { + border-color: var(--blue); + color: var(--blue); + font-size: 12px; + font-weight: 700; + letter-spacing: 0.1em; +} + +.btn.btn-outline.green-haze.active, +.btn.btn-outline.green-haze:active, +.btn.btn-outline.green-haze:active:focus, +.btn.btn-outline.green-haze:active:hover, +.btn.btn-outline.green-haze:focus, +.btn.btn-outline.green-haze:hover { + color: var(--white); + background-color: var(--blue); + border-color: var(--blue); +} + +.btn, +.btn-info, +.btn.grey-cascade:not(.btn-outline), +.btn.blue-madison:not(.btn-outline) { + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 700; + transition: all 300ms ease; + padding: 8px 12px 4px; +} + +.btn.grey-cascade:not(.btn-outline) { + color: var(--blue); + background-color: var(--blue-bg); + border-color: var(--blue-bg); +} + + +.btn-info, +.btn.blue-madison:not(.btn-outline) { + color: var(--white); + background-color: var(--blue); + border-color: var(--blue); +} + +.btn:hover, +.btn-info:hover, +.btn.grey-cascade:not(.btn-outline):hover, +.btn.blue-madison:not(.btn-outline):hover { + color: var(--white); + background-color: var(--blue); + border-color: var(--blue); + box-shadow: 0 4px 14px -4px #0500f4 !important; + transform: translate(0px, -4px); +} + +.tabbable-line>.nav-tabs>li>a { + font-size: 14px; + text-transform: uppercase; + color: var(--black); + font-weight: 700; + letter-spacing: 0.05em; +} + +.tabbable-line>.nav-tabs>li:hover { + border-bottom-width: 2px !important; + border-color: var(--blue); +} + +.tabbable-line>.nav-tabs>li.active { + border-bottom-width: 2px !important; + border-color: var(--blue); +} + +.tabbable-line>.nav-tabs>li.active>a { + color: var(--blue); +} + +.page-prefooter, +.page-footer { + background-color: var(--dark-blue-bg); + color: var(--white); +} + +.social-icons li>a { + transition: none; + border-radius: 50% !important; +} + +.eth-stat-text { + color: var(--grey) +} + +.scroll-to-top { + color: var(--blue); +} + +.node-items { + list-style-type: none; + margin: 0; + padding: 0; +} + +.portlet-body .node-items { + margin: 0 -5px; +} + +.node-item { + display: flex; + align-items: center; + background: #fff; + margin: 1px -15px; + padding: 20px; + cursor: pointer; + width: auto !important; +} + +.node-item h5 { + color: var(--grey); + margin-bottom: 4px; + font-size: 13px; +} + +.node-item h2 { + font-size: 24px; + font-weight: bold; + margin: 10px 0 0; + width: 100%; +} + +.node-item .greened { + background-color: var(--green); + margin: -3px -5px 0; + padding: 3px 5px 0; + display: inline-block; +} + +.node-item:hover { + background: #F8F9FC; +} + +.node-item__left, +.node-item__right { + display: flex; + flex: 1 0 50%; + width: 50%; +} + +.node-item__left { + padding-right: 15px; +} + +.node-item__right { + padding-left: 15px; + border-left: 1px solid #eee; +} + +.node-info { + display: flex; + align-items: center; + width: 100%; +} + +.node-info__avatar { + flex-shrink: 1; + margin-right: 15px; +} + +.node-info__avatar-wrapper { + width: 60px; + height: 60px; + background-color: var(--main-bg); + border: 1px solid var(--main-bg); +} + +.node-info__avatar-wrapper img { + width: 100%; + height: 100%; +} + +.node-info__about { + width: 100%; +} + +.node-info__about-company { + display: flex; + justify-content: space-between; + width: 100%; +} + +.node-info__about-company > div { + flex: 1 0 50%; +} + +.node-stats { + display: flex; + width: 100%; + /* justify-content: space-between; */ +} + +.node-stats__cell { + flex-grow: 1; + flex-basis: 30%; + padding: 0 10px; +} + +.node-stats__cell.nowrap { + white-space: nowrap; +} + +.node-stats__cell.right { + flex-shrink: 1; + flex-basis: 15%; + text-align: right; +} + +.node-stats__cell.right.center { + align-self: center; +} + +.node-votes { + list-style-type: none; + margin: 0; + padding: 0; + display: flex; + margin: 0 -5px; +} + +.node-votes li { + display: inline-flex; + justify-content: center; + align-items: center; + box-sizing: border-box; + margin: 0 5px; + width: 30px; + height: 34px; + border: 1px solid #DCDCDC; + background-color: #EDEDED; +} + +.node-votes li img { + width: 28px; + height: 28px; +} + +.node-votes li.green { + border-color: var(--blue); +} + +@media (max-width: 487px) { + .page-header .page-header-menu { + background-color: transparent; + margin-top: 0 !important; + border: 1px solid rgba(51, 51, 51, .1); + } + + .page-header .page-header-top { + margin-bottom: 0 !important;; + } + + .page-header .page-header-top .menu-toggler { + margin-top: 25px; + } + .page-header .page-header-top .top-menu { + margin-top: 15px; + margin-bottom: 10px; + } + .page-header .page-header-top .top-menu .navbar-nav>li.dropdown { + padding: 0 2px; + } +} + +@media (max-width: 991px) { + .page-header .page-header-top { + margin-bottom: 15px; + } + + .page-header .page-header-menu { + border: 1px solid rgba(51, 51, 51, .1); + margin: 15px 15px; + padding: 0; + } + + .page-header .page-header-menu { + background-color: transparent; + } +} + + diff --git a/public/css/style.css b/public/css/style.css index 7da9c0cb2..0eff4cc6f 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -101,7 +101,7 @@ a:hover { } /*========================================================================== - Misc & Adjust + Misc & Adjust ========================================================================== */ .row { z-index: 9999; @@ -351,13 +351,13 @@ section.section { --- Parallax --- ============================= */ -#parallax1{ +#parallax1{ background-image: url(../img/parallax/img1.jpg); } -#parallax2{ +#parallax2{ background-image: url(../img/parallax/img2.jpg); } -#testimonials{ +#testimonials{ background-image: url(../img/parallax/img3.jpg); } /*=========================== @@ -406,7 +406,7 @@ section.section { .navbar-nav { float: right; margin-bottom: 0; - padding-bottom:0; + padding-bottom:0; } .navbar .navbar-nav > .active > a { @@ -461,14 +461,14 @@ section.featured h3.slogan { font-size: 48px; font-weight: 900; } - + /* inner heading */ section.featured.inner { background: #eee; padding: 150px 0 50px; } - - + + /* --- Flexslider --- */ .flexslider { margin: 0; @@ -571,7 +571,7 @@ section.featured.inner { .tp-bullets.simplebullets.round .bullet { background: url(../img/bullets-new.png) no-repeat top left; -} +} .tp-caption.large_bold_white { font-size:60px; @@ -617,13 +617,13 @@ About box-sizing:border-box; -webkit-border-radius:50%; -moz-border-radius:50%; - border-radius:50%; + border-radius:50%; margin: 0 0 20px 0; } .member-photo img { -webkit-border-radius:50%; -moz-border-radius:50%; - border-radius:50%; + border-radius:50%; } .team-detail h4 { @@ -671,7 +671,7 @@ nav#filter a { } -.portfolio-items article img {width:100%;} +.portfolio-items article img {width:100%;} .portfolio-item { display: block; @@ -762,7 +762,7 @@ nav#filter a { font-size: 18px; font-family: Georgia, sans-serif; line-height: 1.5em; -} +} /*=========================== --- Contact ---- @@ -972,7 +972,7 @@ a.scrollup:hover{ .social-network a.icoLinkedin:hover { background-color:#007bb7; } -.social-network a.icoRss:hover i, .social-network a.icoFacebook:hover i, .social-network a.icoTwitter:hover i, +.social-network a.icoRss:hover i, .social-network a.icoFacebook:hover i, .social-network a.icoTwitter:hover i, .social-network a.icoGoogle:hover i, .social-network a.icoVimeo:hover i, .social-network a.icoLinkedin:hover i { color:#fff; } @@ -1100,12 +1100,12 @@ Media queries section.featured { padding-top: 80px; } - + .team-member,.col-lg-4 { margin-bottom: 30px; } - + .stats .col-md-3 { margin-bottom: 30px; } -} \ No newline at end of file +} diff --git a/public/favicon.ico b/public/favicon.ico index 63d3fa587..8b167ecd4 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/img/etc-mini-logo.svg b/public/img/etc-mini-logo.svg index 2c272644b..4b0c59ed8 100644 --- a/public/img/etc-mini-logo.svg +++ b/public/img/etc-mini-logo.svg @@ -1,289 +1 @@ - - - - - Ethereum Classic Logo - - - - - - image/svg+xml - - Ethereum Classic Logo - - - - Ethereum Classic - - - - - Ethereum Classic - - - - - Ethereum Classic - - - Ethereum Classic Logo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/public/img/logo-sign.svg b/public/img/logo-sign.svg new file mode 100644 index 000000000..d2cd6e502 --- /dev/null +++ b/public/img/logo-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/logo.svg b/public/img/logo.svg new file mode 100644 index 000000000..4fc6261db --- /dev/null +++ b/public/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/js/controllers/AccountsController.js b/public/js/controllers/AccountsController.js index 38363b0e1..d7e2cd08b 100755 --- a/public/js/controllers/AccountsController.js +++ b/public/js/controllers/AccountsController.js @@ -1,6 +1,14 @@ angular.module('BlocksApp').controller('AccountsController', function($stateParams, $rootScope, $scope, $http, $filter) { $scope.settings = $rootScope.setup; - + $scope.authorities = []; + + var getAuthorities = function() { + $http.post('/authorities').then(function(response) { + $scope.authorities = response.data; + }) + }; + getAuthorities(); + // fetch accounts var getAccounts = function() { $("#table_accounts").DataTable({ diff --git a/public/js/controllers/AddressController.js b/public/js/controllers/AddressController.js index 42c0e687f..d298d70c8 100755 --- a/public/js/controllers/AddressController.js +++ b/public/js/controllers/AddressController.js @@ -121,7 +121,7 @@ angular.module('BlocksApp').controller('AddressController', function($stateParam url: '/compile', data: {"addr": scope.addrHash, "action": "find"} }).then(function(resp) { - console.log(resp.data); + // console.log(resp.data); scope.contract = resp.data; }); } diff --git a/public/js/controllers/HomeController.js b/public/js/controllers/HomeController.js index 847e511b5..4e0c6aadd 100755 --- a/public/js/controllers/HomeController.js +++ b/public/js/controllers/HomeController.js @@ -1,63 +1,99 @@ -angular.module('BlocksApp').controller('HomeController', function($rootScope, $scope, $http, $timeout) { - $scope.$on('$viewContentLoaded', function() { - // initialize core components - App.initAjax(); - }); +var FETCH_DELAY = 3000; +angular.module('BlocksApp') + .controller('HomeController', function ($rootScope, $scope, $http, $timeout) { + $scope.$on('$viewContentLoaded', function () { + // initialize core components + App.initAjax(); + }); + var URL = '/data'; - + var timeout; + $rootScope.isHome = true; - - $scope.reloadBlocks = function() { + + $scope.reloadBlocks = function () { $scope.blockLoading = true; - $http({ + return $http({ method: 'POST', url: URL, - data: {"action": "latest_blocks"} - }).then(function(resp) { - $scope.latest_blocks = resp.data.blocks; - $scope.blockLoading = false; - }); - } - $scope.reloadTransactions = function() { + data: { 'action': 'latest_blocks' }, + }) + .then(function (resp) { + $scope.latest_blocks = resp.data.blocks; + $scope.blockLoading = false; + }); + }; + + $scope.reloadTransactions = function () { $scope.txLoading = true; - $http({ + return $http({ method: 'POST', url: URL, - data: {"action": "latest_txs"} - }).then(function(resp) { - $scope.latest_txs = resp.data.txs; - $scope.txLoading = false; - }); + data: { 'action': 'latest_txs' }, + }) + .then(function (resp) { + $scope.latest_txs = resp.data.txs; + $scope.txLoading = false; + }); + }; + + function reloadBoth() { + return Promise.all([$scope.reloadBlocks(), $scope.reloadTransactions()]); + } + function startTimeout() { + cancelTimeout(); + reloadBoth().then( + timeout = $timeout(startTimeout, FETCH_DELAY) + ); + } + function cancelTimeout() { + $timeout.cancel(timeout); + timeout = undefined; } - $scope.reloadBlocks(); - $scope.reloadTransactions(); + + startTimeout(); $scope.txLoading = false; $scope.blockLoading = false; $scope.settings = $rootScope.setup; -}) -.directive('simpleSummaryStats', function($http) { - return { - restrict: 'E', - templateUrl: '/views/simple-summary-stats.html', - scope: true, - link: function(scope, elem, attrs){ - scope.stats = {}; - var statsURL = "/web3relay"; - $http.post(statsURL, {"action": "hashrate"}) - .then(function(res){ - scope.stats.hashrate = res.data.hashrate; - scope.stats.difficulty = res.data.difficulty; - scope.stats.blockHeight = res.data.blockHeight; - scope.stats.blockTime = res.data.blockTime; - //console.log(res); - }); - } - } -}) -.directive('siteNotes', function() { - return { - restrict: 'E', - templateUrl: '/views/site-notes.html' - } -}); + $scope.$on('$destroy', cancelTimeout); + }) + .directive('simpleSummaryStats', function ($http, $timeout) { + return { + restrict: 'E', + templateUrl: '/views/simple-summary-stats.html', + scope: true, + link: function (scope, elem, attrs) { + scope.stats = {}; + var statsURL = '/web3relay'; + var timeout; + function getData() { + return $http.post(statsURL, { 'action': 'hashrate' }) + .then(function (res) { + // scope.stats.hashrate = res.data.hashrate; + // scope.stats.difficulty = res.data.difficulty; + scope.stats.blockHeight = res.data.blockHeight; + scope.stats.blockTime = res.data.blockTime; + //console.log(res); + }); + } + function startTimeout() { + getData().then(function() { + timeout = $timeout(startTimeout, FETCH_DELAY); + }); + } + + startTimeout(); + scope.$on('$destroy', function() { + $timeout.cancel(timeout); + timeout = undefined; + }) + }, + }; + }) + .directive('siteNotes', function () { + return { + restrict: 'E', + templateUrl: '/views/site-notes.html', + }; + }); diff --git a/public/js/controllers/PollController.js b/public/js/controllers/PollController.js new file mode 100644 index 000000000..287dd1ce6 --- /dev/null +++ b/public/js/controllers/PollController.js @@ -0,0 +1,124 @@ +var FETCH_DELAY = 3000; + +angular + .module('BlocksApp') + .controller('PollController', function($rootScope, $scope, $http, $timeout) { + var isBlacklists = $scope.$state.current.name === 'blacklists'; + var type = Number(isBlacklists); + var timeout; + var setNowTimeout; + + $scope.votesRequired = isBlacklists ? 3 : 24; + $scope.millisecondsToWords = function(milliseconds, zero = '0s') { + if (milliseconds <= 0) { + return zero; + } + const hours = Math.floor(milliseconds / 1000 / 3600); + milliseconds = (milliseconds / 1000) % 3600; + const minutes = Math.floor(milliseconds / 60); + const seconds = Math.floor(milliseconds % 60); + if (hours > 0) { + return hours + 'h ' + minutes + 'm ' + seconds + 's'; + } else if (minutes > 0) { + return minutes + 'm ' + seconds + 's'; + } + return seconds + 's'; + }; + + $scope.showModal = false; + $scope.modalDataLoading = true; + $scope.modalAddress = null; + $scope.toggleModal = function(address, isPoll) { + isPoll = isPoll !== undefined ? isPoll : false; + $scope.showModal = !$scope.showModal; + if ($scope.showModal) { + $scope.modalDataLoading = true; + $http({ + method: 'GET', + url: '/votes-list?type='+ type + '&address=' + address + '&poll=' + (isPoll ? 1 : 0), + }).then(function (resp) { + $scope.modalDataLoading = false; + $scope.modalData = resp.data; + }) + } else { + $scope.modalData = null; + } + } + + $scope.addressToSrcIcon = function(address) { + try { + var options = { + margin: 0.1, + size: 60, + format: 'svg' + }; + var data = new window.Identicon(address, options).toString(); + return 'data:image/svg+xml;base64,' + data; + } catch (err) { + return null; + } + } + + function loadPolls() { + return $http({ + method: 'GET', + url: `/polls?type=${type}` + }).then(function (resp) { + $scope.polls = resp.data.polls; + $scope.nodes = resp.data.nodes; + }) + } + + function setNow() { + $scope.now = Date.now(); + setNowTimeout = $timeout(setNow, 100); + } + + function startTimeout() { + cancelTimeout(); + loadPolls().then( + timeout = $timeout(startTimeout, FETCH_DELAY) + ); + } + function cancelTimeout() { + $timeout.cancel(timeout); + timeout = undefined; + } + + setNow(); + startTimeout(); + $scope.$on('$destroy', function() { + cancelTimeout(); + $timeout.cancel(setNowTimeout); + setNowTimeout = undefined; + }); + }) + .directive('votersList', function($http) { + return { + restrict: 'E', + templateUrl: '/views/votersList.html', + transclude: true, + replace:true, + scope:true, + link: function(scope, element, attrs){ + console.log(attrs, element); + scope.$watch(attrs.visible, function(value){ + if(value == true) { + $(element).modal('show'); + } else { + $(element).modal('hide'); + } + }); + $(element).on('shown.bs.modal', function(){ + scope.$apply(function(){ + scope.$parent[attrs.visible] = true; + }); + }); + $(element).on('hidden.bs.modal', function(){ + scope.$apply(function(){ + scope.$parent[attrs.visible] = false; + }); + }); + } + } + }); diff --git a/public/js/controllers/StatsController.js b/public/js/controllers/StatsController.js index 3196d492e..5ee9463aa 100755 --- a/public/js/controllers/StatsController.js +++ b/public/js/controllers/StatsController.js @@ -10,15 +10,15 @@ angular.module('BlocksApp').controller('StatsController', function($stateParams, */ const CHART_TYPES = { - "hashrate": { - "title": "Hashrate chart" - }, + // "hashrate": { + // "title": "Hashrate chart" + // }, "blocktime": { "title": "Blocktime chart" }, - "difficulty": { - "title": "Difficulty chart" - }, + // "difficulty": { + // "title": "Difficulty chart" + // }, "miner_hashrate": { "title": "Miner distribution" } diff --git a/public/js/filters.js b/public/js/filters.js index f0ecdbd20..40b877fc4 100644 --- a/public/js/filters.js +++ b/public/js/filters.js @@ -2,7 +2,6 @@ var getDifficulty = function(hashes) { /* borrowed from https://github.com/cubedro/eth-netstats :D */ - var result = 0; var unit = ''; @@ -46,7 +45,7 @@ var getDifficulty = function(hashes) { unit = 'Z'; } - return result.toFixed(2) + ' ' + unit + 'H'; + return (+result).toFixed(2) + ' ' + unit + 'H'; } /* diff --git a/public/js/main.js b/public/js/main.js index 670f9f458..1abcd7ef5 100755 --- a/public/js/main.js +++ b/public/js/main.js @@ -43,6 +43,7 @@ BlocksApp.factory('setupObj', ['$rootScope', '$http', function($rootScope, $http /* Setup App Main Controller */ BlocksApp.controller('MainController', ['$scope', '$rootScope', function($scope, $rootScope) { $scope.$on('$viewContentLoaded', function() { + $rootScope.isHome = $rootScope.$state.current.name === ('home' || '') //App.initComponents(); // init core components //Layout.init(); // Init entire layout(header, footer, sidebar, etc) on page load if the partials included in server side instead of loading with ng-include directive }); @@ -160,6 +161,47 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide }] } }) + + .state('authorities', { + url: '/authorities', + templateUrl: 'views/authorities.html', + data: { pageTitle: 'Authority Nodes' }, + controller: 'PollController', + resolve: { + deps: ['$ocLazyLoad', function($ocLazyLoad) { + return $ocLazyLoad.load({ + name: 'BlocksApp', + insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before' + files: [ + '/js/controllers/PollController.js', + '/plugins/identicon/pnglib.js', + '/plugins/identicon/identicon.js', + ] + }); + }] + } + }) + + .state('blacklists', { + url: '/blacklists', + templateUrl: 'views/blacklists.html', + data: { pageTitle: 'Blacklist Nodes' }, + controller: 'PollController', + resolve: { + deps: ['$ocLazyLoad', function($ocLazyLoad) { + return $ocLazyLoad.load({ + name: 'BlocksApp', + insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before' + files: [ + '/js/controllers/PollController.js', + '/plugins/identicon/pnglib.js', + '/plugins/identicon/identicon.js', + ] + }); + }] + } + }) + .state('block', { url: "/block/{number}", templateUrl: "views/block.html", @@ -213,42 +255,42 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide }] } }) - .state('viewcontract', { - url: "/contract", - templateUrl: "views/contract.html", - data: {pageTitle: 'Verify Contract'}, - controller: "ContractController", - resolve: { - deps: ['$ocLazyLoad', function($ocLazyLoad) { - return $ocLazyLoad.load({ - name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', - files: [ - '/js/controllers/ContractController.js', - '/js/custom.js' - ] - }); - }] - } - }) - .state('contract', { - url: "/contract/{addr}", - templateUrl: "views/contract.html", - data: {pageTitle: 'Verify Contract'}, - controller: "ContractController", - resolve: { - deps: ['$ocLazyLoad', function($ocLazyLoad) { - return $ocLazyLoad.load({ - name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', - files: [ - '/js/controllers/ContractController.js', - '/js/custom.js' - ] - }); - }] - } - }) + // .state('viewcontract', { + // url: "/contract", + // templateUrl: "views/contract.html", + // data: {pageTitle: 'Verify Contract'}, + // controller: "ContractController", + // resolve: { + // deps: ['$ocLazyLoad', function($ocLazyLoad) { + // return $ocLazyLoad.load({ + // name: 'BlocksApp', + // insertBefore: '#ng_load_plugins_before', + // files: [ + // '/js/controllers/ContractController.js', + // '/js/custom.js' + // ] + // }); + // }] + // } + // }) + // .state('contract', { + // url: "/contract/{addr}", + // templateUrl: "views/contract.html", + // data: {pageTitle: 'Verify Contract'}, + // controller: "ContractController", + // resolve: { + // deps: ['$ocLazyLoad', function($ocLazyLoad) { + // return $ocLazyLoad.load({ + // name: 'BlocksApp', + // insertBefore: '#ng_load_plugins_before', + // files: [ + // '/js/controllers/ContractController.js', + // '/js/custom.js' + // ] + // }); + // }] + // } + // }) .state('stats', { url: "/stats/{chart}", templateUrl: "views/stats/index.html", @@ -344,3 +386,7 @@ BlocksApp.run(["$rootScope", "settings", "$state", "setupObj", function($rootSco $rootScope.setup = res; }); }]); +// .factory('router', ['$rootScope', '$state' function($rootScope, $state) { +// +// }]); + diff --git a/public/plugins/identicon/identicon.js b/public/plugins/identicon/identicon.js new file mode 100644 index 000000000..c02717b76 --- /dev/null +++ b/public/plugins/identicon/identicon.js @@ -0,0 +1,205 @@ +/** + * Identicon.js 2.3.3 + * http://github.com/stewartlord/identicon.js + * + * PNGLib required for PNG output + * http://www.xarg.org/download/pnglib.js + * + * Copyright 2018, Stewart Lord + * Released under the BSD license + * http://www.opensource.org/licenses/bsd-license.php + */ + +(function() { + var PNGlib; + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + PNGlib = require('./pnglib'); + } else { + PNGlib = window.PNGlib; + } + + var Identicon = function(hash, options){ + if (typeof(hash) !== 'string' || hash.length < 15) { + throw 'A hash of at least 15 characters is required.'; + } + + this.defaults = { + background: [240, 240, 240, 255], + margin: 0.08, + size: 64, + saturation: 0.7, + brightness: 0.5, + format: 'png' + }; + + this.options = typeof(options) === 'object' ? options : this.defaults; + + // backward compatibility with old constructor (hash, size, margin) + if (typeof(arguments[1]) === 'number') { this.options.size = arguments[1]; } + if (arguments[2]) { this.options.margin = arguments[2]; } + + this.hash = hash + this.background = this.options.background || this.defaults.background; + this.size = this.options.size || this.defaults.size; + this.format = this.options.format || this.defaults.format; + this.margin = this.options.margin !== undefined ? this.options.margin : this.defaults.margin; + + // foreground defaults to last 7 chars as hue at 70% saturation, 50% brightness + var hue = parseInt(this.hash.substr(-7), 16) / 0xfffffff; + var saturation = this.options.saturation || this.defaults.saturation; + var brightness = this.options.brightness || this.defaults.brightness; + this.foreground = this.options.foreground || this.hsl2rgb(hue, saturation, brightness); + }; + + Identicon.prototype = { + background: null, + foreground: null, + hash: null, + margin: null, + size: null, + format: null, + + image: function(){ + return this.isSvg() + ? new Svg(this.size, this.foreground, this.background) + : new PNGlib(this.size, this.size, 256); + }, + + render: function(){ + var image = this.image(), + size = this.size, + baseMargin = Math.floor(size * this.margin), + cell = Math.floor((size - (baseMargin * 2)) / 5), + margin = Math.floor((size - cell * 5) / 2), + bg = image.color.apply(image, this.background), + fg = image.color.apply(image, this.foreground); + + // the first 15 characters of the hash control the pixels (even/odd) + // they are drawn down the middle first, then mirrored outwards + var i, color; + for (i = 0; i < 15; i++) { + color = parseInt(this.hash.charAt(i), 16) % 2 ? bg : fg; + if (i < 5) { + this.rectangle(2 * cell + margin, i * cell + margin, cell, cell, color, image); + } else if (i < 10) { + this.rectangle(1 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image); + this.rectangle(3 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image); + } else if (i < 15) { + this.rectangle(0 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image); + this.rectangle(4 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image); + } + } + + return image; + }, + + rectangle: function(x, y, w, h, color, image){ + if (this.isSvg()) { + image.rectangles.push({x: x, y: y, w: w, h: h, color: color}); + } else { + var i, j; + for (i = x; i < x + w; i++) { + for (j = y; j < y + h; j++) { + image.buffer[image.index(i, j)] = color; + } + } + } + }, + + // adapted from: https://gist.github.com/aemkei/1325937 + hsl2rgb: function(h, s, b){ + h *= 6; + s = [ + b += s *= b < .5 ? b : 1 - b, + b - h % 1 * s * 2, + b -= s *= 2, + b, + b + h % 1 * s, + b + s + ]; + + return[ + s[ ~~h % 6 ] * 255, // red + s[ (h|16) % 6 ] * 255, // green + s[ (h|8) % 6 ] * 255 // blue + ]; + }, + + toString: function(raw){ + // backward compatibility with old toString, default to base64 + if (raw) { + return this.render().getDump(); + } else { + return this.render().getBase64(); + } + }, + + isSvg: function(){ + return this.format.match(/svg/i) + } + }; + + var Svg = function(size, foreground, background){ + this.size = size; + this.foreground = this.color.apply(this, foreground); + this.background = this.color.apply(this, background); + this.rectangles = []; + }; + + Svg.prototype = { + size: null, + foreground: null, + background: null, + rectangles: null, + + color: function(r, g, b, a){ + var values = [r, g, b].map(Math.round); + values.push((a >= 0) && (a <= 255) ? a/255 : 1); + return 'rgba(' + values.join(',') + ')'; + }, + + getDump: function(){ + var i, + xml, + rect, + fg = this.foreground, + bg = this.background, + stroke = this.size * 0.005; + + xml = "" + + ""; + + for (i = 0; i < this.rectangles.length; i++) { + rect = this.rectangles[i]; + if (rect.color == bg) continue; + xml += ""; + } + xml += "" + + return xml; + }, + + getBase64: function(){ + if ('function' === typeof btoa) { + return btoa(this.getDump()); + } else if (Buffer) { + return new Buffer(this.getDump(), 'binary').toString('base64'); + } else { + throw 'Cannot generate base64 output'; + } + } + }; + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Identicon; + } else { + window.Identicon = Identicon; + } +})(); \ No newline at end of file diff --git a/public/plugins/identicon/pnglib.js b/public/plugins/identicon/pnglib.js new file mode 100644 index 000000000..007ec0624 --- /dev/null +++ b/public/plugins/identicon/pnglib.js @@ -0,0 +1,214 @@ +/** +* A handy class to calculate color values. +* +* @version 1.0 +* @author Robert Eisele +* @copyright Copyright (c) 2010, Robert Eisele +* @link http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/ +* @license http://www.opensource.org/licenses/bsd-license.php BSD License +* +*/ + +(function() { + + // helper functions for that ctx + function write(buffer, offs) { + for (var i = 2; i < arguments.length; i++) { + for (var j = 0; j < arguments[i].length; j++) { + buffer[offs++] = arguments[i].charAt(j); + } + } + } + + function byte2(w) { + return String.fromCharCode((w >> 8) & 255, w & 255); + } + + function byte4(w) { + return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255); + } + + function byte2lsb(w) { + return String.fromCharCode(w & 255, (w >> 8) & 255); + } + + // modified from original source to support NPM + var PNGlib = function(width,height,depth) { + + this.width = width; + this.height = height; + this.depth = depth; + + // pixel data and row filter identifier size + this.pix_size = height * (width + 1); + + // deflate header, pix_size, block headers, adler32 checksum + this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4; + + // offsets and sizes of Png chunks + this.ihdr_offs = 0; // IHDR offset and size + this.ihdr_size = 4 + 4 + 13 + 4; + this.plte_offs = this.ihdr_offs + this.ihdr_size; // PLTE offset and size + this.plte_size = 4 + 4 + 3 * depth + 4; + this.trns_offs = this.plte_offs + this.plte_size; // tRNS offset and size + this.trns_size = 4 + 4 + depth + 4; + this.idat_offs = this.trns_offs + this.trns_size; // IDAT offset and size + this.idat_size = 4 + 4 + this.data_size + 4; + this.iend_offs = this.idat_offs + this.idat_size; // IEND offset and size + this.iend_size = 4 + 4 + 4; + this.buffer_size = this.iend_offs + this.iend_size; // total PNG size + + this.buffer = new Array(); + this.palette = new Object(); + this.pindex = 0; + + var _crc32 = new Array(); + + // initialize buffer with zero bytes + for (var i = 0; i < this.buffer_size; i++) { + this.buffer[i] = "\x00"; + } + + // initialize non-zero elements + write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), "\x08\x03"); + write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE'); + write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS'); + write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT'); + write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND'); + + // initialize deflate header + var header = ((8 + (7 << 4)) << 8) | (3 << 6); + header+= 31 - (header % 31); + + write(this.buffer, this.idat_offs + 8, byte2(header)); + + // initialize deflate block headers + for (var i = 0; (i << 16) - 1 < this.pix_size; i++) { + var size, bits; + if (i + 0xffff < this.pix_size) { + size = 0xffff; + bits = "\x00"; + } else { + size = this.pix_size - (i << 16) - i; + bits = "\x01"; + } + write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size)); + } + + /* Create crc32 lookup table */ + for (var i = 0; i < 256; i++) { + var c = i; + for (var j = 0; j < 8; j++) { + if (c & 1) { + c = -306674912 ^ ((c >> 1) & 0x7fffffff); + } else { + c = (c >> 1) & 0x7fffffff; + } + } + _crc32[i] = c; + } + + // compute the index into a png for a given pixel + this.index = function(x,y) { + var i = y * (this.width + 1) + x + 1; + var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i; + return j; + } + + // convert a color and build up the palette + this.color = function(red, green, blue, alpha) { + + alpha = alpha >= 0 ? alpha : 255; + var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue; + + if (typeof this.palette[color] == "undefined") { + if (this.pindex == this.depth) return "\x00"; + + var ndx = this.plte_offs + 8 + 3 * this.pindex; + + this.buffer[ndx + 0] = String.fromCharCode(red); + this.buffer[ndx + 1] = String.fromCharCode(green); + this.buffer[ndx + 2] = String.fromCharCode(blue); + this.buffer[this.trns_offs+8+this.pindex] = String.fromCharCode(alpha); + + this.palette[color] = String.fromCharCode(this.pindex++); + } + return this.palette[color]; + } + + // output a PNG string, Base64 encoded + this.getBase64 = function() { + + var s = this.getDump(); + + var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var c1, c2, c3, e1, e2, e3, e4; + var l = s.length; + var i = 0; + var r = ""; + + do { + c1 = s.charCodeAt(i); + e1 = c1 >> 2; + c2 = s.charCodeAt(i+1); + e2 = ((c1 & 3) << 4) | (c2 >> 4); + c3 = s.charCodeAt(i+2); + if (l < i+2) { e3 = 64; } else { e3 = ((c2 & 0xf) << 2) | (c3 >> 6); } + if (l < i+3) { e4 = 64; } else { e4 = c3 & 0x3f; } + r+= ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4); + } while ((i+= 3) < l); + return r; + } + + // output a PNG string + this.getDump = function() { + + // compute adler32 of output pixels + row filter bytes + var BASE = 65521; /* largest prime smaller than 65536 */ + var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + var s1 = 1; + var s2 = 0; + var n = NMAX; + + for (var y = 0; y < this.height; y++) { + for (var x = -1; x < this.width; x++) { + s1+= this.buffer[this.index(x, y)].charCodeAt(0); + s2+= s1; + if ((n-= 1) == 0) { + s1%= BASE; + s2%= BASE; + n = NMAX; + } + } + } + s1%= BASE; + s2%= BASE; + write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1)); + + // compute crc32 of the PNG chunks + function crc32(png, offs, size) { + var crc = -1; + for (var i = 4; i < size-4; i += 1) { + crc = _crc32[(crc ^ png[offs+i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff); + } + write(png, offs+size-4, byte4(crc ^ -1)); + } + + crc32(this.buffer, this.ihdr_offs, this.ihdr_size); + crc32(this.buffer, this.plte_offs, this.plte_size); + crc32(this.buffer, this.trns_offs, this.trns_size); + crc32(this.buffer, this.idat_offs, this.idat_size); + crc32(this.buffer, this.iend_offs, this.iend_size); + + // convert PNG to string + return "\x89PNG\r\n\x1a\n"+this.buffer.join(''); + } + } + + // modified from original source to support NPM + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = PNGlib; + } else { + window.PNGlib = PNGlib; + } +})(); \ No newline at end of file diff --git a/public/tokens.json b/public/tokens.json index a823d87ba..fe51488c7 100644 --- a/public/tokens.json +++ b/public/tokens.json @@ -1,30 +1 @@ -[ - { - "address":"0x085fb4f24031eaedbc2b611aa528f22343eb52db", - "symbol":"BEC", - "name": "BitEther", - "decimal":8, - "abi": [{"constant":false,"inputs":[],"name":"getEra","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_eraBlock","type":"uint256"},{"name":"_blockMined","type":"uint256"},{"name":"_blockNumber","type":"uint256"},{"name":"_rewardPrev","type":"uint256"},{"name":"_reward","type":"uint256"}],"name":"getUnclaimed","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_block","type":"uint256"}],"name":"getEraForBlock","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"claim","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"type":"constructor"},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_miner","type":"address"},{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"_current","type":"bool"}],"name":"Reward","type":"event"}] - }, - { - "address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "symbol":"DAO", - "name": "theDAO", - "decimal":16, - "abi": [{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"open","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"proposalHash","type":"bytes32"},{"name":"proposalDeposit","type":"uint256"},{"name":"newCurator","type":"bool"},{"name":"yea","type":"uint256"},{"name":"nay","type":"uint256"},{"name":"creator","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"minTokensToCreate","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"rewardAccount","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"daoCreator","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"divisor","outputs":[{"name":"divisor","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"extraBalance","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_transactionData","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"unblockMe","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalRewardToken","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"actualBalance","outputs":[{"name":"_actualBalance","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"closingTime","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"allowedRecipients","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferWithoutReward","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"refund","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_description","type":"string"},{"name":"_transactionData","type":"bytes"},{"name":"_debatingPeriod","type":"uint256"},{"name":"_newCurator","type":"bool"}],"name":"newProposal","outputs":[{"name":"_proposalID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"DAOpaidOut","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minQuorumDivisor","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_newContract","type":"address"}],"name":"newContract","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_allowed","type":"bool"}],"name":"changeAllowedRecipients","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"halveMinQuorum","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"paidOut","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_newCurator","type":"address"}],"name":"splitDAO","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"DAOrewardAccount","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"proposalDeposit","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numberOfProposals","outputs":[{"name":"_numberOfProposals","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"lastTimeMinQuorumMet","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_toMembers","type":"bool"}],"name":"retrieveDAOReward","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"receiveEther","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"isFueled","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_tokenHolder","type":"address"}],"name":"createTokenProxy","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_proposalID","type":"uint256"}],"name":"getNewDAOAddress","outputs":[{"name":"_newDAO","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_supportsProposal","type":"bool"}],"name":"vote","outputs":[{"name":"_voteID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"getMyReward","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"rewardToken","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFromWithoutReward","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalDeposit","type":"uint256"}],"name":"changeProposalDeposit","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"blocked","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"curator","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_transactionData","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"_codeChecksOut","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"privateCreation","outputs":[{"name":"","type":"address"}],"type":"function"},{"inputs":[{"name":"_curator","type":"address"},{"name":"_daoCreator","type":"address"},{"name":"_proposalDeposit","type":"uint256"},{"name":"_minTokensToCreate","type":"uint256"},{"name":"_closingTime","type":"uint256"},{"name":"_privateCreation","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"FuelingToDate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"CreatedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"newCurator","type":"bool"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":true,"name":"voter","type":"address"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"bool"},{"indexed":false,"name":"quorum","type":"uint256"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_newCurator","type":"address"}],"name":"NewCurator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_recipient","type":"address"},{"indexed":false,"name":"_allowed","type":"bool"}],"name":"AllowedRecipientChanged","type":"event"}] - }, - { - "address":"0xAC55641Cbb734bdf6510d1bBd62E240c2409040f", - "symbol":"SATURN", - "name": "Saturn Classic", - "decimal":4, - "abi": [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"_data","type":"bytes"}],"name":"ERC223Transfer","type":"event"}] - }, - { - "address":"0x085b0fdf115aa9e16ae1bddd396ce1f993c52220", - "symbol":"ONEX", - "name": "ONEX Network", - "decimal":18, - "abi": [{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_name"}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"mint","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_totalSupply"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxTotalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"_decimals"}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"blockNumber"}],"name":"getBlockNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"chainStartTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"balance"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeStartTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_symbol"}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalInitialSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"coinAge","inputs":[{"type":"address","name":"staker"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"interest"}],"name":"annualInterest","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeMinAge","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"chainStartBlockNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeMaxAge","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxMintProofOfStake","inputs":[],"constant":true},{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[]},{"type":"event","name":"Mint","inputs":[{"type":"address","name":"_address","indexed":true},{"type":"uint256","name":"_reward","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false}],"anonymous":false},{"type":"event","name":"ERC223Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false},{"type":"bytes","name":"_data","indexed":false}],"anonymous":false}] - } - ] +[] diff --git a/public/tpl/footer.html b/public/tpl/footer.html index 42380fdd6..4ec6b750e 100755 --- a/public/tpl/footer.html +++ b/public/tpl/footer.html @@ -2,41 +2,44 @@
- -
diff --git a/public/tpl/header.html b/public/tpl/header.html index aae17b0fd..5ff72fd46 100755 --- a/public/tpl/header.html +++ b/public/tpl/header.html @@ -2,11 +2,9 @@
- + + + MENU @@ -36,98 +34,107 @@
-
+
diff --git a/public/views/accounts.html b/public/views/accounts.html index 3fd5a238a..0513cbfbd 100755 --- a/public/views/accounts.html +++ b/public/views/accounts.html @@ -35,3 +35,28 @@
+
+
+
+
Authorities
+
+
+ + + + + + + + + + + + + +
#Address
{{ $index + 1 }} + {{ address }} +
+
+
+
diff --git a/public/views/address.html b/public/views/address.html index a4e526491..45e5a917e 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -13,9 +13,9 @@ {{ settings.symbol }} Balance
-
- {{ addr.balanceUSD | currency : "$" : 4 }} USD balance -
+ + +
{{ addr.mined }} Mined
diff --git a/public/views/authorities.html b/public/views/authorities.html new file mode 100644 index 000000000..6815e9d53 --- /dev/null +++ b/public/views/authorities.html @@ -0,0 +1,121 @@ +
    +
  • +
    +
    +
    +
    + +
    +
    +
    + {{ node.address }} +
    +
    +
    Company
    + Papyrus +
    +
    +
    Home page
    + papyrus.network +
    +
    +
    +
    +
    +
    +
    +
    +
    Votes casted
    +
      +
    • + +
    • +
    +
    +
    +
    Votes recieved
    +

    {{ node.votes }}

    +
    +
    +
    +
  • +
+ +
+
+
+
Candidate Nodes
+
+
+ No active polls yet +
    +
  • +
    +
    +
    +
    + +
    +
    +
    + {{ poll.address }} +
    +
    +
    Company
    + Papyrus +
    +
    +
    Home page
    + papyrus.network +
    +
    +
    +
    +
    +
    +
    +
    +
    Votes recieved
    +

    + + {{ poll.votes }} + +

    +
    +
    +
    Votes required
    +

    {{ votesRequired }}

    +
    +
    +
    Time left
    +

    {{ millisecondsToWords(poll.closeTime * 1000 - now) }}

    +
    +
    +

    {{poll.votes < votesRequired ? '🕐' : '👌'}}

    +
    +
    +
    +
  • +
+
+
+
+ + + + \ No newline at end of file diff --git a/public/views/blacklists.html b/public/views/blacklists.html new file mode 100644 index 000000000..6577df6ee --- /dev/null +++ b/public/views/blacklists.html @@ -0,0 +1,96 @@ +
    +
  • +
    +
    +
    +
    + +
    +
    +
    + {{ node.address }} +
    +
    +
    Company
    + Papyrus +
    +
    +
    Home page
    + papyrus.network +
    +
    +
    +
    +
    +
    +
    +
    +
    Votes recieved
    +

    {{ node.votes }}

    +
    +
    +
    +
  • +
+ +
+
+
+
Blacklist Candidates
+
+
+ No active polls yet +
    +
  • +
    +
    +
    +
    + +
    +
    +
    + {{ poll.address }} +
    +
    +
    Company
    + Papyrus +
    +
    +
    Home page
    + papyrus.network +
    +
    +
    +
    +
    +
    +
    +
    +
    Votes recieved
    +

    + + {{ poll.votes }} + +

    +
    +
    +
    Votes required
    +

    {{ votesRequired }}

    +
    +
    +
    Time left
    +

    {{ millisecondsToWords(poll.closeTime * 1000 - now) }}

    +
    +
    +

    {{poll.votes < votesRequired ? '🕐' : '👌'}}

    +
    +
    +
    +
  • +
+
+
+
+ + \ No newline at end of file diff --git a/public/views/block.html b/public/views/block.html index b8067f691..75d39f9c3 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -44,7 +44,7 @@
-
+
diff --git a/public/views/contract-source.html b/public/views/contract-source.html index 8f3c4d22b..d8e0c23c7 100644 --- a/public/views/contract-source.html +++ b/public/views/contract-source.html @@ -1,10 +1,10 @@
-
+

Contract Source Code Verified diff --git a/public/views/contract.html b/public/views/contract.html index 2367a04bf..4d62cd282 100644 --- a/public/views/contract.html +++ b/public/views/contract.html @@ -67,9 +67,11 @@

Verify and Publish Contract Source Code

- - +
+ + +
diff --git a/public/views/err_404.html b/public/views/err_404.html index b559687af..c72b4c84f 100755 --- a/public/views/err_404.html +++ b/public/views/err_404.html @@ -1,6 +1,6 @@
-
404
+
404

Oops! You're lost.

We can not find the {{thing}} you are looking for. diff --git a/public/views/home.html b/public/views/home.html index 60f6b7c88..d078f96dc 100755 --- a/public/views/home.html +++ b/public/views/home.html @@ -6,8 +6,8 @@

- - Blocks + + Blocks
@@ -18,7 +18,7 @@
-
+
{{t.number}}
@@ -42,8 +42,8 @@
- - Transactions + + Transactions
diff --git a/public/views/simple-summary-stats.html b/public/views/simple-summary-stats.html index 9d25c6e80..77a22cb68 100644 --- a/public/views/simple-summary-stats.html +++ b/public/views/simple-summary-stats.html @@ -1,5 +1,5 @@
-
+
@@ -15,7 +15,7 @@

-
+
@@ -30,34 +30,34 @@

-
-
-
-
- -
-
-

- {{stats.hashrate | totalDifficulty}}/s -

- Network Hashrate -
-
-
-
-
-
-
-
- -
-
-

- {{stats.difficulty | totalDifficulty}} -

- DIFFICULTY -
-
-
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/public/views/stats/index.html b/public/views/stats/index.html index c5d87d2ca..73a975152 100644 --- a/public/views/stats/index.html +++ b/public/views/stats/index.html @@ -4,9 +4,9 @@
- + - +
diff --git a/public/views/tokenlist.html b/public/views/tokenlist.html index ece1553c4..e92c611d2 100755 --- a/public/views/tokenlist.html +++ b/public/views/tokenlist.html @@ -3,8 +3,12 @@
- - + +
{{t.name}} ({{t.symbol}}) {{t.address}} + {{t.name}} ({{t.symbol}}) + + {{t.address}} +
diff --git a/public/views/votersList.html b/public/views/votersList.html new file mode 100644 index 000000000..4dffa3076 --- /dev/null +++ b/public/views/votersList.html @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/routes/authorities.js b/routes/authorities.js new file mode 100644 index 000000000..70938fe25 --- /dev/null +++ b/routes/authorities.js @@ -0,0 +1,25 @@ +const { eth } = require('./web3relay'); +const ABI = require('../abi/bios'); +const { getConfig } = require('../utils'); + +const config = getConfig(); +if (!config.biosAddress) throw new Error('Setup config.biosAddres'); +const contract = new eth.Contract(ABI, config.biosAddress); + +module.exports = function (req, res) { + if (typeof contract.methods.getAuthorities !== 'function') { + console.error('Contract method \'getAuthorities\' not found', err); + res.send([]); + res.end(); + } + contract.methods.getAuthorities().call() + .then(authorities => { + res.send(authorities); + res.end(); + }) + .catch(err => { + console.error('Can\'t get authorities from contract. Silently return empty array', err); + res.send([]); + res.end(); + }) +}; diff --git a/routes/index.js b/routes/index.js index 31f13c6e2..3246331d8 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,10 +3,13 @@ const mongoose = require('mongoose'); const Block = mongoose.model('Block'); const Transaction = mongoose.model('Transaction'); const Account = mongoose.model('Account'); +const Authority = mongoose.model('Authority'); +const Blacklist = mongoose.model('Blacklist'); +const Poll = mongoose.model('Poll'); const async = require('async'); const filters = require('./filters'); -module.exports = function (app) { +module.exports = function(app) { const web3relay = require('./web3relay'); const Token = require('./token'); @@ -33,9 +36,67 @@ module.exports = function (app) { app.post('/web3relay', web3relay.data); app.post('/compile', compile); + app.get('/polls', getPolls); + app.get('/votes-list', getVotesList); + app.post('/stats', stats); + + const authoritiesRoute = require('./authorities'); + app.post('/authorities', authoritiesRoute); +}; + +const getPolls = async (req, res) => { + const type = req.query.type || 0; + async.parallel( + { + nodes: cb => { + (type == 0 ? Authority : Blacklist).find({}) + .lean(true) + .exec('find', (err, docs) => cb(null, docs)); + }, + polls: cb => { + Poll.find({ type, isDisabled: false }) + .lean(true) + .exec('find', (err, docs) => cb(null, docs)); + } + }, + (err, result) => { + if (err) console.log(err); + res.write(JSON.stringify(result)); + res.end(); + } + ); }; +const SIGNATURES = { + voteForNewAuthority: '0xfc3c9afd', + voteForBlackListAuthority: '0x332327a2' +} + +const getVotesList = async (req, res) => { + const type = req.query.type || 0; + const isPoll = req.query.poll || 0; + const address = req.query.address.substr(2).toLowerCase(); + + if (!address) { + res.write(JSON.stringify([])); + res.end(); + return; + } + + const signatute = SIGNATURES[type == 0 ? 'voteForNewAuthority' : 'voteForBlackListAuthority']; + const $and = [ + { input: new RegExp('^' + signatute, 'gi') }, + { input: new RegExp(address + '$', 'gi') }, + ]; + // if (type == 1) { + // $and.push({ status: isPoll ? null : { $ne: null } }); + // } + const results = await Transaction.find({$and}).lean(true); + res.write(JSON.stringify(results)); + res.end(); +} + const getAddr = async (req, res) => { // TODO: validate addr and tx const addr = req.body.addr.toLowerCase(); @@ -44,11 +105,14 @@ const getAddr = async (req, res) => { const limit = parseInt(req.body.length); const start = parseInt(req.body.start); - const data = { - draw: parseInt(req.body.draw), recordsFiltered: count, recordsTotal: count, mined: 0, + const data = { + draw: parseInt(req.body.draw), + recordsFiltered: count, + recordsTotal: count, + mined: 0 }; - const addrFind = Transaction.find({ $or: [{ 'to': addr }, { 'from': addr }] }); + const addrFind = Transaction.find({ $or: [{ to: addr }, { from: addr }] }); let sortOrder = '-blockNumber'; if (req.body.order && req.body.order[0] && req.body.order[0].column) { @@ -60,48 +124,54 @@ const getAddr = async (req, res) => { } } - addrFind.lean(true).sort(sortOrder).skip(start).limit(limit) + addrFind + .lean(true) + .sort(sortOrder) + .skip(start) + .limit(limit) .exec('find', (err, docs) => { if (docs) data.data = filters.filterTX(docs, addr); else data.data = []; res.write(JSON.stringify(data)); res.end(); }); - }; -var getAddrCounter = function (req, res) { +var getAddrCounter = function(req, res) { const addr = req.body.addr.toLowerCase(); const count = parseInt(req.body.count); const data = { recordsFiltered: count, recordsTotal: count, mined: 0 }; - async.waterfall([ - function (callback) { - - Transaction.count({ $or: [{ 'to': addr }, { 'from': addr }] }, (err, count) => { - if (!err && count) { - // fix recordsTotal - data.recordsTotal = count; - data.recordsFiltered = count; - } - callback(null); - }); - - }, function (callback) { - - Block.count({ 'miner': addr }, (err, count) => { - if (!err && count) { - data.mined = count; - } - callback(null); - }); - - }], (err) => { - res.write(JSON.stringify(data)); - res.end(); - }); - + async.waterfall( + [ + function(callback) { + Transaction.count( + { $or: [{ to: addr }, { from: addr }] }, + (err, count) => { + if (!err && count) { + // fix recordsTotal + data.recordsTotal = count; + data.recordsFiltered = count; + } + callback(null); + } + ); + }, + function(callback) { + Block.count({ miner: addr }, (err, count) => { + if (!err && count) { + data.mined = count; + } + callback(null); + }); + } + ], + err => { + res.write(JSON.stringify(data)); + res.end(); + } + ); }; -var getBlock = function (req, res) { +var getBlock = function(req, res) { // TODO: support queries for block hash const txQuery = 'number'; const number = parseInt(req.body.block); @@ -111,7 +181,7 @@ var getBlock = function (req, res) { if (err || !doc) { console.error(`BlockFind error: ${err}`); console.error(req.body); - res.write(JSON.stringify({ 'error': true })); + res.write(JSON.stringify({ error: true })); } else { const block = filters.filterBlocks([doc]); res.write(JSON.stringify(block[0])); @@ -119,10 +189,12 @@ var getBlock = function (req, res) { res.end(); }); }; -var getTx = function (req, res) { +var getTx = function(req, res) { const tx = req.body.tx.toLowerCase(); - const txFind = Block.findOne({ 'transactions.hash': tx }, 'transactions timestamp') - .lean(true); + const txFind = Block.findOne( + { 'transactions.hash': tx }, + 'transactions timestamp' + ).lean(true); txFind.exec((err, doc) => { if (!doc) { console.log(`missing: ${tx}`); @@ -139,7 +211,7 @@ var getTx = function (req, res) { /* Fetch data from DB */ -var getData = function (req, res) { +var getData = function(req, res) { // TODO: error handling for invalid calls const action = req.body.action.toLowerCase(); const { limit } = req.body; @@ -157,9 +229,9 @@ var getData = function (req, res) { /* Total supply API code */ -var getTotal = function (req, res) { +var getTotal = function(req, res) { Account.aggregate([ - { $group: { _id: null, totalSupply: { $sum: '$balance' } } }, + { $group: { _id: null, totalSupply: { $sum: '$balance' } } } ]).exec((err, docs) => { if (err) { res.write('Error getting total supply'); @@ -173,60 +245,71 @@ var getTotal = function (req, res) { /* temporary blockstats here */ -const latestBlock = function (req, res) { +const latestBlock = function(req, res) { const block = Block.findOne({}, 'totalDifficulty') - .lean(true).sort('-number'); + .lean(true) + .sort('-number'); block.exec((err, doc) => { res.write(JSON.stringify(doc)); res.end(); }); }; -const getLatest = function (lim, res, callback) { - const blockFind = Block.find({}, 'number transactions timestamp miner extraData') - .lean(true).sort('-number').limit(lim); +const getLatest = function(lim, res, callback) { + const blockFind = Block.find( + {}, + 'number transactions timestamp miner extraData' + ) + .lean(true) + .sort('-number') + .limit(lim); blockFind.exec((err, docs) => { callback(docs, res); }); }; /* get blocks from db */ -const sendBlocks = function (lim, res) { +const sendBlocks = function(lim, res) { const blockFind = Block.find({}, 'number timestamp miner extraData') - .lean(true).sort('-number').limit(lim); + .lean(true) + .sort('-number') + .limit(lim); blockFind.exec((err, docs) => { if (!err && docs) { const blockNumber = docs[docs.length - 1].number; // aggregate transaction counters Transaction.aggregate([ { $match: { blockNumber: { $gte: blockNumber } } }, - { $group: { _id: '$blockNumber', count: { $sum: 1 } } }, + { $group: { _id: '$blockNumber', count: { $sum: 1 } } } ]).exec((err, results) => { const txns = {}; if (!err && results) { // set transaction counters - results.forEach((txn) => { + results.forEach(txn => { txns[txn._id] = txn.count; }); - docs.forEach((doc) => { + docs.forEach(doc => { doc.txn = txns[doc.number] || 0; }); } - res.write(JSON.stringify({ 'blocks': filters.filterBlocks(docs) })); + res.write(JSON.stringify({ blocks: filters.filterBlocks(docs) })); res.end(); }); } else { console.log(`blockFind error:${err}`); - res.write(JSON.stringify({ 'error': true })); + res.write(JSON.stringify({ error: true })); res.end(); } }); }; -const sendTxs = function (lim, res) { - Transaction.find({}).lean(true).sort('-blockNumber').limit(lim) +const sendTxs = function(lim, res) { + Transaction.find({}) + .lean(true) + .sort('-blockNumber') + .limit(lim) .exec((err, txs) => { - res.write(JSON.stringify({ 'txs': txs })); + res.write(JSON.stringify({ txs: txs })); res.end(); }); }; @@ -234,6 +317,6 @@ const sendTxs = function (lim, res) { const MAX_ENTRIES = 10; const DATA_ACTIONS = { - 'latest_blocks': sendBlocks, - 'latest_txs': sendTxs, + latest_blocks: sendBlocks, + latest_txs: sendTxs }; diff --git a/routes/richlist.js b/routes/richlist.js index 6772f1757..11a9e8fb2 100644 --- a/routes/richlist.js +++ b/routes/richlist.js @@ -103,7 +103,9 @@ var getAccounts = function (req, res) { data.totalSupply = totalSupply; } - Account.find({}).lean(true).sort(sortOrder).skip(start) + Account + .find({ address: { '$ne': '0x0000000000000000000000000000000000000000' }}) + .lean(true).sort(sortOrder).skip(start) .limit(limit) .exec((err, accounts) => { if (err) { diff --git a/routes/stats.js b/routes/stats.js index 243ba5a8e..945571694 100644 --- a/routes/stats.js +++ b/routes/stats.js @@ -9,18 +9,18 @@ const filters = require('./filters'); const etherUnits = require(`${__lib}etherUnits.js`); -let config = {}; -try { - config = require('../config.json'); -} catch (e) { - if (e.code == 'MODULE_NOT_FOUND') { - console.log('No config file found. Using default configuration... (config.example.json)'); - config = require('../config.example.json'); - } else { - throw e; - process.exit(1); - } -} +const config = require('../utils').getConfig(); +// try { +// config = require('../config.json'); +// } catch (e) { +// if (e.code == 'MODULE_NOT_FOUND') { +// console.log('No config file found. Using default configuration... (config.example.json)'); +// config = require('../config.example.json'); +// } else { +// throw e; +// process.exit(1); +// } +// } module.exports = function (req, res) { diff --git a/routes/web3relay.js b/routes/web3relay.js index 96176f092..3dd011034 100644 --- a/routes/web3relay.js +++ b/routes/web3relay.js @@ -53,10 +53,11 @@ else throw 'No connection, please specify web3host in conf.json'; async function detectNode() { const nodeInfo = await web3.eth.getNodeInfo(); - if (nodeInfo.split('/')[0].toLowerCase().includes('parity')) { - console.log('Web3 has detected parity node configuration'); - web3explorer(web3); - } + // if (nodeInfo.split('/')[0].toLowerCase().includes('parity')) { + // console.log('Web3 has detected parity node configuration'); + // TODO: investigate + web3explorer(web3); + // } console.log(`Node version = ${nodeInfo}`); } detectNode(); @@ -312,4 +313,5 @@ exports.data = async (req, res) => { }; +exports.web3 = web3; exports.eth = web3.eth; diff --git a/tools/sync-votes.js b/tools/sync-votes.js new file mode 100644 index 000000000..4dc7bf572 --- /dev/null +++ b/tools/sync-votes.js @@ -0,0 +1,189 @@ +const Web3 = require('web3'); + +const ABI = require('../abi/bios'); +const { getConfig } = require('../utils'); +const config = getConfig(); + +require('../db.js'); +const mongoose = require('mongoose'); + +const Transaction = mongoose.model('Transaction'); +const Authority = mongoose.model('Authority'); +const AuthoritySlot = mongoose.model('AuthoritySlot'); +const Blacklist = mongoose.model('Blacklist'); +const Poll = mongoose.model('Poll'); + +const SYNC_TIMEOUT = 3000; +const SIGNATURES = { + voteForNewAuthority: '0xfc3c9afd', + voteForBlackListAuthority: '0x332327a2' +} + +console.log(`Connecting ${config.nodeAddr}:${config.wsPort}...`); +const web3 = new Web3( + new Web3.providers.WebsocketProvider( + `ws://${config.nodeAddr}:${config.wsPort}` + ) +); +if (web3.eth.net.isListening()) console.log('Web3 connection established'); +const contract = new web3.eth.Contract(ABI, config.biosAddress); + +const callMethod = (method, ...args) => + contract.methods[method](...args).call(); + +const getAuthorities = async () => { + const authorities = await callMethod('getAuthorities'); + const data = await Promise.all( + authorities.map(address => callMethod('getAuthorityState', address)) + ); + return authorities.map((address, index) => ({ + address, + votes: parseInt(data[index][0], 10), + slots: data[index][1].map((a, i) => ({ + address: a, + timestamp: parseInt(data[index][2][i], 10) + })) + })); +}; + +const getBlacklisted = async () => { + const blacklisted = await callMethod('getAuthorityBlacklistPollAddresses'); + const results = await Transaction.aggregate([ + { + $match: { + $and: [ + { input: new RegExp('^' + SIGNATURES.voteForBlackListAuthority, 'gi') }, + { status: { $ne: null }} + ] + } + }, + { + $group: { + _id: "$input", + count: {$sum: 1} + } + } + ]); + return blacklisted.map(address => { + const match = results.find(res => (new RegExp(address.substr(2).toLowerCase(), 'gi').test(res._id))); + return { + address, + votes: match && match.count || 0 + }; + }); +} + +const getNewAuthorityPolls = async () => { + const addresses = await callMethod('getAddNewPollAddresses'); + const data = await Promise.all( + addresses.map(address => callMethod('addNewPoll', address)) + ); + return addresses.map((address, index) => ({ + address, + closeTime: data[index].closeTime, + votes: parseInt(data[index].votes, 10) + })); +}; + +const getBlacklistPolls = async () => { + const addresses = await callMethod('getAuthorityBlacklistPollAddresses'); + const data = await Promise.all( + addresses.map(address => callMethod('authorityBlacklistPoll', address)) + ); + return addresses.map((address, index) => ({ + address, + closeTime: data[index].closeTime, + votes: parseInt(data[index].votes, 10), + isVoted: data[index].voted || false + })); +}; + +const saveOrUpdateAuthorities = authorities => { + authorities.forEach(authority => { + const { address, votes } = authority; + const slots = authority.slots.map(({ address, timestamp }) => + AuthoritySlot({ address, timestamp }) + ); + Authority.update( + { address: address }, + { address, slots, votes }, + { upsert: true, setDefaultsOnInsert: true }, + (err, data) => { + if (err) console.log(err); + } + ); + }); +}; + +const saveOrUpdateBlacklist = blacklist => { + blacklist.forEach(bl => { + const { address, votes } = bl; + Blacklist.update( + { address: address }, + { address, votes }, + { upsert: true, setDefaultsOnInsert: true }, + (err, data) => { + if (err) console.log(err); + } + ) + }) +} + +const saveOrUpdatePolls = (polls, type = 0) => { + if (![0, 1].includes(type)) return; + + polls.forEach(poll => { + const { address } = poll; + Poll.update( + { address }, + { ...poll, type }, + { upsert: true, setDefaultsOnInsert: true }, + (err, data) => { + if (err) console.log(err); + } + ); + }); +}; + +const disableFinalisedPolls = addressesToDelete => { + Poll.updateMany( + { address: { $nin: addressesToDelete }, isDisabled: false }, + { $set: { isDisabled: true } }, + (err, data) => { + if (err) console.log(err); + } + ); +}; + +const saveOrUpdateData = async ( + authorities, + authorityPolls, + blacklist, + blacklistPolls +) => { + saveOrUpdateAuthorities(authorities); + saveOrUpdateBlacklist(blacklist); + disableFinalisedPolls( + [...authorityPolls, ...blacklistPolls].map(p => p.address) + ); + saveOrUpdatePolls(authorityPolls, 0); + saveOrUpdatePolls(blacklistPolls, 1); +}; + +let timeout; +const syncronize = async () => { + clearTimeout(timeout); + try { + const [authorities, authorityPolls, blacklist, blacklistPolls] = await Promise.all([ + getAuthorities(), + getNewAuthorityPolls(), + getBlacklisted(), + getBlacklistPolls() + ]); + saveOrUpdateData(authorities, authorityPolls, blacklist, blacklistPolls); + } finally { + setTimeout(syncronize, SYNC_TIMEOUT); + } +}; + +syncronize(); diff --git a/tools/sync.js b/tools/sync.js index 91392d248..8b50cb86c 100644 --- a/tools/sync.js +++ b/tools/sync.js @@ -25,6 +25,8 @@ const Account = mongoose.model('Account'); const Contract = mongoose.model('Contract'); const TokenTransfer = mongoose.model('TokenTransfer'); +const { getSigner } = require('../utils'); + const ERC20_METHOD_DIC = { '0xa9059cbb': 'transfer', '0xa978501e': 'transferFrom' }; /** @@ -95,6 +97,16 @@ const normalizeTX = async (txData, receipt, blockData) => { Write the whole block object to DB **/ var writeBlockToDB = function (config, blockData, flush) { + + try { + if (blockData) { + blockData.miner = '0x' + getSigner(blockData); + } + } catch (err) { + // do nothing + console.log(err); + } + const self = writeBlockToDB; if (!self.bulkOps) { self.bulkOps = []; diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 000000000..4b79f2829 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,34 @@ +const ethUtils = require('ethereumjs-util'); +const ethBlock = require('ethereumjs-block/from-rpc'); + +function getSigner(block) { + const sealers = block.extraData; + if (sealers.length <= 130) return undefined; + const sig = ethUtils.fromRpcSig('0x' + sealers.substring(sealers.length - 130, sealers.length)); // remove signature + block.extraData = block.extraData.substring(0, block.extraData.length - 130); + const blk = ethBlock(block); + blk.header.difficulty[0] = block.difficulty; + const sigHash = ethUtils.sha3(blk.header.serialize()); + const pubkey = ethUtils.ecrecover(sigHash, sig.v, sig.r, sig.s); + return ethUtils.pubToAddress(pubkey).toString('hex') +} +module.exports.getSigner = getSigner; + +let config; +function getConfig() { + if (config) return config; + try { + config = require('../config.json'); + } catch (e) { + if (e.code == 'MODULE_NOT_FOUND') { + console.log('No config file found. Using default configuration... (config.example.json)'); + config = require('../config.example.json'); + } else { + throw e; + process.exit(1); + } + } + return config; +} +module.exports.getConfig = getConfig; + diff --git a/views/error.ejs b/views/error.ejs index 58f8255fd..7cf94edf1 100644 --- a/views/error.ejs +++ b/views/error.ejs @@ -1,3 +1,3 @@

<%= message %>

<%= error.status %>

-
<%= error.stack %>
\ No newline at end of file +
<%= error.stack %>
diff --git a/views/index.ejs b/views/index.ejs index d209f5456..01c35c1dc 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -16,7 +16,7 @@ - + @@ -31,14 +31,14 @@ - +
- + Loading...