From 62d7a37b28296196c7f158c6d657190b614f8ee8 Mon Sep 17 00:00:00 2001 From: emi Date: Mon, 13 Jul 2020 10:04:59 -0600 Subject: [PATCH] Build 1.1.0 --- CHANGELOG.md | 22 +- dist/api/Api.js | 11 + dist/api/channels.js | 3 +- dist/api/index.js | 8 +- .../lib/DataCollector/DataCollectorItem.js | 8 +- dist/api/modules/Address.js | 7 +- dist/api/modules/Balances.js | 114 ++ dist/api/modules/ContractVerification.js | 56 +- dist/api/modules/InternalTx.js | 211 ++ dist/api/modules/index.js | 16 +- dist/lib/BlocksBase.js | 28 +- dist/lib/Db.js | 27 +- dist/lib/Logger.js | 17 +- dist/lib/Setup.js | 107 +- dist/lib/StoredConfig.js | 32 +- dist/lib/cli.js | 12 +- dist/lib/collections.js | 77 +- dist/lib/config.js | 35 +- dist/lib/dataSource.js | 9 +- dist/lib/defaultConfig.js | 19 +- dist/lib/delayedFields.js | 14 +- dist/lib/ids.js | 38 +- dist/lib/nod3Connect.js | 48 +- dist/lib/types.js | 20 +- dist/lib/utils.js | 28 +- dist/services/Router.js | 169 ++ dist/services/Service/README.md | 1 + dist/services/Service/ServiceClient.js | 94 + dist/services/Service/ServiceServer.js | 197 ++ dist/services/Service/compile.proto.sh | 2 + .../Service/protos/services_grpc_pb.js | 167 ++ dist/services/Service/protos/services_pb.js | 1533 +++++++++++++++ dist/services/Service/serviceProto.js | 26 + dist/services/Service/services.proto | 52 + dist/services/blocks.config.js | 15 + dist/services/blocks/blocksBalances.js | 33 + dist/services/blocks/blocksChecker.js | 52 +- dist/services/blocks/blocksListener.js | 31 +- dist/services/blocks/blocksRequester.js | 113 +- dist/services/blocks/blocksRouter.js | 16 + dist/services/blocks/blocksStats.js | 26 + dist/services/blocks/blocksStatus.js | 26 + dist/services/blocks/index.js | 80 - dist/services/blocks/setup.js | 8 - dist/services/blocks/txPool.js | 22 + dist/services/classes/Address.js | 321 ++- dist/services/classes/Addresses.js | 49 + dist/services/classes/BcThing.js | 21 +- dist/services/classes/Block.js | 302 +-- dist/services/classes/BlockAddresses.js | 17 + dist/services/classes/BlockBalances.js | 59 + dist/services/classes/BlockSummary.js | 177 ++ dist/services/classes/BlockTrace.js | 40 + dist/services/classes/CheckBlocks.js | 44 +- dist/services/classes/Contract.js | 115 +- dist/services/classes/Event.js | 2 +- dist/services/classes/InternalTx.js | 67 + dist/services/classes/ListenBlocks.js | 25 +- dist/services/classes/RequestBlocks.js | 96 +- dist/services/classes/TokenAddress.js | 8 +- dist/services/classes/Tx.js | 189 +- dist/services/classes/TxTrace.js | 66 + dist/services/classes/UpdateBlockBalances.js | 138 ++ dist/services/serviceFactory.js | 78 + dist/services/servicesConfig.js | 34 + dist/services/txPool.js | 19 - dist/services/userEvents/userEventsService.js | 31 +- dist/tools/cacheBlocksTraces.js | 113 ++ dist/tools/checkDbBlocks.js | 42 +- dist/tools/showBlocksTraces.js | 22 + package-lock.json | 1732 +++++++---------- package.json | 2 +- public/swagger.json | 399 +++- 73 files changed, 5887 insertions(+), 1951 deletions(-) create mode 100644 dist/api/modules/Balances.js create mode 100644 dist/api/modules/InternalTx.js create mode 100644 dist/services/Router.js create mode 100644 dist/services/Service/README.md create mode 100644 dist/services/Service/ServiceClient.js create mode 100644 dist/services/Service/ServiceServer.js create mode 100644 dist/services/Service/compile.proto.sh create mode 100644 dist/services/Service/protos/services_grpc_pb.js create mode 100644 dist/services/Service/protos/services_pb.js create mode 100644 dist/services/Service/serviceProto.js create mode 100644 dist/services/Service/services.proto create mode 100644 dist/services/blocks.config.js create mode 100644 dist/services/blocks/blocksBalances.js create mode 100644 dist/services/blocks/blocksRouter.js create mode 100644 dist/services/blocks/blocksStats.js create mode 100644 dist/services/blocks/blocksStatus.js delete mode 100644 dist/services/blocks/index.js delete mode 100644 dist/services/blocks/setup.js create mode 100644 dist/services/blocks/txPool.js create mode 100644 dist/services/classes/Addresses.js create mode 100644 dist/services/classes/BlockAddresses.js create mode 100644 dist/services/classes/BlockBalances.js create mode 100644 dist/services/classes/BlockSummary.js create mode 100644 dist/services/classes/BlockTrace.js create mode 100644 dist/services/classes/InternalTx.js create mode 100644 dist/services/classes/TxTrace.js create mode 100644 dist/services/classes/UpdateBlockBalances.js create mode 100644 dist/services/serviceFactory.js create mode 100644 dist/services/servicesConfig.js delete mode 100644 dist/services/txPool.js create mode 100644 dist/tools/cacheBlocksTraces.js create mode 100644 dist/tools/showBlocksTraces.js diff --git a/CHANGELOG.md b/CHANGELOG.md index cf6bc855..272c957c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ # Changelog -## [1.0.8] - 2019-06-02 +## [1.1.0] - 2020-07-13 + +### Added + +- Internal Transactions +- Address Balances +- Decode events using ABI for verified contracts + +## Changed + +- Services + +## [1.0.8] - 2020-06-02 ### Added @@ -10,7 +22,7 @@ - TxPool collection indexes -## [1.0.7] - 2019-04-08 +## [1.0.7] - 2020-04-08 ### Fixed @@ -22,7 +34,7 @@ - Update the balances of the token accounts, recovered in the previous block, when a new block is saved. -## [1.0.5] - 2019-03-05 +## [1.0.5] - 2020-03-05 ### Fixed @@ -33,7 +45,7 @@ - Docker: expose api documentation -## [1.0.4] - 2019-02-27 +## [1.0.4] - 2020-02-27 ### Added @@ -50,7 +62,7 @@ - API/Address.getMiners -## [1.0.3] - 2019-01-03 +## [1.0.3] - 2020-01-03 ### Added diff --git a/dist/api/Api.js b/dist/api/Api.js index 7f438cad..61a9aa06 100644 --- a/dist/api/Api.js +++ b/dist/api/Api.js @@ -18,6 +18,7 @@ class Api extends _DataCollector.DataCollector { this.latest = undefined; this.lastBlocks = { data: [] }; this.lastTransactions = { data: [] }; + this.balancesStatus = { data: {} }; this.circulatingSupply = null; this.stats = { timestamp: 0 }; this.loadModules((0, _modules.getEnabledApiModules)(modules)); @@ -28,6 +29,7 @@ class Api extends _DataCollector.DataCollector { } tick() { this.setLastBlocks(); + this.updateBalancesStatus(); } loadModules(modules) { @@ -105,6 +107,15 @@ class Api extends _DataCollector.DataCollector { return data[0] || null; } + getBalancesStatus() { + return this.balancesStatus; + } + + async updateBalancesStatus() { + let data = await this.getModule('Balances').run('getStatus'); + this.balancesStatus = data; + } + updateLastBlocks(blocks, transactions) { let blockData = blocks.data; this.lastBlocks = blocks; diff --git a/dist/api/channels.js b/dist/api/channels.js index 7d7296d7..088abf38 100644 --- a/dist/api/channels.js +++ b/dist/api/channels.js @@ -6,7 +6,8 @@ const CHANNELS = { txsChannel: 'transactions', statusChannel: 'status', txPoolChannel: 'txpool', - statsChannel: 'stats' };exports.CHANNELS = CHANNELS; + statsChannel: 'stats', + balancesChannel: 'balances' };exports.CHANNELS = CHANNELS; const createChannels = io => { diff --git a/dist/api/index.js b/dist/api/index.js index dbf396a0..fffe174b 100644 --- a/dist/api/index.js +++ b/dist/api/index.js @@ -39,7 +39,7 @@ const address = _config.default.api.address || 'localhost'; // create channels const channels = (0, _channels.createChannels)(io); - const { blocksChannel, statusChannel, txPoolChannel, statsChannel, txsChannel } = channels.channels; + const { blocksChannel, statusChannel, txPoolChannel, statsChannel, txsChannel, balancesChannel } = channels.channels; // send blocks on join blocksChannel.on('join', socket => { @@ -65,6 +65,7 @@ const address = _config.default.api.address || 'localhost'; api.events.on('newBlocks', result => { blocksChannel.emit('newBlocks', result); txsChannel.emit('newTransactions', api.getLastTransactions()); + balancesChannel.emit('balancesStatus', api.getBalancesStatus()); }); // send stats on join @@ -92,6 +93,11 @@ const address = _config.default.api.address || 'localhost'; statsChannel.emit('stats', result); }); + // send balances status on join + balancesChannel.on('join', socket => { + socket.emit('data', (0, _apiTools.formatRes)({ action: 'balancesStatus', result: api.getBalancesStatus() })); + }); + io.on('connection', socket => { socket.emit('open', { time: Date.now(), settings: api.info() }); socket.on('message', () => {}); diff --git a/dist/api/lib/DataCollector/DataCollectorItem.js b/dist/api/lib/DataCollector/DataCollectorItem.js index 540025b7..03ff6f57 100644 --- a/dist/api/lib/DataCollector/DataCollectorItem.js +++ b/dist/api/lib/DataCollector/DataCollectorItem.js @@ -52,9 +52,10 @@ class DataCollectorItem { return { data }; } - async getOne(query, projection) { + async getOne(query, projection, sort) { projection = projection || this.getDefaultsFields(); - const data = await this.db.findOne(query, { projection }); + sort = sort || this.sort; + const data = await this.db.findOne(query, { projection, sort }); return { data }; } @@ -80,7 +81,10 @@ class DataCollectorItem { let sortDir = this.sortDir; let { limit, next, prev, fields, count, countOnly, page, getPages } = params; + + // fields = parseFields(fields) if (!fields) fields = this.getDefaultsFields(); + sort = filterSort(sort, sortable, defaultSort); return { sort, sortable, defaultSort, sortDir, limit, next, prev, fields, count, countOnly, page, getPages }; } diff --git a/dist/api/modules/Address.js b/dist/api/modules/Address.js index b1507a69..49970f54 100644 --- a/dist/api/modules/Address.js +++ b/dist/api/modules/Address.js @@ -215,7 +215,12 @@ class Address extends _DataCollector.DataCollectorItem { const { createdByTx, code } = data; if (!code) throw new Error('The address does not have code'); if (createdByTx) { - data.creationCode = createdByTx.input; + // is a transaction + if (createdByTx.hasOwnProperty('receipt')) { + data.creationCode = createdByTx.input; + } else {// is an internal transactions + data.creationCode = createdByTx.action.init; + } data.created = createdByTx.timestamp; delete data.createdByTx; } diff --git a/dist/api/modules/Balances.js b/dist/api/modules/Balances.js new file mode 100644 index 00000000..bffc9f84 --- /dev/null +++ b/dist/api/modules/Balances.js @@ -0,0 +1,114 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Balances = void 0;var _DataCollector = require("../lib/DataCollector"); +var _utils = require("../../lib/utils"); + +class Balances extends _DataCollector.DataCollectorItem { + constructor({ Balances }, name) { + let sortable = { timestamp: -1, blockNumber: -1 }; + super(Balances, name, { sortDir: -1, sortable }); + this.fields = {}; + this.publicActions = { + /** + * @swagger + * /api?module=balances&action=getBalance: + * get: + * description: get address balance at blockNumber (if exists) + * tags: + * - balances + * parameters: + * - name: module + * in: query + * required: true + * enum: [balances] + * - name: action + * in: query + * required: true + * enum: [getBalance] + * - $ref: '#/parameters/address' + * - name: block + * in: query + * required: true + * schema: + * type: string + * description: block hash or block number + * example: 30000 + * responses: + * 200: + * $ref: '#/definitions/Response' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getBalance: async params => { + const { address, block } = params; + const query = { address }; + + if ((0, _utils.isBlockHash)(block)) query.blockHash = block;else + query.blockNumber = parseInt(block); + + return this.getItem(query, params); + }, + /** + * @swagger + * /api?module=balances&action=getBalances: + * get: + * description: get address balances + * tags: + * - balances + * parameters: + * - name: module + * in: query + * required: true + * enum: [balances] + * - name: action + * in: query + * required: true + * enum: [getBalances] + * - $ref: '#/parameters/address' + * responses: + * 200: + * $ref: '#/definitions/Response' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getBalances: async params => { + const { address } = params; + return this.getPageData({ address }, params); + }, + /** + * @swagger + * /api?module=balances&action=getStatus: + * get: + * description: get status of balances + * tags: + * - balances + * parameters: + * - name: module + * in: query + * required: true + * enum: [balances] + * - name: action + * in: query + * required: true + * enum: [getStatus] + * responses: + * 200: + * $ref: '#/definitions/Response' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getStatus: async params => { + const projection = { blockHash: 1, blockNumber: 1, _id: 0 }; + const fromBlock = await this.getOne({}, projection, { blockNumber: 1 }); + const toBlock = await this.getOne({}, projection, { blockNumber: -1 }); + return { data: { fromBlock: fromBlock.data, toBlock: toBlock.data } }; + } }; + + }}exports.Balances = Balances;var _default = + + +Balances;exports.default = _default; \ No newline at end of file diff --git a/dist/api/modules/ContractVerification.js b/dist/api/modules/ContractVerification.js index 90754c64..6f63003d 100644 --- a/dist/api/modules/ContractVerification.js +++ b/dist/api/modules/ContractVerification.js @@ -12,24 +12,44 @@ class ContractVerification extends _DataCollector.DataCollectorItem { this.verificationsCollection = VerificationsResults; this.publicActions = { /** - * @swagger - * /api?module=contractVerifier&action=verify: - * get: - * description: Verify contract source - * tags: - * - contract verifier - * parameters: - * - name: request - * in: query - * required: true - * responses: - * 200: - * $ref: '#/definitions/Response' - * 400: - * $ref: '#/responses/BadRequest' - * 404: - * $ref: '#/responses/NotFound' - */ + * @swagger + * /api?module=contractVerifier&action=getVerifiedContracts: + * get: + * description: Gets a list of verified contracts addresses + * tags: + * - contract verifier + * responses: + * 200: + * $ref: '#/definitions/Response' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getVerifiedContracts: params => { + params.fields = ['address']; + let query = { match: true }; + return this.getPageData(query, params); + }, + /** + * @swagger + * /api?module=contractVerifier&action=verify: + * get: + * description: Verify contract source + * tags: + * - contract verifier + * parameters: + * - name: request + * in: query + * required: true + * responses: + * 200: + * $ref: '#/definitions/Response' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ verify: async params => { try { const { request } = params; diff --git a/dist/api/modules/InternalTx.js b/dist/api/modules/InternalTx.js new file mode 100644 index 00000000..685c284a --- /dev/null +++ b/dist/api/modules/InternalTx.js @@ -0,0 +1,211 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.InternalTx = void 0;var _DataCollector = require("../lib/DataCollector"); +var _utils = require("../../lib/utils"); + +class InternalTx extends _DataCollector.DataCollectorItem { + constructor(collections, key) { + const { InternalTransactions } = collections; + let cursorField = 'internalTxId'; + let sortDir = -1; + const sortable = { internalTxId: -1 }; + super(InternalTransactions, key, { cursorField, sortDir, sortable }); + this.publicActions = { + /** + * @swagger + * /api?module=internalTransactions&action=getInternalTransaction: + * get: + * description: get internal transaction + * tags: + * - internal transactions + * produces: + * - application/json + * parameters: + * - name: module + * in: query + * required: true + * enum: [internalTransactions] + * - name: action + * in: query + * required: true + * enum: [getInternalTransaction] + * - name: eventId + * in: query + * schema: + * type: string + * - $ref: '#/parameters/limit' + * - $ref: '#/parameters/next' + * - $ref: '#/parameters/prev' + * responses: + * 200: + * $ref: '#/definitions/ResponseList' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getInternalTransaction: params => { + let { internalTxId } = params; + return this.getItem({ internalTxId }, params); + }, + /** + * @swagger + * /api?module=internalTransactions&action=getInternalTransactions: + * get: + * description: get internal transactions + * tags: + * - internal transactions + * produces: + * - application/json + * parameters: + * - name: module + * in: query + * required: true + * enum: [internalTransactions] + * - name: action + * in: query + * required: true + * enum: [getInternalTransactions] + * - name: query + * in: query + * required: false + * schema: + * type: object + * - $ref: '#/parameters/limit' + * - $ref: '#/parameters/next' + * - $ref: '#/parameters/prev' + * responses: + * 200: + * $ref: '#/definitions/ResponseList' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getInternalTransactions: params => { + let query = {}; + return this.getPageData(query, params); + }, + /** + * @swagger + * /api?module=internalTransactions&action=getInternalTransactionsByAddress: + * get: + * description: get internal transactions by address + * tags: + * - internal transactions + * parameters: + * - name: module + * in: query + * required: true + * enum: [internalTransactions] + * - name: action + * in: query + * required: true + * enum: [getInternalTransactionsByAddress] + * - $ref: '#/parameters/address' + * responses: + * 200: + * $ref: '#/definitions/ResponseList' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getInternalTransactionsByAddress: params => { + const { address } = params; + return this.getPageData( + { + $or: [{ 'action.from': address }, { 'action.to': address }] }, + + params); + + }, + /** + * @swagger + * /api?module=internalTransactions&action=getInternalTransactionsByBlock: + * get: + * description: get internal transactions by block + * tags: + * - internal transactions + * parameters: + * - name: module + * in: query + * required: true + * enum: [internalTransactions] + * - name: action + * in: query + * required: true + * enum: [getInternalTransactionsByBlock] + * - $ref: '#/parameters/hashOrNumber' + * - $ref: '#/parameters/limit' + * - $ref: '#/parameters/next' + * - $ref: '#/parameters/prev' + * responses: + * 200: + * $ref: '#/definitions/ResponseList' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getInternalTransactionsByBlock: params => { + const hashOrNumber = params.hashOrNumber || params.number; + + if ((0, _utils.isBlockHash)(hashOrNumber)) { + params.blockHash = hashOrNumber; + return this.getInternalTransactionsByBlockHash(params); + } else { + params.blockNumber = parseInt(hashOrNumber); + return this.getInternalTransactionsByBlockNumber(params); + } + }, + /** + * @swagger + * /api?module=internalTransactions&action=getInternalTransactionsByTxHash: + * get: + * description: get internal transactions by tx hash + * tags: + * - internal transactions + * parameters: + * - name: module + * in: query + * required: true + * enum: [internalTransactions] + * - name: action + * in: query + * required: true + * enum: [getInternalTransactionsByTxHash] + * - $ref: '#/parameters/transactionHash' + * - $ref: '#/parameters/limit' + * - $ref: '#/parameters/next' + * - $ref: '#/parameters/prev' + * responses: + * 200: + * $ref: '#/definitions/ResponseList' + * 400: + * $ref: '#/responses/BadRequest' + * 404: + * $ref: '#/responses/NotFound' + */ + getInternalTransactionsByTxHash: params => { + let { transactionHash, hash } = params; + transactionHash = transactionHash || hash; + const query = { transactionHash }; + return this.getPageData(query, params); + } }; + + } + getInternalTransactionsByBlockNumber(params) { + const blockNumber = parseInt(params.blockNumber || params.number); + if (undefined !== blockNumber) { + return this.getPageData({ blockNumber }, params); + } + } + + getInternalTransactionsByBlockHash(params) { + const blockHash = params.blockHash; + if (blockHash) { + return this.getPageData({ blockHash }, params); + } + }}exports.InternalTx = InternalTx;var _default = + + +InternalTx;exports.default = _default; \ No newline at end of file diff --git a/dist/api/modules/index.js b/dist/api/modules/index.js index 692f02ae..b7175519 100644 --- a/dist/api/modules/index.js +++ b/dist/api/modules/index.js @@ -8,9 +8,23 @@ var _Stats = require("./Stats"); var _Summary = require("./Summary"); var _ContractVerification = require("./ContractVerification"); +var _InternalTx = require("./InternalTx"); +var _Balances = require("./Balances"); var _apiTools = require("../lib/apiTools"); // import { ExtendedStats } from './ExtendedStats' -const apiModules = { Block: _Block.Block, Tx: _Tx.Tx, Address: _Address.Address, Event: _Event.Event, Token: _Token.Token, TxPending: _TxPending.TxPending, Stats: _Stats.Stats, Summary: _Summary.Summary, ContractVerification: _ContractVerification.ContractVerification }; +const apiModules = { + Block: _Block.Block, + Tx: _Tx.Tx, + Address: _Address.Address, + Event: _Event.Event, + Token: _Token.Token, + TxPending: _TxPending.TxPending, + Stats: _Stats.Stats, + Summary: _Summary.Summary, + ContractVerification: _ContractVerification.ContractVerification, + InternalTx: _InternalTx.InternalTx, + Balances: _Balances.Balances }; + const getEnabledApiModules = modules => { const enabled = (0, _apiTools.getModulesNames)((0, _apiTools.getEnabledModules)(modules)); diff --git a/dist/lib/BlocksBase.js b/dist/lib/BlocksBase.js index d2cbbb15..4ec1b744 100644 --- a/dist/lib/BlocksBase.js +++ b/dist/lib/BlocksBase.js @@ -1,19 +1,35 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.BlocksBase = void 0;var _blocksCollections = require("./blocksCollections"); var _types = require("./types"); -var _nod3Connect = _interopRequireDefault(require("./nod3Connect")); -var _NativeContracts = _interopRequireDefault(require("./NativeContracts"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +var _nod3Connect = require("./nod3Connect"); +var _NativeContracts = _interopRequireDefault(require("./NativeContracts")); +var _config = _interopRequireDefault(require("../lib/config"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class BlocksBase { - constructor(db, { log, initConfig } = {}) { + constructor(db, options = {}) { + let { initConfig, log, debug } = options; + if (undefined === debug) debug = _config.default.blocks.debug; this.initConfig = initConfig || {}; this.db = db; this.collections = db ? (0, _blocksCollections.getDbBlocksCollections)(db) : undefined; - this.nod3 = _nod3Connect.default; - this.log = log || console; - this.et = _types.events; + this.nod3 = options.nod3 || _nod3Connect.nod3Router; + log = options.log || console; + this.log = log; + if (debug) _nod3Connect.nod3Router.setDebug((0, _nod3Connect.nod3Log)(log)); + this.events = _types.events; this.actions = _types.actions; this.nativeContracts = (0, _NativeContracts.default)(initConfig); this.net = this.initConfig.net; + this.emit = event => { + this.log.warn(`Event ${event} received but emitter is not defined`); + }; + } + setEmitter(emitter) { + if (typeof emitter !== 'function') throw new Error('The emitter must be a function'); + this.emit = emitter; + } + getBlockData(block) { + let { number, hash, parentHash } = block; + return { number, hash, parentHash }; }}exports.BlocksBase = BlocksBase;var _default = diff --git a/dist/lib/Db.js b/dist/lib/Db.js index 1bcd3752..04e34b0d 100644 --- a/dist/lib/Db.js +++ b/dist/lib/Db.js @@ -1,21 +1,23 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Db = void 0;var _mongodb = require("mongodb"); +var _Logger = require("./Logger"); const connectionOptions = { useNewUrlParser: true, useUnifiedTopology: true }; class Db { constructor(config) { config = config || {}; - this.server = config.server || 'localhost'; - this.port = config.port || 27017; - this.dbName = config.database || config.db; + const { server, port, password, user, db, database } = config; + this.server = server || 'localhost'; + this.port = port || 27017; + this.dbName = database || db; if (!this.dbName) throw new Error('Missing database name'); - const user = config.user; - const password = config.password; let url = 'mongodb://'; if (user && password) url += `${user}:${password}@`; url += `${this.server}:${this.port}/${this.dbName}`; this.url = url; this.client = null; - this.log = config.Logger || console; + this.log = undefined; + this.DB = undefined; + this.setLogger(config.Logger || console); this.connect(); } async connect() { @@ -31,19 +33,24 @@ class Db { async db() { try { + if (this.DB) return this.DB; let client = await this.connect(); - let db = client.db(this.dbName); - return db; + this.DB = client.db(this.dbName); + return this.DB; } catch (err) { return Promise.reject(err); } } setLogger(log) { - this.log = log; + this.log = log && log.constructor && log.constructor.name === 'Logger' ? log : (0, _Logger.LogProxy)(log); } - async createCollection(collectionName, { indexes, options }, { dropIndexes, validate } = {}) { + getLogger() { + return this.log; + } + + async createCollection(collectionName, { indexes, options } = {}, { dropIndexes, validate } = {}) { try { const db = await this.db(); if (!collectionName) throw new Error('Invalid collection name'); diff --git a/dist/lib/Logger.js b/dist/lib/Logger.js index 257c2e45..e0e9e113 100644 --- a/dist/lib/Logger.js +++ b/dist/lib/Logger.js @@ -1,4 +1,4 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Logger = void 0;var _bunyan = _interopRequireDefault(require("bunyan"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.LogProxy = exports.Logger = void 0;var _bunyan = _interopRequireDefault(require("bunyan"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const Logger = (name, options) => { options = options || {}; @@ -19,6 +19,19 @@ const Logger = (name, options) => { console.error('Log error ', err); }); return log; -};exports.Logger = Logger;var _default = +};exports.Logger = Logger; + +const logProxyHandler = logger => { + return { + get: (target, prop) => { + if (logger && typeof logger === 'object') return logger[prop];else + return () => {}; + } }; + +}; + +const LogProxy = logger => { + return new Proxy({}, logProxyHandler(logger)); +};exports.LogProxy = LogProxy;var _default = Logger;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/Setup.js b/dist/lib/Setup.js index 95a45922..828fee65 100644 --- a/dist/lib/Setup.js +++ b/dist/lib/Setup.js @@ -1,11 +1,21 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getNetInfo = getNetInfo;exports.Setup = Setup;exports.default = exports.dataBase = void 0;var _collections = _interopRequireDefault(require("./collections")); -var _config = _interopRequireDefault(require("./config")); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.networkError = networkError;exports.getNetInfo = getNetInfo;exports.Setup = Setup;exports.default = exports.CONFIG_ID = exports.COLLECTIONS_ID = exports.INIT_ID = void 0;var _collections = _interopRequireDefault(require("./collections")); +var _config = require("./config"); var _Db = _interopRequireDefault(require("./Db.js")); var _StoredConfig = require("./StoredConfig"); -var _nod3Connect = _interopRequireDefault(require("./nod3Connect")); -var _initialConfiguration = _interopRequireDefault(require("./initialConfiguration"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +var _nod3Connect = require("./nod3Connect"); +var _initialConfiguration = _interopRequireDefault(require("./initialConfiguration")); +var _blocksCollections = require("./blocksCollections"); +var _utils = require("./utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const dataBase = new _Db.default(_config.default.db);exports.dataBase = dataBase; +const INIT_ID = '_explorerInitialConfiguration';exports.INIT_ID = INIT_ID; +const COLLECTIONS_ID = '_explorerCollections';exports.COLLECTIONS_ID = COLLECTIONS_ID; +const CONFIG_ID = '_explorerConfig';exports.CONFIG_ID = CONFIG_ID; + +const readOnlyDocsIds = [INIT_ID]; + +function networkError(storedInitConfig, initConfig) { + return `Network stored id (${storedInitConfig.net.id}) is not equal to node network id (${initConfig.net.id})`; +} async function getNetInfo(nod3) { try { @@ -16,62 +26,101 @@ async function getNetInfo(nod3) { } } -async function Setup({ log } = {}) { - log = log || console; - dataBase.setLogger(log); - const db = await dataBase.db(); - const storedConfig = (0, _StoredConfig.StoredConfig)(db); +const defaultInstances = { nod3: _nod3Connect.nod3, config: _config.config, collections: _collections.default }; + +async function Setup({ log } = {}, { nod3, config, collections } = defaultInstances) { + const database = new _Db.default(config.db); + if (undefined !== log) database.setLogger(log); + log = database.getLogger(); + const db = await database.db(); + const storedConfig = (0, _StoredConfig.StoredConfig)(db, readOnlyDocsIds); + + const createHash = thing => (0, _utils.hash)(thing, 'sha1', 'hex'); - const createCollections = async () => { - const names = _config.default.collectionsNames; - const validate = _config.default.blocks.validateCollections; - return dataBase.createCollections(_collections.default, { names, validate }); + const createCollections = async names => { + names = names || config.collectionsNames; + const validate = config.blocks.validateCollections; + return database.createCollections(collections, { names, validate }); }; const getInitConfig = async () => { try { - await _nod3Connect.default.isConnected().catch(err => { + await nod3.isConnected().catch(err => { log.debug(err); throw new Error(`Cannot connect to the node`); }); - const net = await getNetInfo(_nod3Connect.default); + const net = await getNetInfo(nod3); return Object.assign(_initialConfiguration.default, { net }); } catch (err) { return Promise.reject(err); } }; + const checkStoredHash = async (id, value) => { + if (!id || !value) throw new Error(`Invalid id or value id:${id} value:${value}`); + const currentHash = createHash(value); + const storedHash = await storedConfig.get(id); + if (!storedHash) return false; + return currentHash === storedHash.hash; + }; + + const checkConfig = async () => { + const testConfig = await checkStoredHash(CONFIG_ID, config); + const testCollections = await checkStoredHash(COLLECTIONS_ID, collections); + return !!(testConfig && testCollections); + }; + + const saveConfig = async () => { + try { + await storedConfig.update(CONFIG_ID, { hash: createHash(config) }, { create: true }); + await storedConfig.update(COLLECTIONS_ID, { hash: createHash(collections) }, { create: true }); + } catch (err) { + return Promise.reject(err); + } + }; + const checkSetup = async () => { try { - const current = await getInitConfig(); - let stored = await storedConfig.getConfig(); - if (!stored) { - log.info(`Saving initial configuration to db`); - await storedConfig.saveConfig(current); - return checkSetup(); + const initConfig = await getInitConfig(); + const storedInitConfig = await storedConfig.get(INIT_ID); + const configMatches = await checkConfig(); + if (!storedInitConfig || !configMatches) { + await createCollections(); + await saveConfig(); + if (!storedInitConfig) { + log.info(`Saving initial configuration to db`); + await storedConfig.save(INIT_ID, initConfig); + return checkSetup(); + } } - if (stored.net.id !== current.net.id) { - throw new Error(`Network stored id (${stored.net.id}) is not equal to node network id (${current.net.id})`); + if (storedInitConfig.net.id !== initConfig.net.id) { + throw new Error(networkError(storedInitConfig, initConfig)); } - return stored; + return storedInitConfig; } catch (err) { return Promise.reject(err); } }; + const getCollections = db => { + return (0, _blocksCollections.getDbBlocksCollections)(db); + }; + const start = async skipCheck => { try { let initConfig; - if (skipCheck) initConfig = await storedConfig.getConfig();else + if (skipCheck) initConfig = await storedConfig.get(INIT_ID);else initConfig = await checkSetup(); if (!initConfig) throw new Error(`invalid init config, run checkSetup first`); - return { initConfig, db }; + const collections = await getCollections(db); + return { initConfig, db, collections }; } catch (err) { log.error(err); - process.exit(9); + return Promise.reject(err); } }; - return Object.freeze({ start, createCollections, checkSetup, getInitConfig }); + + return Object.freeze({ start, createHash }); }var _default = Setup;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/StoredConfig.js b/dist/lib/StoredConfig.js index ce45aa51..0aa31e6e 100644 --- a/dist/lib/StoredConfig.js +++ b/dist/lib/StoredConfig.js @@ -1,10 +1,10 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.StoredConfig = StoredConfig;exports.default = void 0; +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.StoredConfig = StoredConfig;exports.default = exports.readOnlyError = void 0; var _config = _interopRequireDefault(require("./config"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const collectionName = _config.default.collectionsNames.Config; -const INIT_ID = '_explorerInitialConfiguration'; -const readOnlyDocsIds = [INIT_ID]; -function StoredConfig(db) { +const readOnlyError = id => `The doc with _id ${id} is read only`;exports.readOnlyError = readOnlyError; + +function StoredConfig(db, readOnlyDocsIds = []) { const storage = db.collection(collectionName); const isReadOnly = _id => readOnlyDocsIds.includes(_id); const isValidId = id => typeof id === 'string'; @@ -25,6 +25,10 @@ function StoredConfig(db) { const save = async (id, doc) => { try { if (!id || !isValidId(id)) throw new Error(`Invalid id ${id}`); + if (isReadOnly(id)) { + let exists = await get(id); + if (exists) throw new Error(readOnlyError(id)); + } const newDoc = Object.assign({}, doc); newDoc._id = id; newDoc._created = Date.now(); @@ -37,25 +41,23 @@ function StoredConfig(db) { const update = async (_id, doc, { create } = {}) => { try { if (!_id) throw new Error(`Missing doc._id`); - if (isReadOnly(_id)) throw new Error(`The doc with _id ${_id} is read only`); + if (isReadOnly(_id)) throw new Error(readOnlyError(_id)); const newDoc = Object.assign({}, doc); - newDoc._updated = Date.now(); + const options = {}; - if (create) options.upsert = true; - let res = await storage.updateOne({ _id }, { $set: doc }, options); + if (create) { + let old = await get(_id); + if (!old) return save(_id, newDoc); + } + newDoc._updated = Date.now(); + let res = await storage.updateOne({ _id }, { $set: newDoc }, options); return res; } catch (err) { return Promise.reject(err); } }; - const saveConfig = doc => { - return save(INIT_ID, doc); - }; - const getConfig = async () => { - return get(INIT_ID); - }; - return Object.freeze({ getConfig, saveConfig, save, get, update }); + return Object.freeze({ save, get, update }); }var _default = StoredConfig;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/cli.js b/dist/lib/cli.js index 7fea28ad..c026140e 100644 --- a/dist/lib/cli.js +++ b/dist/lib/cli.js @@ -1,15 +1,25 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.progressBar = exports.randomColor = exports.ansiCode = exports.example = exports.ok = exports.info = exports.warn = exports.error = exports.grey = exports.orange = exports.green = exports.blue = exports.red = exports.reset = void 0;const reset = '\x1b[0m';exports.reset = reset; +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.progressBar = exports.randomColor = exports.ansiCode = exports.log = exports.label = exports.example = exports.ok = exports.debug = exports.info = exports.warn = exports.error = exports.grey = exports.yellow = exports.orange = exports.green = exports.blue = exports.red = exports.reset = void 0;const reset = '\x1b[0m';exports.reset = reset; const red = '\x1b[31m';exports.red = red; const blue = '\x1b[36m';exports.blue = blue; const green = '\x1b[32m';exports.green = green; const orange = '\x1b[33m';exports.orange = orange; +const yellow = '\x1b[93m';exports.yellow = yellow; const grey = '\x1b[90m';exports.grey = grey; const error = l => console.log(red, l, reset);exports.error = error; const warn = l => console.log(orange, l, reset);exports.warn = warn; const info = l => console.log(blue, l, reset);exports.info = info; +const debug = l => console.log(yellow, l, reset);exports.debug = debug; const ok = l => console.log(green, l, reset);exports.ok = ok; const example = l => console.log(grey, l, reset);exports.example = example; +const label = l => console.log(green, l, reset);exports.label = label; +const logMethods = { error, warn, debug, info, label }; + +const log = new Proxy({}, { + get(t, p) { + return logMethods[p] || console.log; + } });exports.log = log; + const ansiCode = number => `\x1b[${parseInt(number)}m`;exports.ansiCode = ansiCode; diff --git a/dist/lib/collections.js b/dist/lib/collections.js index bf1f4d1c..1a8a787d 100644 --- a/dist/lib/collections.js +++ b/dist/lib/collections.js @@ -171,12 +171,6 @@ name: 'eventAddressesIndex' }] }, - TokensAddrs: { - indexes: [ - { - key: { - address: 1, - contract: 1 }, TokensAddrs: { indexes: [ @@ -198,20 +192,6 @@ - OrphanBlocks: { - indexes: [ - { - key: { - hash: 1 }, - - unique: true }] }, - - TxPool: [ - { - key: { - timestamp: -1 } }] }, - - TxPool: { indexes: [ { @@ -221,7 +201,6 @@ - PendingTxs: { indexes: [ { @@ -265,4 +244,58 @@ key: { address: 1 } }, { - key: { match: 1 } }] } };exports.default = _default; \ No newline at end of file + key: { match: 1 } }] }, + + + + InternalTransactions: { + indexes: [ + { + key: { internalTxId: -1 }, + unique: true }, + + { + key: { blockHash: 1 } }, + + { + key: { blockNumber: -1 } }, + + { + key: { transactionHash: 1 } }, + + { + key: { 'action.from': 1 } }, + + { + key: { 'action.to': 1 } }] }, + + + + Balances: { + indexes: [ + { + key: { + address: 1, + blockNumber: -1 }, + + unique: true }, + + { + key: { address: 1 } }, + + { + key: { blockNumber: -1 } }, + + { + key: { blockHash: 1 } }, + + { + key: { timestamp: -1 } }] }, + + + + BlocksTraces: { + indexes: [ + { + key: { hash: 1 }, + unique: true }] } };exports.default = _default; \ No newline at end of file diff --git a/dist/lib/config.js b/dist/lib/config.js index fc454c9e..bd836663 100644 --- a/dist/lib/config.js +++ b/dist/lib/config.js @@ -1,10 +1,15 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.createConfig = createConfig;exports.default = exports.config = void 0;var _path = _interopRequireDefault(require("path")); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.createConfig = createConfig;exports.makeConfig = makeConfig;exports.nodeSources = nodeSources;exports.createNodeSource = createNodeSource;exports.default = exports.config = void 0;var _path = _interopRequireDefault(require("path")); var _fs = _interopRequireDefault(require("fs")); +var _url = _interopRequireDefault(require("url")); var _defaultConfig = _interopRequireDefault(require("./defaultConfig"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const config = createConfig('../../config.json');exports.config = config; function createConfig(file) { + return makeConfig(loadConfig(file)); +} + +function makeConfig(config = {}) { const defaultLogs = key => { const dir = config.log.dir; if (!dir) return; @@ -13,7 +18,6 @@ function createConfig(file) { config[key].log.level = config[key].log.level || config.log.level || 'info'; }; - const config = loadConfig(file); const keys = Object.keys(_defaultConfig.default); for (let key of keys) { @@ -29,12 +33,8 @@ function createConfig(file) { } // defaults servers/ports - - config.blocks.node = config.blocks.node || config.source.node; - config.blocks.port = config.blocks.port || config.source.port; - - let s = config.source; - config.source.url = config.source.url || `${s.protocol}://${s.node}:${s.port}`; + config.source = nodeSources(config.source); + config.blocks.source = config.source; // defaults log files @@ -57,6 +57,25 @@ function loadConfig(file) { } } return config; +} + +function nodeSources(sources) { + if (!Array.isArray(sources)) sources = [sources]; + sources = sources.map(s => createNodeSource(s)); + sources = Object.values(sources.reduce((v, a, i) => { + let { url } = a; + v[url] = a; + return v; + }, {})); + + return sources.length > 1 ? sources : sources[0]; +} + +function createNodeSource(s) { + let url = s.url || `${s.protocol}://${s.node}:${s.port}`; + let { protocol, port, hostname: node } = _url.default.parse(url); + protocol = protocol.replace(/:$/, ''); + return { protocol, node, port, url }; }var _default = config;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/dataSource.js b/dist/lib/dataSource.js index ed1c07c0..5fa24254 100644 --- a/dist/lib/dataSource.js +++ b/dist/lib/dataSource.js @@ -1,5 +1,12 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.dataSource = exports.setup = void 0; var _Setup = _interopRequireDefault(require("./Setup"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const setup = ({ log, skipCheck } = {}) => (0, _Setup.default)(({ log } = {})).then(setup => setup.start(skipCheck));exports.setup = setup; +const setup = async ({ log, skipCheck } = {}) => { + try { + const setup = await (0, _Setup.default)({ log }); + return setup.start(skipCheck); + } catch (err) { + return Promise.reject(err); + } +};exports.setup = setup; const dataSource = setup;exports.dataSource = dataSource;var _default = setup;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/defaultConfig.js b/dist/lib/defaultConfig.js index 565e1073..b5374711 100644 --- a/dist/lib/defaultConfig.js +++ b/dist/lib/defaultConfig.js @@ -19,6 +19,11 @@ reduce((a, v, i) => { port: 4444, url: null }, + sourceRoutes: { // Nod3Router routes, used as default when source is an array of sources + subscribe: 0, // delegates subscriptions to the first node + rsk: 0, // delegates rsk module to the node that handle subscriptions + trace: 1 // delegates trace_ module to the second node + }, log: { dir: '/var/log/rsk-explorer', level: 'info' }, @@ -45,8 +50,12 @@ reduce((a, v, i) => { blocks: { blocksQueueSize: 100, validateCollections: false, - bcTipSize: 12, - batchRequestSize: 20 }, + bcTipSize: 120, + batchRequestSize: 20, + debug: false, + updateTokenBalances: true, // Update token accounts balances on next block + ports: [3010], // list of services ports, if the list runs out, the services will try to take the next ports starting from the last + address: '127.0.0.1' }, collectionsNames: { Config: 'config', @@ -56,10 +65,12 @@ reduce((a, v, i) => { Status: 'status', Events: 'events', TokensAddrs: 'tokensAddresses', - OrphanBlocks: 'orphanBlocks', TxPool: 'txPool', PendingTxs: 'transactionsPending', Stats: 'statsCollection', BlocksSummary: 'blocksSummary', ContractVerification: 'contractsVerifications', - VerificationsResults: 'verificationResults' } };exports.default = _default; \ No newline at end of file + VerificationsResults: 'verificationResults', + InternalTransactions: 'internalTransactions', + Balances: 'balances', + BlocksTraces: 'blockTraces' } };exports.default = _default; \ No newline at end of file diff --git a/dist/lib/delayedFields.js b/dist/lib/delayedFields.js index 234f9884..82a7df7e 100644 --- a/dist/lib/delayedFields.js +++ b/dist/lib/delayedFields.js @@ -1,11 +1,11 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _default = { - Address: { - getAddress: { - fields: ['balance', 'txBalance'], - action: 'updateAddress', - runIfEmpty: true } }, - - + /* Address: { + getAddress: { + fields: ['balance', 'txBalance'], + action: 'updateAddress', + runIfEmpty: true + } + }, */ ContractVerification: { getVersions: { action: 'getVersions', diff --git a/dist/lib/ids.js b/dist/lib/ids.js index 2932eaad..ef8aa6da 100644 --- a/dist/lib/ids.js +++ b/dist/lib/ids.js @@ -1,4 +1,4 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.eventId = exports.getSummaryId = exports.getTxOrEventId = void 0;var _utils = require("./utils"); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getEventId = exports.getSummaryId = exports.getTxOrEventId = exports.generateId = void 0;var _utils = require("./utils"); const checkNumbers = payload => { for (let name in payload) { @@ -9,24 +9,37 @@ const checkNumbers = payload => { const padBlockNumber = number => number.toString(16).padStart(7, 0); -const getTxOrEventId = ({ blockNumber, transactionIndex, blockHash, logIndex }) => { +/** + * Generates sortable and immutable ids for txs and events + * id structure: + * [blockNumber](24b) + * [txIndex][16b] + * [index](optional)(16b) + * [blockHash|txHash][72b] + */ + +const generateId = ({ blockNumber, transactionIndex, hash, index }) => { try { + if (!hash) throw new Error(`Invalid hash ${hash}`); + hash = hash.toLowerCase(); checkNumbers({ blockNumber, transactionIndex }); - if (!(0, _utils.isBlockHash)(blockHash)) throw new Error('blockHash is not a block hash'); + if (!(0, _utils.isTxOrBlockHash)(hash)) throw new Error('blockHash is not a block hash'); let block = padBlockNumber(blockNumber); let txI = transactionIndex.toString(16).padStart(3, 0); - let hash = blockHash.substr(-19, 19); - let id = `${block}${txI}`; - if (undefined !== logIndex) { - if (logIndex) checkNumbers({ logIndex }); - id += logIndex.toString(16).padStart(3, 0); - } - id = `${id}${hash}`; + let hashBit = hash.substr(-19, 19); + index = parseInt(index); + index = isNaN(index) ? '' : index.toString(16).padStart(3, 0); + let id = `${block}${txI}${index}${hashBit}`; return id; } catch (err) { + console.error(err); return err; } +};exports.generateId = generateId; + +const getTxOrEventId = ({ blockNumber, transactionIndex, blockHash: hash, logIndex: index }) => { + return generateId({ blockNumber, transactionIndex, hash, index }); };exports.getTxOrEventId = getTxOrEventId; const getSummaryId = ({ hash, number, timestamp }) => { @@ -43,7 +56,4 @@ const getSummaryId = ({ hash, number, timestamp }) => { } };exports.getSummaryId = getSummaryId; -const eventId = event => { - let id = getTxOrEventId(event); - return id; -};exports.eventId = eventId; \ No newline at end of file +const getEventId = event => getTxOrEventId(event);exports.getEventId = getEventId; \ No newline at end of file diff --git a/dist/lib/nod3Connect.js b/dist/lib/nod3Connect.js index bfdc08db..24918ee0 100644 --- a/dist/lib/nod3Connect.js +++ b/dist/lib/nod3Connect.js @@ -1,13 +1,45 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.nod3 = exports.nod3Connect = void 0;var _nod = _interopRequireDefault(require("nod3")); -var _config = _interopRequireDefault(require("./config"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const url = _config.default.source.url; +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.nod3Router = exports.nod3 = exports.nod3Log = exports.nod3Instance = exports.createNod3Router = exports.nod3BySource = exports.nod3Connect = void 0;var _nod = require("nod3"); +var _config = _interopRequireDefault(require("./config")); +var _utils = require("../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const nod3Connect = url => { - return new _nod.default( - new _nod.default.providers.HttpProvider(url)); +const { HttpProvider } = _nod.Nod3.providers; +const { source, sourceRoutes } = _config.default; -};exports.nod3Connect = nod3Connect; +const nod3Connect = (url, options = {}) => new _nod.Nod3(new HttpProvider(url), options); -const nod3 = nod3Connect(url);exports.nod3 = nod3;var _default = +// return Nod3 | Nod3Router based on source +exports.nod3Connect = nod3Connect;const nod3BySource = (source, options = {}, nod3) => { + if (Array.isArray(source)) return createNod3Router(source, options); + return nod3 || nod3Instance(source, options); +};exports.nod3BySource = nod3BySource; + +const createNod3Router = (sources, options = {}) => { + const providers = sources.map(({ url }) => new HttpProvider(url)); + let { nod3, router } = (0, _nod.Nod3Router)(providers, options); + // Add routes + if (sourceRoutes && typeof sourceRoutes === 'object') { + for (let module in sourceRoutes) { + let to = sourceRoutes[module]; + router.add({ module, to }); + } + } + return nod3; +}; + +// Returns always a nod3 instance +exports.createNod3Router = createNod3Router;const nod3Instance = (source, options = {}) => { + const sources = !Array.isArray(source) ? [source] : [...source]; + return nod3Connect(sources[0].url, options); +};exports.nod3Instance = nod3Instance; + +const nod3Log = log => ({ method, params, time, url }) => { + let m = time > 200 ? 'warn' : 'debug'; + let marks = (0, _utils.quantityMarks)(time, 100, '*'); + params = params ? JSON.stringify(params) : ''; + return log[m](`${marks}[NOD3] [${url}] ${method} (${params}) -- time:${time}ms`); +};exports.nod3Log = nod3Log; + +const nod3 = nod3Instance(source);exports.nod3 = nod3; +const nod3Router = nod3BySource(source, {}, nod3);exports.nod3Router = nod3Router;var _default = nod3;exports.default = _default; \ No newline at end of file diff --git a/dist/lib/types.js b/dist/lib/types.js index ea481157..123d39fb 100644 --- a/dist/lib/types.js +++ b/dist/lib/types.js @@ -4,7 +4,8 @@ const txTypes = { default: 'normal', remasc: 'remasc', bridge: 'bridge', - contract: 'contract deploy' };exports.txTypes = txTypes; + contract: 'contract deploy', + call: 'contract call' };exports.txTypes = txTypes; const errors = (0, _errors.apiErrors)( @@ -38,11 +39,16 @@ ci.ERC721];exports.tokensInterfaces = tokensInterfaces; const events = { + 'SERVICE_STARTED': 'serviceStarted', 'BLOCK_QUEUED': 'blockQueued', 'BLOCK_REQUESTED': 'blockRequested', - 'NEW_BLOCK': 'newBlock', + 'BLOCK_SAVED': 'blockSaved', 'BLOCK_ERROR': 'blockError', - 'QUEUE_DONE': 'queueDone' };exports.events = events; + 'NEW_BLOCK': 'newBlock', + 'REQUEST_BLOCKS': 'requestBlocks', + 'QUEUE_DONE': 'queueDone', + 'NEW_STATUS': 'newStatus', + 'NEW_TIP_BLOCK': 'newTipBlock' };exports.events = events; const actions = { @@ -64,7 +70,9 @@ const MODULES = { summary: 'Summary', txPending: 'TxPending', extendedStats: 'ExtendedStats', - contractVerifier: 'ContractVerification' };exports.MODULES = MODULES; + contractVerifier: 'ContractVerification', + internalTransactions: 'InternalTx', + balances: 'Balances' };exports.MODULES = MODULES; const BIG_NUMBER = 'BigNumber';exports.BIG_NUMBER = BIG_NUMBER; @@ -74,7 +82,9 @@ const OBJECT_ID = 'ObjectID';exports.OBJECT_ID = OBJECT_ID; const TOTAL_SUPPLY = 21 * 10 ** 6;exports.TOTAL_SUPPLY = TOTAL_SUPPLY; const fields = { - LAST_BLOCK_MINED: 'lastBlockMined' };exports.fields = fields; + LAST_BLOCK_MINED: 'lastBlockMined', + DEPLOYED_CODE: 'deployedCode', + CREATED_BY_TX: 'createdByTx' };exports.fields = fields; const EVMversions = [ diff --git a/dist/lib/utils.js b/dist/lib/utils.js index 205464fe..51cc7714 100644 --- a/dist/lib/utils.js +++ b/dist/lib/utils.js @@ -1,8 +1,9 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });var _exportNames = { bigNumberDoc: true, isBigNumber: true, serializeBigNumber: true, isSerializedBigNumber: true, unSerializeBigNumber: true, bigNumberToSring: true, bigNumberSum: true, bigNumberDifference: true, newBigNumber: true, isObj: true, serialize: true, checkBlockHash: true, isBlockHash: true, blockQuery: true, getBestBlock: true, applyDecimals: true, isValidBlockNumber: true, isBlockObject: true, toAscii: true };exports.toAscii = exports.isBlockObject = exports.isValidBlockNumber = exports.applyDecimals = exports.getBestBlock = exports.blockQuery = exports.isBlockHash = exports.checkBlockHash = exports.serialize = exports.isObj = exports.newBigNumber = exports.bigNumberDifference = exports.bigNumberSum = exports.bigNumberToSring = exports.unSerializeBigNumber = exports.isSerializedBigNumber = exports.serializeBigNumber = exports.isBigNumber = exports.bigNumberDoc = void 0;var _bignumber = require("bignumber.js"); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });var _exportNames = { bigNumberDoc: true, isBigNumber: true, serializeBigNumber: true, isSerializedBigNumber: true, unSerializeBigNumber: true, bigNumberToSring: true, bigNumberSum: true, bigNumberDifference: true, newBigNumber: true, isObj: true, serialize: true, checkBlockHash: true, isBlockHash: true, blockQuery: true, getBestBlock: true, applyDecimals: true, isValidBlockNumber: true, isBlockObject: true, toAscii: true, quantityMarks: true, chunkArray: true, hash: true };exports.hash = exports.chunkArray = exports.quantityMarks = exports.toAscii = exports.isBlockObject = exports.isValidBlockNumber = exports.applyDecimals = exports.getBestBlock = exports.blockQuery = exports.isBlockHash = exports.checkBlockHash = exports.serialize = exports.isObj = exports.newBigNumber = exports.bigNumberDifference = exports.bigNumberSum = exports.bigNumberToSring = exports.unSerializeBigNumber = exports.isSerializedBigNumber = exports.serializeBigNumber = exports.isBigNumber = exports.bigNumberDoc = void 0;var _bignumber = require("bignumber.js"); var _types = require("./types"); var _mongodb = require("mongodb"); var _rskUtils = require("rsk-utils"); -Object.keys(_rskUtils).forEach(function (key) {if (key === "default" || key === "__esModule") return;if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;Object.defineProperty(exports, key, { enumerable: true, get: function () {return _rskUtils[key];} });}); + +Object.keys(_rskUtils).forEach(function (key) {if (key === "default" || key === "__esModule") return;if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;Object.defineProperty(exports, key, { enumerable: true, get: function () {return _rskUtils[key];} });});var _crypto = _interopRequireDefault(require("crypto"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const bigNumberDoc = bigNumber => { return '0x' + bigNumber.toString(16); @@ -124,4 +125,25 @@ const isBlockObject = block => { return isBlockHash(hash) && (0, _rskUtils.isAddress)(miner) && isValidBlockNumber(number); };exports.isBlockObject = isBlockObject; -const toAscii = hexString => (0, _rskUtils.toBuffer)((0, _rskUtils.remove0x)(hexString), 'hex').toString('ascii').replace(/\0/g, '');exports.toAscii = toAscii; \ No newline at end of file +const toAscii = hexString => (0, _rskUtils.toBuffer)((0, _rskUtils.remove0x)(hexString), 'hex').toString('ascii').replace(/\0/g, '');exports.toAscii = toAscii; + +const quantityMarks = (quantity, unit, mark = '*') => { + quantity = parseInt(quantity); + unit = parseInt(unit); + if (isNaN(quantity) || isNaN(unit)) return ''; + let steps = Math.floor(quantity / unit); + return Array(++steps).join(mark); +};exports.quantityMarks = quantityMarks; + +const chunkArray = (arr, chunkSize) => { + const result = []; + for (let i = 0; i < arr.length; i += chunkSize) { + let chunk = arr.slice(i, i + chunkSize); + result.push(chunk); + } + return result; +};exports.chunkArray = chunkArray; + +const hash = (thing, alg = 'sha1', out = 'hex') => { + return _crypto.default.createHash(alg).update(JSON.stringify(thing)).digest(out); +};exports.hash = hash; \ No newline at end of file diff --git a/dist/services/Router.js b/dist/services/Router.js new file mode 100644 index 00000000..66edc385 --- /dev/null +++ b/dist/services/Router.js @@ -0,0 +1,169 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.Router = Router; +var _ServiceClient = require("./Service/ServiceClient"); + +function Router({ service, log } = {}) { + log = log || console; + service = service || {}; + const services = new Map(); + const clients = new Map(); + let discovering = false; + let cancelStart; + + const setRouterService = routerService => { + service = routerService; + }; + + const eventListener = ({ uri, name }, { event, data }) => { + log.info(`Broadcasting ${event} from ${name}@${uri}`); + broadcast(event, data, [uri]); + }; + + const addClient = async ({ uri, name }) => { + try { + if (clients.has(uri)) return clients[uri]; + if (uri === service.getUri()) return; + const res = await (0, _ServiceClient.Client)(uri).catch(err => { + if (err.code === 14) return Promise.resolve();else + throw err; + }); + if (!res) return; + const { client, serviceName } = res; + if (serviceName !== name) throw new Error(`Service name mismatch: ${name}/${serviceName}`); + if (client.join) { + let events = client.join(); + events.on('newEvent', data => { + eventListener({ uri, name }, data); + }); + events.on('error', err => { + if (err.code === 14) { + log.warn(`The client ${name}@${uri} was disconnected`); + } else { + log.error(err); + } + clients.delete(uri); + start(); + }); + } + clients.set(uri, client); + return client; + } catch (err) { + return Promise.reject(err); + } + }; + + const addService = (name, config) => { + if (!name) throw new Error(`Invalid name ${name}`); + if (typeof config !== 'object') throw new Error('Config must be an object'); + if (!config.uri) throw new Error(`Invalid uri, ${name}`); + if (service.getUri && config.uri === service.getUri()) return; + if (services.has(name)) throw new Error(`The service ${name} already exists`); + services.set(name, config); + return services.has(name); + }; + + const removeService = name => { + if (!services.has(name)) throw new Error(`Unknown service ${name}`); + services.delete(name); + }; + + const broadcast = (event, data, skipClients = []) => { + if (!Array.isArray(skipClients)) throw new Error('SkipClients must be an array'); + if (service.emit) { + service.emit(event, data); + } + // filter sender and subscribers + let clientsToSend = [...clients].filter(([uri, client]) => { + return !skipClients.includes(uri); + }); + for (let cs of clientsToSend) { + let client = cs[1]; + if (client.send) client.send(event, data); + } + }; + + const getServices = () => { + return [...services.keys()]; + }; + + const getClients = () => { + return [...clients.keys()]; + }; + + const discover = async () => { + try { + const discovered = []; + if (services.size < 1) throw new Error('There not configured services'); + log.info('Discovering services'); + for (let { uri, name } of services.values()) { + let client = await addClient({ uri, name }); + if (client) discovered.push(client); + } + return discovered; + } catch (err) { + return Promise.reject(err); + } + }; + + const status = () => { + return [...services.entries()]. + map(([name, { uri }]) => {return [name, clients.has(uri) ? uri : null];}). + reduce((v, a) => { + let [name, uri] = a; + v[name] = uri; + return v; + }, {}); + }; + + const allServicesWereDiscovered = () => { + return services.size === clients.size; + }; + + const restart = () => { + const time = allServicesWereDiscovered() ? 60000 : 1000; + cancelStart = setTimeout(() => { + start(); + }, time); + }; + const start = async () => { + try { + if (discovering) return; + if (allServicesWereDiscovered()) return restart(); + discovering = true; + let discovered = await discover(); + if (discovered.length) { + log.info(`${discovered.length} services discovered`); + } + if (!allServicesWereDiscovered()) { + log.debug(`Clients:`, status()); + } + discovering = false; + restart(); + } catch (err) { + log.error(err); + process.exit(9); + } + }; + + const stop = () => { + if (cancelStart) clearTimeout(cancelStart); + for (let [uri, client] of clients) { + log.info(`Closing connection to ${uri}`); + client.close(); + } + clients.clear(); + services.clear(); + }; + return Object.freeze({ + setRouterService, + service, + start, + stop, + addService, + removeService, + getServices, + getClients, + discover, + broadcast, + status }); + +} \ No newline at end of file diff --git a/dist/services/Service/README.md b/dist/services/Service/README.md new file mode 100644 index 00000000..76a1d999 --- /dev/null +++ b/dist/services/Service/README.md @@ -0,0 +1 @@ +# gRPC Service diff --git a/dist/services/Service/ServiceClient.js b/dist/services/Service/ServiceClient.js new file mode 100644 index 00000000..5db0fcab --- /dev/null +++ b/dist/services/Service/ServiceClient.js @@ -0,0 +1,94 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.Client = Client; +var _serviceProto = require("./serviceProto"); +var _ServiceServer = require("./ServiceServer"); +var _struct_pb = require("google-protobuf/google/protobuf/struct_pb"); + +const clientRequest = (client, method) => { + return function () { + let args = [...arguments]; + const Request = client[method].requestType; + const request = new Request([...args]); + const response = client[method](request); + return (0, _ServiceServer.decodeResponse)(method, response, client); + }; +}; + +const clientMethodToPromise = (client, method) => { + return function () { + let args = [...arguments]; + const Request = client[method].requestType; + return new Promise((resolve, reject) => { + args = args.map(a => { + if (typeof a === 'object' && !Array.isArray(a)) return _struct_pb.Struct.fromJavaScript(a); + return a; + }); + const request = new Request([...args]); + let obj = Object.entries(request.toObject()); + for (let k in obj) { + let [field, value] = obj[k]; + if (value === undefined && typeof args[k] === 'object') { + let n = `set${field.charAt(0).toUpperCase()}${field.slice(1)}`; + if (typeof request[n] === 'function') { + request[n](args[k]); + } + } + } + client[method](request, (err, res) => { + if (err) reject(err);else + { + try { + let decoded = (0, _ServiceServer.decodeResponse)(method, res); + resolve(decoded); + } catch (err) { + reject(err); + } + } + }); + }); + }; +}; + +/** + * Service Client + * @param {String} uri + * @param {*} credentials + * @returns + */ + +async function Client(uri, credentials) { + credentials = credentials || (0, _ServiceServer.clientCredentials)(); + try { + // Get service info + const infoClient = new _serviceProto.INFO_SERVICE(uri, credentials); + const { serviceName, protos } = await clientMethodToPromise(infoClient, 'getServiceInfo')(); + // Generate client proto + const clientServiceName = '__GeneratedClientService'; + const clientProtoDefinition = (0, _serviceProto.joinProtos)(clientServiceName, protos); + const clientProto = (0, _serviceProto.getProto)(clientProtoDefinition); + const serviceClient = new clientProto[clientServiceName](uri, credentials); + + // get unary methods + const clientMethods = Object.entries(clientProtoDefinition[clientServiceName]). + reduce((v, a) => { + let [method, def] = a; + if (def.requestType) v[method] = def; + return v; + }, {}); + + // Proxy client to promisify unary methods + const client = new Proxy(serviceClient, { + get: (obj, prop) => { + let def = clientMethods[prop]; + if (def) { + if (def.responseStream === false) return clientMethodToPromise(obj, prop);else + return clientRequest(obj, prop); + } + + return obj[prop]; + } }); + + return Object.freeze({ serviceName, client }); + } catch (err) { + return Promise.reject(err); + } +} \ No newline at end of file diff --git a/dist/services/Service/ServiceServer.js b/dist/services/Service/ServiceServer.js new file mode 100644 index 00000000..346f0af9 --- /dev/null +++ b/dist/services/Service/ServiceServer.js @@ -0,0 +1,197 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.Service = Service;exports.decodeResponse = exports.responseDecoders = exports.clientCredentials = void 0; +var _grpc = _interopRequireDefault(require("grpc")); +var _serviceProto = require("./serviceProto"); +var _struct_pb = require("google-protobuf/google/protobuf/struct_pb");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +const createCredentials = _grpc.default.ServerCredentials.createInsecure; +const clientCredentials = _grpc.default.credentials.createInsecure; + +/** + * Service Server + * Creates a service + * @param {String} uri server URI + * @param {Object} [{ name }={}] + * @param {Function} executor, expose the 'create' object that contains + * the methods to create new services. + * @returns {Object} + */exports.clientCredentials = clientCredentials; +function Service(uri, options = {}, executor) { + if (typeof options !== 'object') throw new Error(`Invalid options`); + const { name } = options; + const protos = new Set(); + const methods = {}; + const registeredClients = {}; + const server = new _grpc.default.Server(); + + const getInfo = () => { + return { name, protos: [...protos] }; + }; + + const addMethods = newMethods => { + if (typeof newMethods !== 'object') throw new Error(`newMethods must be an object.`); + for (let name in newMethods) { + const cb = newMethods[name]; + if (typeof cb !== 'function') { + throw new Error(`Method ${name}, the method cb must be a function`); + } + if (methods[name]) throw new Error(`The method ${name} exists.`); + methods[name] = cb; + } + }; + + const getServiceInfo = (call, cb) => { + const { name, protos } = getInfo(); + const response = new _serviceProto.MESSAGES.InfoResponse(); + response.setName(name); + response.setProtosList(protos); + cb(null, response); + }; + + addMethods({ + start: async () => { + try { + let port = await new Promise((resolve, reject) => { + server.bindAsync(uri, createCredentials(), (err, res) => { + if (err) reject(err);else + resolve(res); + }); + }); + if (!port) throw new Error(`Service start error at ${uri}`); + server.start(); + return port; + } catch (err) { + return Promise.reject(err); + } + }, + stop: () => { + server.forceShutdown(); + }, + getServer: () => server, + getUri: () => uri, + getInfo }); + + + // Add service info service + server.addService(_serviceProto.INFO_SERVICE.service, { getServiceInfo }); + + const addService = (serviceName, serviceMethods) => { + serviceName = `${serviceName}Service`; + server.addService(_serviceProto.PROTO[serviceName].service, serviceMethods); + protos.add(serviceName); + }; + + const addClient = (name, value) => { + if (registeredClients[name]) throw new Error(`The client ${name} exists.`); + registeredClients[name] = value; + }; + + // EventsEmitterService + const Emitter = () => { + const clients = new Map(); + addClient('events', clients); + + const join = call => { + const peer = call.getPeer(); + call.on('cancelled', () => { + clients.delete(peer); + }); + + clients.set(peer, call); + }; + + const leave = (call, cb) => { + const peer = call.getPeer(); + const client = clients.get(peer); + client.end(); + clients.delete(peer); + cb(null, new _serviceProto.MESSAGES.Empty()); + }; + + const emit = (event, data) => { + const response = new _serviceProto.MESSAGES.EventResponse(); + response.setEvent(event); + response.setData(_struct_pb.Struct.fromJavaScript(data)); + clients.forEach(client => client.write(response)); + }; + + const getJoined = () => { + return [...clients.keys()]; + }; + + addMethods({ emit, getJoined }); + addService('EventEmitter', { join, leave }); + }; + + // EventListenerService + const Listener = eventHandler => { + if (typeof eventHandler !== 'function') throw new Error(`eventHandler must be a function.`); + const send = (call, cb) => { + const { request } = call; + const event = request.getEvent().toString(); + const data = request.getData().toJavaScript(); + eventHandler(event, data, call); + cb(null, new _serviceProto.MESSAGES.Empty()); + }; + addService('EventListener', { send }); + }; + + // WorkerService + const Worker = actions => { + if (typeof actions !== 'object') throw new Error(`Actions must be an object.`); + if (Object.keys(actions) < 1) throw new Error('Actions is empty.'); + const run = async (call, cb) => { + try { + let { request } = call; + let action = request.getAction(); + let args = request.getArgsList(); + args = args || []; + if (!actions[action]) cb(new Error(`Unknown action:${action}`)); + if (!Array.isArray(args)) args = [args]; + let result = await actions[action](...args); + let response = new _serviceProto.MESSAGES.WorkerResponse(); + result = _struct_pb.Struct.fromJavaScript({ result }); + response.setResult(result); + cb(null, response); + } catch (err) { + cb(err); + return Promise.reject(err); + } + }; + addService('Worker', { run }); + }; + + if (typeof executor === 'function') { + executor({ create: { Emitter, Listener, Worker } }); + } + + return Object.freeze(methods); +} + +const responseDecoders = { + + getServiceInfo: response => { + let { name: serviceName, protosList: protos } = response.toObject(); + return { serviceName, protos }; + }, + join: response => { + response.on('data', res => { + let event = res.getEvent(); + let data = res.getData(); + data = data.toJavaScript(); + response.emit('newEvent', { event, data }); + }); + return response; + }, + leave: response => {}, + send: response => {}, + run: response => { + let result = response.getResult(); + result = result.toJavaScript(); + return result; + } };exports.responseDecoders = responseDecoders; + + +const decodeResponse = (method, response, client) => { + let decoder = responseDecoders[method]; + if (!decoder) throw new Error(`Unknown method ${method}`); + return decoder(response, client); +};exports.decodeResponse = decodeResponse; \ No newline at end of file diff --git a/dist/services/Service/compile.proto.sh b/dist/services/Service/compile.proto.sh new file mode 100644 index 00000000..45bb60bb --- /dev/null +++ b/dist/services/Service/compile.proto.sh @@ -0,0 +1,2 @@ +#!/bin/bash +grpc_tools_node_protoc --js_out=import_style=commonjs,binary:protos --grpc_out=protos --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` services.proto diff --git a/dist/services/Service/protos/services_grpc_pb.js b/dist/services/Service/protos/services_grpc_pb.js new file mode 100644 index 00000000..600aa82b --- /dev/null +++ b/dist/services/Service/protos/services_grpc_pb.js @@ -0,0 +1,167 @@ +// GENERATED CODE -- DO NOT EDIT! + +'use strict'; +var grpc = require('grpc'); +var services_pb = require('./services_pb.js'); +var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js'); + +function serialize_Empty(arg) { + if (!(arg instanceof services_pb.Empty)) { + throw new Error('Expected argument of type Empty'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_Empty(buffer_arg) { + return services_pb.Empty.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_EventRequest(arg) { + if (!(arg instanceof services_pb.EventRequest)) { + throw new Error('Expected argument of type EventRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_EventRequest(buffer_arg) { + return services_pb.EventRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_EventResponse(arg) { + if (!(arg instanceof services_pb.EventResponse)) { + throw new Error('Expected argument of type EventResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_EventResponse(buffer_arg) { + return services_pb.EventResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_InfoRequest(arg) { + if (!(arg instanceof services_pb.InfoRequest)) { + throw new Error('Expected argument of type InfoRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_InfoRequest(buffer_arg) { + return services_pb.InfoRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_InfoResponse(arg) { + if (!(arg instanceof services_pb.InfoResponse)) { + throw new Error('Expected argument of type InfoResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_InfoResponse(buffer_arg) { + return services_pb.InfoResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_JoinRequest(arg) { + if (!(arg instanceof services_pb.JoinRequest)) { + throw new Error('Expected argument of type JoinRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_JoinRequest(buffer_arg) { + return services_pb.JoinRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_WorkerRequest(arg) { + if (!(arg instanceof services_pb.WorkerRequest)) { + throw new Error('Expected argument of type WorkerRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_WorkerRequest(buffer_arg) { + return services_pb.WorkerRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_WorkerResponse(arg) { + if (!(arg instanceof services_pb.WorkerResponse)) { + throw new Error('Expected argument of type WorkerResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_WorkerResponse(buffer_arg) { + return services_pb.WorkerResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + + +var InfoService = exports.InfoService = { + getServiceInfo: { + path: '/Info/getServiceInfo', + requestStream: false, + responseStream: false, + requestType: services_pb.InfoRequest, + responseType: services_pb.InfoResponse, + requestSerialize: serialize_InfoRequest, + requestDeserialize: deserialize_InfoRequest, + responseSerialize: serialize_InfoResponse, + responseDeserialize: deserialize_InfoResponse } }; + + + +exports.InfoClient = grpc.makeGenericClientConstructor(InfoService); +var EventEmitterService = exports.EventEmitterService = { + join: { + path: '/EventEmitter/join', + requestStream: false, + responseStream: true, + requestType: services_pb.JoinRequest, + responseType: services_pb.EventResponse, + requestSerialize: serialize_JoinRequest, + requestDeserialize: deserialize_JoinRequest, + responseSerialize: serialize_EventResponse, + responseDeserialize: deserialize_EventResponse }, + + leave: { + path: '/EventEmitter/leave', + requestStream: false, + responseStream: false, + requestType: services_pb.Empty, + responseType: services_pb.Empty, + requestSerialize: serialize_Empty, + requestDeserialize: deserialize_Empty, + responseSerialize: serialize_Empty, + responseDeserialize: deserialize_Empty } }; + + + +exports.EventEmitterClient = grpc.makeGenericClientConstructor(EventEmitterService); +var EventListenerService = exports.EventListenerService = { + send: { + path: '/EventListener/send', + requestStream: false, + responseStream: false, + requestType: services_pb.EventRequest, + responseType: services_pb.Empty, + requestSerialize: serialize_EventRequest, + requestDeserialize: deserialize_EventRequest, + responseSerialize: serialize_Empty, + responseDeserialize: deserialize_Empty } }; + + + +exports.EventListenerClient = grpc.makeGenericClientConstructor(EventListenerService); +var WorkerService = exports.WorkerService = { + run: { + path: '/Worker/run', + requestStream: false, + responseStream: false, + requestType: services_pb.WorkerRequest, + responseType: services_pb.WorkerResponse, + requestSerialize: serialize_WorkerRequest, + requestDeserialize: deserialize_WorkerRequest, + responseSerialize: serialize_WorkerResponse, + responseDeserialize: deserialize_WorkerResponse } }; + + + +exports.WorkerClient = grpc.makeGenericClientConstructor(WorkerService); \ No newline at end of file diff --git a/dist/services/Service/protos/services_pb.js b/dist/services/Service/protos/services_pb.js new file mode 100644 index 00000000..cea41b44 --- /dev/null +++ b/dist/services/Service/protos/services_pb.js @@ -0,0 +1,1533 @@ +"use strict"; // source: services.proto +/** + * @fileoverview + * @enhanceable + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = Function('return this')(); + +var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js'); +goog.object.extend(proto, google_protobuf_struct_pb); +goog.exportSymbol('proto.Empty', null, global); +goog.exportSymbol('proto.EmptyRequest', null, global); +goog.exportSymbol('proto.EventRequest', null, global); +goog.exportSymbol('proto.EventResponse', null, global); +goog.exportSymbol('proto.InfoRequest', null, global); +goog.exportSymbol('proto.InfoResponse', null, global); +goog.exportSymbol('proto.JoinRequest', null, global); +goog.exportSymbol('proto.WorkerRequest', null, global); +goog.exportSymbol('proto.WorkerResponse', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.Empty = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.Empty, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.Empty.displayName = 'proto.Empty'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.EmptyRequest = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.EmptyRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.EmptyRequest.displayName = 'proto.EmptyRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.WorkerRequest = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.WorkerRequest.repeatedFields_, null); +}; +goog.inherits(proto.WorkerRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.WorkerRequest.displayName = 'proto.WorkerRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.WorkerResponse = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.WorkerResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.WorkerResponse.displayName = 'proto.WorkerResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.EventRequest = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.EventRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.EventRequest.displayName = 'proto.EventRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.EventResponse = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.EventResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.EventResponse.displayName = 'proto.EventResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.JoinRequest = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.JoinRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.JoinRequest.displayName = 'proto.JoinRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.InfoRequest = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.InfoRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.InfoRequest.displayName = 'proto.InfoRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.InfoResponse = function (opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.InfoResponse.repeatedFields_, null); +}; +goog.inherits(proto.InfoResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.InfoResponse.displayName = 'proto.InfoResponse'; +} + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.Empty.prototype.toObject = function (opt_includeInstance) { + return proto.Empty.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.Empty} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.Empty.toObject = function (includeInstance, msg) { + var f,obj = {}; + + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.Empty} + */ +proto.Empty.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.Empty(); + return proto.Empty.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.Empty} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.Empty} + */ +proto.Empty.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.Empty.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.Empty.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.Empty} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.Empty.serializeBinaryToWriter = function (message, writer) { + var f = undefined; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.EmptyRequest.prototype.toObject = function (opt_includeInstance) { + return proto.EmptyRequest.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.EmptyRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.EmptyRequest.toObject = function (includeInstance, msg) { + var f,obj = {}; + + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.EmptyRequest} + */ +proto.EmptyRequest.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.EmptyRequest(); + return proto.EmptyRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.EmptyRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.EmptyRequest} + */ +proto.EmptyRequest.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.EmptyRequest.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.EmptyRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.EmptyRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.EmptyRequest.serializeBinaryToWriter = function (message, writer) { + var f = undefined; +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.WorkerRequest.repeatedFields_ = [2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.WorkerRequest.prototype.toObject = function (opt_includeInstance) { + return proto.WorkerRequest.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.WorkerRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.WorkerRequest.toObject = function (includeInstance, msg) { + var f,obj = { + action: jspb.Message.getFieldWithDefault(msg, 1, ""), + argsList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.WorkerRequest} + */ +proto.WorkerRequest.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.WorkerRequest(); + return proto.WorkerRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.WorkerRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.WorkerRequest} + */ +proto.WorkerRequest.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */reader.readString(); + msg.setAction(value); + break; + case 2: + var value = /** @type {string} */reader.readString(); + msg.addArgs(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.WorkerRequest.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.WorkerRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.WorkerRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.WorkerRequest.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getAction(); + if (f.length > 0) { + writer.writeString( + 1, + f); + + } + f = message.getArgsList(); + if (f.length > 0) { + writer.writeRepeatedString( + 2, + f); + + } +}; + + +/** + * optional string action = 1; + * @return {string} + */ +proto.WorkerRequest.prototype.getAction = function () { + return (/** @type {string} */jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.WorkerRequest} returns this + */ +proto.WorkerRequest.prototype.setAction = function (value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * repeated string args = 2; + * @return {!Array} + */ +proto.WorkerRequest.prototype.getArgsList = function () { + return (/** @type {!Array} */jspb.Message.getRepeatedField(this, 2)); +}; + + +/** + * @param {!Array} value + * @return {!proto.WorkerRequest} returns this + */ +proto.WorkerRequest.prototype.setArgsList = function (value) { + return jspb.Message.setField(this, 2, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.WorkerRequest} returns this + */ +proto.WorkerRequest.prototype.addArgs = function (value, opt_index) { + return jspb.Message.addToRepeatedField(this, 2, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.WorkerRequest} returns this + */ +proto.WorkerRequest.prototype.clearArgsList = function () { + return this.setArgsList([]); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.WorkerResponse.prototype.toObject = function (opt_includeInstance) { + return proto.WorkerResponse.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.WorkerResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.WorkerResponse.toObject = function (includeInstance, msg) { + var f,obj = { + result: (f = msg.getResult()) && google_protobuf_struct_pb.Struct.toObject(includeInstance, f) }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.WorkerResponse} + */ +proto.WorkerResponse.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.WorkerResponse(); + return proto.WorkerResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.WorkerResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.WorkerResponse} + */ +proto.WorkerResponse.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new google_protobuf_struct_pb.Struct(); + reader.readMessage(value, google_protobuf_struct_pb.Struct.deserializeBinaryFromReader); + msg.setResult(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.WorkerResponse.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.WorkerResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.WorkerResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.WorkerResponse.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getResult(); + if (f != null) { + writer.writeMessage( + 1, + f, + google_protobuf_struct_pb.Struct.serializeBinaryToWriter); + + } +}; + + +/** + * optional google.protobuf.Struct result = 1; + * @return {?proto.google.protobuf.Struct} + */ +proto.WorkerResponse.prototype.getResult = function () { + return (/** @type{?proto.google.protobuf.Struct} */ + jspb.Message.getWrapperField(this, google_protobuf_struct_pb.Struct, 1)); +}; + + +/** + * @param {?proto.google.protobuf.Struct|undefined} value + * @return {!proto.WorkerResponse} returns this + */ +proto.WorkerResponse.prototype.setResult = function (value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.WorkerResponse} returns this + */ +proto.WorkerResponse.prototype.clearResult = function () { + return this.setResult(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.WorkerResponse.prototype.hasResult = function () { + return jspb.Message.getField(this, 1) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.EventRequest.prototype.toObject = function (opt_includeInstance) { + return proto.EventRequest.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.EventRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.EventRequest.toObject = function (includeInstance, msg) { + var f,obj = { + event: jspb.Message.getFieldWithDefault(msg, 1, ""), + data: (f = msg.getData()) && google_protobuf_struct_pb.Struct.toObject(includeInstance, f) }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.EventRequest} + */ +proto.EventRequest.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.EventRequest(); + return proto.EventRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.EventRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.EventRequest} + */ +proto.EventRequest.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */reader.readString(); + msg.setEvent(value); + break; + case 2: + var value = new google_protobuf_struct_pb.Struct(); + reader.readMessage(value, google_protobuf_struct_pb.Struct.deserializeBinaryFromReader); + msg.setData(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.EventRequest.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.EventRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.EventRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.EventRequest.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getEvent(); + if (f.length > 0) { + writer.writeString( + 1, + f); + + } + f = message.getData(); + if (f != null) { + writer.writeMessage( + 2, + f, + google_protobuf_struct_pb.Struct.serializeBinaryToWriter); + + } +}; + + +/** + * optional string event = 1; + * @return {string} + */ +proto.EventRequest.prototype.getEvent = function () { + return (/** @type {string} */jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.EventRequest} returns this + */ +proto.EventRequest.prototype.setEvent = function (value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional google.protobuf.Struct data = 2; + * @return {?proto.google.protobuf.Struct} + */ +proto.EventRequest.prototype.getData = function () { + return (/** @type{?proto.google.protobuf.Struct} */ + jspb.Message.getWrapperField(this, google_protobuf_struct_pb.Struct, 2)); +}; + + +/** + * @param {?proto.google.protobuf.Struct|undefined} value + * @return {!proto.EventRequest} returns this + */ +proto.EventRequest.prototype.setData = function (value) { + return jspb.Message.setWrapperField(this, 2, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.EventRequest} returns this + */ +proto.EventRequest.prototype.clearData = function () { + return this.setData(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.EventRequest.prototype.hasData = function () { + return jspb.Message.getField(this, 2) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.EventResponse.prototype.toObject = function (opt_includeInstance) { + return proto.EventResponse.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.EventResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.EventResponse.toObject = function (includeInstance, msg) { + var f,obj = { + event: jspb.Message.getFieldWithDefault(msg, 1, ""), + data: (f = msg.getData()) && google_protobuf_struct_pb.Struct.toObject(includeInstance, f) }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.EventResponse} + */ +proto.EventResponse.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.EventResponse(); + return proto.EventResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.EventResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.EventResponse} + */ +proto.EventResponse.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */reader.readString(); + msg.setEvent(value); + break; + case 2: + var value = new google_protobuf_struct_pb.Struct(); + reader.readMessage(value, google_protobuf_struct_pb.Struct.deserializeBinaryFromReader); + msg.setData(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.EventResponse.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.EventResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.EventResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.EventResponse.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getEvent(); + if (f.length > 0) { + writer.writeString( + 1, + f); + + } + f = message.getData(); + if (f != null) { + writer.writeMessage( + 2, + f, + google_protobuf_struct_pb.Struct.serializeBinaryToWriter); + + } +}; + + +/** + * optional string event = 1; + * @return {string} + */ +proto.EventResponse.prototype.getEvent = function () { + return (/** @type {string} */jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.EventResponse} returns this + */ +proto.EventResponse.prototype.setEvent = function (value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional google.protobuf.Struct data = 2; + * @return {?proto.google.protobuf.Struct} + */ +proto.EventResponse.prototype.getData = function () { + return (/** @type{?proto.google.protobuf.Struct} */ + jspb.Message.getWrapperField(this, google_protobuf_struct_pb.Struct, 2)); +}; + + +/** + * @param {?proto.google.protobuf.Struct|undefined} value + * @return {!proto.EventResponse} returns this + */ +proto.EventResponse.prototype.setData = function (value) { + return jspb.Message.setWrapperField(this, 2, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.EventResponse} returns this + */ +proto.EventResponse.prototype.clearData = function () { + return this.setData(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.EventResponse.prototype.hasData = function () { + return jspb.Message.getField(this, 2) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.JoinRequest.prototype.toObject = function (opt_includeInstance) { + return proto.JoinRequest.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.JoinRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.JoinRequest.toObject = function (includeInstance, msg) { + var f,obj = { + user: jspb.Message.getFieldWithDefault(msg, 1, "") }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.JoinRequest} + */ +proto.JoinRequest.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.JoinRequest(); + return proto.JoinRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.JoinRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.JoinRequest} + */ +proto.JoinRequest.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */reader.readString(); + msg.setUser(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.JoinRequest.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.JoinRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.JoinRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.JoinRequest.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getUser(); + if (f.length > 0) { + writer.writeString( + 1, + f); + + } +}; + + +/** + * optional string user = 1; + * @return {string} + */ +proto.JoinRequest.prototype.getUser = function () { + return (/** @type {string} */jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.JoinRequest} returns this + */ +proto.JoinRequest.prototype.setUser = function (value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.InfoRequest.prototype.toObject = function (opt_includeInstance) { + return proto.InfoRequest.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.InfoRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.InfoRequest.toObject = function (includeInstance, msg) { + var f,obj = {}; + + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.InfoRequest} + */ +proto.InfoRequest.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.InfoRequest(); + return proto.InfoRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.InfoRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.InfoRequest} + */ +proto.InfoRequest.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.InfoRequest.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.InfoRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.InfoRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.InfoRequest.serializeBinaryToWriter = function (message, writer) { + var f = undefined; +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.InfoResponse.repeatedFields_ = [2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ + proto.InfoResponse.prototype.toObject = function (opt_includeInstance) { + return proto.InfoResponse.toObject(opt_includeInstance, this); + }; + + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.InfoResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ + proto.InfoResponse.toObject = function (includeInstance, msg) { + var f,obj = { + name: jspb.Message.getFieldWithDefault(msg, 1, ""), + protosList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f }; + + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.InfoResponse} + */ +proto.InfoResponse.deserializeBinary = function (bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.InfoResponse(); + return proto.InfoResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.InfoResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.InfoResponse} + */ +proto.InfoResponse.deserializeBinaryFromReader = function (msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */reader.readString(); + msg.setName(value); + break; + case 2: + var value = /** @type {string} */reader.readString(); + msg.addProtos(value); + break; + default: + reader.skipField(); + break;} + + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.InfoResponse.prototype.serializeBinary = function () { + var writer = new jspb.BinaryWriter(); + proto.InfoResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.InfoResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.InfoResponse.serializeBinaryToWriter = function (message, writer) { + var f = undefined; + f = message.getName(); + if (f.length > 0) { + writer.writeString( + 1, + f); + + } + f = message.getProtosList(); + if (f.length > 0) { + writer.writeRepeatedString( + 2, + f); + + } +}; + + +/** + * optional string name = 1; + * @return {string} + */ +proto.InfoResponse.prototype.getName = function () { + return (/** @type {string} */jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.InfoResponse} returns this + */ +proto.InfoResponse.prototype.setName = function (value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * repeated string protos = 2; + * @return {!Array} + */ +proto.InfoResponse.prototype.getProtosList = function () { + return (/** @type {!Array} */jspb.Message.getRepeatedField(this, 2)); +}; + + +/** + * @param {!Array} value + * @return {!proto.InfoResponse} returns this + */ +proto.InfoResponse.prototype.setProtosList = function (value) { + return jspb.Message.setField(this, 2, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.InfoResponse} returns this + */ +proto.InfoResponse.prototype.addProtos = function (value, opt_index) { + return jspb.Message.addToRepeatedField(this, 2, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.InfoResponse} returns this + */ +proto.InfoResponse.prototype.clearProtosList = function () { + return this.setProtosList([]); +}; + + +goog.object.extend(exports, proto); \ No newline at end of file diff --git a/dist/services/Service/serviceProto.js b/dist/services/Service/serviceProto.js new file mode 100644 index 00000000..bfd16d1c --- /dev/null +++ b/dist/services/Service/serviceProto.js @@ -0,0 +1,26 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "Struct", { enumerable: true, get: function () {return _struct_pb.Struct;} });exports.joinProtos = exports.INFO_SERVICE = exports.PROTO = exports.PROTO_DEFINITION = exports.getProto = exports.MESSAGES = void 0; +var _grpc = _interopRequireDefault(require("grpc")); +var _services_grpc_pb = _interopRequireDefault(require("./protos/services_grpc_pb")); +var _services_pb = _interopRequireDefault(require("./protos/services_pb")); +var _struct_pb = require("google-protobuf/google/protobuf/struct_pb");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const MESSAGES = _services_pb.default;exports.MESSAGES = MESSAGES; + +const getProto = protoDefinition => _grpc.default.loadPackageDefinition(protoDefinition);exports.getProto = getProto; + +const PROTO_DEFINITION = _services_grpc_pb.default;exports.PROTO_DEFINITION = PROTO_DEFINITION; + +const PROTO = getProto(PROTO_DEFINITION);exports.PROTO = PROTO; + +const INFO_SERVICE = PROTO.InfoService;exports.INFO_SERVICE = INFO_SERVICE; + +const joinProtos = (name, protos) => { + let res = {}; + for (let name of protos) { + let def = PROTO_DEFINITION[name]; + res = Object.assign(res, def); + } + let newProto = Object.assign({}, PROTO_DEFINITION); + newProto[name] = res; + return newProto; +};exports.joinProtos = joinProtos; \ No newline at end of file diff --git a/dist/services/Service/services.proto b/dist/services/Service/services.proto new file mode 100644 index 00000000..8dec6842 --- /dev/null +++ b/dist/services/Service/services.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; +import "google/protobuf/struct.proto"; + +message Empty {} + +message EmptyRequest {} + +message WorkerRequest { + string action = 1; + repeated string args = 2; +} + +message WorkerResponse{ + google.protobuf.Struct result = 1; +} + +message EventRequest { + string event = 1; + google.protobuf.Struct data = 2; +} + +message EventResponse{ + string event = 1; + google.protobuf.Struct data = 2; +} + +message JoinRequest { + string user = 1; +} + +message InfoRequest {} + +message InfoResponse{ + string name = 1; + repeated string protos = 2; +} + + +service Info{ + rpc getServiceInfo(InfoRequest) returns (InfoResponse) {} +} +service EventEmitter{ + rpc join(JoinRequest) returns (stream EventResponse) {} + rpc leave(Empty) returns (Empty) {} +} +service EventListener{ + rpc send(EventRequest) returns (Empty) {} +} +service Worker{ + rpc run(WorkerRequest) returns (WorkerResponse) {} +} + diff --git a/dist/services/blocks.config.js b/dist/services/blocks.config.js new file mode 100644 index 00000000..11b5c23f --- /dev/null +++ b/dist/services/blocks.config.js @@ -0,0 +1,15 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.apps = exports.paths = void 0; +var _servicesConfig = require("./servicesConfig"); + +const scripts = Object.values(_servicesConfig.servicesNames); + +const scriptName = name => `${name}.js`; + +const cwd = `${__dirname}/blocks/`; + +const paths = scripts.map(name => cwd + scriptName(name));exports.paths = paths; + +const apps = scripts.map(name => { + let script = scriptName(name); + return { name, script, cwd }; +});exports.apps = apps; \ No newline at end of file diff --git a/dist/services/blocks/blocksBalances.js b/dist/services/blocks/blocksBalances.js new file mode 100644 index 00000000..39269f4b --- /dev/null +++ b/dist/services/blocks/blocksBalances.js @@ -0,0 +1,33 @@ +"use strict";var _serviceFactory = require("../serviceFactory"); +var _UpdateBlockBalances = require("../classes/UpdateBlockBalances"); + +const serviceConfig = _serviceFactory.services.BALANCES; + +async function main() { + try { + const { log, db, initConfig, events } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const balances = new _UpdateBlockBalances.UpdateBlockBalances(db, { log, initConfig }); + const eventHandler = (event, data) => { + switch (event) { + case events.NEW_TIP_BLOCK: + balances.updateLastBlock(data); + break;} + + }; + const executor = ({ create }) => { + create.Emitter(); + create.Listener(eventHandler); + }; + + const { startService, service } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + const { emit } = service; + await startService(); + balances.setEmitter(emit); + balances.start(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksChecker.js b/dist/services/blocks/blocksChecker.js index c71791bd..6491e7d2 100644 --- a/dist/services/blocks/blocksChecker.js +++ b/dist/services/blocks/blocksChecker.js @@ -1,32 +1,32 @@ -"use strict";var _dataSource = require("../../lib/dataSource.js"); -var _types = require("../../lib/types"); +"use strict";var _serviceFactory = require("../serviceFactory"); var _CheckBlocks = require("../classes/CheckBlocks"); -var _config = _interopRequireDefault(require("../../lib/config")); -var _Logger = _interopRequireDefault(require("../../lib/Logger"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const log = (0, _Logger.default)('Blocks', _config.default.blocks.log); +const serviceConfig = _serviceFactory.services.CHECKER; -(0, _dataSource.dataSource)().then(({ db }) => { - const Checker = new _CheckBlocks.CheckBlocks(db, { log }); - Checker.start(); - process.on('message', msg => { - let action = msg.action; - let args = msg.args; - if (action) { - switch (action) { - case _types.actions.CHECK_DB: - Checker.checkDb(...args); - break; - - case _types.actions.UPDATE_TIP_BLOCK: - Checker.updateTipBlock(...args); +async function main() { + try { + const { log, db, initConfig, events } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const checker = new _CheckBlocks.CheckBlocks(db, { log, initConfig }); + const eventHandler = (event, data) => { + switch (event) { + case events.NEW_TIP_BLOCK: + checker.updateTipBlock(data); break;} - } - }); -}); + }; + const executor = ({ create }) => { + create.Emitter(); + create.Listener(eventHandler); + }; + + const { startService, service } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + const { emit } = service; + await startService(); + checker.start(emit); + } catch (err) { + console.error(err); + process.exit(9); + } +} -process.on('unhandledRejection', err => { - console.error(err); - process.exit(1); -}); \ No newline at end of file +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksListener.js b/dist/services/blocks/blocksListener.js index f55bb7ea..7723a1e1 100644 --- a/dist/services/blocks/blocksListener.js +++ b/dist/services/blocks/blocksListener.js @@ -1,19 +1,20 @@ -"use strict";var _dataSource = require("../../lib/dataSource.js"); -var _config = _interopRequireDefault(require("../../lib/config")); +"use strict";var _serviceFactory = require("../serviceFactory"); var _ListenBlocks = require("../classes/ListenBlocks"); -var _Logger = _interopRequireDefault(require("../../lib/Logger"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const config = Object.assign({}, _config.default.blocks); -const log = (0, _Logger.default)('Blocks', config.log); +const serviceConfig = _serviceFactory.services.LISTENER; +const executor = ({ create }) => {create.Emitter();}; -(0, _dataSource.setup)({ log }).then(({ db }) => { - config.Logger = log; - const listener = new _ListenBlocks.ListenBlocks(db, { log }); - log.info(`Starting blocks listener`); - listener.start(); -}); +async function main() { + try { + const { log, db, initConfig } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const { service, startService } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + await startService(); + const listener = new _ListenBlocks.ListenBlocks(db, { log, initConfig }, service); + listener.start(); + } catch (err) { + console.error(err); + process.exit(9); + } +} -process.on('unhandledRejection', err => { - console.error(err); - process.exit(1); -}); \ No newline at end of file +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksRequester.js b/dist/services/blocks/blocksRequester.js index e92475c1..62c508d6 100644 --- a/dist/services/blocks/blocksRequester.js +++ b/dist/services/blocks/blocksRequester.js @@ -1,74 +1,43 @@ -"use strict";var _RequestBlocks = require("../classes/RequestBlocks"); -var _types = require("../../lib/types"); -var _utils = require("../../lib/utils"); -var _Block = require("../classes/Block"); -var _dataSource = require("../../lib/dataSource"); -var _Logger = _interopRequireDefault(require("../../lib/Logger")); +"use strict";var _serviceFactory = require("../serviceFactory"); +var _RequestBlocks = require("../classes/RequestBlocks"); var _config = _interopRequireDefault(require("../../lib/config"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} -const config = Object.assign({}, _config.default.blocks); - -const log = (0, _Logger.default)('Blocks', config.log); - -(0, _dataSource.dataSource)().then(({ db, initConfig }) => { - let Requester = new _RequestBlocks.RequestBlocks(db, Object.assign(config, { log, initConfig })); - const blocksCollection = Requester.collections.Blocks; - - Requester.updateStatus = function (state) { - state = state || {}; - state.requestingBlocks = this.getRequested(); - state.pendingBlocks = this.getPending(); - let action = _types.actions.STATUS_UPDATE; - process.send({ action, args: [state] }); - }; - - process.on('message', msg => { - let action = msg.action; - let args = msg.args; - if (action) { - switch (action) { - case _types.actions.BLOCK_REQUEST: - Requester.request(...args); - break; - - case _types.actions.BULK_BLOCKS_REQUEST: - Requester.bulkRequest(...args); - break;} - - } - }); - - Requester.events.on(_types.events.QUEUE_DONE, data => { - Requester.updateStatus(); - }); - - Requester.events.on(_types.events.BLOCK_REQUESTED, data => { - log.debug(_types.events.BLOCK_REQUESTED, data); - Requester.updateStatus(); - }); - - Requester.events.on(_types.events.BLOCK_ERROR, data => { - log.debug(_types.events.BLOCK_ERROR, data); - }); - - Requester.events.on(_types.events.NEW_BLOCK, data => { - let block = data.block; - if (!block) return; - let key = data.key; - let isHashKey = (0, _utils.isBlockHash)(key); - if (block) { - process.send({ action: _types.actions.UPDATE_TIP_BLOCK, args: [block] }); - let show = isHashKey ? block.number : block.hash; - log.debug(_types.events.NEW_BLOCK, `New Block DATA ${key} - ${show}`); - let parent = block.parentHash; - - (0, _Block.getBlockFromDb)(parent, blocksCollection).then(parentBlock => { - if (!parentBlock && block.number) { - log.debug(`Getting parent of block ${block.number} - ${parent}`); - Requester.request(parent, true); - } - }); - } - Requester.updateStatus(); - }); -}); \ No newline at end of file +const serviceConfig = _serviceFactory.services.REQUESTER; + +async function main() { + try { + const { log, db, initConfig, events } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const Requester = new _RequestBlocks.RequestBlocks(db, Object.assign(Object.assign({}, _config.default.blocks), { log, initConfig })); + const eventHandler = async (event, data) => { + try { + switch (event) { + case events.NEW_BLOCK: + let { key, prioritize } = data; + Requester.request(key, prioritize); + break; + + case events.REQUEST_BLOCKS: + const { blocks } = data; + Requester.bulkRequest(blocks); + break;} + + } catch (err) { + return Promise.reject(err); + } + }; + const executor = ({ create }) => { + create.Emitter(); + create.Listener(eventHandler); + }; + + const { startService, service } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + const { emit } = service; + Requester.setEmitter(emit); + await startService(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksRouter.js b/dist/services/blocks/blocksRouter.js new file mode 100644 index 00000000..132f0c03 --- /dev/null +++ b/dist/services/blocks/blocksRouter.js @@ -0,0 +1,16 @@ +"use strict";var _serviceFactory = require("../serviceFactory"); + +const serviceConfig = _serviceFactory.services.ROUTER; + +async function main() { + try { + const { router, startService } = await (0, _serviceFactory.createRouter)(serviceConfig, { services: _serviceFactory.services }); + await startService(); + router.start(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksStats.js b/dist/services/blocks/blocksStats.js new file mode 100644 index 00000000..28525a02 --- /dev/null +++ b/dist/services/blocks/blocksStats.js @@ -0,0 +1,26 @@ +"use strict";var _serviceFactory = require("../serviceFactory"); +var _BcStats = require("../classes/BcStats"); + +const serviceConfig = _serviceFactory.services.STATS; + +async function main() { + try { + const { log, db, initConfig, events } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const Stats = new _BcStats.BcStats(db, { log, initConfig }); + const eventHandler = (event, data) => { + switch (event) { + case events.NEW_TIP_BLOCK: + Stats.update(data); + break;} + + }; + const executor = ({ create }) => {create.Listener(eventHandler);}; + const { startService } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + await startService(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/blocks/blocksStatus.js b/dist/services/blocks/blocksStatus.js new file mode 100644 index 00000000..013b869a --- /dev/null +++ b/dist/services/blocks/blocksStatus.js @@ -0,0 +1,26 @@ +"use strict";var _serviceFactory = require("../serviceFactory"); +var _BlocksStatus = require("../classes/BlocksStatus"); + +const serviceConfig = _serviceFactory.services.STATUS; + +async function main() { + try { + const { log, db, initConfig, events } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const Status = new _BlocksStatus.BlocksStatus(db, { log, initConfig }); + const eventHandler = (event, data) => { + switch (event) { + case events.NEW_STATUS: + Status.update(data); + break;} + + }; + const executor = ({ create }) => {create.Listener(eventHandler);}; + const { startService } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + await startService(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/blocks/index.js b/dist/services/blocks/index.js deleted file mode 100644 index 06f97508..00000000 --- a/dist/services/blocks/index.js +++ /dev/null @@ -1,80 +0,0 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.setupBlocks = setupBlocks;var _path = _interopRequireDefault(require("path")); -var _child_process = require("child_process"); -var _config = _interopRequireDefault(require("../../lib/config")); -var _Logger = _interopRequireDefault(require("../../lib/Logger")); -var _BlocksStatus = require("../classes/BlocksStatus"); -var _BcStats = require("../classes/BcStats"); -var _types = require("../../lib/types"); -var _Setup = _interopRequireDefault(require("../../lib/Setup"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} - -const config = Object.assign({}, _config.default.blocks); -const log = (0, _Logger.default)('Blocks', config.log); -config.log = log; - -startBlocks(); - -async function setupBlocks() { - const setup = await (0, _Setup.default)({ log }); - await setup.createCollections(); - return setup; -} - -async function startBlocks() { - const setup = await setupBlocks(); - const { db, initConfig } = await setup.start(); - config.initConfig = initConfig; - const Status = new _BlocksStatus.BlocksStatus(db, config); - const Stats = new _BcStats.BcStats(db, config); - const listenToMessage = (msg, service) => { - let action, args, event, data; - ({ action, args, event, data } = msg); - if (event) { - readEvent(event, data); - } - if (action) { - switch (action) { - case _types.actions.STATUS_UPDATE: - Status.update(...args); - break; - - case _types.actions.BLOCK_REQUEST: - case _types.actions.BULK_BLOCKS_REQUEST: - Requester.send({ action, args }); - break; - - case _types.actions.UPDATE_TIP_BLOCK: - Stats.update(...args); - Checker.send({ action, args }); - break;} - - } - }; - /* eslint-disable-next-line no-unused-vars */ - const Listener = startService('Listener', listenToMessage); - const Checker = startService('Checker', listenToMessage); - const Requester = startService('Requester', listenToMessage); - /* eslint-disable-next-line no-unused-vars */ - const TxPool = startService('TxPool', listenToMessage, '../txPool.js'); -} - -function startService(name, parseMessage, script) { - script = script || `blocks${name}.js`; - let service = (0, _child_process.fork)(_path.default.resolve(__dirname, script)); - service.on('message', msg => parseMessage(msg, name)); - service.on('error', err => {console.error('Service error', err);}); - return service; -} - -// WIP -const readEvent = (event, data) => { - log.info(event, data); -}; - -process.on('unhandledRejection', err => { - console.error(err); - process.exit(1); -}); - -process.on('uncaughtException', err => { - console.error(err); -}); \ No newline at end of file diff --git a/dist/services/blocks/setup.js b/dist/services/blocks/setup.js deleted file mode 100644 index 3c2ec39a..00000000 --- a/dist/services/blocks/setup.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict";var _index = require("./index.js"); - -(0, _index.setupBlocks)().then(() => { - process.exit(0); -}).catch(err => { - console.log(err); - process.exit(9); -}); \ No newline at end of file diff --git a/dist/services/blocks/txPool.js b/dist/services/blocks/txPool.js new file mode 100644 index 00000000..4e2143ec --- /dev/null +++ b/dist/services/blocks/txPool.js @@ -0,0 +1,22 @@ +"use strict";var _TxPool = require("../classes/TxPool"); +var _serviceFactory = require("../serviceFactory"); + +const serviceConfig = _serviceFactory.services.TXPOOL; + +const executor = ({ create }) => {create.Emitter();}; + +async function main() { + try { + const { log, db, initConfig } = await (0, _serviceFactory.bootStrapService)(serviceConfig); + const { startService } = await (0, _serviceFactory.createService)(serviceConfig, executor, { log }); + await startService(); + const txPool = new _TxPool.TxPool(db, { log, initConfig }); + log.info(`Starting txPool`); + txPool.start(); + } catch (err) { + console.error(err); + process.exit(9); + } +} + +main(); \ No newline at end of file diff --git a/dist/services/classes/Address.js b/dist/services/classes/Address.js index 613b4ff4..97a15edd 100644 --- a/dist/services/classes/Address.js +++ b/dist/services/classes/Address.js @@ -1,152 +1,267 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Address = void 0;var _BcThing = require("./BcThing"); -var _GetTxBalance = require("./GetTxBalance"); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.saveAddressToDb = saveAddressToDb;exports.default = exports.Address = void 0;var _BcThing = require("./BcThing"); var _utils = require("../../lib/utils"); var _types = require("../../lib/types"); +var _Contract = _interopRequireDefault(require("./Contract")); +var _rskContractParser = require("rsk-contract-parser"); +var _Tx = require("./Tx"); +var _InternalTx = require("./InternalTx"); +var _rskUtils = require("rsk-utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class Address extends _BcThing.BcThing { - constructor(address, { nod3, initConfig, db, collections, block = 'latest' } = {}) { - super({ nod3, initConfig, collections }); + constructor(address, { nod3, initConfig, collections, tx, block, log } = {}) { + super({ nod3, initConfig, collections, log }); if (!this.isAddress(address)) throw new Error(`Invalid address: ${address}`); + this.isZeroAddress = (0, _rskUtils.isZeroAddress)(address); + this.bcSearch = (0, _rskContractParser.BcSearch)(nod3); this.address = address; - this.db = db || this.collections.Addrs; - this.codeIsSaved = false; - this.TxsBalance = new _GetTxBalance.GetTxBalance(this.collections.Txs); - this.data = new Proxy( - { address, type: _types.addrTypes.ADDRESS }, - { - set(obj, prop, val) { - if (prop === 'code') { - val = val || null; - if (!(0, _utils.isNullData)(val)) { - obj.type = _types.addrTypes.CONTRACT; - obj.code = val; - } - } else if (val && prop === _types.fields.LAST_BLOCK_MINED) { - const lastBlock = obj[_types.fields.LAST_BLOCK_MINED] || {}; - let number = lastBlock.number || -1; - if (val.miner === obj.address && val.number > number) { - obj[prop] = Object.assign({}, val); - } - } else { - obj[prop] = val; - } - return true; - } }); - - this.block = 'latest'; - this.dbData = null; + this.fetched = false; + this.collection = collections ? collections.Addrs : undefined; + this.contract = undefined; + this.block = undefined; + this.blockNumber = undefined; + let { nativeContracts } = this; + let nName = nativeContracts ? nativeContracts.getNativeContractName(address) : undefined; + this.name = nName; + this.isNative = !!nName; + this.dbData = undefined; + this.tx = tx; + this.data = createAddressData(this); this.setBlock(block); } setBlock(block) { - if (!block) block = 'latest'; + if (!(0, _utils.isBlockObject)(block) && !(0, _utils.isValidBlockNumber)(block)) { + throw new Error(`Invalid block ${block}`); + } if ((0, _utils.isBlockObject)(block)) { - this.block = block.number; - this.setLastBlock(block); + this.blockNumber = block.number; + this.block = block; + this.data[_types.fields.LAST_BLOCK_MINED] = block; + } else { + this.blockNumber = block; } } - setLastBlock(block) { - this.setData(_types.fields.LAST_BLOCK_MINED, block); + async getBalance(blockNumber = 'latest') { + try { + if (this.isZeroAddress) return '0x0'; + let { nod3, address } = this; + let balance = await nod3.eth.getBalance(address, blockNumber); + return balance; + } catch (err) { + this.log.debug(err); + return Promise.reject(new Error(`Address: error getting balance of ${this.address} ${err}`)); + } } - setData(prop, value) { - if (prop === 'address') return; - this.data[prop] = value; + async getCode() { + try { + if (this.isZeroAddress) return null; + let { code } = this.getData(); + let { nod3, address, blockNumber } = this; + if (code !== undefined) return code; + code = await nod3.eth.getCode(address, blockNumber); + code = (0, _utils.isNullData)(code) ? null : code; + this.setData({ code }); + return code; + } catch (err) { + return Promise.reject(err); + } } - getBalance() { - return this.nod3.eth.getBalance(this.address, 'latest'); // rskj 1.0.1 returns 500 with blockNumbers - } + async fetch(forceFetch) { + try { + if (this.fetched && !forceFetch) return this.getData(true); + this.fetched = false; + let dbData = this.isZeroAddress ? {} : await this.getFromDb(); + this.setData(dbData); - getCode() { - return this.nod3.eth.getCode(this.address, 'latest'); // rskj 1.0.1 returns 500 with blockNumbers - } + let { blockNumber } = this; - async fetch() { - try { - let balance = await this.getBalance(). - catch(err => { - throw new Error(`Address: error getting balance of ${this.address} ${err}`); - }); - balance = balance || 0; - this.data.balance = balance; - - let code = null; - let dbData = await this.getFromDb(); - this.dbData = dbData; + let storedBlock = this.data.blockNumber || 0; + if (blockNumber > storedBlock) { + let balance = await this.getBalance('latest'); + this.setData({ balance, blockNumber }); + } - if (dbData) { - if (dbData.code) { - code = dbData.code; - this.codeIsSaved = true; + let code = await this.getCode(); + // TODO suicide + if (code) { + // get contract info + let deployedCode = dbData ? dbData[_types.fields.DEPLOYED_CODE] : undefined; + if (!deployedCode) { + let deployData = await this.getDeploymentData(); + + if (!deployData) throw new Error('Deployment data is missing'); + deployedCode = deployData.deployedCode; + let createdByTx = deployData.tx; + // this.tx = createdByTx + let data = {}; + data[_types.fields.CREATED_BY_TX] = createdByTx; + data[_types.fields.DEPLOYED_CODE] = deployedCode; + this.setData(data); } - // Update lastBlockMined to highest block number - this.setData(_types.fields.LAST_BLOCK_MINED, dbData[_types.fields.LAST_BLOCK_MINED]); + this.makeContract(deployedCode, dbData); + let contractData = await this.contract.fetch(); + this.setData(contractData); } - - if (undefined === code || code === null) { - code = await this.getCode(); + this.fetched = true; + return this.getData(true); + } catch (err) { + return Promise.reject(err); + } + } + async getDeploymentData() { + try { + let { address, tx } = this; + let deployedCode = getDeployedCode(tx, address); + if (!deployedCode) { + ({ tx, deployedCode } = await this.searchDeploymentData()); } - this.data.code = code; - const { nativeContracts } = this; - if (nativeContracts) { - const isNative = this.nativeContracts.isNativeContract(this.address); - if (isNative) { - this.data.isNative = true; - this.data.name = this.nativeContracts.getNativeContractName(this.address); - this.data.type = _types.addrTypes.CONTRACT; - } + if (tx && deployedCode) return { tx, deployedCode }; + } catch (err) { + return Promise.reject(err); + } + } + async searchDeploymentData() { + try { + let { bcSearch, address, blockNumber } = this; + if (blockNumber === 'latest') blockNumber = undefined; + let dBlockNumber = await bcSearch.deploymentBlock(address, blockNumber); + if (!dBlockNumber) throw new Error('Missing deployment block'); + let data = await bcSearch.deploymentTx(address, { blockNumber: dBlockNumber }); + if (!data) throw new Error(`Missing deployment data for ${address}`); + if (!data.tx && !data.internalTx) throw new Error(`Invalid deployment data for ${address}`); + let tx; + if (data.tx) { + tx = (0, _Tx.createTxObject)(data.tx, data); + } else { + let { timestamp } = data; + let { initConfig } = this; + let itx = new _InternalTx.InternalTx(Object.assign({ timestamp }, data.internalTx), { initConfig }); + tx = itx.getData(); } - return this.getData(); + return { tx, deployedCode: getDeployedCode(tx, address) }; } catch (err) { return Promise.reject(err); } } - getFromDb() { - return this.db.findOne({ address: this.address }); + async getFromDb() { + try { + let { dbData, collection, address } = this; + if (dbData) return dbData; + if (!collection) return; + dbData = await collection.findOne({ address }); + this.dbData = dbData; + return dbData; + } catch (err) { + return Promise.reject(err); + } } + getData(serialize) { let data = Object.assign(this.data); - if (this.codeIsSaved) delete data.code; + // if (this.codeIsSaved) delete data.code return serialize ? this.serialize(data) : data; } async save() { + let { address } = this; try { - const data = this.getData(true); - let res = await this.update(data); - return res; + await this.fetch(); + let data = this.getData(true); + let { collection, dbData } = this; + // Optimization + for (let p in dbData) { + if (data[p] === dbData[p]) delete data[p]; + } + if (Object.keys(data).length < 1) return; + data.address = address; + let result = await saveAddressToDb(data, collection); + return result; } catch (err) { + this.log.error(`Error updating address ${address}`); return Promise.reject(err); } } - async updateTxBalance() { - try { - let txBalance = await this.getBalanceFromTxs(); - if (txBalance) this.setData('txBalance', txBalance); - return txBalance; - } catch (err) { - return Promise.reject(err); + + isContract() { + let { code, type } = this.getData(); + let { isNative, address } = this; + if (undefined === code && !isNative && !(0, _rskUtils.isZeroAddress)(address)) { + throw new Error(`Run getCode first ${address}`); } + return type === _types.addrTypes.CONTRACT; } - resetTxBalance() { - this.setData('txBalance', '0x00'); + + makeContract(deployedCode, dbData) { + let { address, nod3, initConfig, collections, block } = this; + this.contract = new _Contract.default(address, deployedCode, { dbData, nod3, initConfig, collections, block }); + }}exports.Address = Address; + + +function getDeployedCode(tx, address) { + if (!tx) return; + let contractAddress, code; + // normal tx + if (tx.receipt) { + contractAddress = tx.receipt.contractAddress; + code = tx.input; } - update(data) { - let address = data.address || this.address; - return this.db.updateOne({ address }, { $set: data }, { upsert: true }); + // internal tx + if (tx.type && tx.type === 'create') { + contractAddress = tx.result.address; + code = tx.action.init; } + if (contractAddress === address) return code; +} - async getBalanceFromTxs() { - let address = this.address; - try { - let balance = await this.TxsBalance.getBalanceFromTx(address); - if (balance) return this.serialize(balance); - } catch (err) { - return Promise.reject(err); - } - }}exports.Address = Address;var _default = +/** + * Address data proxy + */ +function createAddressData({ address, isNative, name }) { + const type = isNative ? _types.addrTypes.CONTRACT : _types.addrTypes.ADDRESS; + const dataHandler = { + set: function (data, prop, val) { + let protectedProperties = ['address', 'type', 'isNative', '_id']; + if (protectedProperties.includes(prop)) return true; + switch (prop) { + case 'code': + if ((0, _utils.isNullData)(val)) val = null; + if (val) { + data.type = _types.addrTypes.CONTRACT; + } + // Fix to support suicide + data.code = val; + break; + case _types.fields.LAST_BLOCK_MINED: + const lastBlock = data[_types.fields.LAST_BLOCK_MINED] || {}; + let number = lastBlock.number || -1; + if (val && val.miner === data.address && val.number > number) { + data[prop] = Object.assign({}, val); + } + break; + + default: + data[prop] = val; + break;} + + return true; + } }; + + return new Proxy({ address, type, name, isNative }, dataHandler); +} + +async function saveAddressToDb(data, collection) { + try { + let { address } = data; + if (!(0, _utils.isAddress)(address)) throw new Error(`Invalid address ${address}`); + let { result } = await collection.updateOne({ address }, { $set: data }, { upsert: true }); + return result; + } catch (err) { + return Promise.reject(err); + } +}var _default = Address;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/Addresses.js b/dist/services/classes/Addresses.js new file mode 100644 index 00000000..b9b537cb --- /dev/null +++ b/dist/services/classes/Addresses.js @@ -0,0 +1,49 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Addresses = void 0;var _Address = _interopRequireDefault(require("./Address")); +var _utils = require("../../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +class Addresses { + constructor({ nod3, initConfig, collections }) { + this.collections = collections; + this.nod3 = nod3; + this.initConfig = initConfig; + this.addresses = {}; + } + add(address, options = {}) { + if (!(0, _utils.isAddress)(address)) throw new Error(`Invalid address ${address}`); + if (!this.addresses[address]) { + options = options || {}; + let { nod3, initConfig, collections } = this; + options = Object.assign(options, { nod3, initConfig, collections }); + this.addresses[address] = new _Address.default(address, options); + } + return this.addresses[address]; + } + + list() { + return Object.values(this.addresses); + } + + async fetch(forceFetch) { + try { + let addresses = this.list(); + for (let address of addresses) { + await address.fetch(forceFetch); + } + return addresses.map(a => a.getData()); + } catch (err) { + return Promise.reject(err); + } + } + async save() { + try { + await this.fetch(); + let addresses = this.list(); + let result = await Promise.all([...addresses.map(a => a.save())]); + return result; + } catch (err) { + return Promise.reject(err); + } + }}exports.Addresses = Addresses;var _default = + + +Addresses;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/BcThing.js b/dist/services/classes/BcThing.js index 83110509..a5647b2a 100644 --- a/dist/services/classes/BcThing.js +++ b/dist/services/classes/BcThing.js @@ -2,29 +2,46 @@ var _NativeContracts = _interopRequireDefault(require("../../lib/NativeContracts"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class BcThing { - constructor({ nod3, initConfig, collections } = {}) { + constructor({ nod3, initConfig, collections, log } = {}) { if (!initConfig) throw new Error('missing init config'); this.initConfig = initConfig; - this.nod3 = nod3; this.collections = collections; + this.nod3 = nod3; this.nativeContracts = (0, _NativeContracts.default)(initConfig); this.data = {}; + this.log = log || console; } + + setData(data) { + if (!data) return; + if (typeof data !== 'object') throw new Error('Data must be an object'); + for (let p in data) { + this.data[p] = data[p]; + } + } + getData(serialize = false) { return serialize ? this.serialize(this.data) : this.data; } + serialize(obj) { return (0, _utils.serialize)(obj); } + isAddress(address) { return (0, _utils.isAddress)(address); } + fetch() { return _methodNotImplemented('fetch'); } + save() { return _methodNotImplemented('save'); } + isTxOrBlockHash(str) { + return (0, _utils.isTxOrBlockHash)(str); + } isBlockHash(hashOrNumber) { return (0, _utils.isBlockHash)(hashOrNumber); }}exports.BcThing = BcThing; diff --git a/dist/services/classes/Block.js b/dist/services/classes/Block.js index c72012cb..bbae76cc 100644 --- a/dist/services/classes/Block.js +++ b/dist/services/classes/Block.js @@ -1,58 +1,29 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.deleteBlockDataFromDb = exports.getBlockFromDb = exports.missmatchBlockTransactions = exports.Block = void 0;var _BcThing = require("./BcThing"); -var _Tx = _interopRequireDefault(require("./Tx")); -var _Address = _interopRequireDefault(require("./Address")); -var _Contract = _interopRequireDefault(require("./Contract")); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.deleteBlockDataFromDb = exports.getBlockFromDb = exports.Block = void 0;var _BcThing = require("./BcThing"); +var _BlockSummary = _interopRequireDefault(require("./BlockSummary")); var _utils = require("../../lib/utils"); -var _ids = require("../../lib/ids");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +var _Address = require("./Address");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class Block extends _BcThing.BcThing { constructor(hashOrNumber, { nod3, collections, log, initConfig }) { - super({ nod3, collections, initConfig }); + super({ nod3, collections, initConfig, log }); this.Blocks = this.collections.Blocks; this.fetched = false; this.log = log || console; this.hashOrNumber = hashOrNumber; - this.addresses = {}; - this.contracts = {}; - this.tokenAddresses = {}; + this.summary = new _BlockSummary.default(hashOrNumber, { nod3, initConfig, collections, log }); this.data = { - block: null, - txs: [], - addresses: [], - contracts: [], - tokenAddresses: [], - events: [] }; + block: null }; } async fetch(forceFetch) { - if (this.fetched && !forceFetch) { - return Promise.resolve(this.getData()); - } - - let connected = await this.nod3.isConnected(); - if (!connected) { - return Promise.reject(new Error('nod3 is not connected')); - } try { - let blockData = await this.getBlock(this.hashOrNumber, true); - const { transactions, timestamp } = blockData; - blockData.transactions = transactions.map(tx => tx.hash); - this.data.block = blockData; - this.addAddress(blockData.miner, blockData); - const { nod3, initConfig } = this; - let txs = transactions.map(txData => new _Tx.default(txData.hash, timestamp, { txData, nod3, initConfig })); - let txsData = await this.fetchItems(txs); - this.data.txs = txsData.map(d => d.tx); - this.data.txs.forEach(tx => this.addTxAddresses(tx)); - - this.data.events = [].concat.apply([], txsData.map(d => d.events)); - - this.data.contracts = await this.fetchItems(this.contracts); - this.addEventsAddresses(); - this.mergeContractsAddresses(); - this.data.addresses = await this.fetchItems(this.addresses); - this.data.tokenAddresses = await this.fetchContractsAddresses(); + if (this.fetched && !forceFetch) { + return this.getData(); + } + let { summary } = this; + let data = await summary.fetch(); + this.setData(data); this.fetched = true; return this.getData(); } catch (err) { @@ -61,108 +32,89 @@ class Block extends _BcThing.BcThing { } } - async getBlock(number, txArr = false) { - try { - let blockData = await this.nod3.eth.getBlock(number, txArr); - if (blockData) blockData._received = Date.now(); - return blockData; - } catch (err) { - return Promise.reject(err); - } - } - - addTxAddresses(tx) { - let { receipt, to, from } = tx; - this.addAddress(receipt.contractAddress); - this.addContract(tx); - this.addAddress(to); - this.addAddress(from); - } - - async save() { - let db = this.collections; - const result = {}; - let data = await this.fetch(); + async save(overwrite) { + let result = {}; try { - if (!data) throw new Error(`Fetch returns empty data for block #${this.hashOrNumber}`); - data = this.serialize(data); - let { block, txs, events, tokenAddresses } = data; - - // check transactions - let txsErr = missmatchBlockTransactions(block, txs); - if (txsErr.length) { - this.log.trace(`Block: ${block.number} - ${block.hash} Missing transactions: ${JSON.stringify(txsErr)} `); - throw new Error(`Block: ${block.number} - ${block.hash} Missing transactions `); + let { collections, summary, hashOrNumber } = this; + // Skip saved blocks + if ((0, _utils.isBlockHash)(hashOrNumber) && !overwrite) { + let hash = hashOrNumber; + let exists = await collections.Blocks.findOne({ hash }); + if (exists) throw new Error(`Block ${hash} skipped`); } - - // clean db - block = await this.removeOldBlockData(block, txs); + await this.fetch(); + let data = this.getData(true); + if (!data) throw new Error(`Fetch returns empty data for block #${this.hashOrNumber}`); // save block summary - await this.saveBlockSummary(data); + await summary.save(); + + let { block, transactions, internalTransactions, events, tokenAddresses, addresses } = data; + // clean db + block = await this.removeOldBlockData(block, transactions); // insert block result.block = await this.insertBlock(block); // insert txs - await Promise.all([...txs.map(tx => db.Txs.insertOne(tx))]). + await Promise.all([...transactions.map(tx => collections.Txs.insertOne(tx))]). then(res => {result.txs = res;}); // remove pending txs - await Promise.all([...txs.map(tx => db.PendingTxs.deleteOne({ hash: tx.hash }))]); + await Promise.all([...transactions.map(tx => collections.PendingTxs.deleteOne({ hash: tx.hash }))]); + + // insert internal transactions + await Promise.all([...internalTransactions.map(itx => collections.InternalTransactions.insertOne(itx))]). + then(res => {result.internalTxs = res;}); // insert addresses - await Promise.all( - Object.values(this.addresses).map(a => { - a.resetTxBalance(); // reset to force update in next query - return a.save(); - })). - then(res => {result.addresses = res;}); + result.addresses = await Promise.all([...addresses.map(a => (0, _Address.saveAddressToDb)(a, collections.Addrs))]); // insert events - await Promise.all( - events.map(e => db.Events.updateOne( - { eventId: e.eventId }, - { $set: e }, - { upsert: true }))). - then(res => {result.events = res;}); + result.events = await this.insertEvents(events); // insert tokenAddresses - await Promise.all( - tokenAddresses.map(ta => db.TokensAddrs.updateOne( - { address: ta.address, contract: ta.contract }, { $set: ta }, { upsert: true }))). - then(res => {result.tokenAddresses = res;}); + result.tokenAddresses = await this.insertTokenAddresses(tokenAddresses); return { result, data }; } catch (err) { // remove blockData if block was inserted if (result.block) { - this.deleteBlockDataFromDb(data.block.hash, data.block.number); + let data = this.getData(); + await this.deleteBlockDataFromDb(data.block.hash, data.block.number); } this.log.trace(`Block save error [${this.hashOrNumber}]`, err); return Promise.reject(err); } } - - async saveBlockSummary(data) { + async insertEvents(events) { try { - const { hash, number, timestamp } = data.block; - const collection = this.collections.BlocksSummary; - if (!hash) throw new Error(`Missing block hash`); - const old = await collection.findOne({ hash }, { _id: 1 }); - const _id = old ? old._id : (0, _ids.getSummaryId)(data.block); - const summary = { _id, hash, number, timestamp, data }; - const res = await collection.updateOne({ _id }, { $set: summary }, { upsert: true }); - return res; + let { Events } = this.collections; + let result = await Promise.all([...events.map(e => Events.updateOne( + { eventId: e.eventId }, + { $set: e }, + { upsert: true }))]); + return result; } catch (err) { - this.log.error(`Error saving block summary`); - this.log.debug(err); - return Promise.resolve(); + this.log.error('Error inserting events'); + return Promise.reject(err); + } + } + async insertTokenAddresses(data) { + try { + let { TokensAddrs } = this.collections; + let result = await Promise.all([...data.map(ta => TokensAddrs.updateOne( + { address: ta.address, contract: ta.contract }, { $set: ta }, { upsert: true }))]); + return result; + } catch (err) { + this.log.error('Error inserting token addresses'); + return Promise.reject(err); } } + async getOldBlockData(block) { try { - if (!block || !block.hash) throw new Error('Block data is empty'); + if (!(0, _utils.isBlockObject)(block)) throw new Error('Block data is empty'); let exists = await this.searchBlock(block); if (exists.length > 1) { throw new Error(`ERROR block ${block.number}-${block.hash} has ${exists.length} duplicates`); @@ -179,10 +131,13 @@ class Block extends _BcThing.BcThing { } } - async removeOldBlockData(block, txs) { + async removeOldBlockData(block, txs, oldBlock) { try { - let oldBlock = await this.getOldBlockData(block); - if (oldBlock) block = this.moveOldBlock(block, oldBlock); + if (!(0, _utils.isBlockObject)(oldBlock)) oldBlock = await this.getOldBlockData(block); + if (oldBlock) { + let { hash, number } = oldBlock.block; + await this.deleteBlockDataFromDb(hash, number); + } await this.removeBlocksByTxs(txs); return block; } catch (err) { @@ -190,25 +145,6 @@ class Block extends _BcThing.BcThing { } } - async moveOldBlock(newBlock, oldBlockData) { - try { - if (!oldBlockData || !newBlock) { - this.log.trace(`Replace block missing arguments`, oldBlockData, newBlock); - throw new Error(`Replace block error, missing arguments`); - } - let { block, txs, events } = oldBlockData; - block._replacedBy = newBlock.hash; - block._events = events; - block.transactions = txs; - await this.saveOrphanBlock(block).catch(err => this.log.debug(err)); - await this.deleteBlockDataFromDb(block.hash, block.number); - newBlock._replacedBlockHash = block.hash; - return newBlock; - } catch (err) { - return Promise.reject(err); - } - } - deleteBlockDataFromDb(blockHash, blockNumber) { return deleteBlockDataFromDb(blockHash, blockNumber, this.collections); } @@ -234,9 +170,7 @@ class Block extends _BcThing.BcThing { } } - searchBlock(block) { - let hash = block.hash; - let number = block.number; + searchBlock({ hash, number }) { return this.collections.Blocks.find({ $or: [{ hash }, { number }] }).toArray(); } @@ -281,70 +215,6 @@ class Block extends _BcThing.BcThing { return this.collections.Txs.findOne({ hash }); } - saveOrphanBlock(blockData) { - delete blockData._id; - blockData._updated = Date.now(); - return this.collections.OrphanBlocks.updateOne({ hash: blockData.hash }, { $set: blockData }, { upsert: true }); - } - - addAddress(address, block) { - if (!this.isAddress(address) || this.addresses[address]) return; - let { nod3, collections, initConfig } = this; - const Addr = new _Address.default(address, { initConfig, collections, nod3, block }); - this.addresses[address] = Addr; - } - - addContract(tx) { - let address = tx.receipt.contractAddress; - if (address) { - let data = { tx, code: () => this.getAddressCode(address) }; - return this.getContract(address, data); - } - } - - getContract(address, data) { - let contract = this.contracts[address]; - if (contract) return contract;else - return this.newContract(address, data); - } - - newContract(address, data) { - let { nod3, initConfig } = this; - let { block } = this.data; - let contract = new _Contract.default(address, data, { nod3, initConfig, block }); - this.contracts[address] = contract; - return contract; - } - - getAddressCode(address) { - return this.addresses[address].code; - } - - addEventsAddresses() { - this.data.events.forEach(event => { - if (event && event.args) { - let address = event.address; - this.addAddress(address); - let abi = event.abi; - let contract = this.getContract(address); - if (abi && abi.inputs) { - let eventAddresses = abi.inputs. - filter(i => i.type === 'address'). - map((field, i) => { - let address = event.args[i]; - if (this.isAddress(address)) { - return address; - } - }); - eventAddresses.forEach(a => { - this.addAddress(a); - contract.addAddress(a); - }); - } - } - }); - } - // adds contract data to addresses mergeContractsAddresses() { let contracts = this.data.contracts; @@ -366,50 +236,46 @@ class Block extends _BcThing.BcThing { if (addData.length) data = data.concat(addData); } return data; - } - fetchItems(items) { - return Promise.all(Object.values(items).map(i => i.fetch())); }}exports.Block = Block; -const missmatchBlockTransactions = (block, transactions) => { - let diff = (0, _utils.arrayDifference)(block.transactions, transactions.map(tx => tx.hash)); - if (diff.length) return diff; - let blockHash = block.hash; - return transactions.filter(tx => tx.blockHash !== blockHash || tx.receipt.blockHash !== blockHash); -};exports.missmatchBlockTransactions = missmatchBlockTransactions; - const getBlockFromDb = async (blockHashOrNumber, collection) => { let query = (0, _utils.blockQuery)(blockHashOrNumber); if (query) return collection.findOne(query); return Promise.reject(new Error(`"${blockHashOrNumber}": is not block hash or number`)); };exports.getBlockFromDb = getBlockFromDb; -const deleteBlockDataFromDb = async (blockHash, blockNumber, db) => { +const deleteBlockDataFromDb = async (blockHash, blockNumber, collections) => { try { blockNumber = parseInt(blockNumber); - if (blockNumber < 1) throw new Error(`The blockNumber is wrong`); - if (!blockHash) throw new Error(`Empty block hash`); + if (blockNumber < 1) throw new Error(`The blockNumber: ${blockNumber} is wrong`); + if (!(0, _utils.isBlockHash)(blockHash)) throw new Error(`Empty block hash: ${blockHash}`); let hash = blockHash; let result = {}; - let query = { $or: [{ blockHash }, { blockNumber }] }; + const query = { $or: [{ blockHash }, { blockNumber }] }; - result.block = await db.Blocks.deleteMany({ $or: [{ hash }, { number: blockNumber }] }); + result.block = await collections.Blocks.deleteMany({ $or: [{ hash }, { number: blockNumber }] }); - let txs = (await db.Txs.find(query).toArray()) || []; + let txs = (await collections.Txs.find(query).toArray()) || []; let txsHashes = txs.map(tx => tx.hash); // remove txs - result.txs = await db.Txs.deleteMany({ hash: { $in: txsHashes } }); + result.txs = await collections.Txs.deleteMany({ hash: { $in: txsHashes } }); + + // remove internal txs + result.itxs = await collections.InternalTransactions.deleteMany({ transactionHash: { $in: txsHashes } }); // remove events by block - result.events = await db.Events.deleteMany(query); + result.events = await collections.Events.deleteMany(query); // remove events by txs - result.eventsByTxs = await db.Events.deleteMany({ txHash: { $in: txsHashes } }); + result.eventsByTxs = await collections.Events.deleteMany({ txHash: { $in: txsHashes } }); // remove contracts by blockHash - result.addresses = await db.Addrs.deleteMany({ 'createdByTx.blockHash': blockHash }); + result.addresses = await collections.Addrs.deleteMany({ 'createdByTx.blockHash': blockHash }); + + // remove balances + result.balances = await collections.Balances.deleteMany(query); return result; } catch (err) { diff --git a/dist/services/classes/BlockAddresses.js b/dist/services/classes/BlockAddresses.js new file mode 100644 index 00000000..84b093bf --- /dev/null +++ b/dist/services/classes/BlockAddresses.js @@ -0,0 +1,17 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.BlockAddresses = void 0;var _Addresses = require("./Addresses"); +var _utils = require("../../lib/utils"); + +class BlockAddresses extends _Addresses.Addresses { + constructor(blockData, { nod3, initConfig, collections }) { + if (!(0, _utils.isBlockObject)(blockData)) throw new Error('Invalid blockData'); + super({ nod3, initConfig, collections }); + this.block = blockData; + } + add(address, options) { + options = options || {}; + options.block = this.block; + return super.add(address, options); + }}exports.BlockAddresses = BlockAddresses;var _default = + + +_Addresses.Addresses;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/BlockBalances.js b/dist/services/classes/BlockBalances.js new file mode 100644 index 00000000..9551af95 --- /dev/null +++ b/dist/services/classes/BlockBalances.js @@ -0,0 +1,59 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.BlockBalances = void 0;var _BcThing = require("./BcThing"); +var _Address = require("./Address"); +var _utils = require("../../lib/utils"); + +class BlockBalances extends _BcThing.BcThing { + constructor({ block, addresses }, { nod3, collections, log, initConfig }) { + let { number, hash, timestamp } = block; + if (!Array.isArray(addresses)) throw new Error('addresses must be an array'); + if (!(0, _utils.isBlockHash)(hash)) throw new Error(`Invalid blockHash: ${hash}`); + if (!(0, _utils.isValidBlockNumber)(number)) throw new Error(`Invalid block number: ${number}`); + if (!timestamp) throw new Error('invalid block timestamp'); + super({ nod3, collections, initConfig, log }); + this.blockHash = hash; + this.blockNumber = number; + this.timestamp = timestamp; + addresses = [...new Set(addresses)]; + this.addresses = addresses.map(address => new _Address.Address(address, { nod3, initConfig, collections, block: number })); + this.balances = undefined; + this.collection = this.collections.Balances; + } + async fetch() { + try { + if (this.balances) return this.balances; + let { addresses, blockHash, blockNumber, timestamp } = this; + let balances = await Promise.all(addresses.map(async Addr => { + let { address } = Addr; + let balance = await Addr.getBalance(blockNumber); + balance = parseInt(balance) ? balance : 0; + let _created = Date.now(); + return { address, balance, blockHash, blockNumber, timestamp, _created }; + })); + this.balances = balances; + return this.balances; + } catch (err) { + return Promise.reject(err); + } + } + deleteOldBalances() { + const { blockHash, blockNumber, collection } = this; + return Promise.all([collection.deleteMany({ blockHash }), collection.deleteMany({ blockNumber })]); + } + async save() { + try { + let balances = await this.fetch(); + if (!balances.length) { + let { blockHash, blockNumber } = this; + this.log.warn(`No balances for ${blockHash} / ${blockNumber}`); + return; + } + await this.deleteOldBalances(); + let result = await this.collection.insertMany(balances); + return result; + } catch (err) { + return Promise.reject(err); + } + }}exports.BlockBalances = BlockBalances;var _default = + + +BlockBalances;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/BlockSummary.js b/dist/services/classes/BlockSummary.js new file mode 100644 index 00000000..93752462 --- /dev/null +++ b/dist/services/classes/BlockSummary.js @@ -0,0 +1,177 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.saveBlockSummary = saveBlockSummary;exports.getBlock = getBlock;exports.getBlockSummaryFromDb = getBlockSummaryFromDb;exports.default = exports.mismatchBlockTransactions = exports.BlockSummary = exports.BlocksSummaryCollection = void 0;var _BcThing = require("./BcThing"); +var _Tx = _interopRequireDefault(require("./Tx")); +var _BlockTrace = _interopRequireDefault(require("./BlockTrace")); +var _BlockAddresses = require("./BlockAddresses"); +var _ids = require("../../lib/ids"); +var _utils = require("../../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const BlocksSummaryCollection = 'BlocksSummary';exports.BlocksSummaryCollection = BlocksSummaryCollection; + +class BlockSummary extends _BcThing.BcThing { + constructor(hashOrNumber, { nod3, collections, log, initConfig }) { + super({ nod3, collections, initConfig, log }); + this.hashOrNumber = hashOrNumber; + this.collection = collections ? collections[BlocksSummaryCollection] : undefined; + this.Addresses = undefined; + this.data = { + block: null, + transactions: [], + internalTransactions: [], + addresses: [], + tokenAddresses: [], + events: [] }; + + } + async fetch(forceFetch, skipDb) { + try { + let { fetched, collections } = this; + if (fetched && !forceFetch) { + return this.getData(); + } + let blockData = await this.getBlockData(); + const { hash } = blockData; + if (!skipDb && collections) { + let dbData = await getBlockSummaryFromDb(hash, collections); + if (dbData && dbData.data) { + this.setData(dbData.data); + this.fetched = true; + return this.getData(); + } + } + let Addresses = await this.getAddresses(); + let Txs = await this.createTxs(blockData, Addresses); + let txsData = await this.fetchItems(Txs); + let transactions = txsData.map(d => d.tx); + this.setData({ transactions }); + this.checkTransactions(); + let events = [].concat(...txsData.map(d => d.events)); + let internalTransactions = [].concat(...txsData.map(d => d.internalTransactions)); + let tokenAddresses = [].concat(...txsData.map(d => d.tokenAddresses)); + let addresses = await Addresses.fetch(); + this.setData({ internalTransactions, events, addresses, tokenAddresses }); + this.fetched = true; + return this.getData(); + } catch (err) { + return Promise.reject(err); + } + } + async createTxs(blockData, addresses) { + try { + let { nod3, initConfig, collections, log } = this; + let { timestamp, transactions, hash } = blockData; + let bTrace = new _BlockTrace.default(hash, { nod3, collections, log, initConfig }); + let blockTrace = await bTrace.fetch(); + let txs = await nod3.batchRequest(transactions.map(hash => ['eth.getTransactionByHash', hash])); + let receipts = await nod3.batchRequest(transactions.map(hash => ['eth.getTransactionReceipt', hash])); + return transactions.map(hash => { + let txData = txs.find(tx => tx.hash === hash); + let receipt = receipts.find(re => re.transactionHash === hash); + return new _Tx.default(hash, timestamp, { txData, receipt, blockTrace, blockData, addresses, nod3, initConfig, collections }); + }); + } catch (err) { + return Promise.reject(err); + } + } + + async getBlockData() { + try { + let { block } = this.getData(); + if (block) return block; + let { nod3, hashOrNumber } = this; + block = await getBlock(hashOrNumber, false, nod3); + if (block) { + this.setData({ block }); + return block; + } + } catch (err) { + return Promise.reject(err); + } + } + + checkTransactions() { + let { block, transactions } = this.getData(); + let txsErr = mismatchBlockTransactions(block, transactions); + if (txsErr.length) { + this.log.trace(`Block: ${block.number} - ${block.hash} Missing transactions: ${JSON.stringify(txsErr)} `); + throw new Error(`Block: ${block.number} - ${block.hash} Missing transactions `); + } + } + + fetchItems(items) { + return Promise.all(Object.values(items).map(i => i.fetch())); + } + async getAddresses() { + try { + let { Addresses, nod3, initConfig, collections } = this; + if (!Addresses) { + let blockData = await this.getBlockData(); + Addresses = new _BlockAddresses.BlockAddresses(blockData, { nod3, initConfig, collections }); + let { miner } = blockData; + Addresses.add(miner, { block: blockData }); + this.Addresses = Addresses; + } + return Addresses; + } catch (err) { + return Promise.reject(err); + } + } + + async save() { + try { + let data = await this.fetch(); + let { log, collections } = this; + let res = await saveBlockSummary(data, collections, log); + return res; + } catch (err) { + this.log.error(`Error saving block summary`); + this.log.debug(err); + return Promise.resolve(); + } + }}exports.BlockSummary = BlockSummary; + + +const mismatchBlockTransactions = (block, transactions) => { + let diff = (0, _utils.arrayDifference)(block.transactions, transactions.map(tx => tx.hash)); + if (diff.length) return diff; + let blockHash = block.hash; + return transactions.filter(tx => tx.blockHash !== blockHash || tx.receipt.blockHash !== blockHash); +};exports.mismatchBlockTransactions = mismatchBlockTransactions; + +async function saveBlockSummary(data, collections, log) { + log = log || console; + const { hash, number, timestamp } = data.block; + try { + const collection = collections[BlocksSummaryCollection]; + const old = await collection.findOne({ hash }, { _id: 1 }); + const _id = old ? old._id : (0, _ids.getSummaryId)(data.block); + const summary = { _id, hash, number, timestamp, data }; + let result = await collection.updateOne({ _id }, { $set: summary }, { upsert: true }); + return result; + } catch (err) { + log.error(`Error saving Block Summary ${hash}`); + return Promise.reject(err); + } +} + +async function getBlock(hashOrNumber, txArr = false, nod3) { + try { + let blockData = await nod3.eth.getBlock(hashOrNumber, txArr); + if (blockData) blockData._received = Date.now(); + return blockData; + } catch (err) { + return Promise.reject(err); + } +} + +async function getBlockSummaryFromDb(hash, collections) { + try { + const collection = collections[BlocksSummaryCollection]; + if (!(0, _utils.isBlockHash)(hash)) throw new Error(`Invalid blockHash ${hash}`); + let data = await collection.findOne({ hash }); + return data; + } catch (err) { + return Promise.reject(err); + } +}var _default = + +BlockSummary;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/BlockTrace.js b/dist/services/classes/BlockTrace.js new file mode 100644 index 00000000..c5fbdc7c --- /dev/null +++ b/dist/services/classes/BlockTrace.js @@ -0,0 +1,40 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.BlockTrace = void 0;var _BcThing = require("./BcThing"); +var _utils = require("../../lib/utils"); + +class BlockTrace extends _BcThing.BcThing { + constructor(hash, { nod3, collections, log, initConfig }) { + if (!(0, _utils.isBlockHash)(hash)) throw new Error(`Invalid blockHash ${hash}`); + super({ nod3, collections, log, initConfig }); + this.hash = hash; + this.collection = collections.BlocksTraces; + } + async fetch() { + try { + let { hash } = this; + let data = await this.getFromDb(); + if (!data) { + data = await this.nod3.trace.block(hash); + await this.save(data); + } + return data; + } catch (err) { + return Promise.reject(err); + } + } + async getFromDb() { + try { + let { hash, collection } = this; + let res = await collection.findOne({ hash }); + return res ? res.data : null; + } catch (err) { + return Promise.reject(err); + } + } + save(data) { + if (!data) return this.fetch(); + let { hash } = this; + return this.collection.insertOne({ hash, data }); + }}exports.BlockTrace = BlockTrace;var _default = + + +BlockTrace;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/CheckBlocks.js b/dist/services/classes/CheckBlocks.js index 5fa5ed7b..86f468d8 100644 --- a/dist/services/classes/CheckBlocks.js +++ b/dist/services/classes/CheckBlocks.js @@ -1,6 +1,7 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.checkBlocksTransactions = exports.checkBlocksCongruence = exports.CheckBlocks = void 0;var _BlocksBase = require("../../lib/BlocksBase"); var _Block = require("./Block"); var _RequestBlocks = require("./RequestBlocks"); +var _utils = require("../../lib/utils"); class CheckBlocks extends _BlocksBase.BlocksBase { constructor(db, options) { @@ -11,21 +12,29 @@ class CheckBlocks extends _BlocksBase.BlocksBase { this.tipSize = options.bcTipSize || 12; } - async start() { + async saveTipBlocks() { + await this.getBlock(0).catch(err => this.log.trace(err)); + let lastBlock = await this.getLastBlock().catch(err => this.log.trace(err)); + await this.getBlock(lastBlock.hash).catch(err => this.log.trace(err)); + } + async start(emitter) { try { - await Promise.all([this.getBlock(0), this.getLastBlock()]); + if (emitter) this.setEmitter(emitter); + if (!this.emit) throw new Error('The emitter should be defined'); + await this.saveTipBlocks(); this.log.info('Checking database'); - let res = await this.checkDb(true); + let res = await this.checkDb({ checkOrphans: true, skipTxs: true }); this.log.info('Getting missing blocks'); + if (!res) this.log.info('There are no missing blocks');else this.log.trace(res); - await this.getBlocks(res); + return this.getBlocks(res); } catch (err) { this.log.error(`[CheckBlocks.start] ${err}`); return Promise.reject(err); } } - async checkDb(checkOrphans, lastBlock, firstBlock) { + async checkDb({ checkOrphans, lastBlock, firstBlock, skipTxs }) { if (!lastBlock || !lastBlock.number) lastBlock = await this.getHighDbBlock(); if (!lastBlock) return; lastBlock = lastBlock.number; @@ -35,9 +44,11 @@ class CheckBlocks extends _BlocksBase.BlocksBase { if (blocks < lastBlock + 1) { missingSegments = await this.getMissingSegments(); } - - let missingTxs = await this.getMissingTransactions(lastBlock, firstBlock); - await this.deleteMissingTxsBlocks(missingTxs); + let missingTxs; + if (!skipTxs) { + missingTxs = await this.getMissingTransactions(lastBlock, firstBlock); + await this.deleteMissingTxsBlocks(missingTxs); + } let res = { lastBlock, blocks, missingSegments, missingTxs }; if (checkOrphans) { @@ -92,8 +103,8 @@ class CheckBlocks extends _BlocksBase.BlocksBase { } async getBlock(hashOrNumber) { - const { nod3, collections, log, nativeContracts } = this; - return (0, _RequestBlocks.getBlock)(hashOrNumber, { nod3, collections, log, nativeContracts }); + const { nod3, collections, log, initConfig } = this; + return (0, _RequestBlocks.getBlock)(hashOrNumber, { nod3, collections, log, initConfig }); } getBlockFromDb(hashOrNumber) { @@ -129,9 +140,13 @@ class CheckBlocks extends _BlocksBase.BlocksBase { }); if (values.length) { - this.log.warn(`Getting ${values.length} bad blocks`); - this.log.trace(values); - process.send({ action: this.actions.BULK_BLOCKS_REQUEST, args: [values] }); + let { log, emit, events } = this; + log.warn(`Getting ${values.length} bad blocks`); + log.trace(values); + let chunks = (0, _utils.chunkArray)(values, 100); + for (let blocks of chunks) { + emit(events.REQUEST_BLOCKS, { blocks }); + } } } catch (err) { this.log.error(err); @@ -169,7 +184,8 @@ class CheckBlocks extends _BlocksBase.BlocksBase { let lastBlock = this.tipBlock; this.tipCount = 0; this.log.info(`Checking db / LastBlock: ${lastBlock}`); - let res = await this.checkDb(true, lastBlock, lastBlock - this.tipSize * 10); + let firstBlock = lastBlock - this.tipSize * 10; + let res = await this.checkDb({ checkOrphans: true, lastBlock, firstBlock }); this.log.trace(`Check db: ${res}`); return this.getBlocks(res); } diff --git a/dist/services/classes/Contract.js b/dist/services/classes/Contract.js index 8673bedf..6fad8523 100644 --- a/dist/services/classes/Contract.js +++ b/dist/services/classes/Contract.js @@ -5,52 +5,99 @@ var _TokenAddress = _interopRequireDefault(require("./TokenAddress")); var _utils = require("../../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class Contract extends _BcThing.BcThing { - constructor(address, creationData, { nod3, initConfig, block }) { - super({ nod3, initConfig }); + constructor(address, deployedCode, { dbData, abi, nod3, initConfig, collections, block }) { + super({ nod3, initConfig, collections }); if (!this.isAddress(address)) throw new Error(`Contract: invalid address ${address}`); - this.parser = new _rskContractParser.default({ initConfig, nod3 }); this.address = address; - this.creationData = creationData; - const createdByTx = creationData && creationData.tx ? creationData.tx : null; - this.block = block; + this.deployedCode = deployedCode; this.data = { - address, - createdByTx, - addresses: [] }; + address }; - this.contract = this.makeContract(); this.addresses = {}; + this.fetched = false; + this.contract = undefined; + this.abi = abi; + this.parser = undefined; + this.isToken = false; + this.block = block; + if (dbData) this.setData(dbData); } async fetch() { try { + let { deployedCode, fetched } = this; + + if (fetched) return this.getData(); + let contract = await this.getContract(); // new contracts - if (this.creationData) { - let txInputData = this.creationData.tx.input; - let info = await this.parser.getContractInfo(txInputData, this.contract); + if (!this.data.contractInterfaces) { + if (!deployedCode) throw new Error(`Missing deployed code for contract: ${this.address}`); + let info = await this.parser.getContractInfo(deployedCode, contract); let { interfaces, methods } = info; - if (interfaces.length) this.data.contractInterfaces = interfaces; - if (methods) this.data.contractMethods = methods; - if (this.isToken(interfaces)) { - let tokenData = await this.getTokenData(); - if (tokenData) this.data = Object.assign(this.data, tokenData); - } + if (interfaces.length) this.setData({ contractInterfaces: interfaces }); + if (methods) this.setData({ contractMethods: methods }); + } + let { contractInterfaces, tokenData } = this.data; + this.isToken = (0, _utils.hasValue)(contractInterfaces || [], _types.tokensInterfaces); + if (this.isToken && !tokenData) { + let tokenData = await this.getToken(); + if (tokenData) this.setData(tokenData); } - - this.data.addresses = await this.fetchAddresses(); let data = this.getData(); + this.fetched = true; return data; } catch (err) { return Promise.reject(err); } } - makeContract() { - return this.parser.makeContract(this.address); + async getParser() { + try { + let { parser, nod3, initConfig, log } = this; + if (parser) return parser; + let abi = await this.getAbi(); + this.parser = new _rskContractParser.default({ abi, nod3, initConfig, log }); + return this.parser; + } catch (err) { + return Promise.reject(err); + } } - getTokenData() { - return this.parser.getTokenData(this.contract); + async getContract() { + try { + let { address, contract } = this; + if (contract) return contract; + // get abi + let abi = await this.getAbi(); + let parser = await this.getParser(); + this.contract = parser.makeContract(address, abi); + return this.contract; + } catch (err) { + return Promise.reject(err); + } + } + + async getAbi() { + try { + let { address, collections, abi } = this; + if (abi) return abi; + let data = {}; + if (collections) { + data = await collections.VerificationsResults.findOne({ address }); + if (data && data.abi) this.abi = data.abi; + } + return this.abi; + } catch (err) { + return Promise.reject(err); + } + } + + getToken() { + let { contractMethods } = this.data; + let { parser, contract } = this; + let methods = ['name', 'symbol', 'decimals', 'totalSupply']; + methods = methods.filter(m => contractMethods.includes(`${m}()`)); + return parser.getTokenData(contract, { methods }); } addAddress(address) { @@ -67,18 +114,20 @@ class Contract extends _BcThing.BcThing { } call(method, params = []) { - const contract = this.contract; - return this.parser.call(method, contract, params); + let { contract, parser } = this; + if (!contract) throw new Error('Fetch first'); + return parser.call(method, contract, params); } - isToken(interfaces) { - return (0, _utils.hasValue)(interfaces, _types.tokensInterfaces); - } async fetchAddresses() { + if (!this.fetched) await this.fetch(); let data = []; - for (let a in this.addresses) { - let Address = this.addresses[a]; - let addressData = await Address.fetch(); + let { addresses } = this; + if (!this.isToken) return data; + for (let a in addresses) { + let Address = addresses[a]; + await Address.fetch(); + let addressData = Address.getData(true); if (addressData) data.push(addressData); } return data; diff --git a/dist/services/classes/Event.js b/dist/services/classes/Event.js index e67f61b6..c3837bd8 100644 --- a/dist/services/classes/Event.js +++ b/dist/services/classes/Event.js @@ -2,7 +2,7 @@ const formatEvent = (event, tx) => { let { timestamp, receipt } = tx; - let id = (0, _ids.eventId)(event, tx); + let id = (0, _ids.getEventId)(event, tx); event.eventId = id; event.timestamp = timestamp; event.txStatus = receipt.status; diff --git a/dist/services/classes/InternalTx.js b/dist/services/classes/InternalTx.js new file mode 100644 index 00000000..2efa6fd2 --- /dev/null +++ b/dist/services/classes/InternalTx.js @@ -0,0 +1,67 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getInternalTxId = getInternalTxId;exports.filterValueAddresses = filterValueAddresses;exports.default = exports.InternalTx = void 0;var _BcThing = require("./BcThing"); +var _ids = require("../../lib/ids"); + +const REQUIRED_FIELDS = [ +'blockHash', +'blockNumber', +'transactionHash', +'transactionPosition', +'type', +'subtraces', +'traceAddress', +'result', +'action', +'timestamp']; + + +class InternalTx extends _BcThing.BcThing { + constructor(data, { initConfig }) { + super({ initConfig }); + this.setData(data); + } + + checkData(data) { + if (typeof data !== 'object') throw new Error('Data is not an object'); + for (let field of REQUIRED_FIELDS) { + if (!data.hasOwnProperty(field)) throw new Error(`Missing field: ${field}`); + } + return data; + } + + setData(data) { + data = this.checkData(data); + let id = getInternalTxId(data); + if (!id) throw new Error(`Invalid internalTxId: ${id}`); + data.internalTxId = id; + this.data = data; + } + + getAddresses() { + let data = this.getData(); + let { action } = data; + let { isAddress } = this; + return Object.entries(action). + filter(a => { + let [name, value] = a; + return name !== 'balance' && isAddress(value); + }).map(v => v[1]); + }}exports.InternalTx = InternalTx; + + +function getInternalTxId({ blockNumber, transactionPosition: transactionIndex, transactionHash: hash, _index: index }) { + return (0, _ids.generateId)({ blockNumber, transactionIndex, hash, index }); +} + +function filterValueAddresses(internalTransactions) { + const addresses = new Set(); + internalTransactions.forEach(({ action, error }) => { + let { value, from, to } = action; + if (!error && parseInt(value) > 0) { + addresses.add(from); + addresses.add(to); + } + }); + return [...addresses]; +}var _default = + +InternalTx;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/ListenBlocks.js b/dist/services/classes/ListenBlocks.js index b66b3370..a4f79b39 100644 --- a/dist/services/classes/ListenBlocks.js +++ b/dist/services/classes/ListenBlocks.js @@ -1,9 +1,11 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.Blocks = Blocks;exports.default = exports.ListenBlocks = void 0;var _BlocksBase = require("../../lib/BlocksBase"); class ListenBlocks extends _BlocksBase.BlocksBase { - constructor(db, options) { + constructor(db, options, { emit }) { + if (typeof emit !== 'function') throw new Error('Emit must be a function'); super(db, options); this.Blocks = this.collections.Blocks; + this.setEmitter(emit); } async start() { @@ -22,8 +24,9 @@ class ListenBlocks extends _BlocksBase.BlocksBase { syncing.watch(sync => { let number = sync.currentBlock; if (number) { + number = parseInt(number); this.log.debug('[syncing] New Block reported:', number); - this.requestBlock(number); + this.announceBlock(number); } }, err => { this.log.debug(`Sync err: ${err}`); @@ -34,7 +37,7 @@ class ListenBlocks extends _BlocksBase.BlocksBase { let newBlock = await this.nod3.subscribe.filter('newBlock'); newBlock.watch(blockHash => { this.log.debug('New Block reported:', blockHash); - this.requestBlock(blockHash, true); + this.announceBlock(blockHash, true); }, err => { this.log.debug(`NewBlock error: ${err}`); }); @@ -43,19 +46,9 @@ class ListenBlocks extends _BlocksBase.BlocksBase { } } - bulkRequest(args) { - let action = this.actions.BULK_BLOCKS_REQUEST; - process.send({ action, args: [args] }); - } - - requestBlock(key, prioritize) { - let action = this.actions.BLOCK_REQUEST; - process.send({ action, args: [key, prioritize] }); - } - - updateStatus(state) { - let action = this.actions.STATUS_UPDATE; - process.send({ action, args: [state] }); + announceBlock(key, prioritize = false) { + let event = this.events.NEW_BLOCK; + this.emit(event, { key, prioritize }); }}exports.ListenBlocks = ListenBlocks; diff --git a/dist/services/classes/RequestBlocks.js b/dist/services/classes/RequestBlocks.js index d032215d..0a28d0cb 100644 --- a/dist/services/classes/RequestBlocks.js +++ b/dist/services/classes/RequestBlocks.js @@ -1,29 +1,18 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getBlock = getBlock;exports.default = exports.RequestBlocks = void 0; -var _events = require("events"); var _BlocksBase = require("../../lib/BlocksBase"); -var _types = require("../../lib/types"); var _Block = require("./Block"); var _utils = require("../../lib/utils"); var _UpdateTokenAccountBalances = require("./UpdateTokenAccountBalances"); -class Emitter extends _events.EventEmitter {} - class RequestBlocks extends _BlocksBase.BlocksBase { - constructor(db, options) { - let { log, initConfig } = options; - super(db, { log, initConfig }); - this.queueSize = options.blocksQueueSize || 50; + constructor(db, { log, initConfig, debug, blocksQueueSize, updateTokenBalances }) { + super(db, { log, initConfig, debug }); + this.queueSize = blocksQueueSize || 50; this.pending = new Set(); this.requested = new Map(); - this.events = options.noEvents ? null : new Emitter(); this.maxRequestTime = 1000; - } - - emit(event, data) { - let events = this.events; - if (events) { - events.emit(event, data); - } + this.updateTokenBalances = updateTokenBalances; + this.blocksCollection = this.collections.Blocks; } request(key, prioritize) { @@ -32,6 +21,7 @@ class RequestBlocks extends _BlocksBase.BlocksBase { } bulkRequest(keys) { + if (!Array.isArray(keys)) throw new Error(`Keys must be an array`); for (let key of keys) { this.addToPending(key); } @@ -57,7 +47,10 @@ class RequestBlocks extends _BlocksBase.BlocksBase { let i = this.pending.values(); let free = this.queueSize - this.requested.size; let total = this.requested.size + this.pending.size; - if (total === 0) this.emit(_types.events.QUEUE_DONE); + if (total === 0) { + this.emit(this.events.QUEUE_DONE, {}); + this.updateStatus(); + } while (free > -1) { let key = i.next().value; if (!key) return; @@ -70,9 +63,13 @@ class RequestBlocks extends _BlocksBase.BlocksBase { async requestBlock(key) { try { this.requested.set(key, Date.now()); - this.emit(_types.events.BLOCK_REQUESTED, { key }); + this.emit(this.events.BLOCK_REQUESTED, { key }); + this.log.debug(this.events.BLOCK_REQUESTED, { key }); + this.updateStatus(); let block = await this.getBlock(key); - if (block.error) this.emit(_types.events.BLOCK_ERROR, block); + if (block.error) { + this.log.debug(this.events.BLOCK_ERROR, block.error); + } this.endRequest(key, block); } catch (err) { this.log.error(err); @@ -92,8 +89,13 @@ class RequestBlocks extends _BlocksBase.BlocksBase { } hash = hash || hashOrNumber; const { nod3, collections, log, initConfig } = this; - let block = await getBlock(hash, { nod3, collections, log, initConfig }); - return block; + let result = await getBlock(hash, { nod3, collections, log, initConfig }); + + if (this.updateTokenBalances) { + let { block } = result; + if (block) await (0, _UpdateTokenAccountBalances.updateTokenAccountBalances)(block, { nod3, collections, initConfig, log }); + } + return result; } catch (err) { return Promise.reject(err); } @@ -105,13 +107,34 @@ class RequestBlocks extends _BlocksBase.BlocksBase { this.pending.delete(key); this.log.trace(`Key ${key} time: ${time}`); if (res && res.block) { - let block = res.block; - this.emit(_types.events.NEW_BLOCK, { key, block }); - return res.block; + let block = this.getBlockData(res.block); + this.emit(this.events.BLOCK_SAVED, { key, block }); + res = undefined; + this.requestParentBlock({ key, block }); } this.processPending(); } + async requestParentBlock({ key, block }) { + try { + if (!block) return; + let isHashKey = (0, _utils.isBlockHash)(key); + let data = this.getBlockData(block); + this.emit(this.events.NEW_TIP_BLOCK, data); + let show = isHashKey ? block.number : block.hash; + this.log.debug(this.events.NEW_BLOCK, `New Block DATA ${key} - ${show}`); + let { parentHash } = block; + let parentBlock = await (0, _Block.getBlockFromDb)(parentHash, this.blocksCollection); + if (!parentBlock && block.number) { + this.log.debug(`Getting parent of block ${block.number} - ${parentHash}`); + this.request(parentHash, true); + } + this.updateStatus(); + } catch (err) { + return Promise.reject(err); + } + } + isRequestedOrPending(key) { return this.isRequested(key) || this.isPending(key); } @@ -131,25 +154,26 @@ class RequestBlocks extends _BlocksBase.BlocksBase { getPending() { return this.pending.size; + } + updateStatus(state) { + state = state || {}; + state.requestingBlocks = this.getRequested(); + state.pendingBlocks = this.getPending(); + this.emit(this.events.NEW_STATUS, state); }}exports.RequestBlocks = RequestBlocks; async function getBlock(hashOrNumber, { nod3, collections, log, initConfig }) { - if ((0, _utils.isBlockHash)(hashOrNumber)) { - let block = await (0, _Block.getBlockFromDb)(hashOrNumber, collections.Blocks); - if (block) return { block, key: hashOrNumber }; - } + if (hashOrNumber !== 0 && !(0, _utils.isBlockHash)(hashOrNumber)) throw new Error(`Invalid blockHash: ${hashOrNumber}`); + const key = hashOrNumber; try { let newBlock = new _Block.Block(hashOrNumber, { nod3, collections, log, initConfig }); - let block = await newBlock.save().then(async res => { - if (!res || !res.data) return; - let block = res.data.block; - await (0, _UpdateTokenAccountBalances.updateTokenAccountBalances)(block, { nod3, collections, initConfig, log }); - return block; - }); - return { block, key: hashOrNumber }; + let result = await newBlock.save(); + if (!result || !result.data) return { key }; + let { block } = result.data; + return { block, key }; } catch (error) { - return { error, key: hashOrNumber }; + return { error, key }; } }var _default = diff --git a/dist/services/classes/TokenAddress.js b/dist/services/classes/TokenAddress.js index 22346e77..d5e47877 100644 --- a/dist/services/classes/TokenAddress.js +++ b/dist/services/classes/TokenAddress.js @@ -1,12 +1,14 @@ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.TokenAddress = void 0;var _BcThing = require("./BcThing"); var _Contract = _interopRequireDefault(require("./Contract")); -var _utils = require("../../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +var _utils = require("../../lib/utils"); +var _rskUtils = require("rsk-utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class TokenAddress extends _BcThing.BcThing { constructor(address, contract) { if (!(contract instanceof _Contract.default)) { throw new Error('contract is not instance of Contract'); } + if (!(0, _utils.isAddress)(address)) throw new Error(`Invalid address ${address}`); let { block } = contract; if (!(0, _utils.isBlockObject)(block)) { throw new Error(`Block must be a block object`); @@ -16,6 +18,7 @@ class TokenAddress extends _BcThing.BcThing { if (!this.isAddress(address)) { throw new Error(`TokenAddress: invalid address: ${address}`); } + this.isZeroAddress = (0, _rskUtils.isZeroAddress)(address); this.Contract = contract; this.address = address; let { number, hash } = block; @@ -30,12 +33,13 @@ class TokenAddress extends _BcThing.BcThing { try { let balance = await this.getBalance(); this.data.balance = balance; - return this.getData(); + return this.getData(true); } catch (err) { return Promise.reject(err); } } getBalance() { + if (this.isZeroAddress) return null; return this.Contract.call('balanceOf', [this.address]); }}exports.TokenAddress = TokenAddress;var _default = diff --git a/dist/services/classes/Tx.js b/dist/services/classes/Tx.js index 6c3acd73..01d295b0 100644 --- a/dist/services/classes/Tx.js +++ b/dist/services/classes/Tx.js @@ -1,41 +1,124 @@ -"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.Tx = void 0;var _BcThing = require("./BcThing"); +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.createTxObject = createTxObject;exports.getTraceDataFromBlock = getTraceDataFromBlock;exports.getTimestampFromBlock = getTimestampFromBlock;exports.parseLogs = parseLogs;exports.formatEvents = formatEvents;Object.defineProperty(exports, "txTypes", { enumerable: true, get: function () {return _types.txTypes;} });exports.default = exports.Tx = void 0;var _BcThing = require("./BcThing"); var _Event = require("./Event"); -var _rskContractParser = _interopRequireDefault(require("rsk-contract-parser")); var _types = require("../../lib/types"); var _ids = require("../../lib/ids"); -var _utils = require("../../lib/utils");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} +var _rskContractParser = _interopRequireDefault(require("rsk-contract-parser")); +var _TxTrace = _interopRequireDefault(require("./TxTrace")); +var _Addresses = require("./Addresses"); +var _utils = require("../../lib/utils"); +var _BlockSummary = require("./BlockSummary");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + class Tx extends _BcThing.BcThing { - constructor(hash, timestamp, { txData, nod3, initConfig } = {}) { + constructor(hash, timestamp, { addresses, txData, blockTrace, blockData, traceData, nod3, initConfig, collections, notTrace, receipt, log } = {}) { if (!hash || !timestamp) throw new Error(`Tx, missing arguments`); - super({ nod3, initConfig }); + super({ nod3, initConfig, collections, log }); + if (!this.isTxOrBlockHash(hash)) throw new Error(`Tx, ${hash} is not a tx hash`); this.hash = hash; this.timestamp = timestamp; - this.contractParser = new _rskContractParser.default({ initConfig, nod3 }); this.txData = txData; + this.receipt = receipt; + this.toAddress = undefined; + this.blockData = blockData; + if (blockTrace) traceData = getTraceDataFromBlock(hash, blockTrace); + addresses = addresses || new _Addresses.Addresses({ nod3, initConfig, collections }); + this.addresses = addresses; + this.trace = !notTrace ? new _TxTrace.default(hash, { traceData, timestamp, nod3, initConfig, log }) : undefined; + this.data = { + tx: {}, + events: [], + tokenAddresses: [] }; + } - async fetch() { + async fetch(force) { try { + let { fetched } = this; + if (fetched && !force) return this.getData(); let tx = await this.getTx(); - let events = await this.parseEvents(tx); - this.data = { tx, events }; + if (!tx) throw new Error('Error getting tx'); + await this.setBlockData(tx); + let addressOptions = this.addressOptions(); + await this.setToAddress(tx); + this.addresses.add(tx.from, addressOptions); + let { contractAddress } = tx.receipt; + if (contractAddress) this.addresses.add(contractAddress, addressOptions); + tx = this.txFormat(tx); + let { nod3, initConfig } = this; + let { contract } = this.toAddress || {}; + const parser = contract ? await contract.getParser() : new _rskContractParser.default({ nod3, initConfig }); + if (parser) { + tx.receipt.logs = parseLogs(tx, parser); + let events = formatEvents(tx, parser); + if (tx.receipt.logs.length !== events.length) throw new Error(`logs error ${this.hash}`); + tx.receipt.logs = events; + let eventAddresses = [].concat(...events.filter(e => e._addresses).map(({ _addresses }) => _addresses)); + eventAddresses.forEach(address => this.addresses.add(address, addressOptions)); + this.setData({ events }); + if (contract) { + eventAddresses.forEach(address => contract.addAddress(address)); + let tokenAddresses = await contract.fetchAddresses(); + this.setData({ tokenAddresses }); + } + } + if (this.trace) { + let trace = await this.trace.fetch(); + let { internalTransactions, addresses } = await this.trace.getInternalTransactionsData(trace); + addresses.forEach(address => this.addresses.add(address, addressOptions)); + this.setData({ trace, internalTransactions }); + } + this.setData({ tx }); + this.fetched = true; return this.getData(); } catch (err) { return Promise.reject(err); } } + async setBlockData({ blockHash }) { + try { + let { blockData, nod3 } = this; + if (!(0, _utils.isBlockObject)(blockData) || blockData.hash !== blockHash) { + blockData = await (0, _BlockSummary.getBlock)(blockHash, false, nod3); + this.blockData = blockData; + } + } catch (err) { + return Promise.reject(err); + } + } + async setToAddress({ to }) { + try { + let { isAddress, toAddress } = this; + if (toAddress !== undefined) return toAddress; + if (to !== null) { + if (!isAddress(to)) throw new Error(`Invalid address ${to}`); + this.toAddress = this.addresses.add(to, this.addressOptions()); + await this.toAddress.fetch(); + } else { + this.toAddress = null; + } + return this.toAddress; + } catch (err) { + return Promise.reject(err); + } + } async getTx() { try { let txHash = this.hash; - let tx = this.txData; - if (!this.isTxData(tx)) tx = await this.getTransactionByHash(txHash); - if (tx.hash !== txHash) throw new Error(`Error getting tx: ${txHash}, hash received:${tx.hash}`); - let receipt = await this.getTxReceipt(txHash); - if (!receipt) throw new Error(`The Tx ${txHash} .receipt is: ${receipt} `); - tx.timestamp = this.timestamp; - tx.receipt = receipt; + let { txData } = this; + if (!this.isTxData(txData)) { + txData = await this.getTransactionByHash(txHash); + this.txData = txData; + } + if (txData.hash !== txHash) throw new Error(`Error getting tx: ${txHash}, hash received:${txData.hash}`); + let { receipt } = this; + if (!receipt) { + receipt = await this.getTxReceipt(txHash); + if (!receipt) throw new Error(`The Tx ${txHash} .receipt is: ${receipt} `); + } + this.receipt = receipt; + let { timestamp } = this; + if (!timestamp) timestamp = await getTimestampFromBlock(txData, this.nod3); + let tx = createTxObject(txData, { timestamp, receipt }); if (!tx.transactionIndex) tx.transactionIndex = receipt.transactionIndex; - tx = this.txFormat(tx); return tx; } catch (err) { return Promise.reject(err); @@ -49,41 +132,65 @@ class Tx extends _BcThing.BcThing { getTxReceipt(txHash) { return this.nod3.eth.getTransactionReceipt(txHash); } - async parseEvents(tx) { - try { - let logs = await this.parseLogs(tx.receipt.logs); - tx.receipt.logs = logs; - return logs.map(l => { - l = (0, _Event.formatEvent)(l, tx); - let event = Object.assign({}, l); - delete l._id; - return event; - }); - } catch (err) { - return Promise.reject(err); - } - } txFormat(tx) { - tx.txType = _types.txTypes.default; + let type = _types.txTypes.default; const receipt = tx.receipt || {}; + let { toAddress } = this; + if (toAddress && toAddress.isContract()) type = _types.txTypes.call; const toIsNative = this.nativeContracts.isNativeContract(tx.to); let nativeType = _types.txTypes[toIsNative]; - if (nativeType) tx.txType = nativeType; - if ((0, _utils.isAddress)(receipt.contractAddress)) tx.txType = _types.txTypes.contract; + if (nativeType) type = nativeType; + if (this.isAddress(receipt.contractAddress)) type = _types.txTypes.contract; + tx.txType = type; tx.txId = (0, _ids.getTxOrEventId)(tx); return tx; } - parseLogs(logs) { - let parser = this.contractParser; - return new Promise((resolve, reject) => { - process.nextTick(() => resolve(parser.parseTxLogs(logs))); - }); - } isTxData(data) { if (!data || typeof data !== 'object') return; return data.hash && data.blockHash && data.input; - }}exports.Tx = Tx;var _default = + } + addressOptions() { + let block = this.blockData; + return { block }; + }}exports.Tx = Tx; + + +function createTxObject(tx, { timestamp, receipt }) { + if (!Object.keys(tx).length) throw new Error('invalid tx'); + if (!Object.keys(receipt).length) throw new Error('invalid tx receipt'); + // TODO check timestamp + tx.timestamp = timestamp; + tx.receipt = receipt; + return tx; +} + +function getTraceDataFromBlock(hash, blockTrace) { + if (!Array.isArray(blockTrace)) return; + return blockTrace.filter(({ transactionHash }) => transactionHash === hash); +} + +async function getTimestampFromBlock({ blockHash }, nod3) { + try { + let data = await nod3.eth.getBlok(blockHash); + let { timestamp } = data; + return timestamp; + } catch (err) { + return Promise.reject(err); + } +} + +function parseLogs(tx, parser) { + return parser.parseTxLogs(tx.receipt.logs); +} +function formatEvents(tx) { + return tx.receipt.logs.map(l => { + l = (0, _Event.formatEvent)(l, tx); + let event = Object.assign({}, l); + delete l._id; + return event; + }); +}var _default = Tx;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/TxTrace.js b/dist/services/classes/TxTrace.js new file mode 100644 index 00000000..57848cdb --- /dev/null +++ b/dist/services/classes/TxTrace.js @@ -0,0 +1,66 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = exports.TxTrace = void 0;var _BcThing = require("./BcThing"); +var _InternalTx = require("./InternalTx"); +var _Tx = require("./Tx"); + +class TxTrace extends _BcThing.BcThing { + constructor(hash, { traceData, timestamp, nod3, initConfig, log } = {}) { + super({ nod3, initConfig, log }); + if (!this.isTxOrBlockHash(hash)) throw new Error(`TxTrace, ${hash} is not a tx hash`); + this.hash = hash; + this.data = undefined; + this.traceData = traceData; + this.timestamp = timestamp; + if (traceData) this.setData(traceData); + } + setData(trace) { + if (!Array.isArray(trace)) throw new Error('Invalid trace data'); + trace = trace.filter(d => d.transactionHash === this.hash); + this.data = trace; + return this.getData(); + } + async fetch(force) { + try { + let { fetched, nod3, hash, traceData, timestamp } = this; + if (fetched && !force) return this.getData(); + if (!traceData) { + this.log.debug(`Trace transaction ${hash}`); + traceData = await nod3.trace.transaction(hash); + } + if (!timestamp) { + this.log.debug(`Getting transaction timestamp ${hash}`); + timestamp = await (0, _Tx.getTimestampFromBlock)(traceData, nod3); + } + this.traceData = traceData; + this.timestamp = timestamp; + this.setData(traceData); + this.fetched = true; + return this.getData(); + } catch (err) { + return Promise.reject(err); + } + } + async createInternalTransactions(data) { + try { + let { initConfig, timestamp } = this; + return data.map(d => new _InternalTx.InternalTx(Object.assign(d, { timestamp }), { initConfig })); + } catch (err) { + return Promise.reject(err); + } + } + async getInternalTransactionsData(data) { + try { + await this.fetch(); + data = data || this.getData(); + let iTxs = await this.createInternalTransactions(data); + let internalTransactions = iTxs.map(i => i.getData()); + let addresses = iTxs.map(i => i.getAddresses()); + // merge addresses arrays + addresses = [].concat.apply([], addresses); + return { internalTransactions, addresses }; + } catch (err) { + return Promise.reject(err); + } + }}exports.TxTrace = TxTrace;var _default = + + +TxTrace;exports.default = _default; \ No newline at end of file diff --git a/dist/services/classes/UpdateBlockBalances.js b/dist/services/classes/UpdateBlockBalances.js new file mode 100644 index 00000000..8ebba888 --- /dev/null +++ b/dist/services/classes/UpdateBlockBalances.js @@ -0,0 +1,138 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.MissingBalances = MissingBalances;exports.default = exports.UpdateBlockBalances = void 0;var _BlocksBase = require("../../lib/BlocksBase"); +var _BlockBalances = require("./BlockBalances"); +var _BlockSummary = require("./BlockSummary"); +var _utils = require("../../lib/utils"); +var _InternalTx = require("./InternalTx"); + +class UpdateBlockBalances extends _BlocksBase.BlocksBase { + constructor(db, { log, initConfig, nod3, debug, confirmations }) { + super(db, { log, initConfig, nod3, debug }); + confirmations = parseInt(confirmations); + this.confirmations = !isNaN(confirmations) ? confirmations : 120; + this.lastBlock = { number: undefined }; + let { Blocks, Balances } = this.collections; + this.blocksCollection = Blocks; + this.balancesCollection = Balances; + this.missing = undefined; + this.started = undefined; + } + + async updateBalance(blockHash) { + try { + let { nod3, log, collections, initConfig } = this; + let summary = await (0, _BlockSummary.getBlockSummaryFromDb)(blockHash, collections); + if (!summary) throw new Error(`Missing block summary: ${blockHash}`); + const { block, internalTransactions } = summary.data; + const addresses = (0, _InternalTx.filterValueAddresses)(internalTransactions); + let blockBalances = new _BlockBalances.BlockBalances({ block, addresses }, { nod3, log, collections, initConfig }); + let result = await blockBalances.save(); + blockBalances = undefined; + return result; + } catch (err) { + this.log.error(`Error updating balances of ${blockHash}`); + this.log.trace(err); + return Promise.reject(err); + } + } + + createMissingBalances() { + let { lastBlock, blocksCollection, balancesCollection, confirmations } = this; + let { number } = lastBlock; + let highestBlock = number > confirmations ? number - confirmations : number; + return MissingBalances(blocksCollection, balancesCollection, { highestBlock }); + } + + async updateLastBlock(block, skipStart = false) { + try { + const { lastBlock } = this; + const { number, hash } = block; + if (isNaN(parseInt(number))) throw new Error(`Invalid block number: ${number}`); + if (!(0, _utils.isBlockHash)(hash)) throw new Error(`invalid block hash: ${hash}`); + if (!lastBlock.number || number > lastBlock.number) { + this.log.info(`Last block ${number}/${hash}`); + this.lastBlock = block; + let missing = await this.createMissingBalances(); + this.missing = missing; + if (skipStart !== true) this.start(); + return true; + } + } catch (err) { + return Promise.reject(err); + } + } + async getNextBalances() { + try { + let { missing } = this; + if (!missing) throw new Error('Missing balances generator is undefined'); + let next = await missing.next(); + if (!next) { + this.started = false; + return this.start(); + } + let { hash, number } = next; + this.log.info(`Updating balances for block ${hash} / ${number}`); + await this.updateBalance(hash); + this.log.info(`The balances of block: ${hash}/${number} were updated`); + return this.getNextBalances(); + } catch (err) { + this.started = undefined; + return Promise.reject(err); + } + } + + async start() { + try { + if (this.started) return this.started; + if (!this.emit) throw new Error('Set emitter before start'); + let { blocksCollection } = this; + let lastBlock = await getLastBlock(blocksCollection); + if (lastBlock) await this.updateLastBlock(lastBlock); + this.started = this.getNextBalances(); + return this.started; + } catch (err) { + this.log.error(err); + return Promise.reject(err); + } + }}exports.UpdateBlockBalances = UpdateBlockBalances; + + +async function MissingBalances(blocksCollection, balancesCollection, { highestBlock, lowestBlock } = {}) { + try { + lowestBlock = lowestBlock || 1; + if (!highestBlock) { + let lastBlock = await getLastBlock(blocksCollection); + highestBlock = lastBlock.number; + } + + const projection = { _id: 0, number: 1, hash: 1 }; + const sort = { number: -1 }; + + let currentBlock = highestBlock; + let block; + const current = () => currentBlock; + const next = async () => { + if (currentBlock <= lowestBlock) return; + const query = { number: { $lte: --currentBlock, $gte: lowestBlock } }; + const cursor = blocksCollection.find(query, { projection, sort }); + while (await cursor.hasNext()) { + block = await cursor.next(); + let { hash: blockHash, number } = block; + let balance = await balancesCollection.findOne({ blockHash }); + + currentBlock = number; + if (currentBlock < lowestBlock) currentBlock = lowestBlock; + if (!balance) break; + } + return block; + }; + return Object.freeze({ next, current }); + } catch (err) { + return Promise.reject(err); + } +} + +function getLastBlock(blocksCollection) { + return blocksCollection.findOne({}, { sort: { number: -1 } }); +}var _default = + +UpdateBlockBalances;exports.default = _default; \ No newline at end of file diff --git a/dist/services/serviceFactory.js b/dist/services/serviceFactory.js new file mode 100644 index 00000000..bd87eb3a --- /dev/null +++ b/dist/services/serviceFactory.js @@ -0,0 +1,78 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.createService = createService;exports.createStartService = createStartService;exports.createRouter = createRouter;exports.bootStrapService = bootStrapService;exports.createServiceLogger = exports.services = exports.ports = void 0;var _config = _interopRequireDefault(require("../lib/config")); +var _dataSource = require("../lib/dataSource"); +var _Logger = require("../lib/Logger"); +var _servicesConfig = require("./servicesConfig"); +var _ServiceServer = require("./Service/ServiceServer"); +var _Router = require("./Router"); +var _types = require("../lib/types");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const { blocks } = _config.default; +const { address } = blocks; + +const ports = (0, _servicesConfig.createPorts)(blocks.ports.map(p => parseInt(p)));exports.ports = ports; + +const services = (0, _servicesConfig.createServices)(address, ports);exports.services = services; + +const createServiceLogger = ({ name, uri }) => { + if (!name || !uri) throw new Error('Missing log options'); + return (0, _Logger.Logger)(`${name}|${uri}`); +};exports.createServiceLogger = createServiceLogger; + +async function createService(serviceConfig, executor, { log } = {}) { + try { + const { uri, name, address, port } = serviceConfig; + log = log || createServiceLogger(serviceConfig); + const service = (0, _ServiceServer.Service)(uri, { name }, executor); + const startService = createStartService(service, { name, address, port }, { log }); + return { service, log, startService }; + } catch (err) { + return Promise.reject(err); + } +} + +function createStartService(service, { name, address, port }, { log }) { + return async () => { + try { + let listenPort = await service.start(); + if (listenPort !== port) throw new Error('Binding port mismatch'); + if (log) log.info(`Service ${name} listening on ${address}:${port}`); + return listenPort; + } catch (err) { + return Promise.reject(err); + } + }; +} + +async function createRouter(routerServiceConfig, { services, log }) { + try { + services = services || {}; + log = log || createServiceLogger(routerServiceConfig); + const router = (0, _Router.Router)({ log }); + const executor = ({ create }) => { + create.Emitter(); + create.Listener(router.broadcast); + }; + const { service, startService } = await createService(routerServiceConfig, executor, { log }); + for (let s in services) { + let config = services[s]; + let { name } = config; + if (config.uri !== routerServiceConfig.uri) { + router.addService(name, config); + } + } + router.setRouterService(service); + return Object.freeze({ router, startService, log }); + } catch (err) { + return Promise.reject(err); + } +} + +async function bootStrapService(serviceConfig) { + try { + const log = createServiceLogger(serviceConfig); + const setupData = await (0, _dataSource.setup)({ log }); + return Object.assign(setupData, { log, events: _types.events }); + } catch (err) { + return Promise.reject(err); + } +} \ No newline at end of file diff --git a/dist/services/servicesConfig.js b/dist/services/servicesConfig.js new file mode 100644 index 00000000..ac606ce7 --- /dev/null +++ b/dist/services/servicesConfig.js @@ -0,0 +1,34 @@ +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.createServices = createServices;exports.createPorts = createPorts;exports.servicesNames = void 0; +const servicesNames = { + ROUTER: 'blocksRouter', + LISTENER: 'blocksListener', + REQUESTER: 'blocksRequester', + CHECKER: 'blocksChecker', + TXPOOL: 'txPool', + BALANCES: 'blocksBalances', + STATUS: 'blocksStatus', + STATS: 'blocksStats' };exports.servicesNames = servicesNames; + + +function createServices(address, ports) { + let services = {}; + for (let type in servicesNames) { + let name = servicesNames[type]; + let port = ports.next(); + let uri = `${address}:${port}`; + services[type] = { address, port, uri, name }; + } + return services; +} + +function createPorts(ports) { + let index = 0; + let assigned = []; + const next = () => { + let port = ports[index] || assigned[assigned.length - 1] + 1; + assigned.push(port); + index++; + return port; + }; + return Object.freeze({ next, assigned }); +} \ No newline at end of file diff --git a/dist/services/txPool.js b/dist/services/txPool.js deleted file mode 100644 index 9e797e3b..00000000 --- a/dist/services/txPool.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict";var _dataSource = require("../lib/dataSource"); -var _config = _interopRequireDefault(require("../lib/config")); -var _TxPool = require("./classes/TxPool"); -var _Logger = _interopRequireDefault(require("../lib/Logger"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} - -const config = Object.assign({}, _config.default.blocks); -const log = (0, _Logger.default)('Blocks', config.log); - -(0, _dataSource.setup)({ log }).then(({ db }) => { - config.log = log; - const txPool = new _TxPool.TxPool(db, config); - log.info(`Starting txPool`); - txPool.start(); -}); - -process.on('unhandledRejection', err => { - console.error(err); - process.exit(1); -}); \ No newline at end of file diff --git a/dist/services/userEvents/userEventsService.js b/dist/services/userEvents/userEventsService.js index a9b31376..e3651f80 100644 --- a/dist/services/userEvents/userEventsService.js +++ b/dist/services/userEvents/userEventsService.js @@ -3,38 +3,39 @@ var _blocksCollections = require("../../lib/blocksCollections"); var _config = _interopRequireDefault(require("../../lib/config")); var _Logger = _interopRequireDefault(require("../../lib/Logger")); var _utils = require("../../lib/utils"); -var _RequestCache = require("./RequestCache"); -var _AddressModule = _interopRequireDefault(require("./AddressModule")); -var _ContractVerifierModule = _interopRequireDefault(require("./ContractVerifierModule")); -var _types = require("../../lib/types");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +var _ContractVerifierModule = _interopRequireDefault(require("./ContractVerifierModule")); +var _types = require("../../lib/types");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /* import { RequestCache } from './RequestCache' + import AddressModule from './AddressModule' */ const log = (0, _Logger.default)('UserRequests', _config.default.blocks.log); const verifierConfig = _config.default.api.contractVerifier; (0, _dataSource.default)({ log, skipCheck: true }).then(({ db, initConfig }) => { const collections = (0, _blocksCollections.getDbBlocksCollections)(db); - const cache = new _RequestCache.RequestCache(); + // const cache = new RequestCache() // TODO, conditional creation const verifierModule = (0, _ContractVerifierModule.default)(db, collections, verifierConfig, { log }); - const addressModule = (0, _AddressModule.default)({ db, collections, initConfig, log }); + // const addressModule = AddressModule({ db, collections, initConfig, log }) process.on('message', async msg => { try { - let { action, params, block, module } = msg; + // let { action, params, block, module } = msg + let { action, module } = msg; if (module && action) { switch (module) { // Address module - case 'Address': - if (action === 'updateAddress') { - if (!block) return; - msg = await addressModule.updateAddress({ cache, msg }, params); - sendMessage(msg); - } - break; + /* case 'Address': + if (action === 'updateAddress') { + if (!block) return + msg = await addressModule.updateAddress({ cache, msg }, params) + sendMessage(msg) + } + break */ // Contract Verifier module case 'ContractVerification': const method = verifierModule[action]; - if (!method) throw new Error(`Unknow action ${action}`); + if (!method) throw new Error(`Unknown action ${action}`); try { msg = await method(msg); sendMessage(msg); diff --git a/dist/tools/cacheBlocksTraces.js b/dist/tools/cacheBlocksTraces.js new file mode 100644 index 00000000..8b00fe2e --- /dev/null +++ b/dist/tools/cacheBlocksTraces.js @@ -0,0 +1,113 @@ +"use strict"; +var _dataSource = require("../lib/dataSource"); +var _config = _interopRequireDefault(require("../lib/config")); +var _nod3Connect = require(".././lib/nod3Connect"); +var _nod = require("nod3"); +var _BlockTrace = _interopRequireDefault(require("../services/classes/BlockTrace")); +var _Logger = require("../lib/Logger");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const { HttpProvider } = _nod.Nod3.providers; +const log = (0, _Logger.Logger)('cacheTraces', { level: 'trace' }); +const { source } = _config.default; + +const nod3 = createNod3(source); +nod3.setDebug((0, _nod3Connect.nod3Log)(log)); + +const { argv } = process; + +let lowerBlock = argv[2] || 0; +let higherBlock = argv[3] || 'latest'; +argv[4] = parseInt(argv[4]); +const sourcesLen = Array.isArray(source) ? source.length : 1; +const QUEUE_SIZE = !isNaN(argv[4]) ? argv[4] : sourcesLen; +const requested = {}; + +if (isNaN(parseInt(lowerBlock))) help(`Invalid lowerBlock value ${argv[2]}`); +if (higherBlock !== 'latest') { + higherBlock = parseInt(higherBlock); + if (isNaN(higherBlock)) help(`Invalid lowerBlock value ${argv[3]}`); + if (higherBlock < lowerBlock) help(); +} + +main().then(() => { + log.info('Done'); + process.exit(0); +}); + +async function main() { + try { + const { initConfig, collections } = await (0, _dataSource.setup)(); + log.trace(JSON.stringify({ lowBlock: lowerBlock, highBlock: higherBlock })); + log.info(initConfig.net); + + let block = await nod3.eth.getBlock(higherBlock); + const tasks = []; + for (let i = 0; i < QUEUE_SIZE; i++) { + let { hash, parentHash } = block; + tasks.push(getBlocks(hash, { collections, initConfig })); + block = await nod3.eth.getBlock(parentHash); + } + await Promise.all(tasks); + } catch (err) { + showErrorAndExit(err); + } +} + +async function getBlocks(hash, opts) { + try { + let block = await nod3.eth.getBlock(hash); + let { number, parentHash } = block; + if (number <= lowerBlock) return; + log.info(`Get trace ${hash}/${number}`); + let res = await saveBlockTrace(hash, opts); + if (res) log.info(`Trace ${hash} done`); + return getBlocks(parentHash, opts); + } catch (err) { + return Promise.reject(err); + } +} + +function createNod3(source) { + if (Array.isArray(source)) { + const providers = source.map(({ url }) => new HttpProvider(url)); + const { nod3, router } = new _nod.Nod3Router(providers); + router.reset(); + router.add({ module: 'subscribe', to: 0 }); + return nod3; + } else { + let nod3 = new _nod.Nod3(new HttpProvider(source.url)); + return nod3; + } +} + +async function saveBlockTrace(hash, { collections, initConfig }) { + try { + if (requested[hash] !== undefined) return; + requested[hash] = false; + log.info(`Waiting for block_trace ${hash}`); + let blockTrace = new _BlockTrace.default(hash, { nod3, collections, initConfig }); + await blockTrace.save(); + requested[hash] = true; + return hash; + } catch (err) { + showErrorAndExit(err); + } +} + +function showErrorAndExit(err) { + log.error(err); + process.exit(9); +} + +const p = path => path.split('/').pop(); + +function help(msg) { + if (msg) { + log.error(msg); + console.log(); + } + const myName = p(process.argv[1]); + log.info(`Use: ${p(process.argv[0])} ${myName} [lowerBlock] [higherBlock] `); + log.info(`e.g. ${myName} 0 456`); + process.exit(0); +} \ No newline at end of file diff --git a/dist/tools/checkDbBlocks.js b/dist/tools/checkDbBlocks.js index fc1468a6..0f5bf3d8 100644 --- a/dist/tools/checkDbBlocks.js +++ b/dist/tools/checkDbBlocks.js @@ -1,27 +1,47 @@ "use strict";var _dataSource = _interopRequireDefault(require("../lib/dataSource.js")); var _blocksCollections = require("../lib/blocksCollections"); var _fs = _interopRequireDefault(require("fs")); +var _path = _interopRequireDefault(require("path")); var _util = _interopRequireDefault(require("util")); + var _CheckBlocks = require("../services/classes/CheckBlocks");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const checkTxs = process.argv.find(a => a === '--txs'); +const checkBlocks = process.argv.find(a => a === '--blocks'); +if (!checkTxs && !checkBlocks) { + console.log('Usage:'); + console.log(`${process.argv[0]} ${process.argv[1]} [--blocks][--txs] [--out dir]`); + console.log('--blocks search for missing blocks'); + console.log('--txs: search for missing transactions'); + console.log('--out: path to save results'); + process.exit(0); +} +const out = process.argv.findIndex(a => a === '--out'); +const outDir = out ? _fs.default.existsSync(process.argv[out + 1]) ? _path.default.resolve(process.argv[out + 1]) : _path.default.resolve('./') : null; const writeFile = _util.default.promisify(_fs.default.writeFile); -const outFile = process.argv[2] || '/tmp/blocksLog.json'; + (0, _dataSource.default)({ skipCheck: true }).then(async ({ db }) => { try { const { Blocks, Txs } = (0, _blocksCollections.getDbBlocksCollections)(db); console.log('Getting blocks....'); let res = await (0, _CheckBlocks.checkBlocksCongruence)(Blocks); - res.missingTxs = await (0, _CheckBlocks.checkBlocksTransactions)(Blocks, Txs); - - res.missingTotal = res.missing.length; - res.invalidTotal = res.invalid.length; - res.missingTxsTotal = res.missingTxs.length; + console.log(JSON.stringify(res, null, 2)); + if (checkTxs) { + res.missingTxs = await (0, _CheckBlocks.checkBlocksTransactions)(Blocks, Txs); - console.log(`Missing Blocks: ${res.missingTotal}`); - console.log(`Invalid Blocks: ${res.invalidTotal}`); - console.log(`Blocks with missing txs: ${res.missingTxsTotal}`); + res.missingTotal = res.missing.length; + res.invalidTotal = res.invalid.length; + res.missingTxsTotal = res.missingTxs.length; - await writeFile(outFile, JSON.stringify(res)); - console.log(`Log saved on: ${outFile}`); + console.log(`Missing Blocks: ${res.missingTotal}`); + console.log(`Invalid Blocks: ${res.invalidTotal}`); + console.log(`Blocks with missing txs: ${res.missingTxsTotal} `); + } + if (out > 1) { + const outFile = `${outDir}/blocksLog-${Date.now()}.json`; + await writeFile(outFile, JSON.stringify(res)); + console.log(`Log saved on: ${outFile} `); + } process.exit(0); } catch (err) { console.log(err); diff --git a/dist/tools/showBlocksTraces.js b/dist/tools/showBlocksTraces.js new file mode 100644 index 00000000..6e6c4e39 --- /dev/null +++ b/dist/tools/showBlocksTraces.js @@ -0,0 +1,22 @@ +"use strict"; +var _dataSource = require("../lib/dataSource.js"); +var _Logger = require("../lib/Logger"); +var _blocksCollections = require("../lib/blocksCollections"); +const log = (0, _Logger.Logger)('showTraces', { level: 'trace' }); +const every = process.argv[2] || 10000; + +main(); + +async function main() { + try { + const { db } = await (0, _dataSource.setup)({ skipCheck: true }); + const collections = await (0, _blocksCollections.getDbBlocksCollections)(db); + const collection = collections.BlocksTraces; + const traces = await collection.estimatedDocumentCount(); + log.info(`Traces: ${traces}`); + setTimeout(main, every); + } catch (err) { + log.error(err); + process.exit(9); + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 88bffab4..32c09c48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "rsk-explorer-api", - "version": "1.0.8", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -57,6 +57,22 @@ "make-dir": "^2.1.0", "slash": "^2.0.0", "source-map": "^0.5.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": 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" + } + } } }, "@babel/code-frame": { @@ -394,6 +410,14 @@ "regenerator-runtime": "^0.13.4", "resolve": "^1.13.1", "v8flags": "^3.1.1" + }, + "dependencies": { + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "dev": true + } } }, "@babel/parser": { @@ -1033,13 +1057,6 @@ "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - } } }, "@babel/template": { @@ -1151,9 +1168,9 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz", - "integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==" + "version": "14.0.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.22.tgz", + "integrity": "sha512-emeGcJvdiZ4Z3ohbmw93E/64jRzUHAItSHt8nF7M4TGgQTiWqFVGB8KNpLGFmUHmHLvjvBgFwVlqNcq+VuGv9g==" }, "@types/react": { "version": "16.4.6", @@ -1216,6 +1233,14 @@ "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.3.0" + }, + "dependencies": { + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true + } } }, "ajv-keywords": { @@ -1231,6 +1256,39 @@ "dev": true, "requires": { "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "ansi-colors": { @@ -1449,15 +1507,6 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -1484,11 +1533,6 @@ "regenerator-runtime": "^0.11.0" }, "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - }, "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", @@ -1670,11 +1714,42 @@ "widest-line": "^2.0.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } } }, @@ -1859,15 +1934,14 @@ "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, "caniuse-lite": { - "version": "1.0.30001096", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001096.tgz", - "integrity": "sha512-PFTw9UyVfbkcMEFs82q8XVlRayj7HKvnhu5BLcmjGpv+SNyiWasCcWXPGJuO0rK0dhLRDJmtZcJ+LHUfypbw1w==", + "version": "1.0.30001099", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001099.tgz", + "integrity": "sha512-sdS9A+sQTk7wKoeuZBN/YMAHVztUfVnjDi4/UV3sDE8xoh7YR12hKW+pIdB3oqKGwr9XaFL2ovfzt9w8eUI5CA==", "dev": true }, "capture-stack-trace": { @@ -2003,48 +2077,19 @@ } }, "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "co": { @@ -2229,10 +2274,9 @@ } }, "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", - "dev": true + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "core-js-compat": { "version": "3.6.5", @@ -2532,9 +2576,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.494", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.494.tgz", - "integrity": "sha512-EOZuaDT3L1sCIMAVN5J0nGuGWVq5dThrdl0d8XeDYf4MOzbXqZ19OLKesN8TZj0RxtpYjqHpiw/fR6BKWdMwYA==", + "version": "1.3.496", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.496.tgz", + "integrity": "sha512-TXY4mwoyowwi4Lsrq9vcTUYBThyc1b2hXaTZI13p8/FRhY2CTaq5lK+DVjhYkKiTLsKt569Xes+0J5JsVXFurQ==", "dev": true }, "elliptic": { @@ -2568,17 +2612,27 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "requires": { - "iconv-lite": "~0.4.13" + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } } }, "engine.io": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz", - "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", + "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", @@ -2609,11 +2663,11 @@ } }, "engine.io-client": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz", - "integrity": "sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", + "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", "requires": { - "component-emitter": "1.2.1", + "component-emitter": "~1.3.0", "component-inherit": "0.0.3", "debug": "~4.1.0", "engine.io-parser": "~2.2.0", @@ -2626,6 +2680,11 @@ "yeast": "0.1.2" }, "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -2816,6 +2875,12 @@ "text-table": "~0.2.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -2844,6 +2909,15 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } } }, @@ -2957,15 +3031,6 @@ "esutils": "^2.0.2", "isarray": "^1.0.0" } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, @@ -3013,9 +3078,9 @@ } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { @@ -3034,18 +3099,18 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.2.0.tgz", - "integrity": "sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^5.0.0" + "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz", - "integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", "dev": true } } @@ -3331,10 +3396,9 @@ } }, "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-json-patch": { "version": "2.2.1", @@ -3342,13 +3406,6 @@ "integrity": "sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==", "requires": { "fast-deep-equal": "^2.0.1" - }, - "dependencies": { - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - } } }, "fast-json-stable-stringify": { @@ -3574,672 +3631,103 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" + "nan": "^2.12.1" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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 + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "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" + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "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 + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "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" }, "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, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "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.4", - "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": "3.2.6", - "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.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "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.6", - "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.3", - "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.4", - "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": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.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.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^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.1", - "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" - } - }, - "readable-stream": { - "version": "2.3.7", - "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.7.1", - "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.1", - "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.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "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.1.1", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "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 - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "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" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "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 - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": 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" - } - }, - "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" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "^2.1.0" } } } @@ -4284,9 +3772,9 @@ } }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "growl": { @@ -4349,16 +3837,6 @@ "tar": "^4" } }, - "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -4645,6 +4123,39 @@ "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "invariant": { @@ -4788,9 +4299,12 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-glob": { "version": "4.0.1", @@ -4872,9 +4386,9 @@ } }, "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "is-redirect": { "version": "1.0.0", @@ -4979,9 +4493,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -5203,6 +4717,14 @@ "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" + }, + "dependencies": { + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } } }, "lru-queue": { @@ -5345,16 +4867,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -5393,13 +4915,6 @@ "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "minizlib": { @@ -5471,6 +4986,12 @@ "yargs-unparser": "1.6.0" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -5512,6 +5033,17 @@ "readdirp": "~3.2.0" } }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -5569,12 +5101,28 @@ "binary-extensions": "^2.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -5590,6 +5138,26 @@ "picomatch": "^2.0.4" } }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", @@ -5607,6 +5175,41 @@ "requires": { "is-number": "^7.0.0" } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } } } }, @@ -5652,9 +5255,9 @@ } }, "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" }, "nanomatch": { "version": "1.2.13", @@ -5781,15 +5384,6 @@ "path-is-absolute": "^1.0.0" } }, - "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -5842,12 +5436,12 @@ } }, "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "requires": { - "abbrev": "1" + "abbrev": "1", + "osenv": "^0.1.4" } }, "normalize-package-data": { @@ -6351,26 +5945,11 @@ "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", "requires": { "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" + }, + "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -6383,60 +5962,6 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } } } }, @@ -6456,9 +5981,9 @@ "dev": true }, "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, "punycode": { @@ -6921,9 +6446,9 @@ "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -6963,21 +6488,6 @@ "optional": true, "requires": { "glob": "^6.0.1" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "ripemd160": { @@ -7009,7 +6519,7 @@ } }, "rsk-openapi-ui": { - "version": "git+https://git@github.com/rsksmart/rsk-openapi-ui.git#00aab44d91d203f785b3d8c24c5a6e18cd9bcae3", + "version": "git+https://git@github.com/rsksmart/rsk-openapi-ui.git#2a311b7aee53e8557c8ce511b3bef190f6d123b2", "from": "git+https://git@github.com/rsksmart/rsk-openapi-ui.git", "requires": { "swagger-ui": "^3.24.0" @@ -7024,13 +6534,10 @@ } }, "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true }, "rx-lite": { "version": "4.0.8", @@ -7238,6 +6745,14 @@ "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } } }, "snapdragon": { @@ -7273,12 +6788,6 @@ "requires": { "is-extendable": "^0.1.0" } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, @@ -7453,9 +6962,9 @@ } }, "socket.io-parser": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", - "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", + "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", "requires": { "component-emitter": "1.2.1", "debug": "~4.1.0", @@ -7615,12 +7124,13 @@ } }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string.prototype.trimend": { @@ -7652,18 +7162,11 @@ } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - } + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -7735,20 +7238,6 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -7802,6 +7291,16 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -7891,13 +7390,6 @@ "url-parse": "^1.4.7", "xml-but-prettier": "^1.0.1", "zenscroll": "^4.0.2" - }, - "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - } } }, "symbol-observable": { @@ -7917,6 +7409,39 @@ "lodash": "^4.17.4", "slice-ansi": "1.0.0", "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "tar": { @@ -7931,13 +7456,6 @@ "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" - }, - "dependencies": { - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "term-size": { @@ -8055,6 +7573,17 @@ "dev": true, "requires": { "nopt": "~1.0.10" + }, + "dependencies": { + "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" + } + } } }, "traverse": { @@ -8338,9 +7867,9 @@ } }, "validator": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-11.1.0.tgz", - "integrity": "sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", + "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==", "dev": true }, "vary": { @@ -8383,58 +7912,61 @@ "dev": true, "requires": { "string-width": "^2.1.1" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "strip-ansi": "^4.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^3.0.0" } } } }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8461,9 +7993,9 @@ } }, "ws": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" }, "xdg-basedir": { "version": "3.0.0", @@ -8485,33 +8017,56 @@ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" }, "dependencies": { "ansi-regex": { @@ -8520,6 +8075,23 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -8539,45 +8111,59 @@ "requires": { "ansi-regex": "^4.1.0" } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } } } }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" }, "z-schema": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.2.tgz", - "integrity": "sha512-7bGR7LohxSdlK1EOdvA/OHksvKGE4jTLSjd8dBj9YKT0S43N9pdMZ0Z7GZt9mHrBFhbNTRh3Ky6Eu2MHsPJe8g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.3.tgz", + "integrity": "sha512-zkvK/9TC6p38IwcrbnT3ul9in1UX4cm1y/VZSs4GHKIiDCrlafc+YQBgQBUdDXLAoZHf2qvQ7gJJOo6yT1LH6A==", "dev": true, "requires": { "commander": "^2.7.1", "lodash.get": "^4.4.2", "lodash.isequal": "^4.5.0", - "validator": "^11.0.0" + "validator": "^12.0.0" }, "dependencies": { "commander": { diff --git a/package.json b/package.json index 2c0bc3ce..98efd554 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rsk-explorer-api", - "version": "1.0.8", + "version": "1.1.0", "description": "", "main": "index.js", "scripts": { diff --git a/public/swagger.json b/public/swagger.json index 458dab70..57537a93 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -1,7 +1,7 @@ { "info": { "title": "rsk-explorer-api", - "version": "1.0.8", + "version": "1.1.0", "description": "explorer API Documentation" }, "swagger": "2.0", @@ -304,6 +304,133 @@ } } }, + "/api?module=balances&action=getBalance": { + "get": { + "description": "get address balance at blockNumber (if exists)", + "tags": [ + "balances" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "balances" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getBalance" + ] + }, + { + "$ref": "#/parameters/address" + }, + { + "name": "block", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "block hash or block number", + "example": 30000 + } + } + ], + "responses": { + "200": { + "$ref": "#/definitions/Response" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=balances&action=getBalances": { + "get": { + "description": "get address balances", + "tags": [ + "balances" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "balances" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getBalances" + ] + }, + { + "$ref": "#/parameters/address" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/Response" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=balances&action=getStatus": { + "get": { + "description": "get status of balances", + "tags": [ + "balances" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "balances" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getStatus" + ] + } + ], + "responses": { + "200": { + "$ref": "#/definitions/Response" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, "/api?module=blocks&action=getBlock": { "get": { "description": "get block data", @@ -400,6 +527,25 @@ } } }, + "/api?module=contractVerifier&action=getVerifiedContracts": { + "get": { + "description": "Gets a list of verified contracts addresses", + "tags": [ + "contract verifier" + ], + "responses": { + "200": { + "$ref": "#/definitions/Response" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, "/api?module=contractVerifier&action=verify": { "get": { "description": "Verify contract source", @@ -812,6 +958,257 @@ } } }, + "/api?module=internalTransactions&action=getInternalTransaction": { + "get": { + "description": "get internal transaction", + "tags": [ + "internal transactions" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "internalTransactions" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getInternalTransaction" + ] + }, + { + "name": "eventId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/prev" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/ResponseList" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=internalTransactions&action=getInternalTransactions": { + "get": { + "description": "get internal transactions", + "tags": [ + "internal transactions" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "internalTransactions" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getInternalTransactions" + ] + }, + { + "name": "query", + "in": "query", + "required": false, + "schema": { + "type": "object" + } + }, + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/prev" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/ResponseList" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=internalTransactions&action=getInternalTransactionsByAddress": { + "get": { + "description": "get internal transactions by address", + "tags": [ + "internal transactions" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "internalTransactions" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getInternalTransactionsByAddress" + ] + }, + { + "$ref": "#/parameters/address" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/ResponseList" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=internalTransactions&action=getInternalTransactionsByBlock": { + "get": { + "description": "get internal transactions by block", + "tags": [ + "internal transactions" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "internalTransactions" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getInternalTransactionsByBlock" + ] + }, + { + "$ref": "#/parameters/hashOrNumber" + }, + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/prev" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/ResponseList" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, + "/api?module=internalTransactions&action=getInternalTransactionsByTxHash": { + "get": { + "description": "get internal transactions by tx hash", + "tags": [ + "internal transactions" + ], + "parameters": [ + { + "name": "module", + "in": "query", + "required": true, + "enum": [ + "internalTransactions" + ] + }, + { + "name": "action", + "in": "query", + "required": true, + "enum": [ + "getInternalTransactionsByTxHash" + ] + }, + { + "$ref": "#/parameters/transactionHash" + }, + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/prev" + } + ], + "responses": { + "200": { + "$ref": "#/definitions/ResponseList" + }, + "400": { + "$ref": "#/responses/BadRequest" + }, + "404": { + "$ref": "#/responses/NotFound" + } + } + } + }, "/api?module=stats&action=getStats": { "get": { "description": "get stats",