diff --git a/packages/bitcore-lib/index.js b/packages/bitcore-lib/index.js index b4d039837c1..79e0b9fbda1 100644 --- a/packages/bitcore-lib/index.js +++ b/packages/bitcore-lib/index.js @@ -68,7 +68,6 @@ bitcore.deps.bs58 = require('bs58'); bitcore.deps.Buffer = Buffer; bitcore.deps.elliptic = require('elliptic'); -bitcore.deps._ = require('lodash'); // Internal usage, exposed for testing/advanced tweaking bitcore.Transaction.sighash = require('./lib/transaction/sighash'); diff --git a/packages/bitcore-lib/lib/address.js b/packages/bitcore-lib/lib/address.js index b51d14748d3..d8240aaacdc 100644 --- a/packages/bitcore-lib/lib/address.js +++ b/packages/bitcore-lib/lib/address.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const $ = require('./util/preconditions'); const Hash = require('./crypto/hash'); const Base58Check = require('./encoding/base58check'); @@ -29,16 +28,16 @@ const PublicKey = require('./publickey'); * @example * ```javascript * // validate that an input field is valid - * let error = Address.getValidationError(input, 'testnet'); + * const error = Address.getValidationError(input, 'testnet'); * if (!error) { - * let address = Address(input, 'testnet'); + * const address = Address(input, 'testnet'); * } else { * // invalid network or checksum (typo?) - * let message = error.messsage; + * const message = error.messsage; * } * * // get an address from a public key - * let address = Address(publicKey, 'testnet').toString(); + * const address = Address(publicKey, 'testnet').toString(); * ``` * * @param {*} data - The encoded data in various formats @@ -56,7 +55,7 @@ function Address(data, network, type, multisigType) { return new Address(data, network, type); } - if (_.isArray(data) && _.isNumber(network)) { + if (Array.isArray(data) && typeof network === 'number') { return Address.createMultisig(data, network, type, false, multisigType); } @@ -113,7 +112,7 @@ Address.prototype._classifyArguments = function(data, network, type) { return Address._transformScript(data, network); } else if (typeof(data) === 'string') { return Address._transformString(data, network, type); - } else if (_.isObject(data)) { + } else if (typeof data === 'object' && data !== null) { return Address._transformObject(data); } else { throw new TypeError('First argument is an unrecognized data format.'); @@ -247,7 +246,6 @@ Address._classifyFromVersion = function(buffer) { } else { throw new TypeError('Witness data must be 32 bytes for v1'); } - } else { } version.network = Networks.get(info.prefix, 'bech32prefix'); } else { @@ -378,7 +376,7 @@ Address.createMultisig = function(publicKeys, threshold, network, nestedWitness, throw new TypeError('Type must be either scripthash or witnessscripthash to create multisig.'); } if (nestedWitness || Address.isPayToWitnessScriptHash(type)) { - publicKeys = _.map(publicKeys, PublicKey); + publicKeys = publicKeys.map(key => PublicKey(key)); for (let i = 0; i < publicKeys.length; i++) { if (!publicKeys[i].compressed) { throw new TypeError('Witness addresses must use compressed public keys.'); @@ -563,7 +561,7 @@ Address.fromObject = function fromObject(obj) { * @example * ```javascript * // a network mismatch error - * let error = Address.getValidationError('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'testnet'); + * const error = Address.getValidationError('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'testnet'); * ``` * * @param {string} data - The encoded data diff --git a/packages/bitcore-lib/lib/block/block.js b/packages/bitcore-lib/lib/block/block.js index 3ae48736cdf..eca3a88090f 100644 --- a/packages/bitcore-lib/lib/block/block.js +++ b/packages/bitcore-lib/lib/block/block.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const BN = require('../crypto/bn'); const Hash = require('../crypto/hash'); const BufferReader = require('../encoding/bufferreader'); @@ -22,7 +21,7 @@ function Block(arg) { if (!(this instanceof Block)) { return new Block(arg); } - _.extend(this, Block._from(arg)); + Object.assign(this, Block._from(arg)); return this; } @@ -39,7 +38,7 @@ Block._from = function _from(arg) { let info = {}; if (BufferUtil.isBuffer(arg)) { info = Block._fromBufferReader(BufferReader(arg)); - } else if (_.isObject(arg)) { + } else if (typeof arg === 'object' && arg !== null) { info = Block._fromObject(arg); } else { throw new TypeError('Unrecognized argument for Block'); @@ -53,12 +52,11 @@ Block._from = function _from(arg) { * @private */ Block._fromObject = function _fromObject(data) { - const transactions = []; - data.transactions.forEach(function(tx) { + const transactions = data.transactions.map(tx => { if (tx instanceof Transaction) { - transactions.push(tx); + return tx; } else { - transactions.push(Transaction().fromObject(tx)); + return Transaction().fromObject(tx); } }); const info = { @@ -139,10 +137,7 @@ Block.fromRawBlock = function fromRawBlock(data) { * @returns {Object} - A plain object with the block properties */ Block.prototype.toObject = Block.prototype.toJSON = function toObject() { - const transactions = []; - this.transactions.forEach(function(tx) { - transactions.push(tx.toObject()); - }); + const transactions = this.transactions.map(tx => tx.toObject()); return { header: this.header.toObject(), transactions: transactions @@ -261,7 +256,7 @@ const idProperty = { } return this._id; }, - set: _.noop + set: function () {/** no op */} }; Object.defineProperty(Block.prototype, 'id', idProperty); Object.defineProperty(Block.prototype, 'hash', idProperty); diff --git a/packages/bitcore-lib/lib/block/blockheader.js b/packages/bitcore-lib/lib/block/blockheader.js index 4aa7b2d9e17..2b7d0cc2fd9 100644 --- a/packages/bitcore-lib/lib/block/blockheader.js +++ b/packages/bitcore-lib/lib/block/blockheader.js @@ -1,12 +1,10 @@ 'use strict'; -const _ = require('lodash'); const BN = require('../crypto/bn'); const Hash = require('../crypto/hash'); const BufferReader = require('../encoding/bufferreader'); const BufferWriter = require('../encoding/bufferwriter'); const BufferUtil = require('../util/buffer'); -const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const GENESIS_BITS = 0x1d00ffff; @@ -52,7 +50,7 @@ BlockHeader._from = function _from(arg) { let info = {}; if (BufferUtil.isBuffer(arg)) { info = BlockHeader._fromBufferReader(BufferReader(arg)); - } else if (_.isObject(arg)) { + } else if (typeof arg === 'object' && arg !== null) { info = BlockHeader._fromObject(arg); } else { throw new TypeError('Unrecognized argument for BlockHeader'); @@ -69,10 +67,10 @@ BlockHeader._fromObject = function _fromObject(data) { $.checkArgument(data, 'data is required'); let prevHash = data.prevHash; let merkleRoot = data.merkleRoot; - if (_.isString(data.prevHash)) { + if (typeof data.prevHash === 'string') { prevHash = BufferUtil.reverse(Buffer.from(data.prevHash, 'hex')); } - if (_.isString(data.merkleRoot)) { + if (typeof data.merkleRoot === 'string') { merkleRoot = BufferUtil.reverse(Buffer.from(data.merkleRoot, 'hex')); } const info = { @@ -208,7 +206,9 @@ BlockHeader.prototype.toBufferWriter = function toBufferWriter(bw) { BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(bits) { bits = bits || this.bits; + // eslint-disable-next-line no-bitwise let target = new BN(bits & 0xffffff); + // eslint-disable-next-line no-bitwise let mov = 8 * ((bits >>> 24) - 3); while (mov-- > 0) { target = target.mul(new BN(2)); @@ -251,7 +251,7 @@ const idProperty = { } return this._id; }, - set: _.noop + set: function () {/** no op */} }; Object.defineProperty(BlockHeader.prototype, 'id', idProperty); Object.defineProperty(BlockHeader.prototype, 'hash', idProperty); diff --git a/packages/bitcore-lib/lib/block/merkleblock.js b/packages/bitcore-lib/lib/block/merkleblock.js index 6f4e271886d..0584f535703 100644 --- a/packages/bitcore-lib/lib/block/merkleblock.js +++ b/packages/bitcore-lib/lib/block/merkleblock.js @@ -1,13 +1,11 @@ 'use strict'; -const _ = require('lodash'); const Hash = require('../crypto/hash'); const BufferReader = require('../encoding/bufferreader'); const BufferWriter = require('../encoding/bufferwriter'); const errors = require('../errors'); const Transaction = require('../transaction'); const BufferUtil = require('../util/buffer'); -const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const BlockHeader = require('./blockheader'); @@ -29,7 +27,7 @@ function MerkleBlock(arg) { let info = {}; if (BufferUtil.isBuffer(arg)) { info = MerkleBlock._fromBufferReader(BufferReader(arg)); - } else if (_.isObject(arg)) { + } else if (typeof arg === 'object' && arg !== null) { let header; if (arg.header instanceof BlockHeader) { header = arg.header; @@ -61,7 +59,7 @@ function MerkleBlock(arg) { } else { throw new TypeError('Unrecognized argument for MerkleBlock'); } - _.extend(this, info); + Object.assign(this, info); this._flagBitsUsed = 0; this._hashesUsed = 0; @@ -129,8 +127,8 @@ MerkleBlock.prototype.toObject = MerkleBlock.prototype.toJSON = function toObjec * @returns {Boolean} - True/False whether this MerkleBlock is Valid */ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() { - $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array'); - $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array'); + $.checkState(Array.isArray(this.flags), 'MerkleBlock flags is not an array'); + $.checkState(Array.isArray(this.hashes), 'MerkleBlock hashes is not an array'); // Can't have more hashes than numTransactions if (this.hashes.length > this.numTransactions) { @@ -156,8 +154,8 @@ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() { * @returns {Array} - txs hash that match the filter */ MerkleBlock.prototype.filterdTxsHash = function filterdTxsHash() { - $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array'); - $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array'); + $.checkState(Array.isArray(this.flags), 'MerkleBlock flags is not an array'); + $.checkState(Array.isArray(this.hashes), 'MerkleBlock hashes is not an array'); // Can't have more hashes than numTransactions if (this.hashes.length > this.numTransactions) { @@ -210,6 +208,7 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p if (opts.flagBitsUsed > this.flags.length * 8) { return null; } + // eslint-disable-next-line no-bitwise const isParentOfMatch = (this.flags[opts.flagBitsUsed >> 3] >>> (opts.flagBitsUsed++ & 7)) & 1; if (depth === 0 || !isParentOfMatch) { if (opts.hashesUsed >= this.hashes.length) { @@ -241,6 +240,7 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p * @private */ MerkleBlock.prototype._calcTreeWidth = function calcTreeWidth(height) { + // eslint-disable-next-line no-bitwise return (this.numTransactions + (1 << height) - 1) >> height; }; @@ -263,7 +263,7 @@ MerkleBlock.prototype._calcTreeHeight = function calcTreeHeight() { * @private */ MerkleBlock.prototype.hasTransaction = function hasTransaction(tx) { - $.checkArgument(!_.isUndefined(tx), 'tx cannot be undefined'); + $.checkArgument(tx != null, 'tx cannot be undefined'); $.checkArgument(tx instanceof Transaction || typeof tx === 'string', 'Invalid tx given, tx must be a "string" or "Transaction"'); diff --git a/packages/bitcore-lib/lib/crypto/bn.js b/packages/bitcore-lib/lib/crypto/bn.js index 58299f22ff3..6bc089bdbaf 100644 --- a/packages/bitcore-lib/lib/crypto/bn.js +++ b/packages/bitcore-lib/lib/crypto/bn.js @@ -1,7 +1,6 @@ 'use strict'; const BN = require('bn.js'); -const _ = require('lodash'); const BufferUtil = require('../util/buffer'); const $ = require('../util/preconditions'); @@ -18,12 +17,12 @@ BN.One = new BN(1); BN.Minus1 = new BN(-1); BN.fromNumber = function(n) { - $.checkArgument(_.isNumber(n)); + $.checkArgument(typeof n === 'number'); return new BN(n); }; BN.fromString = function(str, base) { - $.checkArgument(_.isString(str)); + $.checkArgument(typeof str === 'string'); return new BN(str, base); }; @@ -56,7 +55,9 @@ BN.fromSM = function(buf, opts) { buf = reversebuf(buf); } + // eslint-disable-next-line no-bitwise if (buf[0] & 0x80) { + // eslint-disable-next-line no-bitwise buf[0] = buf[0] & 0x7f; ret = BN.fromBuffer(buf); ret.neg().copy(ret); @@ -99,18 +100,22 @@ BN.prototype.toSMBigEndian = function() { let buf; if (this.cmp(BN.Zero) === -1) { buf = this.neg().toBuffer(); + // eslint-disable-next-line no-bitwise if (buf[0] & 0x80) { buf = Buffer.concat([Buffer.from([0x80]), buf]); } else { + // eslint-disable-next-line no-bitwise buf[0] = buf[0] | 0x80; } } else { buf = this.toBuffer(); + // eslint-disable-next-line no-bitwise if (buf[0] & 0x80) { buf = Buffer.concat([Buffer.from([0x00]), buf]); } } + // eslint-disable-next-line no-bitwise if (buf.length === 1 & buf[0] === 0) { buf = Buffer.from([]); } @@ -145,12 +150,14 @@ BN.fromScriptNumBuffer = function(buf, fRequireMinimal, size) { // If the most-significant-byte - excluding the sign bit - is zero // then we're not minimal. Note how this test also rejects the // negative-zero encoding, 0x80. + // eslint-disable-next-line no-bitwise if ((buf[buf.length - 1] & 0x7f) === 0) { // One exception: if there's more than one byte and the most // significant bit of the second-most-significant-byte is set // it would conflict with the sign bit. An example of this case // is +-255, which encode to 0xff00 and 0xff80 respectively. // (big-endian). + // eslint-disable-next-line no-bitwise if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) { throw new Error('non-minimally encoded script number'); } diff --git a/packages/bitcore-lib/lib/crypto/point.js b/packages/bitcore-lib/lib/crypto/point.js index 41d32621eb5..d35216f2322 100644 --- a/packages/bitcore-lib/lib/crypto/point.js +++ b/packages/bitcore-lib/lib/crypto/point.js @@ -1,8 +1,8 @@ 'use strict'; +const EC = require('elliptic').ec; const BufferUtil = require('../util/buffer'); const BN = require('./bn'); -const EC = require('elliptic').ec; const ec = new EC('secp256k1'); const ecPoint = ec.curve.point.bind(ec.curve); @@ -24,7 +24,7 @@ const Point = function Point(x, y, isRed) { let point; try { point = ecPoint(x, y, isRed); - } catch (e) { + } catch { throw new Error('Invalid Point'); } point.validate(); @@ -46,7 +46,7 @@ Point.fromX = function fromX(odd, x) { let point; try { point = ecPointFromX(x, odd); - } catch (e) { + } catch { throw new Error('Invalid X'); } point.validate(); @@ -127,7 +127,7 @@ Point.prototype.validate = function validate() { let p2; try { p2 = ecPointFromX(this.getX(), this.getY().isOdd()); - } catch (e) { + } catch { throw new Error('Point does not lie on the curve'); } diff --git a/packages/bitcore-lib/lib/crypto/signature.js b/packages/bitcore-lib/lib/crypto/signature.js index 2458c0b9e56..f7706b6c111 100644 --- a/packages/bitcore-lib/lib/crypto/signature.js +++ b/packages/bitcore-lib/lib/crypto/signature.js @@ -1,11 +1,16 @@ 'use strict'; -const _ = require('lodash'); const BufferUtil = require('../util/buffer'); const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const BN = require('./bn'); +/** Whether the byte's high bit is set (DER integer sign bit). */ +function isDerByteMsbSet(byte) { + // eslint-disable-next-line no-bitwise + return (byte & 0x80) !== 0; +} + const Signature = function Signature(r, s, isSchnorr) { if (!(this instanceof Signature)) { return new Signature(r, s, isSchnorr); @@ -102,7 +107,7 @@ Signature.fromString = function(str) { */ Signature.parseDER = function(buf, strict) { $.checkArgument(BufferUtil.isBuffer(buf), new Error('DER formatted signature should be a buffer')); - if (_.isUndefined(strict)) { + if (strict == null) { strict = true; } @@ -189,8 +194,8 @@ Signature.prototype.toBuffer = Signature.prototype.toDER = function() { const rnbuf = this.r.toBuffer(); const snbuf = this.s.toBuffer(); - const rneg = rnbuf[0] & 0x80 ? true : false; - const sneg = snbuf[0] & 0x80 ? true : false; + const rneg = isDerByteMsbSet(rnbuf[0]); + const sneg = isDerByteMsbSet(snbuf[0]); const rbuf = rneg ? Buffer.concat([Buffer.from([0x00]), rnbuf]) : rnbuf; const sbuf = sneg ? Buffer.concat([Buffer.from([0x00]), snbuf]) : snbuf; @@ -260,11 +265,11 @@ Signature.isTxDER = function(buf) { // Non-canonical signature: R length is zero return false; } - if (R[0] & 0x80) { + if (isDerByteMsbSet(R[0])) { // Non-canonical signature: R value negative return false; } - if (nLenR > 1 && (R[0] === 0x00) && !(R[1] & 0x80)) { + if (nLenR > 1 && (R[0] === 0x00) && !isDerByteMsbSet(R[1])) { // Non-canonical signature: R value excessively padded return false; } @@ -278,11 +283,11 @@ Signature.isTxDER = function(buf) { // Non-canonical signature: S length is zero return false; } - if (S[0] & 0x80) { + if (isDerByteMsbSet(S[0])) { // Non-canonical signature: S value negative return false; } - if (nLenS > 1 && (S[0] === 0x00) && !(S[1] & 0x80)) { + if (nLenS > 1 && (S[0] === 0x00) && !isDerByteMsbSet(S[1])) { // Non-canonical signature: S value excessively padded return false; } @@ -311,6 +316,7 @@ Signature.prototype.hasDefinedHashtype = function() { return false; } // accept with or without Signature.SIGHASH_ANYONECANPAY by ignoring the bit + // eslint-disable-next-line no-bitwise const temp = this.nhashtype & ~Signature.SIGHASH_ANYONECANPAY; if (temp < Signature.SIGHASH_ALL || temp > Signature.SIGHASH_SINGLE) { return false; diff --git a/packages/bitcore-lib/lib/encoding/base58.js b/packages/bitcore-lib/lib/encoding/base58.js index 25a28ed49b2..5896c292c48 100644 --- a/packages/bitcore-lib/lib/encoding/base58.js +++ b/packages/bitcore-lib/lib/encoding/base58.js @@ -1,8 +1,6 @@ 'use strict'; -const buffer = require('buffer'); const bs58 = require('bs58'); -const _ = require('lodash'); const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split(''); @@ -23,10 +21,23 @@ const Base58 = function Base58(obj) { }; Base58.validCharacters = function validCharacters(chars) { - if (buffer.Buffer.isBuffer(chars)) { + if (Buffer.isBuffer(chars)) { chars = chars.toString(); } - return _.every(_.map(chars, function(char) { return _.includes(ALPHABET, char); })); + // Backwards compat: lodash _.map(null/undefined) yields [], _.every([]) is true. + if (chars == null) { + return true; + } + if (typeof chars !== 'string') { + // Backwards compat: lodash _.map on non-string primitives (number, boolean, etc.) yields []. + // Boxed strings must be unwrapped: lodash maps each character of String objects. + if (chars instanceof String) { + chars = chars.valueOf(); + } else { + return true; + } + } + return Array.prototype.every.call(chars, char => ALPHABET.includes(char)); }; Base58.prototype.set = function(obj) { @@ -35,7 +46,7 @@ Base58.prototype.set = function(obj) { }; Base58.encode = function(buf) { - if (!buffer.Buffer.isBuffer(buf)) { + if (!Buffer.isBuffer(buf)) { throw new Error('Input should be a buffer'); } return bs58.encode(buf); diff --git a/packages/bitcore-lib/lib/encoding/base58check.js b/packages/bitcore-lib/lib/encoding/base58check.js index 7fb1f3011ab..ee764b699b7 100644 --- a/packages/bitcore-lib/lib/encoding/base58check.js +++ b/packages/bitcore-lib/lib/encoding/base58check.js @@ -1,9 +1,7 @@ 'use strict'; -const buffer = require('buffer'); -const _ = require('lodash'); -const Base58 = require('./base58'); const sha256sha256 = require('../crypto/hash').sha256sha256; +const Base58 = require('./base58'); const Base58Check = function Base58Check(obj) { if (!(this instanceof Base58Check)) @@ -25,10 +23,10 @@ Base58Check.prototype.set = function(obj) { }; Base58Check.validChecksum = function validChecksum(data, checksum) { - if (_.isString(data)) { + if (typeof data === 'string') { data = Buffer.from(Base58.decode(data)); } - if (_.isString(checksum)) { + if (typeof checksum === 'string') { checksum = Buffer.from(Base58.decode(checksum)); } if (!checksum) { diff --git a/packages/bitcore-lib/lib/encoding/bufferreader.js b/packages/bitcore-lib/lib/encoding/bufferreader.js index 024276acd37..2d1be1b8e43 100644 --- a/packages/bitcore-lib/lib/encoding/bufferreader.js +++ b/packages/bitcore-lib/lib/encoding/bufferreader.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const BN = require('../crypto/bn'); const BufferUtil = require('../util/buffer'); const $ = require('../util/preconditions'); @@ -9,18 +8,18 @@ const BufferReader = function BufferReader(buf) { if (!(this instanceof BufferReader)) { return new BufferReader(buf); } - if (_.isUndefined(buf)) { + if (buf == null) { return; } if (Buffer.isBuffer(buf)) { this.set({ buf: buf }); - } else if (_.isString(buf)) { + } else if (typeof buf === 'string') { this.set({ buf: Buffer.from(buf, 'hex'), }); - } else if (_.isObject(buf)) { + } else if (typeof buf === 'object' && buf !== null /** null case handled above, here for redundancy */) { const obj = buf; this.set(obj); } else { @@ -45,7 +44,7 @@ BufferReader.prototype.eof = function() { BufferReader.prototype.finished = BufferReader.prototype.eof; BufferReader.prototype.read = function(len) { - $.checkArgument(!_.isUndefined(len), 'Must specify a length'); + $.checkArgument(len != null, 'Must specify a length'); const buf = this.buf.slice(this.pos, this.pos + len); this.pos = this.pos + len; return buf; @@ -136,7 +135,6 @@ BufferReader.prototype.readVarintNum = function() { } else { throw new Error('number too large to retain precision - use readVarintBN'); } - break; default: return first; } @@ -191,7 +189,7 @@ BufferReader.prototype.reverse = function() { }; BufferReader.prototype.readReverse = function(len) { - if (_.isUndefined(len)) { + if (len == null) { len = this.buf.length; } const buf = this.buf.slice(this.pos, this.pos + len); diff --git a/packages/bitcore-lib/lib/errors/index.js b/packages/bitcore-lib/lib/errors/index.js index 0d93e1562db..9e6910e93a6 100644 --- a/packages/bitcore-lib/lib/errors/index.js +++ b/packages/bitcore-lib/lib/errors/index.js @@ -1,7 +1,5 @@ 'use strict'; -const _ = require('lodash'); - function format(message, args) { return message .replace('{0}', args[0]) @@ -10,9 +8,9 @@ function format(message, args) { } const traverseNode = function(parent, errorDefinition) { const NodeError = function() { - if (_.isString(errorDefinition.message)) { + if (typeof errorDefinition.message === 'string') { this.message = format(errorDefinition.message, arguments); - } else if (_.isFunction(errorDefinition.message)) { + } else if (typeof errorDefinition.message === 'function') { this.message = errorDefinition.message.apply(null, arguments); } else { throw new Error('Invalid error definition for ' + errorDefinition.name); @@ -30,9 +28,9 @@ const traverseNode = function(parent, errorDefinition) { /* jshint latedef: false */ const childDefinitions = function(parent, childDefinitions) { - _.each(childDefinitions, function(childDefinition) { - traverseNode(parent, childDefinition); - }); + for (const childDef of childDefinitions) { + traverseNode(parent, childDef); + } }; /* jshint latedef: true */ diff --git a/packages/bitcore-lib/lib/hdprivatekey.js b/packages/bitcore-lib/lib/hdprivatekey.js index 9dafbc11577..7fda2153c14 100644 --- a/packages/bitcore-lib/lib/hdprivatekey.js +++ b/packages/bitcore-lib/lib/hdprivatekey.js @@ -3,7 +3,6 @@ const assert = require('assert'); const buffer = require('buffer'); -const _ = require('lodash'); const BN = require('./crypto/bn'); const Hash = require('./crypto/hash'); const Point = require('./crypto/point'); @@ -46,7 +45,7 @@ function HDPrivateKey(arg) { if (Network.get(arg)) { return this._generateRandomly(arg); - } else if (_.isString(arg) || BufferUtil.isBuffer(arg)) { + } else if (typeof arg === 'string' || BufferUtil.isBuffer(arg)) { if (HDPrivateKey.isValidSerialized(arg)) { this._buildFromSerialized(arg); } else if (JSUtil.isValidJSON(arg)) { @@ -56,7 +55,7 @@ function HDPrivateKey(arg) { } else { throw HDPrivateKey.getSerializedError(arg); } - } else if (_.isObject(arg)) { + } else if (typeof arg === 'object' && arg !== null) { this._buildFromObject(arg); } else { throw new hdErrors.UnrecognizedArgument(arg); @@ -71,12 +70,12 @@ function HDPrivateKey(arg) { * @return {boolean} */ HDPrivateKey.isValidPath = function(arg, hardened) { - if (_.isString(arg)) { + if (typeof arg === 'string') { const indexes = HDPrivateKey._getDerivationIndexes(arg); - return indexes !== null && _.every(indexes, HDPrivateKey.isValidPath); + return indexes !== null && indexes.every(index => HDPrivateKey.isValidPath(index)); } - if (_.isNumber(arg)) { + if (typeof arg === 'number') { if (arg < HDPrivateKey.Hardened && hardened === true) { arg += HDPrivateKey.Hardened; } @@ -98,11 +97,11 @@ HDPrivateKey._getDerivationIndexes = function(path) { const steps = path.split('/'); // Special cases: - if (_.includes(HDPrivateKey.RootElementAlias, path)) { + if (HDPrivateKey.RootElementAlias.includes(path)) { return []; } - if (!_.includes(HDPrivateKey.RootElementAlias, steps[0])) { + if (!HDPrivateKey.RootElementAlias.includes(steps[0])) { return null; } @@ -122,7 +121,7 @@ HDPrivateKey._getDerivationIndexes = function(path) { return index; }); - return _.some(indexes, isNaN) ? null : indexes; + return indexes.some(index => isNaN(index)) ? null : indexes; }; /** @@ -142,9 +141,9 @@ HDPrivateKey._getDerivationIndexes = function(path) { * * @example * ```javascript - * let parent = new HDPrivateKey('xprv...'); - * let child_0_1_2h = parent.derive(0).derive(1).derive(2, true); - * let copy_of_child_0_1_2h = parent.derive("m/0/1/2'"); + * const parent = new HDPrivateKey('xprv...'); + * const child_0_1_2h = parent.derive(0).derive(1).derive(2, true); + * const copy_of_child_0_1_2h = parent.derive("m/0/1/2'"); * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h); * ``` * @@ -175,9 +174,9 @@ HDPrivateKey.prototype.derive = function(arg, hardened) { * * @example * ```javascript - * let parent = new HDPrivateKey('xprv...'); - * let child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true); - * let copy_of_child_0_1_2h = parent.deriveChild("m/0/1/2'"); + * const parent = new HDPrivateKey('xprv...'); + * const child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true); + * const copy_of_child_0_1_2h = parent.deriveChild("m/0/1/2'"); * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h); * ``` * @@ -185,9 +184,9 @@ HDPrivateKey.prototype.derive = function(arg, hardened) { * @param {boolean?} hardened */ HDPrivateKey.prototype.deriveChild = function(arg, hardened) { - if (_.isNumber(arg)) { + if (typeof arg === 'number') { return this._deriveWithNumber(arg, hardened); - } else if (_.isString(arg)) { + } else if (typeof arg === 'string') { return this._deriveFromString(arg); } else { throw new hdErrors.InvalidDerivationArgument(arg); @@ -211,9 +210,9 @@ HDPrivateKey.prototype.deriveChild = function(arg, hardened) { * @param {boolean?} hardened */ HDPrivateKey.prototype.deriveNonCompliantChild = function(arg, hardened) { - if (_.isNumber(arg)) { + if (typeof arg === 'number') { return this._deriveWithNumber(arg, hardened, true); - } else if (_.isString(arg)) { + } else if (typeof arg === 'string') { return this._deriveFromString(arg, true); } else { throw new hdErrors.InvalidDerivationArgument(arg); @@ -311,7 +310,7 @@ HDPrivateKey.isValidSerialized = function(data, network) { */ HDPrivateKey.getSerializedError = function(data, network) { /* jshint maxcomplexity: 10 */ - if (!(_.isString(data) || BufferUtil.isBuffer(data))) { + if (!(typeof data === 'string' || BufferUtil.isBuffer(data))) { return new hdErrors.UnrecognizedArgument('Expected string or buffer'); } if (!Base58.validCharacters(data)) { @@ -319,13 +318,13 @@ HDPrivateKey.getSerializedError = function(data, network) { } try { data = Base58Check.decode(data); - } catch (e) { + } catch { return new errors.InvalidB58Checksum(data); } if (data.length !== HDPrivateKey.DataLength) { return new hdErrors.InvalidLength(data); } - if (!_.isUndefined(network)) { + if (network != null) { const error = HDPrivateKey._validateNetwork(data, network); if (error) { return error; @@ -347,12 +346,12 @@ HDPrivateKey._validateNetwork = function(data, networkArg) { }; HDPrivateKey.fromString = function(arg) { - $.checkArgument(_.isString(arg), 'No valid string was provided'); + $.checkArgument(typeof arg === 'string', 'No valid string was provided'); return new HDPrivateKey(arg); }; HDPrivateKey.fromObject = function(arg) { - $.checkArgument(_.isObject(arg), 'No valid argument was provided'); + $.checkArgument(typeof arg === 'object' && arg !== null, 'No valid argument was provided'); return new HDPrivateKey(arg); }; @@ -365,11 +364,11 @@ HDPrivateKey.prototype._buildFromObject = function(arg) { // TODO: Type validation const buffers = { version: arg.network ? BufferUtil.integerAsBuffer(Network.get(arg.network).xprivkey) : arg.version, - depth: _.isNumber(arg.depth) ? BufferUtil.integerAsSingleByteBuffer(arg.depth) : arg.depth, - parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? BufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint, - childIndex: _.isNumber(arg.childIndex) ? BufferUtil.integerAsBuffer(arg.childIndex) : arg.childIndex, - chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode, - privateKey: (_.isString(arg.privateKey) && JSUtil.isHexa(arg.privateKey)) ? Buffer.from(arg.privateKey, 'hex') : arg.privateKey, + depth: typeof arg.depth === 'number' ? BufferUtil.integerAsSingleByteBuffer(arg.depth) : arg.depth, + parentFingerPrint: typeof arg.parentFingerPrint === 'number' ? BufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint, + childIndex: typeof arg.childIndex === 'number' ? BufferUtil.integerAsBuffer(arg.childIndex) : arg.childIndex, + chainCode: typeof arg.chainCode === 'string' ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode, + privateKey: (typeof arg.privateKey === 'string' && JSUtil.isHexa(arg.privateKey)) ? Buffer.from(arg.privateKey, 'hex') : arg.privateKey, checksum: arg.checksum ? (arg.checksum.length ? arg.checksum : BufferUtil.integerAsBuffer(arg.checksum)) : undefined }; return this._buildFromBuffers(buffers); @@ -475,8 +474,7 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) { } const network = Network.get(BufferUtil.integerFromBuffer(arg.version)); - let xprivkey; - xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence)); + const xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence)); arg.xprivkey = Buffer.from(xprivkey); const privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network); diff --git a/packages/bitcore-lib/lib/hdpublickey.js b/packages/bitcore-lib/lib/hdpublickey.js index 081cb1c1a3f..6dc404bd6ed 100644 --- a/packages/bitcore-lib/lib/hdpublickey.js +++ b/packages/bitcore-lib/lib/hdpublickey.js @@ -1,6 +1,6 @@ 'use strict'; -const _ = require('lodash'); +const assert = require('assert'); const BN = require('./crypto/bn'); const Hash = require('./crypto/hash'); const Point = require('./crypto/point'); @@ -10,13 +10,12 @@ const bitcoreErrors = require('./errors'); const HDPrivateKey = require('./hdprivatekey'); const Network = require('./networks'); const PublicKey = require('./publickey'); +const BufferUtil = require('./util/buffer'); +const JSUtil = require('./util/js'); const $ = require('./util/preconditions'); const errors = bitcoreErrors; const hdErrors = bitcoreErrors.HDPublicKey; -const assert = require('assert'); -const JSUtil = require('./util/js'); -const BufferUtil = require('./util/buffer'); /** * The representation of an hierarchically derived public key. @@ -36,7 +35,7 @@ function HDPublicKey(arg) { return new HDPublicKey(arg); } if (arg) { - if (_.isString(arg) || BufferUtil.isBuffer(arg)) { + if (typeof arg === 'string' || BufferUtil.isBuffer(arg)) { const error = HDPublicKey.getSerializedError(arg); if (!error) { return this._buildFromSerialized(arg); @@ -49,7 +48,7 @@ function HDPublicKey(arg) { throw error; } } else { - if (_.isObject(arg)) { + if (typeof arg === 'object' && arg !== null) { if (arg instanceof HDPrivateKey) { return this._buildFromPrivate(arg); } else { @@ -71,12 +70,12 @@ function HDPublicKey(arg) { * @return {boolean} */ HDPublicKey.isValidPath = function(arg) { - if (_.isString(arg)) { + if (typeof arg === 'string') { const indexes = HDPrivateKey._getDerivationIndexes(arg); - return indexes !== null && _.every(indexes, HDPublicKey.isValidPath); + return indexes !== null && indexes.every(index => HDPublicKey.isValidPath(index)); } - if (_.isNumber(arg)) { + if (typeof arg === 'number') { return arg >= 0 && arg < HDPublicKey.Hardened; } @@ -138,9 +137,9 @@ HDPublicKey.prototype.derive = function(arg, hardened) { * @param {string|number} arg */ HDPublicKey.prototype.deriveChild = function(arg, hardened) { - if (_.isNumber(arg)) { + if (typeof arg === 'number') { return this._deriveWithNumber(arg, hardened); - } else if (_.isString(arg)) { + } else if (typeof arg === 'string') { return this._deriveFromString(arg); } else { throw new hdErrors.InvalidDerivationArgument(arg); @@ -164,7 +163,7 @@ HDPublicKey.prototype._deriveWithNumber = function(index, hardened) { let publicKey; try { publicKey = PublicKey.fromPoint(Point.getG().mul(leftPart).add(this.publicKey.point)); - } catch (e) { + } catch { return this._deriveWithNumber(index + 1); } @@ -182,7 +181,7 @@ HDPublicKey.prototype._deriveWithNumber = function(index, hardened) { HDPublicKey.prototype._deriveFromString = function(path) { /* jshint maxcomplexity: 8 */ - if (_.includes(path, "'")) { + if (path.includes("'")) { throw new hdErrors.InvalidIndexCantDeriveHardened(); } else if (!HDPublicKey.isValidPath(path)) { throw new hdErrors.InvalidPath(path); @@ -206,7 +205,7 @@ HDPublicKey.prototype._deriveFromString = function(path) { * @return {boolean} */ HDPublicKey.isValidSerialized = function(data, network) { - return _.isNull(HDPublicKey.getSerializedError(data, network)); + return HDPublicKey.getSerializedError(data, network) === null; }; /** @@ -221,7 +220,7 @@ HDPublicKey.isValidSerialized = function(data, network) { HDPublicKey.getSerializedError = function(data, network) { /* jshint maxcomplexity: 10 */ /* jshint maxstatements: 20 */ - if (!(_.isString(data) || BufferUtil.isBuffer(data))) { + if (!(typeof data === 'string' || BufferUtil.isBuffer(data))) { return new hdErrors.UnrecognizedArgument('expected buffer or string'); } if (!Base58.validCharacters(data)) { @@ -229,13 +228,13 @@ HDPublicKey.getSerializedError = function(data, network) { } try { data = Base58Check.decode(data); - } catch (e) { + } catch { return new errors.InvalidB58Checksum(data); } if (data.length !== HDPublicKey.DataSize) { return new hdErrors.InvalidLength(data); } - if (!_.isUndefined(network)) { + if (network != null) { const error = HDPublicKey._validateNetwork(data, network); if (error) { return error; @@ -261,7 +260,7 @@ HDPublicKey._validateNetwork = function(data, networkArg) { }; HDPublicKey.prototype._buildFromPrivate = function (arg) { - const args = _.clone(arg._buffers); + const args = { ...arg._buffers }; const point = Point.getG().mul(BN.fromBuffer(args.privateKey)); args.publicKey = Point.pointToCompressed(point); args.version = BufferUtil.integerAsBuffer(Network.get(BufferUtil.integerFromBuffer(args.version)).xpubkey); @@ -276,13 +275,13 @@ HDPublicKey.prototype._buildFromObject = function(arg) { // TODO: Type validation const buffers = { version: arg.network ? BufferUtil.integerAsBuffer(Network.get(arg.network).xpubkey) : arg.version, - depth: _.isNumber(arg.depth) ? BufferUtil.integerAsSingleByteBuffer(arg.depth) : arg.depth, - parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? BufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint, - childIndex: _.isNumber(arg.childIndex) ? BufferUtil.integerAsBuffer(arg.childIndex) : arg.childIndex, - chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode, - publicKey: _.isString(arg.publicKey) ? Buffer.from(arg.publicKey, 'hex') : + depth: typeof arg.depth === 'number' ? BufferUtil.integerAsSingleByteBuffer(arg.depth) : arg.depth, + parentFingerPrint: typeof arg.parentFingerPrint === 'number' ? BufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint, + childIndex: typeof arg.childIndex === 'number' ? BufferUtil.integerAsBuffer(arg.childIndex) : arg.childIndex, + chainCode: typeof arg.chainCode === 'string' ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode, + publicKey: typeof arg.publicKey === 'string' ? Buffer.from(arg.publicKey, 'hex') : BufferUtil.isBuffer(arg.publicKey) ? arg.publicKey : arg.publicKey.toBuffer(), - checksum: _.isNumber(arg.checksum) ? BufferUtil.integerAsBuffer(arg.checksum) : arg.checksum + checksum: typeof arg.checksum === 'number' ? BufferUtil.integerAsBuffer(arg.checksum) : arg.checksum }; return this._buildFromBuffers(buffers); }; @@ -344,8 +343,7 @@ HDPublicKey.prototype._buildFromBuffers = function(arg) { } const network = Network.get(BufferUtil.integerFromBuffer(arg.version)); - let xpubkey; - xpubkey = Base58Check.encode(BufferUtil.concat(sequence)); + const xpubkey = Base58Check.encode(BufferUtil.concat(sequence)); arg.xpubkey = Buffer.from(xpubkey); const publicKey = new PublicKey(arg.publicKey, { network: network }); @@ -384,12 +382,12 @@ HDPublicKey._validateBufferArguments = function(arg) { }; HDPublicKey.fromString = function(arg) { - $.checkArgument(_.isString(arg), 'No valid string was provided'); + $.checkArgument(typeof arg === 'string', 'No valid string was provided'); return new HDPublicKey(arg); }; HDPublicKey.fromObject = function(arg) { - $.checkArgument(_.isObject(arg), 'No valid argument was provided'); + $.checkArgument(typeof arg === 'object' && arg !== null, 'No valid argument was provided'); return new HDPublicKey(arg); }; diff --git a/packages/bitcore-lib/lib/message.js b/packages/bitcore-lib/lib/message.js index 17d012a2efe..3d2e4990716 100644 --- a/packages/bitcore-lib/lib/message.js +++ b/packages/bitcore-lib/lib/message.js @@ -1,14 +1,12 @@ 'use strict'; -const _ = require('lodash'); const Address = require('./address'); const ECDSA = require('./crypto/ecdsa'); +const sha256sha256 = require('./crypto/hash').sha256sha256; const Signature = require('./crypto/signature'); const BufferWriter = require('./encoding/bufferwriter'); const PrivateKey = require('./privatekey'); const PublicKey = require('./publickey'); -const sha256sha256 = require('./crypto/hash').sha256sha256; -const Script = require('./script'); const JSUtil = require('./util/js'); const $ = require('./util/preconditions'); @@ -16,7 +14,7 @@ function Message(message) { if (!(this instanceof Message)) { return new Message(message); } - $.checkArgument(_.isString(message), 'First argument should be a string'); + $.checkArgument(typeof message === 'string', 'First argument should be a string'); this.message = message; return this; @@ -73,9 +71,9 @@ Message.prototype._verify = function _verify(publicKey, signature) { */ Message.prototype.verify = function verify(bitcoinAddress, signatureString) { $.checkArgument(bitcoinAddress); - $.checkArgument(signatureString && _.isString(signatureString)); + $.checkArgument(typeof signatureString === 'string' && signatureString !== ''); - if (_.isString(bitcoinAddress)) { + if (typeof bitcoinAddress === 'string') { bitcoinAddress = Address.fromString(bitcoinAddress); } const signature = Signature.fromCompact(Buffer.from(signatureString, 'base64')); @@ -105,9 +103,9 @@ Message.prototype.verify = function verify(bitcoinAddress, signatureString) { */ Message.prototype.recoverPublicKey = function recoverPublicKey(bitcoinAddress, signatureString) { $.checkArgument(bitcoinAddress); - $.checkArgument(signatureString && _.isString(signatureString)); + $.checkArgument(typeof signatureString === 'string' && signatureString !== ''); - if (_.isString(bitcoinAddress)) { + if (typeof bitcoinAddress === 'string') { bitcoinAddress = Address.fromString(bitcoinAddress); } const signature = Signature.fromCompact(Buffer.from(signatureString, 'base64')); diff --git a/packages/bitcore-lib/lib/opcode.js b/packages/bitcore-lib/lib/opcode.js index 07a7fe4de76..c4f944b1880 100644 --- a/packages/bitcore-lib/lib/opcode.js +++ b/packages/bitcore-lib/lib/opcode.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const BufferUtil = require('./util/buffer'); const JSUtil = require('./util/js'); const $ = require('./util/preconditions'); @@ -12,9 +11,9 @@ function Opcode(num) { let value; - if (_.isNumber(num)) { + if (typeof num === 'number') { value = num; - } else if (_.isString(num)) { + } else if (typeof num === 'string') { value = Opcode.map[num]; } else { throw new TypeError('Unrecognized num type: "' + typeof(num) + '" for Opcode'); @@ -33,12 +32,12 @@ Opcode.fromBuffer = function(buf) { }; Opcode.fromNumber = function(num) { - $.checkArgument(_.isNumber(num)); + $.checkArgument(typeof num === 'number'); return new Opcode(num); }; Opcode.fromString = function(str) { - $.checkArgument(_.isString(str)); + $.checkArgument(typeof str === 'string'); const value = Opcode.map[str]; if (typeof value === 'undefined') { throw new TypeError('Invalid opcodestr'); @@ -67,7 +66,7 @@ Opcode.prototype.toString = function() { }; Opcode.smallInt = function(n) { - $.checkArgument(_.isNumber(n), 'Invalid Argument: n should be number'); + $.checkArgument(typeof n === 'number', 'Invalid Argument: n should be number'); $.checkArgument(n >= 0 && n <= 16, 'Invalid Argument: n must be between 0 and 16'); if (n === 0) { return Opcode('OP_0'); @@ -257,7 +256,7 @@ for (const k in Opcode.map) { } // Easier access to opcodes -_.extend(Opcode, Opcode.map); +Object.assign(Opcode, Opcode.map); /** * @returns true if opcode is one of OP_0, OP_1, ..., OP_16 diff --git a/packages/bitcore-lib/lib/privatekey.js b/packages/bitcore-lib/lib/privatekey.js index 8464adeb8d7..5df81f9a7d1 100644 --- a/packages/bitcore-lib/lib/privatekey.js +++ b/packages/bitcore-lib/lib/privatekey.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const Address = require('./address'); const BN = require('./crypto/bn'); const Point = require('./crypto/point'); @@ -91,7 +90,7 @@ PrivateKey.prototype._classifyArguments = function(data, network) { }; // detect type of data - if (_.isUndefined(data) || _.isNull(data)) { + if (data == null) { info.bn = PrivateKey._getRandomBN(); } else if (data instanceof BN) { info.bn = data; @@ -233,7 +232,7 @@ PrivateKey._transformObject = function(json) { * @returns {PrivateKey} A new valid instance of PrivateKey */ PrivateKey.fromString = PrivateKey.fromWIF = function(str) { - $.checkArgument(_.isString(str), 'First argument is expected to be a string.'); + $.checkArgument(typeof str === 'string', 'First argument is expected to be a string.'); return new PrivateKey(str); }; @@ -243,7 +242,7 @@ PrivateKey.fromString = PrivateKey.fromWIF = function(str) { * @param {Object} obj - The output from privateKey.toObject() */ PrivateKey.fromObject = function(obj) { - $.checkArgument(_.isObject(obj), 'First argument is expected to be an object.'); + $.checkArgument(typeof obj === 'object' && obj !== null, 'First argument is expected to be an object.'); return new PrivateKey(obj); }; diff --git a/packages/bitcore-lib/lib/publickey.js b/packages/bitcore-lib/lib/publickey.js index 1b1fbd59e28..e95f85229b9 100644 --- a/packages/bitcore-lib/lib/publickey.js +++ b/packages/bitcore-lib/lib/publickey.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const BN = require('./crypto/bn'); const Hash = require('./crypto/hash'); const Point = require('./crypto/point'); @@ -70,7 +69,8 @@ function PublicKey(data, extra) { PublicKey.prototype._classifyArgs = function(data, extra) { /* jshint maxcomplexity: 10 */ let info = { - compressed: _.isUndefined(extra.compressed) || extra.compressed + // Default true only if extra.compressed is left off + compressed: extra.compressed === undefined || extra.compressed }; // detect type of data @@ -88,7 +88,8 @@ PublicKey.prototype._classifyArgs = function(data, extra) { throw new TypeError('First argument is an unrecognized data format.'); } if (!info.network) { - info.network = _.isUndefined(extra.network) ? undefined : Network.get(extra.network); + // Maintain undefined specifically + info.network = extra.network === undefined ? undefined : Network.get(extra.network); } return info; }; @@ -146,7 +147,7 @@ PublicKey._transformDER = function(buf, strict) { $.checkArgument(PublicKey._isBuffer(buf), 'Must be a hex buffer of DER encoded public key'); let info = {}; - strict = _.isUndefined(strict) ? true : strict; + strict = strict === undefined ? true : strict; let x; let y; @@ -320,7 +321,7 @@ PublicKey.fromTaproot = function(hexBuf) { PublicKey.isValidTaproot = function(hexBuf) { try { return !!PublicKey.fromTaproot(hexBuf); - } catch (e) { + } catch { return false; } }; @@ -366,6 +367,7 @@ PublicKey.prototype.checkTapTweak = function(p, merkleRoot, control) { const P = p.point.liftX(); const Q = P.add(this.point.curve.g.mul(BN.fromBuffer(tweak))); + // eslint-disable-next-line no-bitwise return this.point.x.eq(Q.x) && Q.y.mod(new BN(2)).eq(new BN(control[0] & 1)); }; diff --git a/packages/bitcore-lib/lib/script/interpreter.js b/packages/bitcore-lib/lib/script/interpreter.js index af661589178..bfa74c2e8e5 100644 --- a/packages/bitcore-lib/lib/script/interpreter.js +++ b/packages/bitcore-lib/lib/script/interpreter.js @@ -1,7 +1,6 @@ /* eslint-disable no-bitwise */ 'use strict'; -const _ = require('lodash'); const BN = require('../crypto/bn'); const Hash = require('../crypto/hash'); const Signature = require('../crypto/signature'); @@ -11,6 +10,7 @@ const Opcode = require('../opcode'); const PublicKey = require('../publickey'); const SighashSchnorr = require('../transaction/sighashschnorr'); const SighashWitness = require('../transaction/sighashwitness'); +const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const Script = require('./script'); @@ -237,19 +237,19 @@ Interpreter.prototype.executeWitnessScript = function(scriptPubKey, stack, sigve Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) { const Transaction = require('../transaction'); - if (_.isUndefined(tx)) { + if (tx == null) { tx = new Transaction(); } - if (_.isUndefined(nin)) { + if (nin == null) { nin = 0; } - if (_.isUndefined(flags)) { + if (flags == null) { flags = 0; } - if (_.isUndefined(witness)) { + if (witness == null) { witness = null; } - if (_.isUndefined(satoshis)) { + if (satoshis == null) { satoshis = 0; } @@ -505,6 +505,7 @@ Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 7); // be true". // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. +// eslint-disable-next-line @typescript-eslint/no-unused-expressions Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8), // Verify CHECKLOCKTIMEVERIFY @@ -1080,7 +1081,7 @@ Interpreter.prototype.step = function() { const chunk = this.script.chunks[this.pc]; this.pc++; const opcodenum = chunk.opcodenum; - if (_.isUndefined(opcodenum)) { + if (opcodenum == null) { this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE'; return false; } diff --git a/packages/bitcore-lib/lib/script/script.js b/packages/bitcore-lib/lib/script/script.js index 5a6442914ea..30dd0e17f85 100644 --- a/packages/bitcore-lib/lib/script/script.js +++ b/packages/bitcore-lib/lib/script/script.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const Address = require('../address'); const Hash = require('../crypto/hash'); const Signature = require('../crypto/signature'); @@ -38,14 +37,14 @@ const Script = function Script(from) { return Script.fromBuffer(from.toBuffer()); } else if (typeof from === 'string') { return Script.fromString(from); - } else if (_.isObject(from) && Array.isArray(from.chunks)) { + } else if (typeof from === 'object' && from && Array.isArray(from.chunks)) { this.set(from); } }; Script.prototype.set = function(obj) { - $.checkArgument(_.isObject(obj)); + $.checkArgument(typeof obj === 'object' && obj !== null); $.checkArgument(Array.isArray(obj.chunks)); this.chunks = obj.chunks; return this; @@ -812,8 +811,17 @@ Script.buildMultisigOut = function(publicKeys, threshold, opts) { publicKeys = publicKeys.map(PublicKey); let sorted = publicKeys; if (!opts.noSorting) { - sorted = _.sortBy(publicKeys, function(publicKey) { - return publicKey.toString('hex'); + // avoid mutating input + sorted = [...publicKeys].sort(function(a, b) { + const aHex = a.toString('hex'); + const bHex = b.toString('hex'); + if (aHex < bHex) { + return -1; + } + if (aHex > bHex) { + return 1; + } + return 0; }); } for (let i = 0; i < sorted.length; i++) { @@ -842,7 +850,7 @@ Script.buildWitnessMultisigOutFromScript = function(script) { * @param {PublicKey[]} pubkeys list of all public keys controlling the output * @param {number} threshold amount of required signatures to spend the output * @param {Array} signatures and array of signature buffers to append to the script - * @param {Object=} opts + * @param {Object=} _opts * @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default) * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript * diff --git a/packages/bitcore-lib/lib/transaction/input/input.js b/packages/bitcore-lib/lib/transaction/input/input.js index 781ecd7b484..2f72acca2ad 100644 --- a/packages/bitcore-lib/lib/transaction/input/input.js +++ b/packages/bitcore-lib/lib/transaction/input/input.js @@ -1,7 +1,5 @@ 'use strict'; -const buffer = require('buffer'); -const _ = require('lodash'); const BufferWriter = require('../../encoding/bufferwriter'); const errors = require('../../errors'); const Script = require('../../script'); @@ -53,7 +51,7 @@ Object.defineProperty(Input.prototype, 'script', { }); Input.fromObject = function(obj) { - $.checkArgument(_.isObject(obj)); + $.checkArgument(typeof obj === 'object' && obj !== null); const input = new Input(); return input._fromObject(obj); }; @@ -130,7 +128,7 @@ Input.prototype.setScript = function(script) { } else if (JSUtil.isHexa(script)) { // hex string script this._scriptBuffer = Buffer.from(script, 'hex'); - } else if (_.isString(script)) { + } else if (typeof script === 'string') { // human readable string script this._script = new Script(script); this._script._isInput = true; @@ -242,13 +240,14 @@ Input.prototype._getBaseSize = function() { * @return {Transaction} this */ Input.prototype.lockForSeconds = function(seconds) { - $.checkArgument(_.isNumber(seconds)); + $.checkArgument(typeof seconds === 'number'); if (seconds < 0 || seconds >= SEQUENCE_LOCKTIME_GRANULARITY * SEQUENCE_LOCKTIME_MASK) { throw new errors.Transaction.Input.LockTimeRange(); } seconds = parseInt(Math.floor(seconds / SEQUENCE_LOCKTIME_GRANULARITY)); // SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 + // eslint-disable-next-line no-bitwise this.sequenceNumber = seconds | SEQUENCE_LOCKTIME_TYPE_FLAG ; return this; }; @@ -260,7 +259,7 @@ Input.prototype.lockForSeconds = function(seconds) { * @return {Transaction} this */ Input.prototype.lockUntilBlockHeight = function(heightDiff) { - $.checkArgument(_.isNumber(heightDiff)); + $.checkArgument(typeof heightDiff === 'number'); if (heightDiff < 0 || heightDiff >= SEQUENCE_BLOCKDIFF_LIMIT) { throw new errors.Transaction.Input.BlockHeightOutOfRange(); } @@ -279,14 +278,18 @@ Input.prototype.lockUntilBlockHeight = function(heightDiff) { * else it returns a Date object. */ Input.prototype.getLockTime = function() { + // eslint-disable-next-line no-bitwise if (this.sequenceNumber & SEQUENCE_LOCKTIME_DISABLE_FLAG) { return null; } + // eslint-disable-next-line no-bitwise if (this.sequenceNumber & SEQUENCE_LOCKTIME_TYPE_FLAG) { + // eslint-disable-next-line no-bitwise const seconds = SEQUENCE_LOCKTIME_GRANULARITY * (this.sequenceNumber & SEQUENCE_LOCKTIME_MASK); return seconds; } else { + // eslint-disable-next-line no-bitwise const blockHeight = this.sequenceNumber & SEQUENCE_LOCKTIME_MASK; return blockHeight; } diff --git a/packages/bitcore-lib/lib/transaction/input/multisig.js b/packages/bitcore-lib/lib/transaction/input/multisig.js index 961b9a6922b..c4020eeee8d 100644 --- a/packages/bitcore-lib/lib/transaction/input/multisig.js +++ b/packages/bitcore-lib/lib/transaction/input/multisig.js @@ -1,16 +1,13 @@ 'use strict'; const inherits = require('inherits'); -const _ = require('lodash'); const Signature = require('../../crypto/signature'); -const PublicKey = require('../../publickey'); const Script = require('../../script'); const BufferUtil = require('../../util/buffer'); const $ = require('../../util/preconditions'); const Output = require('../output'); const Sighash = require('../sighash'); const TransactionSignature = require('../signature'); -const Transaction = require('../transaction'); const Input = require('./input'); /** @@ -19,21 +16,31 @@ const Input = require('./input'); function MultiSigInput(input, pubkeys, threshold, signatures, opts) { opts = opts || {}; Input.apply(this, arguments); - const self = this; pubkeys = pubkeys || input.publicKeys; threshold = threshold || input.threshold; signatures = signatures || input.signatures; if (opts.noSorting) { this.publicKeys = pubkeys; } else { - this.publicKeys = _.sortBy(pubkeys, function(publicKey) { return publicKey.toString('hex'); }); + this.publicKeys = [...pubkeys].sort(function(a, b) { + const aHex = a.toString('hex'); + const bHex = b.toString('hex'); + if (aHex < bHex) { + return -1; + } + if (aHex > bHex) { + return 1; + } + return 0; + }); } $.checkState(Script.buildMultisigOut(this.publicKeys, threshold).equals(this.output.script), 'Provided public keys don\'t match to the provided output script'); this.publicKeyIndex = {}; - _.each(this.publicKeys, function(publicKey, index) { - self.publicKeyIndex[publicKey.toString()] = index; - }); + for (let i = 0; i < this.publicKeys.length; i++) { + const publicKeyString = this.publicKeys[i].toString(); + this.publicKeyIndex[publicKeyString] = i; + } this.threshold = threshold; // Empty array of signatures this.signatures = signatures ? this._deserializeSignatures(signatures) : new Array(this.publicKeys.length); @@ -43,13 +50,14 @@ inherits(MultiSigInput, Input); MultiSigInput.prototype.toObject = function() { const obj = Input.prototype.toObject.apply(this, arguments); obj.threshold = this.threshold; - obj.publicKeys = _.map(this.publicKeys, function(publicKey) { return publicKey.toString(); }); + obj.publicKeys = this.publicKeys.map(publicKey => publicKey.toString()); obj.signatures = this._serializeSignatures(); return obj; }; MultiSigInput.prototype._deserializeSignatures = function(signatures) { - return _.map(signatures, function(signature) { + // Keeps ordering and size + return signatures.map(signature => { if (!signature) { return undefined; } @@ -58,7 +66,8 @@ MultiSigInput.prototype._deserializeSignatures = function(signatures) { }; MultiSigInput.prototype._serializeSignatures = function() { - return _.map(this.signatures, function(signature) { + // Keeps ordering and size + return this.signatures.map(signature => { if (!signature) { return undefined; } @@ -118,7 +127,7 @@ MultiSigInput.prototype.getSignatures = function(transaction, privateKey, index, MultiSigInput.prototype.addSignature = function(transaction, signature, signingMethod) { $.checkState(!this.isFullySigned(), 'All needed signatures have already been added'); - $.checkArgument(!_.isUndefined(this.publicKeyIndex[signature.publicKey.toString()], 'Signature Undefined'), + $.checkArgument(this.publicKeyIndex[signature.publicKey.toString()] != null, 'Signature has no matching public key'); $.checkState(this.isValidSignature(transaction, signature, signingMethod), 'Invalid Signature'); this.signatures[this.publicKeyIndex[signature.publicKey.toString()]] = signature; @@ -136,16 +145,8 @@ MultiSigInput.prototype._updateScript = function() { }; MultiSigInput.prototype._createSignatures = function() { - return _.map( - _.filter(this.signatures, function(signature) { return !_.isUndefined(signature); }), - // Future signature types may need refactor of toDER - function(signature) { - return BufferUtil.concat([ - signature.signature.toDER(), - BufferUtil.integerAsSingleByteBuffer(signature.sigtype) - ]); - } - ); + return this.signatures.filter(signature => signature != null) + .map(signature => BufferUtil.concat([signature.signature.toDER(), BufferUtil.integerAsSingleByteBuffer(signature.sigtype)])); }; MultiSigInput.prototype.clearSignatures = function() { @@ -162,16 +163,11 @@ MultiSigInput.prototype.countMissingSignatures = function() { }; MultiSigInput.prototype.countSignatures = function() { - return _.reduce(this.signatures, function(sum, signature) { - return sum + (!!signature); - }, 0); + return this.signatures.reduce((sum, signature) => sum + (signature ? 1 : 0), 0); }; MultiSigInput.prototype.publicKeysWithoutSignature = function() { - const self = this; - return _.filter(this.publicKeys, function(publicKey) { - return !(self.signatures[self.publicKeyIndex[publicKey.toString()]]); - }); + return this.publicKeys.filter(publicKey => !this.signatures[this.publicKeyIndex[publicKey.toString()]]); }; MultiSigInput.prototype.isValidSignature = function(transaction, signature, signingMethod) { diff --git a/packages/bitcore-lib/lib/transaction/input/multisigscripthash.js b/packages/bitcore-lib/lib/transaction/input/multisigscripthash.js index 31e4853ab86..bbfef0dfcac 100644 --- a/packages/bitcore-lib/lib/transaction/input/multisigscripthash.js +++ b/packages/bitcore-lib/lib/transaction/input/multisigscripthash.js @@ -3,7 +3,6 @@ /* jshint maxparams:5 */ const inherits = require('inherits'); -const _ = require('lodash'); const Address = require('../../address'); const Signature = require('../../crypto/signature'); const BufferWriter = require('../../encoding/bufferwriter'); @@ -29,7 +28,17 @@ function MultiSigScriptHashInput(input, pubkeys, threshold, signatures, opts) { if (opts.noSorting) { this.publicKeys = pubkeys; } else { - this.publicKeys = _.sortBy(pubkeys, function(publicKey) { return publicKey.toString('hex'); }); + this.publicKeys = [...pubkeys].sort(function(a, b) { + const aHex = a.toString('hex'); + const bHex = b.toString('hex'); + if (aHex < bHex) { + return -1; + } + if (aHex > bHex) { + return 1; + } + return 0; + }); } this.redeemScript = Script.buildMultisigOut(this.publicKeys, threshold, opts); const nested = Script.buildWitnessMultisigOutFromScript(this.redeemScript); diff --git a/packages/bitcore-lib/lib/transaction/output.js b/packages/bitcore-lib/lib/transaction/output.js index 8dd841862a1..3bec1e7ab83 100644 --- a/packages/bitcore-lib/lib/transaction/output.js +++ b/packages/bitcore-lib/lib/transaction/output.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const BN = require('../crypto/bn'); const TaggedHash = require('../crypto/taggedhash'); const BufferWriter = require('../encoding/bufferwriter'); @@ -17,13 +16,13 @@ function Output(args) { if (!(this instanceof Output)) { return new Output(args); } - if (_.isObject(args)) { + if (typeof args === 'object' && args !== null) { this.satoshis = args.satoshis; if (bufferUtil.isBuffer(args.script)) { this.setScriptFromBuffer(args.script); } else { let script; - if (_.isString(args.script) && JSUtil.isHexa(args.script)) { + if (typeof args.script === 'string' && JSUtil.isHexa(args.script)) { script = Buffer.from(args.script, 'hex'); } else { script = args.script; @@ -32,6 +31,9 @@ function Output(args) { } if (args.type === 'taproot') { + // FIXME: This taproot-specific Output builder path appears incomplete and may be dead code. + // The state initialized here (`branch`) does not match later callers (`_branch`), and the + // `isValid` getter below does not return a value, so `add()` currently bails out immediately. this.branch = []; Object.defineProperty(this, 'isValid', { configurable: false, @@ -80,7 +82,7 @@ Object.defineProperty(Output.prototype, 'satoshis', { if (num instanceof BN) { this._satoshisBN = num; this._satoshis = num.toNumber(); - } else if (_.isString(num)) { + } else if (typeof num === 'string') { this._satoshis = parseInt(num); this._satoshisBN = BN.fromNumber(this._satoshis); } else { @@ -142,7 +144,7 @@ Output.prototype.setScript = function(script) { this._scriptBuffer = script.toBuffer(); this._script = script; this._script._isOutput = true; - } else if (_.isString(script)) { + } else if (typeof script === 'string') { this._script = Script.fromString(script); this._scriptBuffer = this._script.toBuffer(); this._script._isOutput = true; @@ -205,6 +207,7 @@ Output.prototype.calculateSize = function() { * @param {Boolean} track If true, the leaf will be included in GetSpendData() output */ Output.prototype.add = function(depth, script, leafVersion, track = true) { + // eslint-disable-next-line no-bitwise $.checkArgument((leafVersion & ~Interpreter.TAPROOT_LEAF_MASK) === 0, 'invalid leafVersion'); if (!this.isValid) { return; @@ -228,6 +231,10 @@ Output.prototype.add = function(depth, script, leafVersion, track = true) { Output.prototype._insertNode = function(node, depth) { + // FIXME: This helper is currently inconsistent with the state initialized above: + // it reads `_branch` / `_nodes`, but the taproot constructor path initializes `branch`, + // and `m_branch` below is undefined. If this path is ever revived, it likely needs a full + // pass rather than an isolated lint fix. $.checkArgument(depth >= 0 && depth <= Interpreter.TAPROOT_CONTROL_MAX_NODE_COUNT, 'invalid depth'); /* We cannot insert a leaf at a lower depth while a deeper branch is unfinished. Doing * so would mean the Add() invocations do not correspond to a DFS traversal of a @@ -284,12 +291,12 @@ Output.prototype._combineNodes = function(a, b) { /** * Finalize the construction. Can only be called when IsComplete() is true. * internal_key.IsFullyValid() must be true. - * @param {PublicKey} pubKey + * @param {PublicKey} pubkey + * @returns {void} */ Output.prototype.finalize = function(pubKey) { $.checkState(this.isComplete === true, 'finalize can only be called when isComplete is true'); - const ret = pubKey.createTapTweak(this._branch.length === 0 ? null : this._branch[0].hash); - + pubKey.createTapTweak(this._branch.length === 0 ? null : this._branch[0].hash); }; module.exports = Output; diff --git a/packages/bitcore-lib/lib/transaction/transaction.js b/packages/bitcore-lib/lib/transaction/transaction.js index 9c50814b2c8..989c0bbd7fb 100644 --- a/packages/bitcore-lib/lib/transaction/transaction.js +++ b/packages/bitcore-lib/lib/transaction/transaction.js @@ -1,7 +1,6 @@ 'use strict'; const buffer = require('buffer'); -const _ = require('lodash'); const Address = require('../address'); const BN = require('../crypto/bn'); const Hash = require('../crypto/hash'); @@ -9,25 +8,26 @@ const Signature = require('../crypto/signature'); const BufferReader = require('../encoding/bufferreader'); const BufferWriter = require('../encoding/bufferwriter'); const errors = require('../errors'); +const PrivateKey = require('../privatekey'); +const Script = require('../script'); const BufferUtil = require('../util/buffer'); const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const compare = Buffer.compare || require('buffer-compare'); - const Input = require('./input'); +const Output = require('./output'); const Sighash = require('./sighash'); const SighashSchnorr = require('./sighashschnorr'); const SighashWitness = require('./sighashwitness'); const UnspentOutput = require('./unspentoutput'); +const objectToString = Object.prototype.toString; + const PublicKeyHashInput = Input.PublicKeyHash; const PublicKeyInput = Input.PublicKey; const MultiSigScriptHashInput = Input.MultiSigScriptHash; const MultiSigInput = Input.MultiSig; const TaprootInput = Input.Taproot; -const Output = require('./output'); -const Script = require('../script'); -const PrivateKey = require('../privatekey'); /** * Represents a transaction, a set of inputs and outputs to change ownership of tokens @@ -52,7 +52,7 @@ function Transaction(serialized, opts) { this.fromString(serialized); } else if (BufferUtil.isBuffer(serialized)) { this.fromBuffer(serialized); - } else if (_.isObject(serialized)) { + } else if (typeof serialized === 'object' && serialized !== null) { this.fromObject(serialized, opts); } else { throw new errors.InvalidArgument('Must provide an object or string to deserialize a transaction'); @@ -415,14 +415,8 @@ Transaction.prototype.fromBufferReader = function(reader) { Transaction.prototype.toObject = Transaction.prototype.toJSON = function toObject() { - const inputs = []; - this.inputs.forEach(function(input) { - inputs.push(input.toObject()); - }); - const outputs = []; - this.outputs.forEach(function(output) { - outputs.push(output.toObject()); - }); + const inputs = this.inputs.map(input => input.toObject()); + const outputs = this.outputs.map(output => output.toObject()); const obj = { hash: this.hash, version: this.version, @@ -444,7 +438,7 @@ Transaction.prototype.toObject = Transaction.prototype.toJSON = function toObjec Transaction.prototype.fromObject = function fromObject(arg, opts) { /* jshint maxstatements: 20 */ - $.checkArgument(_.isObject(arg) || arg instanceof Transaction); + $.checkArgument(arg instanceof Transaction || (typeof arg === 'object' && arg !== null)); let transaction; if (arg instanceof Transaction) { transaction = arg.toObject(); @@ -513,7 +507,8 @@ Transaction.prototype.lockUntilDate = function(time) { if (!isNaN(time) && time < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) { throw new errors.Transaction.LockTimeTooEarly(); } - if (_.isDate(time)) { + // Handles all values that have an internal class of Date. like prior lodash implementation. + if (objectToString.call(time) === '[object Date]') { time = time.getTime() / 1000; } @@ -974,12 +969,13 @@ Transaction.prototype._getOutputAmount = function() { */ Transaction.prototype._getInputAmount = function() { if (this._inputAmount == null) { - this._inputAmount = _.sumBy(this.inputs, function(input) { + this._inputAmount = 0; + for (const input of this.inputs || []) { if (input.output == null) { throw new errors.Transaction.Input.MissingPreviousOutput(); } - return input.output.satoshis; - }); + this._inputAmount += input.output.satoshis; + } } return this._inputAmount; }; @@ -1115,7 +1111,8 @@ Transaction.prototype._calculateWeight = function() { Transaction.prototype._removeOutput = function(index) { const output = this.outputs[index]; - this.outputs = _.without(this.outputs, output); + // Remove by object identity (maintains prior lodash .without implementation) + this.outputs = this.outputs.filter(el => el !== output); this._outputAmount = undefined; }; @@ -1132,9 +1129,12 @@ Transaction.prototype.removeOutput = function(index) { */ Transaction.prototype.sort = function() { this.sortInputs(function(inputs) { - const copy = Array.prototype.concat.apply([], inputs); - let i = 0; - copy.forEach((x) => { x.i = i++;}); + // New array, with mutated elements (maintains prior behavior) + const copy = inputs.map((input, i) => { + input.i = i; + return input; + }); + copy.sort(function(first, second) { return compare(first.prevTxId, second.prevTxId) || first.outputIndex - second.outputIndex @@ -1143,9 +1143,11 @@ Transaction.prototype.sort = function() { return copy; }); this.sortOutputs(function(outputs) { - const copy = Array.prototype.concat.apply([], outputs); - let i = 0; - copy.forEach((x) => { x.i = i++;}); + // New array, with mutated elements (maintains prior behavior) + const copy = outputs.map((output, i) => { + output.i = i; + return output; + }); copy.sort(function(first, second) { return first.satoshis - second.satoshis || compare(first.script.toBuffer(), second.script.toBuffer()) @@ -1157,13 +1159,21 @@ Transaction.prototype.sort = function() { }; /** - * Randomize this transaction's outputs ordering. The shuffling algorithm is a - * version of the Fisher-Yates shuffle, provided by lodash's _.shuffle(). + * Randomize this transaction's outputs ordering using Fisher-Yates. * * @return {Transaction} this */ Transaction.prototype.shuffleOutputs = function() { - return this.sortOutputs(_.shuffle); + return this.sortOutputs(function(outputs) { + const shuffled = [...outputs]; + + for (let i = shuffled.length - 1; i >= 1; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; + } + + return shuffled; + }); }; /** @@ -1195,8 +1205,10 @@ Transaction.prototype.sortInputs = function(sortingFunction) { }; Transaction.prototype._newOutputOrder = function(newOutputs) { + // TODO: Tighten this validation to account for duplicate output references (e.g. [A, A, B] = [A, B, B] should fail validation, but doesn't currently). const isInvalidSorting = (this.outputs.length !== newOutputs.length || - _.difference(this.outputs, newOutputs).length !== 0); + !this.outputs.every(output => newOutputs.includes(output))); + if (isInvalidSorting) { throw new errors.Transaction.InvalidSorting(); } @@ -1223,7 +1235,8 @@ Transaction.prototype.removeInput = function(txId, outputIndex) { throw new errors.Transaction.InvalidIndex(index, this.inputs.length); } const input = this.inputs[index]; - this.inputs = _.without(this.inputs, input); + // Filter on object identity (maintain prior lodash `without()` implementation) + this.inputs = this.inputs.filter(el => el !== input); this._inputAmount = undefined; this._updateChangeOutput(); }; diff --git a/packages/bitcore-lib/lib/transaction/unspentoutput.js b/packages/bitcore-lib/lib/transaction/unspentoutput.js index abb9127c426..38d147def71 100644 --- a/packages/bitcore-lib/lib/transaction/unspentoutput.js +++ b/packages/bitcore-lib/lib/transaction/unspentoutput.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const Address = require('../address'); const Script = require('../script'); const Unit = require('../unit'); @@ -29,24 +28,24 @@ function UnspentOutput(data) { if (!(this instanceof UnspentOutput)) { return new UnspentOutput(data); } - $.checkArgument(_.isObject(data), 'Must provide an object from where to extract data'); + $.checkArgument(typeof data === 'object' && data !== null, 'Must provide an object from where to extract data'); const address = data.address ? new Address(data.address) : undefined; const txId = data.txid ? data.txid : data.txId; if (!txId || !JSUtil.isHexaString(txId) || txId.length > 64) { // TODO: Use the errors library throw new Error('Invalid TXID in object', data); } - const outputIndex = _.isUndefined(data.vout) ? data.outputIndex : data.vout; - if (!_.isNumber(outputIndex)) { + const outputIndex = data.vout === undefined ? data.outputIndex : data.vout; + if (typeof outputIndex !== 'number') { throw new Error('Invalid outputIndex, received ' + outputIndex); } - $.checkArgument(!_.isUndefined(data.scriptPubKey) || !_.isUndefined(data.script), + $.checkArgument(data.scriptPubKey != null || data.script != null, 'Must provide the scriptPubKey for that output!'); const script = new Script(data.scriptPubKey || data.script); - $.checkArgument(!_.isUndefined(data.amount) || !_.isUndefined(data.satoshis), + $.checkArgument(data.amount != null || data.satoshis != null, 'Must provide an amount for the output'); - const amount = !_.isUndefined(data.amount) ? new Unit.fromBTC(data.amount).toSatoshis() : data.satoshis; - $.checkArgument(_.isNumber(amount), 'Amount must be a number'); + const amount = data.amount != null ? new Unit.fromBTC(data.amount).toSatoshis() : data.satoshis; + $.checkArgument(typeof amount === 'number', 'Amount must be a number'); JSUtil.defineImmutable(this, { address: address, txId: txId, diff --git a/packages/bitcore-lib/lib/unit.js b/packages/bitcore-lib/lib/unit.js index a31cac28d66..af246a0a4ea 100644 --- a/packages/bitcore-lib/lib/unit.js +++ b/packages/bitcore-lib/lib/unit.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const errors = require('./errors'); const $ = require('./util/preconditions'); @@ -42,7 +41,7 @@ function Unit(amount, code) { } // convert fiat to BTC - if (_.isNumber(code)) { + if (typeof code === 'number') { if (code <= 0) { throw new errors.Unit.InvalidRate(code); } @@ -53,19 +52,19 @@ function Unit(amount, code) { this._value = this._from(amount, code); const self = this; - const defineAccesor = function(key) { + // Enumerable getters per unit name (e.g. instance.BTC → this.to('BTC')). + for (const key of Object.keys(UNITS)) { Object.defineProperty(self, key, { get: function() { return self.to(key); }, enumerable: true, }); - }; - - Object.keys(UNITS).forEach(defineAccesor); + } } -Object.keys(UNITS).forEach(function(key) { +// Unit.BTC, Unit.mBTC, ... — unit code string constants on the constructor. +for (const key of Object.keys(UNITS)) { Unit[key] = key; -}); +} /** * Returns a Unit instance created from JSON string or object @@ -74,7 +73,7 @@ Object.keys(UNITS).forEach(function(key) { * @returns {Unit} A Unit instance */ Unit.fromObject = function fromObject(data) { - $.checkArgument(_.isObject(data), 'Argument is expected to be an object'); + $.checkArgument(typeof data === 'object' && data !== null, 'Argument is expected to be an object'); return new Unit(data.amount, data.code); }; @@ -143,7 +142,7 @@ Unit.prototype._from = function(amount, code) { * @returns {Number} The converted value */ Unit.prototype.to = function(code) { - if (_.isNumber(code)) { + if (typeof code === 'number') { if (code <= 0) { throw new errors.Unit.InvalidRate(code); } diff --git a/packages/bitcore-lib/lib/uri.js b/packages/bitcore-lib/lib/uri.js index 912a0c3dbaf..eabea6b63c5 100644 --- a/packages/bitcore-lib/lib/uri.js +++ b/packages/bitcore-lib/lib/uri.js @@ -1,10 +1,8 @@ 'use strict'; -var _ = require('lodash'); -var URL = require('url'); - -var Address = require('./address'); -var Unit = require('./unit'); +const url = require('url'); +const Address = require('./address'); +const Unit = require('./unit'); /** * Bitcore URI @@ -32,7 +30,7 @@ var Unit = require('./unit'); * @returns {URI} A new valid and frozen instance of URI * @constructor */ -var URI = function(data, knownParams) { +const URI = function(data, knownParams) { if (!(this instanceof URI)) { return new URI(data, knownParams); } @@ -42,7 +40,7 @@ var URI = function(data, knownParams) { this.address = this.network = this.amount = this.message = null; if (typeof(data) === 'string') { - var params = URI.parse(data); + const params = URI.parse(data); if (params.amount) { params.amount = this._parseAmount(params.amount); } @@ -94,7 +92,7 @@ URI.fromObject = function fromObject(json) { URI.isValid = function(arg, knownParams) { try { new URI(arg, knownParams); - } catch (err) { + } catch { return false; } return true; @@ -108,14 +106,14 @@ URI.isValid = function(arg, knownParams) { * @returns {Object} An object with the parsed params */ URI.parse = function(uri) { - var info = URL.parse(uri, true); + const info = url.parse(uri, true); if (info.protocol !== 'bitcoin:') { throw new TypeError('Invalid bitcoin URI'); } // workaround to host insensitiveness - var group = /[^:]*:\/?\/?([^?]*)/.exec(uri); + const group = /[^:]*:\/?\/?([^?]*)/.exec(uri); info.query.address = group && group[1] || undefined; return info.query; @@ -142,7 +140,7 @@ URI.prototype._fromObject = function(obj) { this.network = this.address.network; this.amount = obj.amount; - for (var key in obj) { + for (const key in obj) { if (key === 'address' || key === 'amount') { continue; } @@ -151,7 +149,7 @@ URI.prototype._fromObject = function(obj) { throw Error('Unknown required argument ' + key); } - var destination = URI.Members.indexOf(key) > -1 ? this : this.extras; + const destination = URI.Members.indexOf(key) > -1 ? this : this.extras; destination[key] = obj[key]; } }; @@ -172,14 +170,14 @@ URI.prototype._parseAmount = function(amount) { }; URI.prototype.toObject = URI.prototype.toJSON = function toObject() { - var json = {}; - for (var i = 0; i < URI.Members.length; i++) { - var m = URI.Members[i]; + const json = {}; + for (let i = 0; i < URI.Members.length; i++) { + const m = URI.Members[i]; if (this.hasOwnProperty(m) && typeof(this[m]) !== 'undefined') { json[m] = this[m].toString(); } } - _.extend(json, this.extras); + Object.assign(json, this.extras); return json; }; @@ -189,7 +187,7 @@ URI.prototype.toObject = URI.prototype.toJSON = function toObject() { * @returns {string} Bitcoin URI string */ URI.prototype.toString = function() { - var query = {}; + const query = {}; if (this.amount) { query.amount = Unit.fromSatoshis(this.amount).toBTC(); } @@ -202,9 +200,9 @@ URI.prototype.toString = function() { if (this.r) { query.r = this.r; } - _.extend(query, this.extras); + Object.assign(query, this.extras); - return URL.format({ + return url.format({ protocol: 'bitcoin:', host: this.address, query: query diff --git a/packages/bitcore-lib/lib/util/js.js b/packages/bitcore-lib/lib/util/js.js index e6b77f66d49..36c3f982616 100644 --- a/packages/bitcore-lib/lib/util/js.js +++ b/packages/bitcore-lib/lib/util/js.js @@ -1,7 +1,5 @@ 'use strict'; -const _ = require('lodash'); - /** * Determines whether a string contains only hexadecimal values * @@ -10,7 +8,7 @@ const _ = require('lodash'); * @return {boolean} true if the string is the hexa representation of a number */ const isHexa = function isHexa(value) { - if (!_.isString(value)) { + if (typeof value !== 'string') { return false; } return /^[0-9a-fA-F]+$/.test(value); @@ -29,12 +27,12 @@ module.exports = { */ isValidJSON: function isValidJSON(arg) { let parsed; - if (!_.isString(arg)) { + if (typeof arg !== 'string') { return false; } try { parsed = JSON.parse(arg); - } catch (e) { + } catch { return false; } if (typeof(parsed) === 'object') { @@ -60,13 +58,14 @@ module.exports = { * @return {Object} The target object */ defineImmutable: function defineImmutable(target, values) { - Object.keys(values).forEach(function(key) { + for (const key of Object.keys(values)) { Object.defineProperty(target, key, { configurable: false, enumerable: true, value: values[key] }); - }); + } + return target; }, /** diff --git a/packages/bitcore-lib/lib/util/preconditions.js b/packages/bitcore-lib/lib/util/preconditions.js index 17a08f63579..8ba09742f53 100644 --- a/packages/bitcore-lib/lib/util/preconditions.js +++ b/packages/bitcore-lib/lib/util/preconditions.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const errors = require('../errors'); module.exports = { @@ -16,7 +15,7 @@ module.exports = { }, checkArgumentType: function(argument, type, argumentName) { argumentName = argumentName || '(unknown name)'; - if (_.isString(type)) { + if (typeof type === 'string') { if (type === 'Buffer') { const buffer = require('buffer'); // './buffer' fails on cordova & RN if (!buffer.Buffer.isBuffer(argument)) { diff --git a/packages/bitcore-lib/package-lock.json b/packages/bitcore-lib/package-lock.json index 29e703f82cf..9db20fd4977 100644 --- a/packages/bitcore-lib/package-lock.json +++ b/packages/bitcore-lib/package-lock.json @@ -13,9 +13,8 @@ "bn.js": "=4.11.8", "bs58": "^4.0.1", "buffer-compare": "=1.1.1", - "elliptic": "^6.5.3", - "inherits": "=2.0.1", - "lodash": "^4.17.20" + "elliptic": "=6.5.3", + "inherits": "=2.0.1" }, "devDependencies": { "brfs": "^2.0.1", @@ -981,16 +980,40 @@ "node": ">= 0.10" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/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==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { - "object-keys": "^1.0.12" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-property": { @@ -1097,6 +1120,7 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "license": "MIT", "dependencies": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -1107,6 +1131,18 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", + "license": "MIT" + }, + "node_modules/elliptic/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -1125,6 +1161,26 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", @@ -1657,16 +1713,16 @@ }, "node_modules/fsevents/node_modules/abbrev": { "version": "1.1.1", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/ansi-regex": { "version": "2.1.1", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -1674,16 +1730,16 @@ }, "node_modules/fsevents/node_modules/aproba": { "version": "1.2.0", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/are-we-there-yet": { "version": "1.1.5", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "delegates": "^1.0.0", @@ -1692,16 +1748,16 @@ }, "node_modules/fsevents/node_modules/balanced-match": { "version": "1.0.0", - "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/brace-expansion": { "version": "1.1.11", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "balanced-match": "^1.0.0", @@ -1710,16 +1766,16 @@ }, "node_modules/fsevents/node_modules/chownr": { "version": "1.1.3", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/code-point-at": { "version": "1.1.0", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -1727,31 +1783,30 @@ }, "node_modules/fsevents/node_modules/concat-map": { "version": "0.0.1", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/console-control-strings": { "version": "1.1.0", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/core-util-is": { "version": "1.0.2", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/debug": { "version": "3.2.6", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "ms": "^2.1.1" @@ -1759,9 +1814,9 @@ }, "node_modules/fsevents/node_modules/deep-extend": { "version": "0.6.0", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=4.0.0" @@ -1769,16 +1824,16 @@ }, "node_modules/fsevents/node_modules/delegates": { "version": "1.0.0", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/detect-libc": { "version": "1.0.3", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "inBundle": true, + "license": "Apache-2.0", "optional": true, "bin": { "detect-libc": "bin/detect-libc.js" @@ -1789,9 +1844,9 @@ }, "node_modules/fsevents/node_modules/fs-minipass": { "version": "1.2.7", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "minipass": "^2.6.0" @@ -1799,16 +1854,16 @@ }, "node_modules/fsevents/node_modules/fs.realpath": { "version": "1.0.0", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/gauge": { "version": "2.7.4", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "aproba": "^1.0.3", @@ -1823,9 +1878,9 @@ }, "node_modules/fsevents/node_modules/glob": { "version": "7.1.6", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -1844,16 +1899,16 @@ }, "node_modules/fsevents/node_modules/has-unicode": { "version": "2.0.1", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/iconv-lite": { "version": "0.4.24", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -1864,9 +1919,9 @@ }, "node_modules/fsevents/node_modules/ignore-walk": { "version": "3.0.3", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "minimatch": "^3.0.4" @@ -1874,9 +1929,9 @@ }, "node_modules/fsevents/node_modules/inflight": { "version": "1.0.6", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "once": "^1.3.0", @@ -1885,17 +1940,16 @@ }, "node_modules/fsevents/node_modules/inherits": { "version": "2.0.4", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/ini": { "version": "1.3.5", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "engines": { "node": "*" @@ -1903,9 +1957,9 @@ }, "node_modules/fsevents/node_modules/is-fullwidth-code-point": { "version": "1.0.0", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "number-is-nan": "^1.0.0" @@ -1916,16 +1970,16 @@ }, "node_modules/fsevents/node_modules/isarray": { "version": "1.0.0", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/minimatch": { "version": "3.0.4", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -1936,16 +1990,16 @@ }, "node_modules/fsevents/node_modules/minimist": { "version": "0.0.8", - "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/minipass": { "version": "2.9.0", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "safe-buffer": "^5.1.2", @@ -1954,9 +2008,9 @@ }, "node_modules/fsevents/node_modules/minizlib": { "version": "1.3.3", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "minipass": "^2.9.0" @@ -1964,10 +2018,9 @@ }, "node_modules/fsevents/node_modules/mkdirp": { "version": "0.5.1", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "minimist": "0.0.8" @@ -1978,16 +2031,16 @@ }, "node_modules/fsevents/node_modules/ms": { "version": "2.1.2", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/needle": { "version": "2.4.0", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "debug": "^3.2.6", @@ -2003,10 +2056,9 @@ }, "node_modules/fsevents/node_modules/node-pre-gyp": { "version": "0.14.0", - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", - "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", "dev": true, "inBundle": true, + "license": "BSD-3-Clause", "optional": true, "dependencies": { "detect-libc": "^1.0.2", @@ -2026,9 +2078,9 @@ }, "node_modules/fsevents/node_modules/nopt": { "version": "4.0.1", - "integrity": "sha512-+5XZFpQZEY0cg5JaxLwGxDlKNKYxuXwGt8/Oi3UXm5/4ymrJve9d2CURituxv3rSrVCGZj4m1U1JlHTdcKt2Ng==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "abbrev": "1", @@ -2040,9 +2092,9 @@ }, "node_modules/fsevents/node_modules/npm-bundled": { "version": "1.1.1", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "npm-normalize-package-bin": "^1.0.1" @@ -2050,16 +2102,16 @@ }, "node_modules/fsevents/node_modules/npm-normalize-package-bin": { "version": "1.0.1", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/npm-packlist": { "version": "1.4.7", - "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "ignore-walk": "^3.0.1", @@ -2068,9 +2120,9 @@ }, "node_modules/fsevents/node_modules/npmlog": { "version": "4.1.2", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "are-we-there-yet": "~1.1.2", @@ -2081,9 +2133,9 @@ }, "node_modules/fsevents/node_modules/number-is-nan": { "version": "1.0.1", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2091,9 +2143,9 @@ }, "node_modules/fsevents/node_modules/object-assign": { "version": "4.1.1", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2101,9 +2153,9 @@ }, "node_modules/fsevents/node_modules/once": { "version": "1.4.0", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "wrappy": "1" @@ -2111,9 +2163,9 @@ }, "node_modules/fsevents/node_modules/os-homedir": { "version": "1.0.2", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2121,9 +2173,9 @@ }, "node_modules/fsevents/node_modules/os-tmpdir": { "version": "1.0.2", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2131,9 +2183,9 @@ }, "node_modules/fsevents/node_modules/osenv": { "version": "0.1.5", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "os-homedir": "^1.0.0", @@ -2142,9 +2194,9 @@ }, "node_modules/fsevents/node_modules/path-is-absolute": { "version": "1.0.1", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2152,16 +2204,16 @@ }, "node_modules/fsevents/node_modules/process-nextick-args": { "version": "2.0.1", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/rc": { "version": "1.2.8", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "inBundle": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -2175,16 +2227,16 @@ }, "node_modules/fsevents/node_modules/rc/node_modules/minimist": { "version": "1.2.0", - "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/readable-stream": { "version": "2.3.6", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "core-util-is": "~1.0.0", @@ -2198,9 +2250,9 @@ }, "node_modules/fsevents/node_modules/rimraf": { "version": "2.7.1", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "glob": "^7.1.3" @@ -2211,30 +2263,30 @@ }, "node_modules/fsevents/node_modules/safe-buffer": { "version": "5.1.2", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/safer-buffer": { "version": "2.1.2", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/sax": { "version": "1.2.4", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/semver": { "version": "5.7.1", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -2242,23 +2294,23 @@ }, "node_modules/fsevents/node_modules/set-blocking": { "version": "2.0.0", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/signal-exit": { "version": "3.0.2", - "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/string_decoder": { "version": "1.1.1", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "safe-buffer": "~5.1.0" @@ -2266,9 +2318,9 @@ }, "node_modules/fsevents/node_modules/string-width": { "version": "1.0.2", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "code-point-at": "^1.0.0", @@ -2281,9 +2333,9 @@ }, "node_modules/fsevents/node_modules/strip-ansi": { "version": "3.0.1", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "dependencies": { "ansi-regex": "^2.0.0" @@ -2294,9 +2346,9 @@ }, "node_modules/fsevents/node_modules/strip-json-comments": { "version": "2.0.1", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -2304,9 +2356,9 @@ }, "node_modules/fsevents/node_modules/tar": { "version": "4.4.13", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "chownr": "^1.1.1", @@ -2323,16 +2375,16 @@ }, "node_modules/fsevents/node_modules/util-deprecate": { "version": "1.0.2", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, "inBundle": true, + "license": "MIT", "optional": true }, "node_modules/fsevents/node_modules/wide-align": { "version": "1.1.3", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true, "dependencies": { "string-width": "^1.0.2 || 2" @@ -2340,23 +2392,27 @@ }, "node_modules/fsevents/node_modules/wrappy": { "version": "1.0.2", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/fsevents/node_modules/yallist": { "version": "3.1.1", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "inBundle": true, + "license": "ISC", "optional": true }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/get-assigned-identifiers": { "version": "1.2.0", @@ -2510,11 +2566,25 @@ "node": ">= 0.10" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, "node_modules/gulp": { "version": "4.0.2", @@ -2599,11 +2669,25 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3124,9 +3208,11 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" }, "node_modules/lolex": { "version": "4.2.0", @@ -3283,10 +3369,14 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -3691,10 +3781,11 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" }, "node_modules/path-root": { "version": "0.1.1", @@ -3887,10 +3978,11 @@ } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4095,9 +4187,24 @@ } }, "node_modules/safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/safe-regex": { "version": "1.1.0", diff --git a/packages/bitcore-lib/package.json b/packages/bitcore-lib/package.json index 46131e14164..d34cf17bdcc 100644 --- a/packages/bitcore-lib/package.json +++ b/packages/bitcore-lib/package.json @@ -39,9 +39,8 @@ "bn.js": "=4.11.8", "bs58": "^4.0.1", "buffer-compare": "=1.1.1", - "elliptic": "^6.5.3", - "inherits": "=2.0.1", - "lodash": "^4.17.20" + "elliptic": "=6.5.3", + "inherits": "=2.0.1" }, "devDependencies": { "@bitpay-labs/bitcore-build": "^11.8.1", diff --git a/packages/bitcore-lib/test/crypto/signature.js b/packages/bitcore-lib/test/crypto/signature.js index c3d994fcf06..d6821449d9a 100644 --- a/packages/bitcore-lib/test/crypto/signature.js +++ b/packages/bitcore-lib/test/crypto/signature.js @@ -1,6 +1,6 @@ +/* eslint-disable no-bitwise */ 'use strict'; -const _ = require('lodash'); const should = require('chai').should(); const bitcore = require('../..'); @@ -254,8 +254,8 @@ describe('Signature', function() { describe('bitcoind fixtures', function() { const test_sigs = function(set, expected) { - let i = 0; - set.forEach(function(vector) { + for (let i = 0; i < set.length; i++) { + const vector = set[i]; if (!JSUtil.isHexa(vector)) { // non-hex strings are ignored return; @@ -263,13 +263,11 @@ describe('Signature', function() { it('should be ' + (expected ? '' : 'in') + 'valid for fixture #' + i, function() { const sighex = vector; const interp = Interpreter(); - interp.flags = Interpreter.SCRIPT_VERIFY_DERSIG | - Interpreter.SCRIPT_VERIFY_STRICTENC; + interp.flags = Interpreter.SCRIPT_VERIFY_DERSIG | Interpreter.SCRIPT_VERIFY_STRICTENC; const result = interp.checkSignatureEncoding(Buffer.from(sighex, 'hex')); result.should.equal(expected); }); - i++; - }); + } }; test_sigs(sig_canonical, true); test_sigs(sig_noncanonical, false); @@ -331,11 +329,10 @@ describe('Signature', function() { [(Signature.SIGHASH_ANYONECANPAY | Signature.SIGHASH_SINGLE) + 1, false], [(Signature.SIGHASH_ANYONECANPAY | Signature.SIGHASH_ALL) - 1, false], ]; - _.each(testCases, function(testCase) { + for (const testCase of testCases) { sig.nhashtype = testCase[0]; sig.hasDefinedHashtype().should.equal(testCase[1]); - }); + }; }); }); - }); diff --git a/packages/bitcore-lib/test/hdkeys.js b/packages/bitcore-lib/test/hdkeys.js index 3c606284c0c..05773168b9b 100644 --- a/packages/bitcore-lib/test/hdkeys.js +++ b/packages/bitcore-lib/test/hdkeys.js @@ -10,8 +10,6 @@ /* jshint maxstatements: 100 */ /* jshint unused: false */ -const _ = require('lodash'); -const should = require('chai').should(); const expect = require('chai').expect; const sinon = require('sinon'); const bitcore = require('..'); @@ -22,9 +20,8 @@ const HDPublicKey = bitcore.HDPublicKey; describe('HDKeys building with static methods', function() { const classes = [HDPublicKey, HDPrivateKey]; - let clazz, index; - _.each(classes, function(clazz) { + for (const clazz of classes) { const expectStaticMethodFail = function(staticMethod, argument, message) { expect(clazz[staticMethod].bind(null, argument)).to.throw(message); }; @@ -50,7 +47,7 @@ describe('HDKeys building with static methods', function() { expectStaticMethodFail(method, null, errorMessage); expectStaticMethodFail(method, '', errorMessage); }); - }); + } }); describe('BIP32 compliance', function() { diff --git a/packages/bitcore-lib/test/hdprivatekey.js b/packages/bitcore-lib/test/hdprivatekey.js index 4977635ec3c..9bb2299b7d0 100644 --- a/packages/bitcore-lib/test/hdprivatekey.js +++ b/packages/bitcore-lib/test/hdprivatekey.js @@ -1,14 +1,11 @@ 'use strict'; /* jshint unused: false */ -const _ = require('lodash'); -const assert = require('assert'); const should = require('chai').should(); const expect = require('chai').expect; const bitcore = require('..'); const errors = bitcore.errors; const hdErrors = errors.HDPrivateKey; -const buffer = require('buffer'); const Networks = bitcore.Networks; const BufferUtil = bitcore.util.buffer; @@ -87,10 +84,9 @@ describe('HDPrivate key interface', function() { }); it('builds a json keeping the structure and same members', function() { - assert(_.isEqual( - new HDPrivateKey(json).toJSON(), + expect(new HDPrivateKey(json).toJSON()).to.deep.equal( new HDPrivateKey(xprivkey).toJSON() - )); + ); }); describe('instantiation', function() { @@ -254,13 +250,13 @@ describe('HDPrivate key interface', function() { 'm/12asd', 'm/1/2//3' ]; - - invalid.forEach(function(datum) { + + for (const datum of invalid) { it('rejects illegal path ' + datum, function() { HDPrivateKey.isValidPath(datum).should.equal(false); expect(HDPrivateKey._getDerivationIndexes(datum)).to.equal(null); }); - }); + } it('generates deriving indexes correctly', function() { let indexes; @@ -304,9 +300,9 @@ describe('HDPrivate key interface', function() { it('toObject leaves no Buffer instances', function() { const privKey = new HDPrivateKey(xprivkey); const object = privKey.toObject(); - _.each(_.values(object), function(value) { + for (const value of Object.values(object)) { expect(BufferUtil.isBuffer(value)).to.equal(false); - }); + } }); it('roundtrips toObject', function() { expect(HDPrivateKey.fromObject(new HDPrivateKey(xprivkey).toObject()).xprivkey).to.equal(xprivkey); diff --git a/packages/bitcore-lib/test/hdpublickey.js b/packages/bitcore-lib/test/hdpublickey.js index 29369d2b94b..ed8748b11ab 100644 --- a/packages/bitcore-lib/test/hdpublickey.js +++ b/packages/bitcore-lib/test/hdpublickey.js @@ -1,42 +1,38 @@ 'use strict'; /* jshint unused: false */ -var _ = require('lodash'); -var assert = require('assert'); -var should = require('chai').should(); -var expect = require('chai').expect; -var bitcore = require('..'); -var buffer = require('buffer'); -var errors = bitcore.errors; -var hdErrors = bitcore.errors.HDPublicKey; -var BufferUtil = bitcore.util.buffer; -var HDPrivateKey = bitcore.HDPrivateKey; -var HDPublicKey = bitcore.HDPublicKey; -var Base58Check = bitcore.encoding.Base58Check; -var Networks = bitcore.Networks; - -var xprivkey = 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'; -var xpubkey = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'; -var xpubkeyTestnet = 'tpubD6NzVbkrYhZ4WZaiWHz59q5EQ61bd6dUYfU4ggRWAtNAyyYRNWT6ktJ7UHJEXURvTfTfskFQmK7Ff4FRkiRN5wQH8nkGAb6aKB4Yyeqsw5m'; -var json = '{"network":"livenet","depth":0,"fingerPrint":876747070,"parentFingerPrint":0,"childIndex":0,"chainCode":"873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508","publicKey":"0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2","checksum":-1421395167,"xpubkey":"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"}'; -var derived_0_1_200000 = 'xpub6BqyndF6rkBNTV6LXwiY8Pco8aqctqq7tGEUdA8fmGDTnDJphn2fmxr3eM8Lm3m8TrNUsLbEjHvpa3adBU18YpEx4tp2Zp6nqax3mQkudhX'; +const expect = require('chai').expect; +const bitcore = require('..'); + +const errors = bitcore.errors; +const hdErrors = bitcore.errors.HDPublicKey; +const BufferUtil = bitcore.util.buffer; +const HDPublicKey = bitcore.HDPublicKey; +const Base58Check = bitcore.encoding.Base58Check; +const Networks = bitcore.Networks; + +const xprivkey = 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'; +const xpubkey = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'; +const xpubkeyTestnet = 'tpubD6NzVbkrYhZ4WZaiWHz59q5EQ61bd6dUYfU4ggRWAtNAyyYRNWT6ktJ7UHJEXURvTfTfskFQmK7Ff4FRkiRN5wQH8nkGAb6aKB4Yyeqsw5m'; +const json = '{"network":"livenet","depth":0,"fingerPrint":876747070,"parentFingerPrint":0,"childIndex":0,"chainCode":"873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508","publicKey":"0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2","checksum":-1421395167,"xpubkey":"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"}'; +const derived_0_1_200000 = 'xpub6BqyndF6rkBNTV6LXwiY8Pco8aqctqq7tGEUdA8fmGDTnDJphn2fmxr3eM8Lm3m8TrNUsLbEjHvpa3adBU18YpEx4tp2Zp6nqax3mQkudhX'; describe('HDPublicKey interface', function() { - var expectFail = function(func, errorType) { + const expectFail = function(func, errorType) { (function() { func(); }).should.throw(errorType); }; - var expectDerivationFail = function(argument, error) { + const expectDerivationFail = function(argument, error) { (function() { - var pubkey = new HDPublicKey(xpubkey); + const pubkey = new HDPublicKey(xpubkey); pubkey.derive(argument); }).should.throw(error); }; - var expectFailBuilding = function(argument, error) { + const expectFailBuilding = function(argument, error) { (function() { return new HDPublicKey(argument); }).should.throw(error); @@ -45,12 +41,12 @@ describe('HDPublicKey interface', function() { describe('creation formats', function() { it('returns same argument if already an instance of HDPublicKey', function() { - var publicKey = new HDPublicKey(xpubkey); + const publicKey = new HDPublicKey(xpubkey); publicKey.should.equal(new HDPublicKey(publicKey)); }); it('returns the correct xpubkey for a xprivkey', function() { - var publicKey = new HDPublicKey(xprivkey); + const publicKey = new HDPublicKey(xprivkey); publicKey.xpubkey.should.equal(xpubkey); }); @@ -63,7 +59,7 @@ describe('HDPublicKey interface', function() { }); it('should not be able to change read-only properties', function() { - var publicKey = new HDPublicKey(xprivkey); + const publicKey = new HDPublicKey(xprivkey); expect(function() { publicKey.fingerPrint = 'notafingerprint'; }).to.throw(TypeError); @@ -98,10 +94,9 @@ describe('HDPublicKey interface', function() { }); it('can generate a json that has a particular structure', function() { - assert(_.isEqual( - new HDPublicKey(JSON.parse(json)).toJSON(), + expect(new HDPublicKey(JSON.parse(json)).toJSON()).to.deep.equal( new HDPublicKey(xpubkey).toJSON() - )); + ); }); it('builds from a buffer object', function() { @@ -109,7 +104,7 @@ describe('HDPublicKey interface', function() { }); it('checks the checksum', function() { - var buffers = new HDPublicKey(xpubkey)._buffers; + const buffers = new HDPublicKey(xpubkey)._buffers; buffers.checksum = BufferUtil.integerAsBuffer(1); expectFail(function() { return new HDPublicKey(buffers); @@ -118,7 +113,7 @@ describe('HDPublicKey interface', function() { }); describe('error checking on serialization', function() { - var compareType = function(a, b) { + const compareType = function(a, b) { expect(a instanceof b).to.equal(true); }; it('throws invalid argument when argument is not a string or buffer', function() { @@ -136,48 +131,48 @@ describe('HDPublicKey interface', function() { }); it('toString() returns the same value as .xpubkey', function() { - var pubKey = new HDPublicKey(xpubkey); + const pubKey = new HDPublicKey(xpubkey); pubKey.toString().should.equal(pubKey.xpubkey); }); it('publicKey property matches network', function() { - var livenet = new HDPublicKey(xpubkey); - var testnet = new HDPublicKey(xpubkeyTestnet); + const livenet = new HDPublicKey(xpubkey); + const testnet = new HDPublicKey(xpubkeyTestnet); livenet.publicKey.network.should.equal(Networks.livenet); testnet.publicKey.network.should.equal(Networks.testnet); }); it('inspect() displays correctly', function() { - var pubKey = new HDPublicKey(xpubkey); + const pubKey = new HDPublicKey(xpubkey); pubKey.inspect().should.equal(''); }); describe('conversion to/from buffer', function() { it('should roundtrip to an equivalent object', function() { - var pubKey = new HDPublicKey(xpubkey); - var toBuffer = pubKey.toBuffer(); - var fromBuffer = HDPublicKey.fromBuffer(toBuffer); - var roundTrip = new HDPublicKey(fromBuffer.toBuffer()); + const pubKey = new HDPublicKey(xpubkey); + const toBuffer = pubKey.toBuffer(); + const fromBuffer = HDPublicKey.fromBuffer(toBuffer); + const roundTrip = new HDPublicKey(fromBuffer.toBuffer()); roundTrip.xpubkey.should.equal(xpubkey); }); }); describe('conversion to different formats', function() { - var plainObject = { - 'network':'livenet', - 'depth':0, - 'fingerPrint':876747070, - 'parentFingerPrint':0, - 'childIndex':0, - 'chainCode':'873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508', - 'publicKey':'0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2', - 'checksum':-1421395167, - 'xpubkey':'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8' + const plainObject = { + 'network': 'livenet', + 'depth': 0, + 'fingerPrint': 876747070, + 'parentFingerPrint': 0, + 'childIndex': 0, + 'chainCode': '873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508', + 'publicKey': '0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2', + 'checksum': -1421395167, + 'xpubkey': 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8' }; it('roundtrips to JSON and to Object', function() { - var pubkey = new HDPublicKey(xpubkey); + const pubkey = new HDPublicKey(xpubkey); expect(HDPublicKey.fromObject(pubkey.toJSON()).xpubkey).to.equal(xpubkey); }); it('recovers state from Object', function() { @@ -187,15 +182,15 @@ describe('HDPublicKey interface', function() { describe('derivation', function() { it('derivation is the same whether deriving with number or string', function() { - var pubkey = new HDPublicKey(xpubkey); - var derived1 = pubkey.derive(0).derive(1).derive(200000); - var derived2 = pubkey.derive('m/0/1/200000'); + const pubkey = new HDPublicKey(xpubkey); + const derived1 = pubkey.derive(0).derive(1).derive(200000); + const derived2 = pubkey.derive('m/0/1/200000'); derived1.xpubkey.should.equal(derived_0_1_200000); derived2.xpubkey.should.equal(derived_0_1_200000); }); it('allows special parameters m, M', function() { - var expectDerivationSuccess = function(argument) { + const expectDerivationSuccess = function(argument) { new HDPublicKey(xpubkey).derive(argument).xpubkey.should.equal(xpubkey); }; expectDerivationSuccess('m'); @@ -218,8 +213,8 @@ describe('HDPublicKey interface', function() { /* jshint quotmark: double */ expectDerivationFail("m'", hdErrors.InvalidIndexCantDeriveHardened); expectDerivationFail("M'", hdErrors.InvalidIndexCantDeriveHardened); - expectDerivationFail("1", hdErrors.InvalidPath); - expectDerivationFail("S", hdErrors.InvalidPath); + expectDerivationFail('1', hdErrors.InvalidPath); + expectDerivationFail('S', hdErrors.InvalidPath); }); it('can\'t derive hardened keys', function() { @@ -235,7 +230,7 @@ describe('HDPublicKey interface', function() { }); it('validates correct paths', function() { - var valid; + let valid; valid = HDPublicKey.isValidPath('m/123/12'); valid.should.equal(true); @@ -248,7 +243,7 @@ describe('HDPublicKey interface', function() { }); it('rejects illegal paths', function() { - var valid; + let valid; valid = HDPublicKey.isValidPath('m/-1/12'); valid.should.equal(false); @@ -256,7 +251,7 @@ describe('HDPublicKey interface', function() { valid = HDPublicKey.isValidPath("m/0'/12"); valid.should.equal(false); - valid = HDPublicKey.isValidPath("m/8000000000/12"); + valid = HDPublicKey.isValidPath('m/8000000000/12'); valid.should.equal(false); valid = HDPublicKey.isValidPath('bad path'); diff --git a/packages/bitcore-lib/test/opcode.js b/packages/bitcore-lib/test/opcode.js index 87e6e5c9cc5..c69f03477ad 100644 --- a/packages/bitcore-lib/test/opcode.js +++ b/packages/bitcore-lib/test/opcode.js @@ -1,6 +1,5 @@ 'use strict'; -const _ = require('lodash'); const chai = require('chai'); const should = chai.should(); @@ -129,7 +128,7 @@ describe('Opcode', function() { describe('@map', function() { it('should have a map containing 119 elements', function() { - _.size(Opcode.map).should.equal(119); + Object.keys(Opcode.map).length.should.equal(119); }); }); diff --git a/packages/bitcore-lib/test/script/interpreter.js b/packages/bitcore-lib/test/script/interpreter.js index ada8de451b2..51ffc1fcea8 100644 --- a/packages/bitcore-lib/test/script/interpreter.js +++ b/packages/bitcore-lib/test/script/interpreter.js @@ -1,3 +1,4 @@ +/* eslint-disable no-bitwise */ 'use strict'; const should = require('chai').should(); @@ -12,7 +13,6 @@ const BN = bitcore.crypto.BN; const BufferWriter = bitcore.encoding.BufferWriter; const BufferReader = bitcore.encoding.BufferReader; const Opcode = bitcore.Opcode; -const _ = require('lodash'); const script_tests = require('../data/bitcoind/script_tests'); const script_asset_tests = require('../data/bitcoind/script_assets_test.json'); @@ -343,21 +343,21 @@ describe('Interpreter', function() { const testAllFixtures = function(set) { let c = 0; - set.forEach(function(vector) { + for (const vector of set) { if (vector.length === 1) { - return; + continue; } c++; let witness, amount; - if (_.isArray(vector[0])) { + if (Array.isArray(vector[0])) { const extra = vector.shift(); amount = extra.pop() * 1e8; - witness = extra.map(function(x) { + witness = extra.map(function(x) { return Buffer.from(x, 'hex'); }); } else { - return; + continue; } const fullScriptString = vector[0] + ' ' + vector[1]; @@ -370,10 +370,9 @@ describe('Interpreter', function() { function() { testFixture(vector, expected, witness, amount); }); - }); + } }; testAllFixtures(script_tests); - }); describe('bitcoind transaction evaluation fixtures', function() { const test_txs = function(set, expected) { diff --git a/packages/bitcore-lib/test/transaction/input/input.js b/packages/bitcore-lib/test/transaction/input/input.js index acef68d9004..6fd6c41e6f2 100644 --- a/packages/bitcore-lib/test/transaction/input/input.js +++ b/packages/bitcore-lib/test/transaction/input/input.js @@ -2,7 +2,6 @@ const should = require('chai').should(); const expect = require('chai').expect; -const _ = require('lodash'); const bitcore = require('../../..'); @@ -54,11 +53,12 @@ describe('Transaction.Input', function() { it('has abstract methods: "getSignatures", "isFullySigned", "addSignature", "clearSignatures"', function() { const input = new Input(output); - _.each(['getSignatures', 'isFullySigned', 'addSignature', 'clearSignatures'], function(method) { + const methods = ['getSignatures', 'isFullySigned', 'addSignature', 'clearSignatures']; + for (const method of methods) { expect(function() { return input[method](); }).to.throw(errors.AbstractMethodInvoked); - }); + } }); it('detects coinbase transactions', function() { new Input(output).isNull().should.equal(false); @@ -111,7 +111,9 @@ describe('Transaction.Input', function() { let expected = (parseInt(1e5 / 512) * 512) ; input.getLockTime().should.deep.equal(expected); + // eslint-disable-next-line no-bitwise expected = (Math.floor(expected/512) ) | Input.SEQUENCE_LOCKTIME_TYPE_FLAG; + // eslint-disable-next-line no-bitwise input.sequenceNumber.should.equal(expected | Input.SEQUENCE_LOCKTIME_TYPE_FLAG); }); it('accepts a block height', function() { diff --git a/packages/bitcore-lib/test/transaction/input/multisig.js b/packages/bitcore-lib/test/transaction/input/multisig.js index 8a7c0ce16be..3b2598ae48c 100644 --- a/packages/bitcore-lib/test/transaction/input/multisig.js +++ b/packages/bitcore-lib/test/transaction/input/multisig.js @@ -2,9 +2,6 @@ /* jshint unused: false */ const should = require('chai').should(); -const expect = require('chai').expect; -const _ = require('lodash'); - const bitcore = require('../../..'); const Transaction = bitcore.Transaction; @@ -72,18 +69,21 @@ describe('MultiSigInput', function() { .to(address, 1000000); const input = transaction.inputs[0]; - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public1.toString() || - serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingPublicKeys = input.publicKeysWithoutSignature().map(publicKey => publicKey.toString()); + missingPublicKeys.should.have.members([ + public1.toString(), + public2.toString(), + public3.toString() + ]); + missingPublicKeys.should.have.length(3); + transaction.sign(privateKey1); - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingAfterSign = input.publicKeysWithoutSignature().map(publicKey => publicKey.toString()); + missingAfterSign.should.have.members([ + public2.toString(), + public3.toString() + ]); + missingAfterSign.should.have.length(2); }); it('can clear all signatures', function() { const transaction = new Transaction() diff --git a/packages/bitcore-lib/test/transaction/input/multisigscripthash.js b/packages/bitcore-lib/test/transaction/input/multisigscripthash.js index 75430403152..391768de35f 100644 --- a/packages/bitcore-lib/test/transaction/input/multisigscripthash.js +++ b/packages/bitcore-lib/test/transaction/input/multisigscripthash.js @@ -1,12 +1,7 @@ 'use strict'; /* jshint unused: false */ - -const should = require('chai').should(); -const expect = require('chai').expect; -const _ = require('lodash'); - const bitcore = require('../../..'); - + const Transaction = bitcore.Transaction; const PrivateKey = bitcore.PrivateKey; const Address = bitcore.Address; @@ -65,18 +60,25 @@ describe('MultiSigScriptHashInput', function() { .to(address, 1000000); const input = transaction.inputs[0]; - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public1.toString() || - serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingPublicKeys = input.publicKeysWithoutSignature().map(function(publicKey) { + return publicKey.toString(); + }); + missingPublicKeys.should.have.members([ + public1.toString(), + public2.toString(), + public3.toString() + ]); + missingPublicKeys.should.have.length(3); + transaction.sign(privateKey1); - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingAfterSign = input.publicKeysWithoutSignature().map(function(publicKey) { + return publicKey.toString(); + }); + missingAfterSign.should.have.members([ + public2.toString(), + public3.toString() + ]); + missingAfterSign.should.have.length(2); }); it('can clear all signatures', function() { const transaction = new Transaction() @@ -180,18 +182,25 @@ describe('MultiSigScriptHashInput', function() { .to(address, 1000000); const input = transaction.inputs[0]; - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public1.toString() || - serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingPublicKeys = input.publicKeysWithoutSignature().map(function(publicKey) { + return publicKey.toString(); + }); + missingPublicKeys.should.have.members([ + public1.toString(), + public2.toString(), + public3.toString() + ]); + missingPublicKeys.should.have.length(3); + transaction.sign(privateKey1); - _.every(input.publicKeysWithoutSignature(), function(publicKeyMissing) { - const serialized = publicKeyMissing.toString(); - return serialized === public2.toString() || - serialized === public3.toString(); - }).should.equal(true); + const missingAfterSign = input.publicKeysWithoutSignature().map(function(publicKey) { + return publicKey.toString(); + }); + missingAfterSign.should.have.members([ + public2.toString(), + public3.toString() + ]); + missingAfterSign.should.have.length(2); }); it('can clear all signatures', function() { const transaction = new Transaction() diff --git a/packages/bitcore-lib/test/transaction/input/publickeyhash.js b/packages/bitcore-lib/test/transaction/input/publickeyhash.js index fd737682642..c8116ae9f92 100644 --- a/packages/bitcore-lib/test/transaction/input/publickeyhash.js +++ b/packages/bitcore-lib/test/transaction/input/publickeyhash.js @@ -1,10 +1,5 @@ 'use strict'; /* jshint unused: false */ - -const should = require('chai').should(); -const expect = require('chai').expect; -const _ = require('lodash'); - const bitcore = require('../../..'); const Transaction = bitcore.Transaction; @@ -12,7 +7,6 @@ const PrivateKey = bitcore.PrivateKey; const Address = bitcore.Address; const Script = bitcore.Script; const Networks = bitcore.Networks; -const Signature = bitcore.crypto.Signature; describe('PublicKeyHashInput', function() { diff --git a/packages/bitcore-lib/test/transaction/output.js b/packages/bitcore-lib/test/transaction/output.js index 236ee283b0d..ab59d7628b4 100644 --- a/packages/bitcore-lib/test/transaction/output.js +++ b/packages/bitcore-lib/test/transaction/output.js @@ -3,8 +3,6 @@ /* jshint unused: false */ /* jshint latedef: false */ const should = require('chai').should(); -const expect = require('chai').expect; -const _ = require('lodash'); const bitcore = require('../..'); @@ -14,8 +12,6 @@ const BufferReader = bitcore.encoding.BufferReader; const Output = bitcore.Transaction.Output; const Script = bitcore.Script; -const errors = bitcore.errors; - describe('Output', function() { const output = new Output({ satoshis: 0, diff --git a/packages/bitcore-lib/test/transaction/signature.js b/packages/bitcore-lib/test/transaction/signature.js index 20cb08b4e14..3e6b686d6f0 100644 --- a/packages/bitcore-lib/test/transaction/signature.js +++ b/packages/bitcore-lib/test/transaction/signature.js @@ -2,9 +2,7 @@ /* jshint unused: false */ /* jshint latedef: false */ -const should = require('chai').should(); const expect = require('chai').expect; -const _ = require('lodash'); const bitcore = require('../..'); diff --git a/packages/bitcore-lib/test/transaction/transaction.js b/packages/bitcore-lib/test/transaction/transaction.js index 92eec5f782e..e51823c1523 100644 --- a/packages/bitcore-lib/test/transaction/transaction.js +++ b/packages/bitcore-lib/test/transaction/transaction.js @@ -1,8 +1,8 @@ +/* eslint-disable no-bitwise */ 'use strict'; const should = require('chai').should(); const expect = require('chai').expect; -const _ = require('lodash'); const sinon = require('sinon'); const bitcore = require('../..'); const transactionVector = require('../data/tx_creation'); @@ -24,7 +24,6 @@ const PrivateKey = bitcore.PrivateKey; const Script = bitcore.Script; const Interpreter = bitcore.Script.Interpreter; const Address = bitcore.Address; -const Networks = bitcore.Networks; const Opcode = bitcore.Opcode; const errors = bitcore.errors; @@ -1226,8 +1225,10 @@ describe('Transaction', function() { }); it('allows the user to randomize the output order', function() { - const shuffle = sinon.stub(_, 'shuffle'); - shuffle.onFirstCall().returns([out2, out1, out4, out3]); + const random = sinon.stub(Math, 'random'); + random.onCall(0).returns(0.6); + random.onCall(1).returns(0.9); + random.onCall(2).returns(0.1); transaction._changeIndex.should.equal(3); transaction.shuffleOutputs(); @@ -1237,7 +1238,7 @@ describe('Transaction', function() { transaction.outputs[3].should.equal(out3); transaction._changeIndex.should.equal(2); - _.shuffle.restore(); + Math.random.restore(); }); it('fails if the provided function does not work as expected', function() { @@ -1352,14 +1353,14 @@ describe('Transaction', function() { it(inputSet.description, function() { const tx = new Transaction(); inputSet.inputs = inputSet.inputs.map(function(input) { - input = new Input({ + const inputMapOut = new Input({ prevTxId: input.txId, outputIndex: input.vout, script: new Script(), output: new Output({ script: new Script(), satoshis: 0 }) }); - input.clearSignatures = function () {}; - return input; + inputMapOut.clearSignatures = function () {}; + return inputMapOut; }); tx.inputs = inputSet.inputs; tx.sort(); @@ -1717,9 +1718,6 @@ describe('Transaction', function() { check.should.equal(false); }); it('will verify witness 2-of-2 multisig (part 3)', function() { - let flags; - let check; - let interpreter; const output1 = bitcore.Transaction('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff0101000000000000002200207780f1145ef7ba4e703388c155d94bc399e24345e11c4559e683d5070feeb27400000000'); const input1 = bitcore.Transaction('01000000000101791890e3effa9d4061a984812a90675418d0eb141655c106cce9b4bbbf9a3be00000000000ffffffff010100000000000000000400483045022100db977a31834033466eb103131b1ef9c57d6cea17f9a7eb3f3bafde1d7c1ddff502205ad84c9ca9c4139dce6e8e7850cc09a49ad57197b266814e79a78527ab4a9f950147304402205bd26da7dab9e379019ffd5e76fa77e161090bf577ed875e8e969f06cd66ba0a0220082cf7315ff7dc7aa8f6cebf7e70af1ffa45e63581c08e6fbc4e964035e6326b0147522102f86e3dc39cf9cd6c0eeb5fe25e3abe34273b8e79cc888dd5512001c7dac31b9921032e16a3c764fb6485345d91b39fb6da52c7026b8819e1e7d2f838a0df1445851a52ae00000000'); const scriptPubkey = output1.outputs[0].script; @@ -1727,9 +1725,9 @@ describe('Transaction', function() { const witnesses = input1.inputs[0].getWitnesses(); const satoshis = 1; - interpreter = new Interpreter(); - flags = Interpreter.SCRIPT_VERIFY_P2SH | Interpreter.SCRIPT_VERIFY_WITNESS; - check = interpreter.verify(scriptSig, scriptPubkey, input1, 0, flags, witnesses, satoshis); + const interpreter = new Interpreter(); + const flags = Interpreter.SCRIPT_VERIFY_P2SH | Interpreter.SCRIPT_VERIFY_WITNESS; + const check = interpreter.verify(scriptSig, scriptPubkey, input1, 0, flags, witnesses, satoshis); check.should.equal(true); }); it('will verify p2sh witness 2-of-2 multisig (part 1)', function() { @@ -1775,9 +1773,6 @@ describe('Transaction', function() { check.should.equal(false); }); it('will verify p2sh witness 2-of-2 multisig (part 3)', function() { - let flags; - let check; - let interpreter; const output1 = bitcore.Transaction('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff01010000000000000017a9143f588990832299c654d8032bc6c5d181427a321e8700000000'); const input1 = bitcore.Transaction('01000000000101ef6f782539d100d563d736339c4a57485b562f9705b28680b08b3efe9dd815870000000023220020a51db581b721c64132415f985ac3086bcf7817f1bbf45be984718b41f4189b39ffffffff01010000000000000000040047304402203202c4c3b40c091a051707421def9adb0d101076672ab220db36a3f87bbecad402205f976ff87af9149e83c87c94ec3b308c1abe4b8c5b3f43c842ebffc22885fc530147304402203c0a50f199774f6393e42ee29d3540cf868441b47efccb11139a357ecd45c5b702205e8442ff34f6f836cd9ad96c158504469db178d63a309d813ba68b86c7293f66014752210334f22ecf25636ba18f8c89e90d38f05036094fe0be48187fb9842374a237b1062102993d85ece51cec8c4d841fce02faa6130f57c811078c5f2a48c204caf12853b552ae00000000'); const scriptPubkey = output1.outputs[0].script; @@ -1785,9 +1780,9 @@ describe('Transaction', function() { const witnesses = input1.inputs[0].getWitnesses(); const satoshis = 1; - interpreter = new Interpreter(); - flags = Interpreter.SCRIPT_VERIFY_P2SH | Interpreter.SCRIPT_VERIFY_WITNESS; - check = interpreter.verify(scriptSig, scriptPubkey, input1, 0, flags, witnesses, satoshis); + const interpreter = new Interpreter(); + const flags = Interpreter.SCRIPT_VERIFY_P2SH | Interpreter.SCRIPT_VERIFY_WITNESS; + const check = interpreter.verify(scriptSig, scriptPubkey, input1, 0, flags, witnesses, satoshis); check.should.equal(true); }); it('will verify witness pay-to-uncompressed-pubkey (v1) part 1', function() { diff --git a/packages/bitcore-lib/test/transaction/unspentoutput.js b/packages/bitcore-lib/test/transaction/unspentoutput.js index 4079e3757de..5c221bcd0f4 100644 --- a/packages/bitcore-lib/test/transaction/unspentoutput.js +++ b/packages/bitcore-lib/test/transaction/unspentoutput.js @@ -1,9 +1,7 @@ 'use strict'; -const _ = require('lodash'); const chai = require('chai'); -const should = chai.should(); const expect = chai.expect; const bitcore = require('../..'); @@ -42,7 +40,7 @@ describe('UnspentOutput', function() { }); it('fails if vout is not a number', function() { - const sample = _.cloneDeep(sampleData2); + const sample = structuredClone(sampleData2); sample.vout = '1'; expect(function() { return new UnspentOutput(sample);