diff --git a/Gruntfile.js b/Gruntfile.js index e9b938c00..0183f688e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -83,6 +83,7 @@ module.exports = function(grunt) { 'js/shell.js', // shell must be loaded before moment due to the way moment loads in a commonjs env 'lib/moment/min/moment.min.js', 'lib/qrcode-generator/js/qrcode.js', + 'lib/underscore/underscore.js', 'lib/bitcore.js', 'lib/crypto-js/rollups/sha256.js', 'lib/crypto-js/rollups/pbkdf2.js', diff --git a/bower.json b/bower.json index d58a6e511..331b065ca 100644 --- a/bower.json +++ b/bower.json @@ -21,7 +21,8 @@ "socket.io-client": ">=1.0.0", "mousetrap": "1.4.6", "zeroclipboard": "~1.3.5", - "ng-idle": "*" + "ng-idle": "*", + "underscore": "~1.7.0" }, "resolutions": { "angular": "=1.2.19" diff --git a/js/app.js b/js/app.js index e90e55275..fcc03a23a 100644 --- a/js/app.js +++ b/js/app.js @@ -1,20 +1,20 @@ 'use strict'; var copay = require('copay'); +var _ = require('underscore'); var config = defaultConfig; var localConfig = JSON.parse(localStorage.getItem('config')); + if (localConfig) { var cmv = copay.version.split('.')[1]; var lmv = localConfig.version ? localConfig.version.split('.')[1] : '-1'; if (cmv === lmv) { - for (name in localConfig) { - if (localConfig.hasOwnProperty(name)) { - if (name === 'networkName' && config['forceNetwork']) { - continue; - } - config[name] = localConfig[name]; + _.each(localConfig, function(value, key) { + if (key === 'networkName' && config['forceNetwork']) { + return; } - } + config[name] = value; + }); } } diff --git a/js/models/core/TxProposal.js b/js/models/core/TxProposal.js index 2c7b6d02b..2340bde8d 100644 --- a/js/models/core/TxProposal.js +++ b/js/models/core/TxProposal.js @@ -1,6 +1,7 @@ 'use strict'; var bitcore = require('bitcore'); +var _ = require('underscore'); var util = bitcore.util; var Transaction = bitcore.Transaction; var BuilderMockV0 = require('./BuilderMockV0');; @@ -51,22 +52,19 @@ TxProposal.prototype._check = function() { if (!tx.ins.length) throw new Error('Invalid tx proposal: no ins'); - for (var i in tx.ins) { - var scriptSig = tx.ins[i].s; + _.each(tx.ins, function(value, index) { + var scriptSig = value.s; if (!scriptSig || !scriptSig.length) { throw new Error('Invalid tx proposal: no signatures'); } - } - - for (var i = 0; i < tx.ins.length; i++) { - var hashType = tx.getHashType(i); + var hashType = tx.getHashType(index); if (hashType && hashType !== Transaction.SIGHASH_ALL) throw new Error('Invalid tx proposal: bad signatures'); - } + }); }; TxProposal.prototype.rejectCount = function() { - return Object.keys(this.rejectedBy).length; + return _.size(this.rejectedBy); }; TxProposal.prototype.isPending = function(maxRejectCount) { diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 0a9785516..272e27d11 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1,6 +1,7 @@ 'use strict'; var EventEmitter = require('events').EventEmitter; +var _ = require('underscore'); var async = require('async'); var preconditions = require('preconditions').singleton(); var util = require('util'); @@ -34,8 +35,7 @@ function Wallet(opts) { 'publicKeyRing', 'txProposals', 'privateKey', 'version', 'reconnectDelay' ].forEach(function(k) { - preconditions.checkArgument(typeof opts[k] !== 'undefined', - 'missing required option for Wallet: ' + k); + preconditions.checkArgument(!_.isUndefined(opts[k]), 'missing required option for Wallet: ' + k); self[k] = opts[k]; }); preconditions.checkArgument(!copayConfig.forceNetwork || this.getNetworkName() === copayConfig.networkName, @@ -161,7 +161,7 @@ Wallet.prototype._getKeyMap = function(txp) { for (var i in txp._inputSigners) { var keyMap = this.publicKeyRing.copayersForPubkeys(txp._inputSigners[i], txp.inputChainPaths); - if (Object.keys(keyMap).length !== txp._inputSigners[i].length) + if (_.size(keyMap) !== _.size(txp._inputSigners[i])) throw new Error('Signature does not match known copayers'); for (var j in keyMap) { @@ -170,8 +170,8 @@ Wallet.prototype._getKeyMap = function(txp) { // From here -> only to check that all inputs have the same sigs var inSigArr = []; - Object.keys(keyMap).forEach(function(k) { - inSigArr.push(keyMap[k]); + _.each(keyMap, function(value, key) { + inSigArr.push(value); }); var inSig = JSON.stringify(inSigArr.sort()); if (i === '0') { @@ -299,7 +299,7 @@ Wallet.prototype._onAddressBook = function(senderId, data) { Wallet.prototype.updateTimestamp = function(ts) { preconditions.checkArgument(ts); - preconditions.checkArgument(typeof ts === 'number'); + preconditions.checkArgument(_.isNumber(ts)); this.lastTimestamp = ts; this.store(); }; @@ -315,7 +315,7 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(data); preconditions.checkArgument(data.type); preconditions.checkArgument(ts); - preconditions.checkArgument(typeof ts === 'number'); + preconditions.checkArgument(_.isNumber(ts)); log.debug('RECV', senderId, data); @@ -582,11 +582,11 @@ Wallet.prototype.send = function(recipients, obj) { }; Wallet.prototype.sendAllTxProposals = function(recipients) { - var ntxids = this.txProposals.getNtxids(); - for (var i in ntxids) { - var ntxid = ntxids[i]; - this.sendTxProposal(ntxid, recipients); - } + var ntxids = this.txProposals.getNtxids(), + that = this; + _.each(ntxids, function(ntxid, key) { + that.sendTxProposal(ntxid, recipients); + }); }; Wallet.prototype.sendTxProposal = function(ntxid, recipients) { @@ -730,7 +730,7 @@ Wallet.prototype.reject = function(ntxid) { }; Wallet.prototype.sign = function(ntxid, cb) { - preconditions.checkState(typeof this.getMyCopayerId() !== 'undefined'); + preconditions.checkState(!_.isUndefined(this.getMyCopayerId())); var self = this; setTimeout(function() { var myId = self.getMyCopayerId(); @@ -805,7 +805,7 @@ Wallet.prototype.sendTx = function(ntxid, cb) { Wallet.prototype.createPaymentTx = function(options, cb) { var self = this; - if (typeof options === 'string') { + if (_.isString(options)) { options = { uri: options }; @@ -849,7 +849,7 @@ Wallet.prototype.fetchPaymentTx = function(options, cb) { var self = this; options = options || {}; - if (typeof options === 'string') { + if (_.isString(options)) { options = { uri: options }; @@ -1160,7 +1160,7 @@ Wallet.prototype.createPaymentTxSync = function(options, merchantData, unspent) } }; - if (typeof opts.spendUnconfirmed === 'undefined') { + if (_.isUndefined(opts.spendUnconfirmed)) { opts.spendUnconfirmed = this.spendUnconfirmed; } @@ -1270,7 +1270,7 @@ Wallet.prototype.createPaymentTxSync = function(options, merchantData, unspent) Wallet.prototype.verifyPaymentRequest = function(ntxid) { if (!ntxid) return false; - var txp = typeof ntxid !== 'object' ? this.txProposals.get(ntxid) : ntxid; + var txp = _.isObject(ntxid) ? ntxid : this.txProposals.get(ntxid); // If we're not a payment protocol proposal, ignore. if (!txp.merchant) return true; @@ -1443,16 +1443,7 @@ Wallet.prototype.getAddressesInfo = function(opts) { Wallet.prototype.addressIsOwn = function(addrStr, opts) { var addrList = this.getAddressesStr(opts); - var l = addrList.length; - var ret = false; - - for (var i = 0; i < l; i++) { - if (addrList[i] === addrStr) { - ret = true; - break; - } - } - return ret; + return _.any(addrList, function(value) { return value === addrStr; }); }; //retunrs values in SATOSHIs @@ -1476,10 +1467,10 @@ Wallet.prototype.getBalance = function(cb) { // we multiply and divide by BIT to avoid rounding errors when adding for (var a in balanceByAddr) { - balanceByAddr[a] = parseInt(balanceByAddr[a].toFixed(0)); + balanceByAddr[a] = parseInt(balanceByAddr[a].toFixed(0), 10); } - balance = parseInt(balance.toFixed(0)); + balance = parseInt(balance.toFixed(0), 10); for (var i = 0; i < safeUnspent.length; i++) { var u = safeUnspent[i]; @@ -1487,7 +1478,7 @@ Wallet.prototype.getBalance = function(cb) { safeBalance += amt; } - safeBalance = parseInt(safeBalance.toFixed(0)); + safeBalance = parseInt(safeBalance.toFixed(0), 10); return cb(null, balance, balanceByAddr, safeBalance); }); }; @@ -1529,7 +1520,7 @@ Wallet.prototype.getUnspent = function(cb) { Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) { var self = this; - if (typeof amountSatStr === 'function') { + if (_.isFunction(amountSatStr)) { var cb = amountSatStr; var merchant = toAddress; return this.createPaymentTx({ @@ -1537,7 +1528,7 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) }, cb); } - if (typeof comment === 'function') { + if (_.isFunction(comment)) { var cb = comment; var merchant = toAddress; var comment = amountSatStr; @@ -1547,13 +1538,13 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) }, cb); } - if (typeof opts === 'function') { + if (_.isFunction(opts)) { cb = opts; opts = {}; } opts = opts || {}; - if (typeof opts.spendUnconfirmed === 'undefined') { + if (_.isUndefined(opts.spendUnconfirmed)) { opts.spendUnconfirmed = this.spendUnconfirmed; } @@ -1816,7 +1807,7 @@ Wallet.prototype.verifySignedJson = function(senderId, payload, signature) { // } Wallet.request = function(options, callback) { - if (typeof options === 'string') { + if (_.isString(options)) { options = { uri: options }; diff --git a/karma.conf.js b/karma.conf.js index 74d8f7377..bc467f9bb 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -29,6 +29,7 @@ module.exports = function(config) { 'lib/angular-foundation/mm-foundation.min.js', 'lib/angular-foundation/mm-foundation-tpls.min.js', 'lib/bitcore.js', + 'lib/underscore/underscore.js', 'lib/crypto-js/rollups/sha256.js', 'lib/crypto-js/rollups/pbkdf2.js', 'lib/crypto-js/rollups/aes.js', diff --git a/package.json b/package.json index 258a25603..c970b0737 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "optimist": "^0.6.1", "preconditions": "^1.0.7", "request": "^2.40.0", - "sinon": "1.9.1" + "sinon": "1.9.1", + "underscore": "^1.7.0" }, "scripts": { "shell": "node shell/scripts/launch.js", @@ -72,7 +73,7 @@ "travis-cov": "0.2.5", "uglifyify": "1.2.3", "crypto-js": "3.1.2", - "shelljs":"0.3.0", + "shelljs": "0.3.0", "browser-request": "0.3.2", "request": "2.40.0" }, diff --git a/util/build.js b/util/build.js index bcd6f5ec1..c3b8b7bd6 100644 --- a/util/build.js +++ b/util/build.js @@ -43,6 +43,9 @@ var createBundle = function(opts) { b.require('browser-request', { expose: 'request' }); + b.require('underscore', { + expose: 'underscore' + }); b.require('./copay', { expose: 'copay'