diff --git a/.gitignore b/.gitignore index c760344..f081cae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ logs/ .vscode/ test.js package-lock.json - diff --git a/README.md b/README.md index 1d48832..f6c6169 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ # ADAMANT JavaScript API library -ADAMANT JavaScript API is a library intended to interact with ADAMANT blockchain for Node.js developers. Also [ADAMANT Console](https://github.com/Adamant-im/adamant-console/wiki) and [ADAMANT node Direct API](https://github.com/Adamant-im/adamant/wiki/) are available. +ADAMANT JavaScript API is a library intended to interact with ADAMANT blockchain for JavaScript developers. Also [ADAMANT Console](https://github.com/Adamant-im/adamant-console/wiki) and [ADAMANT node Direct API](https://github.com/Adamant-im/adamant/wiki/) are available. -Abilities: +Features: -* Internal Health Check for ADAMANT nodes. Health Check system pings all nodes in the list using [`/status`](https://github.com/Adamant-im/adamant/wiki/API-Specification#get-blockchain-and-network-status) endpoint, and connect to a node with actual height. +* High reliability +* GET-requests to the blockchain +* Sending tokens +* Sending messages +* Caching public keys * Encrypting and decrypting of messages * Forming and signing transactions * Working with ADM key pairs @@ -13,14 +17,19 @@ Abilities: * Support for WebSocket connections * Logging warnings, errors, info -# Usage +## Reliability -Add current version of ADAMANT JavaScript API library in project's `package.json` in `dependencies` section like this: +JS API shows decentralization in action—if a network node cannot fulfill your request, the library will redirect it to another node, and so on several times. You will get the result and you do not need to think about processing the request. + +Health Check system pings all nodes in the list using [`/status`](https://github.com/Adamant-im/adamant/wiki/API-Specification#get-blockchain-and-network-status) endpoint, and connects to a node with actual height. When the library unable to process request with current node, it forces to re-initialize Health Check. + +## Usage + +Add current version of ADAMANT JavaScript API library in project's `package.json` in `dependencies` section: ``` json "dependencies": { - "adamant-api": "^0.5.3", - ... + "adamant-api": "^1.0.0-beta.2", ``` Or install library from npm: @@ -29,6 +38,28 @@ Or install library from npm: npm i adamant-api ``` -# Documentation +Initialize the library: + +``` JS +const nodesList = [ + "http://localhost:36666", + "https://endless.adamant.im", + "https://clown.adamant.im", + "http://23.226.231.225:36666", + "http://88.198.156.44:36666", + "https://lake.adamant.im" +]; +const api = require('adamant-api')({ node: nodesList, logLevel: 'info' }); +``` + +Request example: + +``` JS +api.get('blocks').then(response => { + console.log(response.data) +}) +``` + +## Documentation See [Wiki](https://github.com/Adamant-im/adamant-api-jsclient/wiki) for documentation and usage. diff --git a/groups/decodeMsg.js b/groups/decodeMsg.js index 460dcf3..31829bb 100644 --- a/groups/decodeMsg.js +++ b/groups/decodeMsg.js @@ -3,6 +3,7 @@ const nacl = require('tweetnacl/nacl-fast'); const keys = require('../helpers/keys'); module.exports = (msg, senderPublicKey, passPhrase, nonce) => { + const keypair = keys.createKeypairFromPassPhrase(passPhrase); let privateKey = keypair.privateKey; if (typeof msg === 'string') { @@ -23,10 +24,11 @@ module.exports = (msg, senderPublicKey, passPhrase, nonce) => { const DHSecretKey = ed2curve.convertSecretKey(privateKey); const decrypted = nacl.box.open(msg, nonce, DHPublicKey, DHSecretKey); return decrypted ? Utf8ArrayToStr(decrypted) : '' -} +} function hexToBytes(hexString = '') { + const bytes = [] for (let c = 0; c < hexString.length; c += 2) { @@ -34,9 +36,11 @@ function hexToBytes(hexString = '') { } return Uint8Array.from(bytes); + } function Utf8ArrayToStr(array) { + var out, i, len, c; var char2, char3; @@ -75,4 +79,5 @@ function Utf8ArrayToStr(array) { } return out; + } \ No newline at end of file diff --git a/groups/eth.js b/groups/eth.js index 737f31a..efd3548 100644 --- a/groups/eth.js +++ b/groups/eth.js @@ -1,10 +1,8 @@ -// https://web3js.readthedocs.io/en/1.0/web3-eth.html#eth-getbalance -const Web3 = require('web3'); var Mnemonic = require('bitcore-mnemonic'); const hdkey = require('hdkey'); const HD_KEY_PATH = "m/44'/60'/3'/1/0"; -const {bufferToHex, privateToAddress } = require('ethereumjs-util'); -const {eth} = new Web3('https://ethnode1.adamant.im'); +const { bufferToHex, privateToAddress } = require('ethereumjs-util'); +const eth = { } /** * Generates a ETH account from the passphrase specified. diff --git a/groups/get.js b/groups/get.js index fa6c51f..507c522 100644 --- a/groups/get.js +++ b/groups/get.js @@ -1,74 +1,46 @@ -const request = require('sync-request'); +const axios = require('axios'); const logger = require('../helpers/logger'); +const validator = require('../helpers/validator'); -module.exports = (syncReq) => { - return async (type, params) => { - let endpoint; - let returned_field = false; - switch (type) { - case 'account': - endpoint = '/api/accounts?address=' + params; - break; - case 'delegate_forged': - endpoint = '/api/delegates/forging/getForgedByAccount?generatorPublicKey=' + params; - break; - case 'account_delegates': - endpoint = '/api/accounts/delegates?address=' + params; - returned_field = 'delegates'; - break; - case 'block': - endpoint = '/api/blocks/get?id=' + params; - break; - case 'states': - endpoint = '/api/states/get'; - if (params) { - endpoint = endpoint + '?' + params; - } - break; - case 'delegate': - endpoint = '/api/delegates/get?username=' + params; - returned_field = 'delegate'; - break; - case 'delegate_voters': - endpoint = '/api/delegates/voters?publicKey=' + params; - returned_field = 'accounts'; - break; - case 'blocks': - endpoint = '/api/blocks'; - if (params) { - endpoint = endpoint + '?' + params; - } - returned_field = 'blocks'; - break; - case 'transaction': - endpoint = '/api/transactions/get?id=' + params; - break; - case 'transactions': - endpoint = '/api/transactions?' + params.split(' ').join('').split(',').join('&'); - break; - case 'uri': - endpoint = '/api/' + params; - break; - default: - logger.error(`ADAMANT endpoint ${type} not implemented yet. Use 'uri' to use not implemented endpoints.`); - return false; - } +const DEFAULT_GET_REQUEST_RETRIES = 3; // How much re-tries for get-requests by default. Total 3+1 tries - try { - const res = await syncReq(endpoint); - if (res && res.success) { - if (returned_field) { - return res[returned_field]; - } - return res; - } +module.exports = (nodeManager) => { + return (endpoint, params, maxRetries = DEFAULT_GET_REQUEST_RETRIES, retryNo = 0) => { - logger.warn(`Get request to ADAMANT node was not successful. Type: ${type}, URL: ${endpoint}, Result: ${res && res.error}`); - return false; + let url = trimAny(endpoint, "/ ").replace(/^api\//, ''); + if (!url || !validator.validateEndpoint(endpoint)) + return validator.badParameter('endpoint') - } catch (e) { - logger.error(`Failed to process Get request of type ${type} to ADAMANT node. Error: ${e}.`); - return false; - } - }; + url = nodeManager.node() + '/api/' + url; + return axios.get(url, { params }) + .then(function (response) { + return validator.formatRequestResults(response, true) + }) + .catch(function (error) { + let logMessage = `[ADAMANT js-api] Get-request: Request to ${url} failed with ${error.response ? error.response.status : undefined} status code, ${error.toString()}${error.response && error.response.data ? '. Message: ' + error.response.data.toString().trim() : ''}. Try ${retryNo+1} of ${maxRetries+1}.`; + if (retryNo < maxRetries) { + logger.log(`${logMessage} Retrying…`); + return nodeManager.changeNodes() + .then(function () { + return module.exports(nodeManager)(endpoint, params, maxRetries, ++retryNo) + }) + } + logger.warn(`${logMessage} No more attempts, returning error.`); + return validator.formatRequestResults(error, false) + }) + + } }; + +function trimAny(str, chars) { + if (!str || typeof str !== 'string') + return '' + let start = 0, + end = str.length; + while(start < end && chars.indexOf(str[start]) >= 0) + ++start; + while(end > start && chars.indexOf(str[end - 1]) >= 0) + --end; + return (start > 0 || end < str.length) ? str.substring(start, end) : str; +} + diff --git a/groups/getPublicKey.js b/groups/getPublicKey.js new file mode 100644 index 0000000..dc40b21 --- /dev/null +++ b/groups/getPublicKey.js @@ -0,0 +1,21 @@ +const get = require('./get'); +const logger = require('../helpers/logger'); +const publicKeysCache = { }; + +module.exports = (nodeManager) => { + + return async (address) => { + if (publicKeysCache[address]) + return publicKeysCache[address] + + const publicKey = await get(nodeManager)('/accounts/getPublicKey', { address }); + if (publicKey.success) { + publicKeysCache[address] = publicKey.data.publicKey; + return publicKey.data.publicKey + } else { + logger.warn(`[ADAMANT js-api] Failed to get public key for ${address}. ${publicKey.errorMessage}.`); + return false + } + } + +}; diff --git a/groups/send.js b/groups/send.js deleted file mode 100644 index 0257c31..0000000 --- a/groups/send.js +++ /dev/null @@ -1,88 +0,0 @@ -const request = require('sync-request'); -const keys = require('../helpers/keys'); -const encrypter = require('../helpers/encrypter'); -const constants = require('../helpers/constants'); -const logger = require('../helpers/logger'); -const transactionFormer = require('../helpers/transactionFormer'); -const SAT = 100000000; - -module.exports = (hotNode) => { - - return (passPhrase, address, payload, type = 'tokens', isEncode, amount_comment) => { - - const recipientId = address; - const keyPair = keys.createKeypairFromPassPhrase(passPhrase); - - if (type === 'tokens') { - try { - const amount = parseInt(parseFloat(String(payload)) * SAT); - const data = { - keyPair, - recipientId, - amount - }; - const transaction = transactionFormer.createTransaction(constants.transactionTypes.SEND, data); - const res = JSON.parse(request('POST', hotNode() + '/api/transactions/process', { - json: { - transaction - } - }).getBody().toString()); - - return res; - - } catch (e) { - logger.error('Error while sending tokens: ' + e); - return false; - } - - } else if (['message', 'rich', 'signal'].includes(type)) { - - try { - let message_type = 1; - - if (type === 'rich') - message_type = 2; - if (type === 'signal') - message_type = 3; - - const data = { - keyPair, - recipientId, - message_type - }; - - if (amount_comment) { - data.amount = parseInt(parseFloat(String(amount_comment)) * SAT); - } - - const res = request('GET', hotNode() + '/api/accounts/getPublicKey?address=' + recipientId); - const answer = JSON.parse(res.getBody().toString()); - - if (answer.success) { - const encrypt_data = encrypter.encodeMessage(payload, keyPair, answer.publicKey); - - data.message = encrypt_data.message; - data.own_message = encrypt_data.own_message; - const transaction = transactionFormer.createTransaction(constants.transactionTypes.CHAT_MESSAGE, data); - - if (isEncode) { - return transaction; - } - - const res = JSON.parse(request('POST', hotNode() + '/api/transactions/process', { - json: { - transaction - } - }).getBody().toString()); - - return res; - - } - - } catch (e) { - logger.error(`Error while sending message of type ${type}: ${e}`); - return false; - } - } - }; -}; diff --git a/groups/sendMessage.js b/groups/sendMessage.js new file mode 100644 index 0000000..991628c --- /dev/null +++ b/groups/sendMessage.js @@ -0,0 +1,143 @@ +const axios = require('axios'); +const logger = require('../helpers/logger'); +const keys = require('../helpers/keys'); +const constants = require('../helpers/constants'); +const encryptor = require('../helpers/encryptor'); +const transactionFormer = require('../helpers/transactionFormer'); +const validator = require('../helpers/validator'); +const getPublicKey = require('./getPublicKey'); + +const DEFAULT_SEND_MESSAGE_RETRIES = 4; // How much re-tries for send message requests by default. Total 4+1 tries + +module.exports = (nodeManager) => { + /** + * Encrypts a message, creates Message transaction, signs it, and broadcasts to ADAMANT network. Supports Basic, Rich and Signal Message Types. + * See https://github.com/Adamant-im/adamant/wiki/Message-Types + * @param {string} passPhrase Senders's passPhrase. Sender's address will be derived from it. + * @param {string} addressOrPublicKey Recipient's ADAMANT address or public key. + * Using public key is faster, as the library wouldn't request it from the network. + * Though we cache public keys, and next request with address will be processed as fast as with public key. + * @param {string} message Message plain text in case of basic message. Stringified JSON in case of rich or signal messages. The library will encrypt a message. + * Example of rich message for Ether in-chat transfer: `{"type":"eth_transaction","amount":"0.002","hash":"0xfa46d2b3c99878f1f9863fcbdb0bc27d220d7065c6528543cbb83ced84487deb","comments":"I like to send it, send it"}` + * @param {string, number} message_type Type of message: basic, rich, or signal + * @param {string, number} amount Amount to send with a message + * @param {boolean} isAmountInADM If amount specified in ADM, or in sats (10^-8 ADM) + * @param {number} maxRetries How much times to retry request + * @returns {Promise} Request results + */ + return async (passPhrase, addressOrPublicKey, message, message_type = 'basic', amount, isAmountInADM = true, maxRetries = DEFAULT_SEND_MESSAGE_RETRIES, retryNo = 0) => { + + let keyPair, data; + let address, publicKey; + + try { + + if (!validator.validatePassPhrase(passPhrase)) + return validator.badParameter('passPhrase') + + keyPair = keys.createKeypairFromPassPhrase(passPhrase); + + if (!validator.validateAdmAddress(addressOrPublicKey)) { + if (!validator.validateAdmPublicKey(addressOrPublicKey)) { + return validator.badParameter('addressOrPublicKey', addressOrPublicKey) + } else { + publicKey = addressOrPublicKey; + try { + address = keys.createAddressFromPublicKey(publicKey) + } catch (e) { + return validator.badParameter('addressOrPublicKey', addressOrPublicKey) + } + } + } else { + publicKey = ''; + address = addressOrPublicKey + } + + if (message_type === 'basic') + message_type = 1; + if (message_type === 'rich') + message_type = 2; + if (message_type === 'signal') + message_type = 3; + + if (!validator.validateMessageType(message_type)) + return validator.badParameter('message_type', message_type) + + let messageValidation = validator.validateMessage(message, message_type); + if (!messageValidation.result) + return validator.badParameter('message', message, messageValidation.error) + + data = { + keyPair, + recipientId: address, + message_type + }; + + if (amount) { + if (isAmountInADM) { + amountInSat = validator.AdmToSats(amount) + } else { + amountInSat = amount + } + if (!validator.validateIntegerAmount(amountInSat)) + return validator.badParameter('amount', amount) + data.amount = amountInSat; + } + + } catch (e) { + + return validator.badParameter('#exception_catched#', e) + + } + + if (!publicKey) + publicKey = await getPublicKey(nodeManager)(address); + + if (!publicKey) + return new Promise((resolve, reject) => { + resolve({ + success: false, + errorMessage: `Unable to get public key for ${addressOrPublicKey}. It is necessary for sending an encrypted message. Account may be uninitialized (https://medium.com/adamant-im/chats-and-uninitialized-accounts-in-adamant-5035438e2fcd), or network error` + }) + }) + + try { + + const encryptedMessage = encryptor.encodeMessage(message, keyPair, publicKey); + data.message = encryptedMessage.message; + data.own_message = encryptedMessage.own_message; + + let transaction = transactionFormer.createTransaction(constants.transactionTypes.CHAT_MESSAGE, data); + + let url = nodeManager.node() + '/api/transactions/process'; + return axios.post(url, { transaction }) + .then(function (response) { + return validator.formatRequestResults(response, true) + }) + .catch(function (error) { + let logMessage = `[ADAMANT js-api] Send message request: Request to ${url} failed with ${error.response ? error.response.status : undefined} status code, ${error.toString()}${error.response && error.response.data ? '. Message: ' + error.response.data.toString().trim() : ''}. Try ${retryNo+1} of ${maxRetries+1}.`; + if (retryNo < maxRetries) { + logger.log(`${logMessage} Retrying…`); + return nodeManager.changeNodes() + .then(function () { + return module.exports(nodeManager)(passPhrase, addressOrPublicKey, message, message_type, tokensAmount, maxRetries, ++retryNo) + }) + } + logger.warn(`${logMessage} No more attempts, returning error.`); + return validator.formatRequestResults(error, false) + }) + + } catch (e) { + + return new Promise((resolve, reject) => { + resolve({ + success: false, + errorMessage: `Unable to encode message '${message}' with public key ${publicKey}, or unable to build a transaction. Exception: ` + e + }) + }) + + } + + } // sendMessage() + +}; diff --git a/groups/sendTokens.js b/groups/sendTokens.js new file mode 100644 index 0000000..6e5da0d --- /dev/null +++ b/groups/sendTokens.js @@ -0,0 +1,92 @@ +const axios = require('axios'); +const logger = require('../helpers/logger'); +const keys = require('../helpers/keys'); +const constants = require('../helpers/constants'); +const transactionFormer = require('../helpers/transactionFormer'); +const validator = require('../helpers/validator'); + +const DEFAULT_SEND_TOKENS_RETRIES = 4; // How much re-tries for send tokens requests by default. Total 4+1 tries + +module.exports = (nodeManager) => { + /** + * Creates Token Transfer transaction, signs it, and broadcasts to ADAMANT network + * See https://github.com/Adamant-im/adamant/wiki/Transaction-Types#type-0-token-transfer-transaction + * @param {string} passPhrase Senders's passPhrase. Sender's address will be derived from it. + * @param {string} addressOrPublicKey Recipient's ADAMANT address or public key. + * Address is preferred, as if we get public key, we should derive address from it. + * @param {string, number} amount Amount to send + * @param {boolean} isAmountInADM If amount specified in ADM, or in sats (10^-8 ADM) + * @param {number} maxRetries How much times to retry request + * @returns {Promise} Request results + */ + return (passPhrase, addressOrPublicKey, amount, isAmountInADM = true, maxRetries = DEFAULT_SEND_TOKENS_RETRIES, retryNo = 0) => { + + let transaction; + let address, publicKey; + + try { + + if (!validator.validatePassPhrase(passPhrase)) + return validator.badParameter('passPhrase') + + const keyPair = keys.createKeypairFromPassPhrase(passPhrase); + + if (!validator.validateAdmAddress(addressOrPublicKey)) { + if (!validator.validateAdmPublicKey(addressOrPublicKey)) { + return validator.badParameter('addressOrPublicKey', addressOrPublicKey) + } else { + publicKey = addressOrPublicKey; + try { + address = keys.createAddressFromPublicKey(publicKey) + } catch (e) { + return validator.badParameter('addressOrPublicKey', addressOrPublicKey) + } + } + } else { + publicKey = ''; + address = addressOrPublicKey + } + + if (isAmountInADM) { + amountInSat = validator.AdmToSats(amount) + } else { + amountInSat = amount + } + + if (!validator.validateIntegerAmount(amountInSat)) + return validator.badParameter('amount', amount) + + const data = { + keyPair, + recipientId: address, + amount: amountInSat + }; + + transaction = transactionFormer.createTransaction(constants.transactionTypes.SEND, data); + + } catch (e) { + + return validator.badParameter('#exception_catched#', e) + + } + + let url = nodeManager.node() + '/api/transactions/process'; + return axios.post(url, { transaction }) + .then(function (response) { + return validator.formatRequestResults(response, true) + }) + .catch(function (error) { + let logMessage = `[ADAMANT js-api] Send tokens request: Request to ${url} failed with ${error.response ? error.response.status : undefined} status code, ${error.toString()}${error.response && error.response.data ? '. Message: ' + error.response.data.toString().trim() : ''}. Try ${retryNo+1} of ${maxRetries+1}.`; + if (retryNo < maxRetries) { + logger.log(`${logMessage} Retrying…`); + return nodeManager.changeNodes() + .then(function () { + return module.exports(nodeManager)(passPhrase, addressOrPublicKey, amount, isAmountInADM, maxRetries, ++retryNo) + }) + } + logger.warn(`${logMessage} No more attempts, returning error.`); + return validator.formatRequestResults(error, false) + }) + + } +}; diff --git a/groups/syncGet.js b/groups/syncGet.js deleted file mode 100644 index 701409e..0000000 --- a/groups/syncGet.js +++ /dev/null @@ -1,30 +0,0 @@ -const request = require('request'); -const logger = require('../helpers/logger'); - -module.exports = (node, changeNodes) => { - return (uri, isUrl, isNoJson) => { - return new Promise(resolve => { - let url = isUrl && uri || node() + uri; - request(url, (a, b) => { - try { - const {body} = b; - if (isNoJson) { - resolve(body); - } else { - resolve(JSON.parse(body)); - } - } catch (e) { - let output = `Failed to process Syn-Get request ${url}. `; - if (isUrl) { // Request not to ADAMANT node - output += `Host may be unavailable. Error: ${e}` - } else { // Request to ADAMANT node - output += `Forcing to change active node now. Error: ${e}` - changeNodes(); - } - logger.warn(output); - resolve(null); - } - }); - }); - }; -}; diff --git a/helpers/constants.js b/helpers/constants.js index aa45399..55ed58e 100644 --- a/helpers/constants.js +++ b/helpers/constants.js @@ -1,4 +1,5 @@ module.exports = { + epochTime: new Date(Date.UTC(2017, 8, 2, 17, 0, 0, 0)), fees: { send: 50000000, @@ -25,5 +26,14 @@ module.exports = { CHAT_MESSAGE: 8, STATE: 9 }, - maxVotesPerTransaction: 33 -} \ No newline at end of file + maxVotesPerTransaction: 33, + SAT: 100000000, + RE_HEX: /^[a-fA-F0-9]+$/, + RE_BASE64: /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/, + RE_ADM_ADDRESS: /^U([0-9]{6,})$/, + RE_BTC_ADDRESS: /^(bc1|[13])[a-km-zA-HJ-NP-Z02-9]{25,39}$/, + RE_DASH_ADDRESS: /^[7X][1-9A-HJ-NP-Za-km-z]{33,}$/, + RE_DOGE_ADDRESS: /^[A|D|9][A-Z0-9]([0-9a-zA-Z]{9,})$/, + RE_LSK_ADDRESS: /^[0-9]{2,21}L$/ + +} diff --git a/helpers/encrypter.js b/helpers/encryptor.js similarity index 81% rename from helpers/encrypter.js rename to helpers/encryptor.js index 66b06bd..fe5e4cf 100644 --- a/helpers/encrypter.js +++ b/helpers/encryptor.js @@ -1,14 +1,9 @@ var sodium = require('sodium-browserify-tweetnacl') -var crypto = require('crypto') -var Mnemonic = require('bitcore-mnemonic') -var bignum = require('./bignumber.js') -var keys = require('./keys.js') var nacl = require('tweetnacl/nacl-fast') var ed2curve = require('ed2curve') -var ByteBuffer = require('bytebuffer') -const constants = require('./constants.js') module.exports = { + bytesToHex: function (bytes) { for (var hex = [], i = 0; i < bytes.length; i++) { hex.push((bytes[i] >>> 4).toString(16)) @@ -16,12 +11,14 @@ module.exports = { } return hex.join('') }, + hexToBytes: function (hex) { for (var bytes = [], c = 0; c < hex.length; c += 2) { bytes.push(parseInt(hex.substr(c, 2), 16)) } return bytes }, + encodeMessage: function (msg, keypair, recipientPublicKey) { var nonce = Buffer.allocUnsafe(24) sodium.randombytes(nonce) @@ -34,4 +31,5 @@ module.exports = { own_message: this.bytesToHex(nonce) } } + } diff --git a/helpers/healthCheck.js b/helpers/healthCheck.js index a111895..239e541 100644 --- a/helpers/healthCheck.js +++ b/helpers/healthCheck.js @@ -1,130 +1,198 @@ -const request = require('request'); -const _ = require('lodash'); +const axios = require('axios'); const socket = require('./wsClient'); const logger = require('./logger'); -const HEIGHT_EPSILON = 10; // Used to group nodes by height and choose synced +const validator = require('./validator'); +const dnsPromises = require('dns').promises; + +const CHECK_NODES_INTERVAL = 60 * 5 * 1000; // Update active nodes every 5 minutes +const HEIGHT_EPSILON = 5; // Used to group nodes by height and choose synced module.exports = (nodes) => { - if (typeof nodes === 'string') { - return () => nodes; + isCheckingNodes = false; + nodesList = nodes; + activeNode = nodesList[0]; + liveNodes = []; + + /** + * Updates active nodes. If nodes are already updating, returns Promise of previous call + * @returns {Promise} Call changeNodes().then to do something when update complete + */ + function changeNodes (isPlannedUpdate = false) { + if (!isCheckingNodes) { + changeNodesPromise = new Promise(async (resolve) => { + if (!isPlannedUpdate) { + logger.warn('[ADAMANT js-api] Health check: Forcing to update active nodes…'); + } + await checkNodes(isPlannedUpdate? false : true) + resolve(true) + }); + } + return changeNodesPromise } - this.hotNode = nodes[0]; - this.liveNodes = []; - checkNodes(nodes, this); - - setInterval(() => { - checkNodes(_.shuffle(nodes), this); - }, 60 * 1000); + + changeNodes(true) + setInterval(() => { changeNodes(true) }, CHECK_NODES_INTERVAL); return { - node: () => { // Current active node for REST requests - return this.hotNode; + + /** + * @returns {string} Current active node, f. e. http://88.198.156.44:36666 + */ + node: () => { + return activeNode; }, - changeNodes: _.throttle(() => { - logger.warn('[Health check]: Forcing to change node.'); - // To do: choose not the fastest node? May the fastest be defective? - checkNodes(_.shuffle(nodes), this); - }, 5000) + + changeNodes + }; + }; -// Request every node for its status and make a list of active ones -async function checkNodes(nodes, context) { - - context.liveNodes = []; - nodes.forEach(async n => { - try { - const start = unix(); - const req = await checkNode(n + '/api/node/status'); - - if (req.status) { - context.liveNodes.push({ - node: n, - ifHttps: n.startsWith("https"), - url: n.replace(/^https?:\/\/(.*)$/, '$1').split(":")[0], - outOfSync: false, - ping: unix() - start, - height: req.status.network.height, - heightEpsilon: Math.round(req.status.network.height / HEIGHT_EPSILON), - ip: req.ip, - socketSupport: req.status.wsClient && req.status.wsClient.enabled, - wsPort: req.status.wsClient.port - }); - } else { - logger.log(`Node ${n} haven't returned its status.`); +/** + * Requests every ADAMANT node for its status, makes a list of live nodes, and chooses one active + */ +async function checkNodes(forceChangeActiveNode) { + + this.isCheckingNodes = true; + this.liveNodes = []; + + try { + + for (const n of this.nodesList) { + try { + let start = unixTimestamp(); + let req = await checkNode(n + '/api/node/status'); + let url = n.replace(/^https?:\/\/(.*)$/, '$1').split(":")[0]; + let ifIP = /(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/.test(url) + + if (req.status) { + this.liveNodes.push({ + node: n, + ifHttps: n.startsWith("https"), + ifIP, + url, + outOfSync: false, + ping: unixTimestamp() - start, + height: req.status.network.height, + heightEpsilon: Math.round(req.status.network.height / HEIGHT_EPSILON), + ip: ifIP ? url : await getIP(url), + socketSupport: req.status.wsClient && req.status.wsClient.enabled, + wsPort: req.status.wsClient.port + }); + + } else { + logger.log(`[ADAMANT js-api] Health check: Node ${n} haven't returned its status`); + } + + } catch (e) { + logger.log(`[ADAMANT js-api] Health check: Error while checking node ${n}, ` + e); } - } catch (e) { - logger.log('Error while checking node', n); } - }); - setTimeout(() => { // Allow 3 seconds to request nodes + const count = this.liveNodes.length; + let outOfSyncCount = 0; - const count = context.liveNodes.length; if (!count) { - logger.error('[Health check]: All of ADAMANT nodes are unavailable. Check internet connection and nodes list in config.'); - return; - } + logger.error(`[ADAMANT js-api] Health check: All of ${this.nodesList.length} nodes are unavailable. Check internet connection and nodes list in config.`); + } else { - // Set hotNode to one that have maximum height and minimum ping - if (count === 1) { - context.hotNode = context.liveNodes[0].node; - } else if (count === 2) { - const h0 = context.liveNodes[0]; - const h1 = context.liveNodes[1]; - context.hotNode = h0.height > h1.height ? h0.node : h1.node; - - // Mark node outOfSync if needed - if (h0.heightEpsilon > h1.heightEpsilon) { - context.liveNodes[1].outOfSync = true - } else if (h0.heightEpsilon < h1.heightEpsilon) { - context.liveNodes[0].outOfSync = true - } + // Set activeNode to one that have maximum height and minimum ping + if (count === 1) { - } else { - let biggestGroup = []; - const groups = _.groupBy(context.liveNodes, n => n.heightEpsilon); - Object.keys(groups).forEach(key => { - if (groups[key].length > biggestGroup.length){ - biggestGroup = groups[key]; + this.activeNode = this.liveNodes[0].node; + + } else if (count === 2) { + + const h0 = this.liveNodes[0]; + const h1 = this.liveNodes[1]; + this.activeNode = h0.height > h1.height ? h0.node : h1.node; + // Mark node outOfSync if needed + if (h0.heightEpsilon > h1.heightEpsilon) { + this.liveNodes[1].outOfSync = true + outOfSyncCount += 1; + } else if (h0.heightEpsilon < h1.heightEpsilon) { + this.liveNodes[0].outOfSync = true + outOfSyncCount += 1; } - }); - // All the nodes from the biggestGroup list are considered to be in sync, all the others are not - context.liveNodes.forEach(node => { - node.outOfSync = !biggestGroup.includes(node) - }) - - biggestGroup.sort((a, b) => a.ping - b.ping); - context.liveNodes.sort((a, b) => a.ping - b.ping); - context.hotNode = biggestGroup[0].node; // Use node with minimum ping among which are synced + } else { + + let biggestGroup = []; + // Removing lodash: const groups = _.groupBy(this.liveNodes, n => n.heightEpsilon); + const groups = this.liveNodes.reduce(function (grouped, node) { + var int = Math.floor(node.heightEpsilon); // Excessive, it is already rounded + if (!grouped.hasOwnProperty(int)) { + grouped[int] = []; + } + grouped[int].push(node); + return grouped; + }, {}); + + Object.keys(groups).forEach(key => { + if (groups[key].length > biggestGroup.length) { + biggestGroup = groups[key]; + } + }); + + // All the nodes from the biggestGroup list are considered to be in sync, all the others are not + this.liveNodes.forEach(node => { + node.outOfSync = !biggestGroup.includes(node) + }) + outOfSyncCount = this.liveNodes.length - biggestGroup.length; + + biggestGroup.sort((a, b) => a.ping - b.ping); + this.liveNodes.sort((a, b) => a.ping - b.ping); + + if (forceChangeActiveNode && biggestGroup.length > 1 && this.activeNode === biggestGroup[0].node) + this.activeNode = biggestGroup[validator.getRandomIntInclusive(1, biggestGroup.length-1)].node // Use random node from which are synced + else + this.activeNode = biggestGroup[0].node; // Use node with minimum ping among which are synced + + } + socket.reviseConnection(this.liveNodes); + let unavailableCount = this.nodesList.length - this.liveNodes.length; + let supportedCount = this.liveNodes.length - outOfSyncCount; + let nodesInfoString = ''; + if (unavailableCount) + nodesInfoString += `, ${unavailableCount} nodes didn't respond` + if (outOfSyncCount) + nodesInfoString += `, ${outOfSyncCount} nodes are not synced` + logger.log(`[ADAMANT js-api] Health check: Found ${supportedCount} supported and synced nodes${nodesInfoString}. Active node is ${this.activeNode}.`); + } - socket.reviseConnection(context.liveNodes); - logger.log(`[Health check] Supported nodes: ${context.liveNodes.length}. hotNode is ${context.hotNode}.`); - // logger.logog('liveNodes', context.liveNodes, context.liveNodes.length); - }, 3000); + + } catch (e) { + logger.warn('[ADAMANT js-api] Health check: Error in checkNodes(), ' + e); + } + + this.isCheckingNodes = false; + } -// Request status from a single node +async function getIP(url) { + try { + let addresses = await dnsPromises.resolve4(url); + if (addresses && addresses[0] !== '0.0.0.0') + return addresses[0] + } catch (e) { } +}; + +/** + * Requests status from a single ADAMANT node + * @param url {string} Node URL to request + * @returns {Promise} Node's status information + */ function checkNode(url) { - return new Promise(resolve => { - request(url, (err, res, body) => { - if (err) { - resolve(false); - } else { - try { - const status = JSON.parse(body); - const result = {status: status, ip: res.connection.remoteAddress}; - resolve(result); - } catch (e) { - resolve(false); - } - } - }); - }); + return axios.get(url) + .then(function (response) { + return { status: response.data } + }) + .catch(function (error) { + return false + }) }; -function unix(){ +function unixTimestamp() { return new Date().getTime(); } diff --git a/helpers/keys.js b/helpers/keys.js index 3a938ec..0e2b317 100644 --- a/helpers/keys.js +++ b/helpers/keys.js @@ -4,9 +4,11 @@ var Mnemonic = require('bitcore-mnemonic'); var bignum = require('./bignumber.js'); module.exports = { - createNewPassPhrase: function () { + + createNewPassPhrase: function () { return new Mnemonic(Mnemonic.Words.ENGLISH).toString(); }, + makeKeypairFromHash: function (hash) { var keypair = sodium.crypto_sign_seed_keypair(hash); return { @@ -14,22 +16,24 @@ module.exports = { privateKey: keypair.secretKey }; }, + createHashFromPassPhrase: function (passPhrase) { var secretMnemonic = new Mnemonic(passPhrase, Mnemonic.Words.ENGLISH); return crypto.createHash('sha256').update(secretMnemonic.toSeed().toString('hex'), 'hex').digest(); }, + createKeypairFromPassPhrase: function (passPhrase) { var hash = this.createHashFromPassPhrase(passPhrase); return this.makeKeypairFromHash(hash); }, + createAddressFromPublicKey: function (publicKey) { var publicKeyHash = crypto.createHash('sha256').update(publicKey, 'hex').digest(); var temp = Buffer.alloc(8); - for (var i = 0; i < 8; i++) { temp[i] = publicKeyHash[7 - i]; } - return 'U' + bignum.fromBuffer(temp).toString(); } -}; \ No newline at end of file + +} diff --git a/helpers/logger.js b/helpers/logger.js index bfd1a07..43ca552 100644 --- a/helpers/logger.js +++ b/helpers/logger.js @@ -1,28 +1,35 @@ let logger = { - errorLevel: 'log', - l: console, - initLogger(errorLevel, log) { - if (errorLevel) - this.errorLevel = errorLevel; - if (log) - this.l = log; - }, + + errorLevel: 'log', + l: console, + + initLogger(errorLevel, log) { + if (errorLevel) + this.errorLevel = errorLevel; + if (log) + this.l = log; + }, + error(str) { - if (['error', 'warn', 'info', 'log'].includes(this.errorLevel)) - this.l.error(str); + if (['error', 'warn', 'info', 'log'].includes(this.errorLevel)) + this.l.error(str); }, + warn(str) { - if (['warn', 'info', 'log'].includes(this.errorLevel)) - this.l.warn(str); + if (['warn', 'info', 'log'].includes(this.errorLevel)) + this.l.warn(str); }, + info(str) { - if (['info', 'log'].includes(this.errorLevel)) - this.l.info(str); + if (['info', 'log'].includes(this.errorLevel)) + this.l.info(str); }, + log(str) { - if (['log'].includes(this.errorLevel)) - this.l.log(str); + if (['log'].includes(this.errorLevel)) + this.l.log(str); } + }; -module.exports = logger; \ No newline at end of file +module.exports = logger; diff --git a/helpers/time.js b/helpers/time.js index 11185ee..4e46bf4 100644 --- a/helpers/time.js +++ b/helpers/time.js @@ -1,16 +1,18 @@ const constants = require('./constants.js'); + module.exports = { + getEpochTime: function (time) { if (time === undefined) { time = Date.now(); } - var d = constants.epochTime; var t = d.getTime(); - return Math.floor((time - t) / 1000); }, + getTime: function (time) { return this.getEpochTime(time); } -} \ No newline at end of file + +} diff --git a/helpers/transactionFormer.js b/helpers/transactionFormer.js index 7fa8ca5..52107cd 100644 --- a/helpers/transactionFormer.js +++ b/helpers/transactionFormer.js @@ -1,6 +1,5 @@ var sodium = require('sodium-browserify-tweetnacl'); var crypto = require('crypto'); -var Mnemonic = require('bitcore-mnemonic'); var bignum = require('./bignumber.js'); var keys = require('./keys.js'); var ByteBuffer = require('bytebuffer'); @@ -8,25 +7,28 @@ const constants = require('./constants.js'); const time = require('./time.js'); module.exports = { + createTransaction: function (type, data) { switch (type) { - case constants.transactionTypes.SEND: - return this.createSendTransaction(data); - case constants.transactionTypes.VOTE: - return this.createVoteTransaction(data); - case constants.transactionTypes.DELEGATE: - return this.createDelegateTransaction(data); - case constants.transactionTypes.CHAT_MESSAGE: - return this.createChatTransaction(data); - case constants.transactionTypes.STATE: - return this.createStateTransaction(data); + case constants.transactionTypes.SEND: + return this.createSendTransaction(data); + case constants.transactionTypes.VOTE: + return this.createVoteTransaction(data); + case constants.transactionTypes.DELEGATE: + return this.createDelegateTransaction(data); + case constants.transactionTypes.CHAT_MESSAGE: + return this.createChatTransaction(data); + case constants.transactionTypes.STATE: + return this.createStateTransaction(data); } return {}; }, + createBasicTransaction: function (data) { - var transaction = {type: data.transactionType, amount: 0, timestamp: time.getTime(), asset: {}, senderPublicKey: data.keyPair.publicKey.toString('hex'), senderId: keys.createAddressFromPublicKey(data.keyPair.publicKey)}; + var transaction = { type: data.transactionType, amount: 0, timestamp: time.getTime(), asset: {}, senderPublicKey: data.keyPair.publicKey.toString('hex'), senderId: keys.createAddressFromPublicKey(data.keyPair.publicKey) }; return transaction; }, + createSendTransaction: function (data) { data.transactionType = constants.transactionTypes.SEND; var transaction = this.createBasicTransaction(data); @@ -36,103 +38,113 @@ module.exports = { transaction.signature = this.transactionSign(transaction, data.keyPair); return transaction; }, + createStateTransaction: function (data) { data.transactionType = constants.transactionTypes.STATE; var transaction = this.createBasicTransaction(data); - transaction.asset = {"state": { - key: data.key, - value: data.value, - type: 0 - }}; + transaction.asset = { + "state": { + key: data.key, + value: data.value, + type: 0 + } + }; transaction.recipientId = null; transaction.amount = 0; transaction.signature = this.transactionSign(transaction, data.keyPair); return transaction; }, + createChatTransaction: function (data) { data.transactionType = constants.transactionTypes.CHAT_MESSAGE; var transaction = this.createBasicTransaction(data); - transaction.asset = {"chat": { - message: data.message, - own_message: data.own_message, - type: data.message_type - }}; + transaction.asset = { + "chat": { + message: data.message, + own_message: data.own_message, + type: data.message_type + } + }; transaction.recipientId = data.recipientId; transaction.amount = data.amount || 0; transaction.signature = this.transactionSign(transaction, data.keyPair); return transaction; }, + createDelegateTransaction: function (data) { data.transactionType = constants.transactionTypes.DELEGATE; var transaction = this.createBasicTransaction(data); - transaction.asset = {"delegate": { "username": data.username, publicKey: data.keyPair.publicKey.toString('hex')}}; + transaction.asset = { "delegate": { "username": data.username, publicKey: data.keyPair.publicKey.toString('hex') } }; transaction.recipientId = null; transaction.signature = this.transactionSign(transaction, data.keyPair); return transaction; }, + createVoteTransaction: function (data) { data.transactionType = constants.transactionTypes.VOTE; var transaction = this.createBasicTransaction(data); - transaction.asset = {"votes": data.votes}; + transaction.asset = { "votes": data.votes }; transaction.recipientId = transaction.senderId; transaction.signature = this.transactionSign(transaction, data.keyPair); return transaction; }, + getHash: function (trs) { return crypto.createHash('sha256').update(this.getBytes(trs)).digest(); }, + getBytes: function (transaction) { var skipSignature = false; var skipSecondSignature = true; var assetSize = 0; var assetBytes = null; - + switch (transaction.type) { - case constants.transactionTypes.SEND: - break; - case constants.transactionTypes.DELEGATE: - assetBytes = this.delegatesGetBytes(transaction); - assetSize = assetBytes.length; - break; - case constants.transactionTypes.STATE: - assetBytes = this.statesGetBytes(transaction); - assetSize = assetBytes.length; - break; - case constants.transactionTypes.VOTE: - assetBytes = this.voteGetBytes(transaction); - assetSize = assetBytes.length; - break; - case constants.transactionTypes.CHAT_MESSAGE: - assetBytes = this.chatGetBytes(transaction); - assetSize = assetBytes.length; - break; - default: - // 'Not supported yet' - return 0; + case constants.transactionTypes.SEND: + break; + case constants.transactionTypes.DELEGATE: + assetBytes = this.delegatesGetBytes(transaction); + assetSize = assetBytes.length; + break; + case constants.transactionTypes.STATE: + assetBytes = this.statesGetBytes(transaction); + assetSize = assetBytes.length; + break; + case constants.transactionTypes.VOTE: + assetBytes = this.voteGetBytes(transaction); + assetSize = assetBytes.length; + break; + case constants.transactionTypes.CHAT_MESSAGE: + assetBytes = this.chatGetBytes(transaction); + assetSize = assetBytes.length; + break; + default: + // 'Not supported yet' + return 0; } - + var bb = new ByteBuffer(1 + 4 + 32 + 8 + 8 + 64 + 64 + assetSize, true); - + bb.writeByte(transaction.type); bb.writeInt(transaction.timestamp); - + var senderPublicKeyBuffer = Buffer.from(transaction.senderPublicKey, 'hex'); for (var i = 0; i < senderPublicKeyBuffer.length; i++) { bb.writeByte(senderPublicKeyBuffer[i]); } - + if (transaction.requesterPublicKey) { var requesterPublicKey = Buffer.from(transaction.requesterPublicKey, 'hex'); - + for (var i = 0; i < requesterPublicKey.length; i++) { bb.writeByte(requesterPublicKey[i]); } } - + if (transaction.recipientId) { var recipient = transaction.recipientId.slice(1); - recipient = new bignum(recipient).toBuffer({size: 8}); - + recipient = new bignum(recipient).toBuffer({ size: 8 }); + for (i = 0; i < 8; i++) { bb.writeByte(recipient[i] || 0); } @@ -141,43 +153,45 @@ module.exports = { bb.writeByte(0); } } - + bb.writeLong(transaction.amount); - + if (assetSize > 0) { for (var i = 0; i < assetSize; i++) { bb.writeByte(assetBytes[i]); } } - + if (!skipSignature && transaction.signature) { var signatureBuffer = Buffer.from(transaction.signature, 'hex'); for (var i = 0; i < signatureBuffer.length; i++) { bb.writeByte(signatureBuffer[i]); } } - + if (!skipSecondSignature && transaction.signSignature) { var signSignatureBuffer = Buffer.from(transaction.signSignature, 'hex'); for (var i = 0; i < signSignatureBuffer.length; i++) { bb.writeByte(signSignatureBuffer[i]); } } - + bb.flip(); var arrayBuffer = new Uint8Array(bb.toArrayBuffer()); var buffer = []; - + for (var i = 0; i < arrayBuffer.length; i++) { buffer[i] = arrayBuffer[i]; } - + return Buffer.from(buffer); }, + transactionSign: function (trs, keypair) { var hash = this.getHash(trs); return this.sign(hash, keypair).toString('hex'); }, + voteGetBytes: function (trs) { var buf; try { @@ -187,12 +201,13 @@ module.exports = { } return buf; }, + delegatesGetBytes: function (trs) { if (!trs.asset.delegate.username) { return null; } var buf; - + try { buf = Buffer.from(trs.asset.delegate.username, 'utf8'); } catch (e) { @@ -200,12 +215,13 @@ module.exports = { } return buf; }, + statesGetBytes: function (trs) { if (!trs.asset.state.value) { return null; } var buf; - + try { buf = Buffer.from([]); var stateBuf = Buffer.from(trs.asset.state.value); @@ -214,26 +230,27 @@ module.exports = { var keyBuf = Buffer.from(trs.asset.state.key); buf = Buffer.concat([buf, keyBuf]); } - + var bb = new ByteBuffer(4 + 4, true); bb.writeInt(trs.asset.state.type); bb.flip(); - + buf = Buffer.concat([buf, bb.toBuffer()]); } catch (e) { throw e; } - + return buf; }, + chatGetBytes: function (trs) { var buf; - + try { buf = Buffer.from([]); var messageBuf = Buffer.from(trs.asset.chat.message, 'hex'); buf = Buffer.concat([buf, messageBuf]); - + if (trs.asset.chat.own_message) { var ownMessageBuf = Buffer.from(trs.asset.chat.own_message, 'hex'); buf = Buffer.concat([buf, ownMessageBuf]); @@ -245,10 +262,12 @@ module.exports = { } catch (e) { throw e; } - + return buf; }, + sign: function (hash, keypair) { return sodium.crypto_sign_detached(hash, Buffer.from(keypair.privateKey, 'hex')); } + }; diff --git a/helpers/validator.js b/helpers/validator.js new file mode 100644 index 0000000..4483aaf --- /dev/null +++ b/helpers/validator.js @@ -0,0 +1,153 @@ +const constants = require('./constants'); +const BigNumber = require('bignumber.js') + +module.exports = { + + getRandomIntInclusive(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive + }, + + isNumeric(str) { + if (typeof str !== "string") return false + return !isNaN(str) && !isNaN(parseFloat(str)) + }, + + tryParseJSON(jsonString) { + try { + let o = JSON.parse(jsonString); + if (o && typeof o === "object") { + return o; + } + } catch (e) { } + return false + }, + + validatePassPhrase(passPhrase) { + if (!passPhrase || typeof(passPhrase) !== 'string' || passPhrase.length < 30) + return false + else + return true + }, + + validateEndpoint(endpoint) { + if (!endpoint || typeof(endpoint) !== 'string') + return false + else + return true + }, + + validateAdmAddress(address) { + if (!address || typeof(address) !== 'string' || !constants.RE_ADM_ADDRESS.test(address)) + return false + else + return true + }, + + validateAdmPublicKey(publicKey) { + if (!publicKey || typeof(publicKey) !== 'string' || publicKey.length !== 64 || !constants.RE_HEX.test(publicKey)) + return false + else + return true + }, + + validateIntegerAmount(amount) { + if (!amount || typeof(amount) !== 'number' || isNaN(amount) || !Number.isSafeInteger(amount)) + return false + else + return true + }, + + validateStringAmount(amount) { + if (!amount || !this.isNumeric(amount)) + return false + else + return true + }, + + validateMessageType(message_type) { + if (!message_type || typeof(message_type) !== 'number' || ![1,2,3].includes(message_type)) + return false + else + return true + }, + + validateMessage(message, message_type) { + if (typeof(message) !== 'string') + return { + result: false, + error: `Message must be a string` + } + else { + if (message_type === 2 || message_type === 3) { + + let json = this.tryParseJSON(message) + + if (!json) + return { + result: false, + error: `For rich and signal messages, 'message' must be a JSON string` + } + + if (json.type && json.type.toLowerCase().includes('_transaction')) + if (json.type.toLowerCase() !== json.type) + return { + result: false, + error: `Value '_transaction' must be in lower case` + } + + if (typeof json.amount !== 'string' || !this.validateStringAmount(json.amount)) + return { + result: false, + error: `Field 'amount' must be a string, representing a number` + } + + } + } + return { + result: true + } + }, + + AdmToSats(amount) { + return BigNumber(String(amount)).multipliedBy(constants.SAT).integerValue().toNumber() + }, + + badParameter(name, value, customMessage) { + return new Promise((resolve, reject) => { + resolve({ + success: false, + errorMessage: `Wrong '${name}' parameter${value ? ': ' + value : ''}${customMessage ? '. Error: ' + customMessage : ''}` + }) + }) + }, + + formatRequestResults(response, isRequestSuccess) { + let results = {}; + results.details = {}; + + if (isRequestSuccess) { + results.success = response.data && response.data.success; + results.data = response.data; + results.details.status = response.status; + results.details.statusText = response.statusText; + results.details.response = response; + if (!results.success && results.data) + results.errorMessage = `Node's reply: ${results.data.error}` + } else { + results.success = false; + results.data = undefined; + results.details.status = response.response ? response.response.status : undefined; + results.details.statusText = response.response ? response.response.statusText : undefined; + results.details.error = response.toString(); + results.details.message = response.response && response.response.data ? response.response.data.toString().trim() : undefined; + results.details.response = response.response; + results.errorMessage = `${results.details.error}${results.details.message ? '. Message: ' + results.details.message : ''}`; + } + + return results; + + } + +}; diff --git a/helpers/wsClient.js b/helpers/wsClient.js index ff2faa3..05853b7 100644 --- a/helpers/wsClient.js +++ b/helpers/wsClient.js @@ -1,99 +1,100 @@ const ioClient = require("socket.io-client"); -const _ = require('lodash'); const logger = require('./logger'); +const validator = require('./validator'); module.exports = { - isSocketEnabled: false, // If we need socket connection - wsType: "ws", // Socket connection type, "ws" (default) or "wss" - admAddress: '', // ADM address to subscribe to notifications - connection: null, // Socket connection - onNewMessage: null, // Method to process new messages or transactions - activeNodes: [], // List of nodes that are active. Not all of them synced and support socket. - activeSocketNodes: [], // List of nodes that are active, synced and support socket - useFastest: false, // If to connect to node with minimum ping. Not recommended. + + isSocketEnabled: false, // If we need socket connection + wsType: "ws", // Socket connection type, "ws" (default) or "wss" + admAddress: '', // ADM address to subscribe to notifications + connection: null, // Socket connection + onNewMessage: null, // Method to process new messages or transactions + activeNodes: [], // List of nodes that are active. Not all of them synced and support socket. + activeSocketNodes: [], // List of nodes that are active, synced and support socket + useFastest: false, // If to connect to node with minimum ping. Not recommended. - // Constructor - initSocket(params) { - this.onNewMessage = params.onNewMessage; - this.isSocketEnabled = params.socket; - this.wsType = params.wsType; - this.admAddress = params.admAddress; - }, + // Constructor + initSocket(params) { + this.onNewMessage = params.onNewMessage; + this.isSocketEnabled = params.socket; + this.wsType = params.wsType; + this.admAddress = params.admAddress; + }, - // Runs after every healthCheck() to re-connect socket if needed - reviseConnection(nodes) { - if (!this.isSocketEnabled) { - return; - } - if (!this.connection || !this.connection.connected) { - this.activeNodes = nodes.slice(); - this.setNodes(); - this.setConnection(); - } - }, + // Runs after every healthCheck() to re-connect socket if needed + reviseConnection(nodes) { + if (!this.isSocketEnabled) { + return; + } + if (!this.connection || !this.connection.connected) { + this.activeNodes = nodes.slice(); + this.setNodes(); + this.setConnection(); + } + }, - // Make socket connection and subscribe to new transactions - setConnection() { - if (this.activeSocketNodes.length === 0) { - logger.warn(`[Socket] No supported socket nodes at the moment.`); - return; - } + // Make socket connection and subscribe to new transactions + setConnection() { + if (this.activeSocketNodes.length === 0) { + logger.warn(`[Socket] No supported socket nodes at the moment.`); + return; + } - const node = this.socketAddress(); - logger.log(`[Socket] Supported nodes: ${this.activeSocketNodes.length}. Connecting to ${node}...`); - this.connection = ioClient.connect(node, { reconnection: false, timeout: 5000 }); + const node = this.socketAddress(); + logger.log(`[Socket] Supported nodes: ${this.activeSocketNodes.length}. Connecting to ${node}...`); + this.connection = ioClient.connect(node, { reconnection: false, timeout: 5000 }); - this.connection.on('connect', () => { - this.connection.emit('address', this.admAddress); - logger.info('[Socket] Connected to ' + node + ' and subscribed to incoming transactions for ' + this.admAddress + '.'); - }); - - this.connection.on('disconnect', reason => { - logger.warn('[Socket] Disconnected. Reason: ' + reason) - }); - - this.connection.on('connect_error', (err) => { - logger.warn('[Socket] Connection error: ' + err) - }); - - this.connection.on('newTrans', transaction => { - if ((transaction.recipientId === this.admAddress) && (transaction.type === 0 || transaction.type === 8)) { - // console.info(`[Socket] New incoming socket transaction received: ${transaction.id}`); - this.onNewMessage(transaction); - } - }); - }, + this.connection.on('connect', () => { + this.connection.emit('address', this.admAddress); + logger.info('[Socket] Connected to ' + node + ' and subscribed to incoming transactions for ' + this.admAddress + '.'); + }); - // Save the list of nodes activeSocketNodes that are active, synced and support socket - setNodes() { - this.activeSocketNodes = this.activeNodes.filter(n => n.socketSupport & !n.outOfSync); - // Remove nodes without IP if "ws" connection type - if (this.wsType === "ws") { - this.activeSocketNodes = this.activeSocketNodes.filter(n => !n.ifHttps || n.ip); - } - }, + this.connection.on('disconnect', reason => { + logger.warn('[Socket] Disconnected. Reason: ' + reason) + }); + + this.connection.on('connect_error', (err) => { + logger.warn('[Socket] Connection error: ' + err) + }); + + this.connection.on('newTrans', transaction => { + if ((transaction.recipientId === this.admAddress) && (transaction.type === 0 || transaction.type === 8)) { + // console.info(`[Socket] New incoming socket transaction received: ${transaction.id}`); + this.onNewMessage(transaction); + } + }); + }, + + // Save the list of nodes activeSocketNodes that are active, synced and support socket + setNodes() { + this.activeSocketNodes = this.activeNodes.filter(n => n.socketSupport & !n.outOfSync); + // Remove nodes without IP if "ws" connection type + if (this.wsType === "ws") { + this.activeSocketNodes = this.activeSocketNodes.filter(n => !n.ifHttps || n.ip); + } + }, + + // Returns socket url for connection + socketAddress() { + const node = this.useFastest ? this.fastestNode() : this.randomNode(); + let socketUrl = this.wsType + "://"; + if (this.wsType === "ws") { + let host = node.ip; + if (!host || host === undefined) + host = node.url; + socketUrl = socketUrl + host + ":" + node.wsPort + } else { + socketUrl = socketUrl + node.url; // no port if wss + } + return socketUrl; + }, + + fastestNode() { + return this.activeSocketNodes[0]; // They are sorted by ping + }, + + randomNode() { + return this.activeSocketNodes[validator.getRandomIntInclusive(0, this.activeSocketNodes.length - 1)] + } - // Returns socket url for connection - socketAddress() { - const node = this.useFastest ? this.fastestNode() : this.randomNode(); - let socketUrl = this.wsType + "://"; - if (this.wsType === "ws") { - let host = node.ip; - if (!host || host === undefined) - host = node.url; - socketUrl = socketUrl + host + ":" + node.wsPort - } else { - socketUrl = socketUrl + node.url; // no port if wss - } - return socketUrl; - }, - - fastestNode() { - return this.activeSocketNodes[0]; // They are sorted by ping - }, - - randomNode() { - return this.activeSocketNodes[_.random(this.activeSocketNodes.length - 1)] - } - } diff --git a/index.js b/index.js index 4fdea05..8a063f0 100644 --- a/index.js +++ b/index.js @@ -1,30 +1,33 @@ -const Get = require('./groups/get'); +const constants = require('./helpers/constants.js'); +const get = require('./groups/get'); +const getPublicKey = require('./groups/getPublicKey'); const decodeMsg = require('./groups/decodeMsg'); -const Send = require('./groups/send'); +const sendTokens = require('./groups/sendTokens'); +const sendMessage = require('./groups/sendMessage'); const healthCheck = require('./helpers/healthCheck'); const eth = require('./groups/eth'); -const syncGet = require('./groups/syncGet'); const transactionFormer = require('./helpers/transactionFormer'); const keys = require('./helpers/keys'); -const encrypter = require('./helpers/encrypter'); +const encryptor = require('./helpers/encryptor'); const socket = require('./helpers/wsClient'); -const logger = require('adamant-api/helpers/logger'); +const logger = require('./helpers/logger'); module.exports = (params, log) => { log = log || console; logger.initLogger(params.logLevel, log); - const {node, changeNodes} = healthCheck(params.node); - const syncReq = syncGet(node, changeNodes); + const nodeManager = healthCheck(params.node); return { - get: Get(syncReq), - send: Send(node), + get: get(nodeManager), + getPublicKey: getPublicKey(nodeManager), + sendTokens: sendTokens(nodeManager), + sendMessage: sendMessage(nodeManager), decodeMsg, eth, - syncGet: syncReq, transactionFormer, keys, - encrypter, - socket + encryptor, + socket, + constants }; }; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index ae77a2f..0000000 --- a/package-lock.json +++ /dev/null @@ -1,1919 +0,0 @@ -{ - "name": "adamant-api", - "version": "0.1.18", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", - "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@types/bn.js": { - "version": "4.11.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", - "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", - "requires": { - "@types/node": "*" - } - }, - "@types/concat-stream": { - "version": "1.6.0", - "resolved": "http://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "http://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "9.6.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.39.tgz", - "integrity": "sha512-c3OkjgNpSMdHan56WhklP0FMOk5ocilKz2Mpa0NOGzu8jw5YERjCf9FG0epYB1+TxScv/oI4uJ204u2mUg7Hcw==" - }, - "@types/qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-mNhVdZHdtKHMMxbqzNK3RzkBcN1cux3AvuCYGTvjEIQT2uheH3eCAyYsbMbh2Bq8nXkeOWs1kyDiF7geWRFQ4Q==" - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "base-x": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", - "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bignumber.js": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.0.1.tgz", - "integrity": "sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bitcore-lib": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-0.15.0.tgz", - "integrity": "sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ==", - "requires": { - "bn.js": "=4.11.8", - "bs58": "=4.0.1", - "buffer-compare": "=1.1.1", - "elliptic": "=6.4.0", - "inherits": "=2.0.1", - "lodash": "=4.17.4" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } - }, - "bitcore-mnemonic": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bitcore-mnemonic/-/bitcore-mnemonic-1.5.0.tgz", - "integrity": "sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g==", - "requires": { - "bitcore-lib": "^0.15.0", - "unorm": "^1.3.3" - } - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "buffer-compare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz", - "integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { - "long": "~3" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chloride-test": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/chloride-test/-/chloride-test-1.2.2.tgz", - "integrity": "sha1-F4aGqF6SeARREulujHkXk/mhCuo=", - "requires": { - "json-buffer": "^2.0.11" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "coinstring": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", - "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" - }, - "dependencies": { - "bs58": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" - } - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ed2curve": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.2.1.tgz", - "integrity": "sha1-Iuaqo1aePE2/Tu+ilhLsMp5YGQw=", - "requires": { - "tweetnacl": "0.x.x" - } - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" - }, - "ethereumjs-tx": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", - "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-util": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz", - "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "ethers": { - "version": "4.0.28", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.28.tgz", - "integrity": "sha512-5JTHrPoFLqf+xCAI3pKwXSOgWBSJJoAUdPtPLr1ZlKbSKiIFMkPlRNovmZS3jhIw5sHW1YoVWOaJ6ZR2gKRbwg==", - "requires": { - "@types/node": "^10.3.2", - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.3.3", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==" - }, - "elliptic": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", - "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" - } - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "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": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hdkey": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.1.tgz", - "integrity": "sha512-DvHZ5OuavsfWs5yfVJZestsnc3wzPvLWNk6c2nRUfo6X+OtxypGt20vDDf7Ba+MJzjL3KS1og2nw2eBbLCOUTA==", - "requires": { - "coinstring": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "http-basic": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-7.0.0.tgz", - "integrity": "sha1-gvClBr6UJzLsje6+6A50bvVzbbo=", - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/node": "^9.4.1", - "caseless": "~0.12.0", - "concat-stream": "^1.4.6", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-response-object": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.1.tgz", - "integrity": "sha512-6L0Fkd6TozA8kFSfh9Widst0wfza3U1Ex2RjJ6zNDK0vR1U1auUR6jY4Nn2Xl7CCy0ikFmxW1XcspVpb9RvwTg==", - "requires": { - "@types/node": "^9.3.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" - } - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-buffer": { - "version": "2.0.11", - "resolved": "http://registry.npmjs.org/json-buffer/-/json-buffer-2.0.11.tgz", - "integrity": "sha1-PkQf2jCYvo0eMXGtWRvGKjPi1V8=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", - "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" - }, - "parse-headers": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz", - "integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==", - "requires": { - "for-each": "^0.3.3", - "string.prototype.trim": "^1.1.2" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "promise": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.2.tgz", - "integrity": "sha512-EIyzM39FpVOMbqgzEHhxdrEhtOSDOtjMZQ0M6iVfCE+kWNgCkAyOdnuCWqfmflylftfadU6FkiMgHZA2kUzwRw==", - "requires": { - "asap": "~2.0.6" - } - }, - "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.3.tgz", - "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==", - "requires": { - "bn.js": "^4.11.1", - "safe-buffer": "^5.1.1" - } - }, - "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "optional": true, - "requires": { - "nan": "^2.0.8" - } - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==" - }, - "scrypt.js": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.3.0.tgz", - "integrity": "sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A==", - "requires": { - "scrypt": "^6.0.2", - "scryptsy": "^1.2.1" - } - }, - "scryptsy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sodium-browserify-tweetnacl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/sodium-browserify-tweetnacl/-/sodium-browserify-tweetnacl-0.2.3.tgz", - "integrity": "sha1-tVN//LufdOvEQ7i2ohGykej8vI4=", - "requires": { - "chloride-test": "^1.1.0", - "ed2curve": "^0.1.4", - "sha.js": "^2.4.8", - "tweetnacl": "^0.14.1", - "tweetnacl-auth": "^0.3.0" - }, - "dependencies": { - "ed2curve": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.1.4.tgz", - "integrity": "sha1-lKRCSLuH2jXbDv968KpXYWgRf1k=", - "requires": { - "tweetnacl": "0.x.x" - } - } - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "sync-request": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.0.0.tgz", - "integrity": "sha512-jGNIAlCi9iU4X3Dm4oQnNQshDD3h0/1A7r79LyqjbjUnj69sX6mShAXlhRXgImsfVKtTcnra1jfzabdZvp+Lmw==", - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.4.tgz", - "integrity": "sha512-Iug+t1ICVFenUcTnDu8WXFnT+k8IVoLKGh8VA3eXUtl2Rt9SjKX3YEv33OenABqpTPL9QEaHv1+CNn2LK8vMow==", - "requires": { - "get-port": "^3.1.0" - } - }, - "then-request": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.0.tgz", - "integrity": "sha512-xA+7uEMc+jsQIoyySJ93Ad08Kuqnik7u6jLS5hR91Z3smAoCfL3M8/MqMlobAa9gzBfO9pA88A/AntfepkkMJQ==", - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^7.0.0", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.38", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.38.tgz", - "integrity": "sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A==" - } - } - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "tweetnacl-auth": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tweetnacl-auth/-/tweetnacl-auth-0.3.1.tgz", - "integrity": "sha1-t1vC3xVkm7hOi5qjwGacbEvODSU=", - "requires": { - "tweetnacl": "0.x.x" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", - "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", - "requires": { - "querystringify": "^2.0.0", - "requires-port": "^1.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "utf8": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", - "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.55.tgz", - "integrity": "sha512-yJpwy4IUA3T/F9hWzYQVn0GbJCrAaZ0KTIO3iuqkhaYH0Y09KV7k4GzFi4hN7hT4cFTj4yIKaeVCwQ5kzvi2Vg==", - "requires": { - "@babel/runtime": "^7.3.1", - "@types/node": "^10.12.18", - "web3-core": "1.0.0-beta.55", - "web3-eth": "1.0.0-beta.55", - "web3-eth-personal": "1.0.0-beta.55", - "web3-net": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-shh": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==" - } - } - }, - "web3-core": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.55.tgz", - "integrity": "sha512-AMMp7TLEtE7u8IJAu/THrRhBTZyZzeo7Y6GiWYNwb5+KStC9hIGLr9cI1KX9R6ZioTOLRHrqT7awDhnJ1ku2mg==", - "requires": { - "@babel/runtime": "^7.3.1", - "@types/bn.js": "^4.11.4", - "@types/node": "^10.12.18", - "lodash": "^4.17.11", - "web3-core-method": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==" - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-core-helpers": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.55.tgz", - "integrity": "sha512-suj9Xy/lIqajaYLJTEjr2rlFgu6hGYwChHmf8+qNrC2luZA6kirTamtB9VThWMxbywx7p0bqQFjW6zXogAgWhg==", - "requires": { - "@babel/runtime": "^7.3.1", - "lodash": "^4.17.11", - "web3-core": "1.0.0-beta.55", - "web3-eth-iban": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-core-method": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.55.tgz", - "integrity": "sha512-w1cW/s2ji9qGELHk2uMJCn1ooay0JJLVoPD1nvmsW6OTRWcVjxa62nJrFQhe6P5lEb83Xk9oHgmCxZoVUHibOw==", - "requires": { - "@babel/runtime": "^7.3.1", - "eventemitter3": "3.1.0", - "lodash": "^4.17.11", - "rxjs": "^6.4.0", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-subscriptions": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-core-subscriptions": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.55.tgz", - "integrity": "sha512-pb3oQbUzK7IoyXwag8TYInQddg0rr7BHxKc+Pbs/92hVNQ5ps4iGMVJKezdrjlQ1IJEEUiDIglXl4LZ1hIuMkw==", - "requires": { - "@babel/runtime": "^7.3.1", - "eventemitter3": "^3.1.0", - "lodash": "^4.17.11" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-eth": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.55.tgz", - "integrity": "sha512-F3zJ9I1gOgQdNGfi2Dy2lmj6OqCMJoRN01XHhQZagq0HY1JYMfObtfMi5E3L+qsegsSddHbqp4YY57tKx6uxpA==", - "requires": { - "@babel/runtime": "^7.3.1", - "ethereumjs-tx": "^1.3.7", - "rxjs": "^6.4.0", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-core-subscriptions": "1.0.0-beta.55", - "web3-eth-abi": "1.0.0-beta.55", - "web3-eth-accounts": "1.0.0-beta.55", - "web3-eth-contract": "1.0.0-beta.55", - "web3-eth-ens": "1.0.0-beta.55", - "web3-eth-iban": "1.0.0-beta.55", - "web3-eth-personal": "1.0.0-beta.55", - "web3-net": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - } - }, - "web3-eth-abi": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.55.tgz", - "integrity": "sha512-3h1xnm/vYmKUXTOYAOP0OsB5uijQV76pNNRGKOB6Dq6GR1pbcbD3WrB/4I643YA8l91t5FRzFzUiA3S77R2iqw==", - "requires": { - "@babel/runtime": "^7.3.1", - "ethers": "^4.0.27", - "lodash": "^4.17.11", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-eth-accounts": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.55.tgz", - "integrity": "sha512-VfzvwpSDHXqRVelIxsBVhgbV9BkFvhJ/q+bKhnVUUXV0JAhMK/7uC92TsqKk4EBYuqpHyZ1jjqrL4n03fMU7zw==", - "requires": { - "@babel/runtime": "^7.3.1", - "browserify-cipher": "^1.0.1", - "eth-lib": "0.2.8", - "lodash": "^4.17.11", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "scrypt.js": "0.3.0", - "uuid": "3.3.2", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-eth-contract": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.55.tgz", - "integrity": "sha512-v6oB1wfH039/A5sTb4ZTKX++fcBTHEkuQGpq50ATIDoxP/UTz2+6S+iL+3sCJTsByPw2/Bni/HM7NmLkXqzg/Q==", - "requires": { - "@babel/runtime": "^7.3.1", - "@types/bn.js": "^4.11.4", - "lodash": "^4.17.11", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-core-subscriptions": "1.0.0-beta.55", - "web3-eth-abi": "1.0.0-beta.55", - "web3-eth-accounts": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-eth-ens": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.55.tgz", - "integrity": "sha512-jEL17coO0FJXb7KYq4+7DhVXj0Rh+wHfZ86jOvFUvJsRaUHfqK2TlMatuhD2mbrmxpBYb6oMPnXVnNK9bnD5Rg==", - "requires": { - "@babel/runtime": "^7.3.1", - "eth-ens-namehash": "2.0.8", - "lodash": "^4.17.11", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-eth-abi": "1.0.0-beta.55", - "web3-eth-accounts": "1.0.0-beta.55", - "web3-eth-contract": "1.0.0-beta.55", - "web3-net": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-eth-iban": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.55.tgz", - "integrity": "sha512-a2Fxsb5Mssa+jiXgjUdIzJipE0175IcQXJbZLpKft2+zeSJWNTbaa3PQD2vPPpIM4W789q06N+f9Zc0Fyls+1g==", - "requires": { - "@babel/runtime": "^7.3.1", - "bn.js": "4.11.8", - "web3-utils": "1.0.0-beta.55" - } - }, - "web3-eth-personal": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.55.tgz", - "integrity": "sha512-H0mahLQx6Oj7lpgTamKAswr3rHChRUZijeWAar2Hj7BABQlLRKwx8n09nYhxggvvLYQNQS90JjvQue7rAo2LQQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-eth-accounts": "1.0.0-beta.55", - "web3-net": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - } - }, - "web3-net": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.55.tgz", - "integrity": "sha512-do2WY8+/GArJSWX7k/zZ7nBnV9Y3n6LhPYkwT3LeFqDzD515bKwlomaNC8hOaTc6UQyXIoPprYTK2FevL7jrZw==", - "requires": { - "@babel/runtime": "^7.3.1", - "lodash": "^4.17.11", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-providers": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-providers/-/web3-providers-1.0.0-beta.55.tgz", - "integrity": "sha512-MNifc7W+iF6rykpbDR1MuX152jshWdZXHAU9Dk0Ja2/23elhIs4nCWs7wOX9FHrKgdrQbscPoq0uy+0aGzyWVQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "@types/node": "^10.12.18", - "eventemitter3": "3.1.0", - "lodash": "^4.17.11", - "url-parse": "1.4.4", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55", - "websocket": "^1.0.28", - "xhr2-cookies": "1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==" - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "web3-shh": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.55.tgz", - "integrity": "sha512-lGP2HQ/1ThNnfoU8677aL48KsTx4Ht+2KQIn39dGpxVZqysQmovQIltbymVnAr4h8wofwcEz46iNHGa+PAyNzA==", - "requires": { - "@babel/runtime": "^7.3.1", - "web3-core": "1.0.0-beta.55", - "web3-core-helpers": "1.0.0-beta.55", - "web3-core-method": "1.0.0-beta.55", - "web3-core-subscriptions": "1.0.0-beta.55", - "web3-net": "1.0.0-beta.55", - "web3-providers": "1.0.0-beta.55", - "web3-utils": "1.0.0-beta.55" - } - }, - "web3-utils": { - "version": "1.0.0-beta.55", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.55.tgz", - "integrity": "sha512-ASWqUi8gtWK02Tp8ZtcoAbHenMpQXNvHrakgzvqTNNZn26wgpv+Q4mdPi0KOR6ZgHFL8R/9b5BBoUTglS1WPpg==", - "requires": { - "@babel/runtime": "^7.3.1", - "@types/bn.js": "^4.11.4", - "@types/node": "^10.12.18", - "bn.js": "4.11.8", - "eth-lib": "0.2.8", - "ethjs-unit": "^0.1.6", - "lodash": "^4.17.11", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "2.1.1" - }, - "dependencies": { - "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==" - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - } - } - }, - "websocket": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.28.tgz", - "integrity": "sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA==", - "requires": { - "debug": "^2.2.0", - "nan": "^2.11.0", - "typedarray-to-buffer": "^3.1.5", - "yaeti": "^0.0.6" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xhr": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", - "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", - "requires": { - "global": "~4.3.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", - "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", - "requires": { - "xhr-request": "^1.0.1" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - } - } -} diff --git a/package.json b/package.json index 9907166..b242447 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,58 @@ { - "name": "adamant-api", - "version": "0.5.3", - "description": "\"REST API for ADAMANT Blockchain\"", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [ - "adm", - "adm api", - "adamant", - "adamant api", - "blockchain", - "messenger", - "chat", - "bitcoin", - "ethereum" - ], - "author": "RomanS, Aleksei Lebedev (https://adamant.im)", - "license": "GPL-3.0", - "dependencies": { - "socket.io-client": "^2.2.0", - "bignumber.js": "^8.0.1", - "bitcore-mnemonic": "^1.5.0", - "bytebuffer": "^5.0.1", - "crypto": "^1.0.1", - "ed2curve": "^0.2.1", - "ethereumjs-util": "^6.1.0", - "hdkey": "^1.1.1", - "request": "^2.88.0", - "sodium-browserify-tweetnacl": "^0.2.3", - "sync-request": "^6.0.0", - "web3": "^1.0.0-beta.55" - }, - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Adamant-im/adamant-api-jsclient.git" - }, - "bugs": { - "url": "https://github.com/Adamant-im/adamant-api-jsclient/issues" - }, - "homepage": "https://github.com/Adamant-im/adamant-api-jsclient#readme" + "name": "adamant-api", + "version": "1.0.0", + "description": "REST API for ADAMANT Blockchain", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "RomanS, Aleksei Lebedev (https://adamant.im)", + "license": "GPL-3.0", + "dependencies": { + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "bitcore-mnemonic": "^8.25.10", + "bytebuffer": "^5.0.1", + "ed2curve": "^0.3.0", + "ethereumjs-util": "^7.0.10", + "hdkey": "^2.0.1", + "socket.io-client": "^2.4.0", + "sodium-browserify-tweetnacl": "^0.2.6" + }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "adm", + "adamant", + "blockchain", + "messenger", + "chat", + "decentralized messenger", + "anonymous messenger", + "secure messenger", + "wallet", + "crypto wallet", + "private keys", + "communication", + "decentralized", + "decentralization", + "anonymous", + "anonymity", + "secure", + "encrypted", + "encryption", + "crypto", + "cryptocurrency", + "bitcoin", + "ethereum" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Adamant-im/adamant-api-jsclient.git" + }, + "bugs": { + "url": "https://github.com/Adamant-im/adamant-api-jsclient/issues" + }, + "homepage": "https://github.com/Adamant-im/adamant-api-jsclient#readme" }