diff --git a/config.js b/config.js index ff0a27f19..a15369429 100644 --- a/config.js +++ b/config.js @@ -1,8 +1,12 @@ 'use strict'; var defaultConfig = { - // livenet or testnet + // DEFAULT network (livenet or testnet) networkName: 'testnet', + // DEFAULT unit: Bit + unitName: 'bits', + unitToSatoshi: 100, + // wallet limits limits: { totalCopayers: 12, @@ -21,7 +25,7 @@ var defaultConfig = { */ // Use this to connect to bitpay's PeerJS server - key: 'satoshirocks', + key: 'satoshirocks', host: '162.242.219.26', port: 10000, path: '/', @@ -107,7 +111,7 @@ var defaultConfig = { // local encryption/security config passphrase: { iterations: 100, - storageSalt: 'mjuBtGybi/4=', + storageSalt: 'mjuBtGybi/4=', }, // theme list diff --git a/index.html b/index.html index fbb762c54..caf3c0eb1 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,7 @@ - {{totalBalance || 0 |number}} bits + {{totalBalance || 0 |number}} {{$root.unitName}}
@@ -43,7 +43,7 @@ - {{availableBalance || 0|number}} bits + {{availableBalance || 0|number}} {{$root.unitName}}
@@ -381,11 +381,11 @@
- {{$root.balanceByAddr[addr.address] || 0|number}} bits + {{$root.balanceByAddr[addr.address] || 0|number}} {{$root.unitName}} - {{addr.balance || 0|number}} bits + {{addr.balance || 0|number}} {{$root.unitName}} @@ -408,7 +408,7 @@ {{selectedAddr.address}}
- {{selectedAddr.balance || 0|number}} bits + {{selectedAddr.balance || 0|number}} {{$root.unitName}}

@@ -439,7 +439,7 @@
-
{{out.value | number}} bits
+
{{out.value | number}} {{$root.unitName}}
{{out.address}}
@@ -521,7 +521,7 @@

{{tx.missingSignatures}} signatures missing

- Fee: {{tx.fee|number}} bits + Fee: {{tx.fee|number}} {{$root.unitName}} Proposal ID: {{tx.ntxid}}
@@ -565,7 +565,7 @@
- {{vin.value| number}} bits + {{vin.value| number}} {{$root.unitName}}

{{vin.addr}}

@@ -574,7 +574,7 @@
- {{vout.value| number}} bits + {{vout.value| number}} {{$root.unitName}}

{{vout.addr}}

@@ -582,9 +582,9 @@
-
Fees: {{btx.fees | number}} bits
+
Fees: {{btx.fees | number}} {{$root.unitName}}
Confirmations: {{btx.confirmations || 0}}
-
Total: {{btx.valueOut| number}} bits
+
Total: {{btx.valueOut| number}} {{$root.unitName}}
@@ -646,11 +646,11 @@
- bits + {{$root.unitName}}
@@ -669,13 +669,13 @@ Total amount for this transaction:
- {{amount + defaultFee |number}} bits + {{amount + defaultFee |number}} {{$root.unitName}} - {{((amount + defaultFee)/1e6).toFixed(3) |number}} BTC + {{ ((amount + defaultFee) * unitToBtc) |number}} BTC
- Including fee of {{defaultFee|number}} bits + Including fee of {{defaultFee|number}} {{$root.unitName}} @@ -750,6 +750,17 @@ +
+ Wallet Unit + + +
+
+ Videoconferencing + + +
Insight API server @@ -768,13 +779,6 @@
-
- Videoconferencing - - -
- -
diff --git a/js/controllers/header.js b/js/controllers/header.js index bbbbce675..708ac02f7 100644 --- a/js/controllers/header.js +++ b/js/controllers/header.js @@ -32,6 +32,7 @@ angular.module('copayApp.controllers').controller('HeaderController', } }); + $rootScope.unitName = config.unitName; // Initialize alert notification (not show when init wallet) $rootScope.txAlertCount = 0; diff --git a/js/controllers/send.js b/js/controllers/send.js index e99c670f0..8673d2107 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -5,7 +5,9 @@ angular.module('copayApp.controllers').controller('SendController', function($scope, $rootScope, $window, $location, $timeout) { $scope.title = 'Send'; $scope.loading = false; - $scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT / bitcore.util.BIT; + var satToUnit = 1 / config.unitToSatoshi; + $scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit; + $scope.unitToBtc = config.unitToSatoshi / bitcore.util.COIN; // TODO this shouldnt be on a particular controller. // Detect mobile devices @@ -49,7 +51,7 @@ angular.module('copayApp.controllers').controller('SendController', $scope.loading = true; var address = form.address.$modelValue; - var amount = (form.amount.$modelValue * 100) | 0; + var amount = (form.amount.$modelValue * config.unitToSatoshi) | 0; var commentText = form.comment.$modelValue; var w = $rootScope.wallet; diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 9c9f21824..78a5f5762 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -11,10 +11,35 @@ angular.module('copayApp.controllers').controller('SettingsController', $scope.networkHost = config.network.host; $scope.networkPort = config.network.port; $scope.networkSecure = config.network.secure || false; - $scope.disableVideo = config.disableVideo || true; + $scope.disableVideo = config.disableVideo || true; + + $scope.unitOpts = [{ + name: 'Satoshis (100,000,000 bits = 1BTC)', + shortName: 'SAT', + value: 1 + }, { + name: 'bits (1,000,000 bits = 1BTC)', + shortName: 'bits', + value: 100 + }, { + name: 'mBTC (1,000 mBTC = 1BTC)', + shortName: 'mBTC', + value: 100000 + }, { + name: 'BTC', + shortName: 'BTC', + value: 100000000 + }]; + + for (var ii in $scope.unitOpts) { + if (config.unitName === $scope.unitOpts[ii].shortName) { + $scope.selectedUnit = $scope.unitOpts[ii]; + break; + } + } $scope.$watch('networkName', function(net) { - $scope.insightHost = net === 'testnet' ? 'test.insight.is' : 'live.insight.is'; + $scope.insightHost = net === 'testnet' ? 'test.insight.is' : 'live.insight.is'; }); $scope.save = function() { @@ -25,20 +50,21 @@ angular.module('copayApp.controllers').controller('SettingsController', network.secure = $scope.networkSecure; localStorage.setItem('config', JSON.stringify({ - networkName: $scope.networkName, - blockchain: { - host: $scope.insightHost, - port: $scope.insightPort - }, - socket: { - host: $scope.insightHost, - port: $scope.insightPort - }, - network: network, - disableVideo: $scope.disableVideo, - }) - ); + networkName: $scope.networkName, + blockchain: { + host: $scope.insightHost, + port: $scope.insightPort + }, + socket: { + host: $scope.insightHost, + port: $scope.insightPort + }, + network: network, + disableVideo: $scope.disableVideo, + unitName: $scope.selectedUnit.shortName, + unitToSatoshi: $scope.selectedUnit.value, + })); - $window.location.href= $window.location.origin + $window.location.pathname; + $window.location.href = $window.location.origin + $window.location.pathname; }; }); diff --git a/js/controllers/transactions.js b/js/controllers/transactions.js index cd318ff4a..1b8154d54 100644 --- a/js/controllers/transactions.js +++ b/js/controllers/transactions.js @@ -13,9 +13,11 @@ angular.module('copayApp.controllers').controller('TransactionsController', $scope.txpItemsPerPage = 4; $scope.blockchain_txs = []; - $scope.update = function () { + var satToUnit = 1 / config.unitToSatoshi; + + $scope.update = function() { $scope.loading = false; - var from = ($scope.txpCurrentPage-1) * $scope.txpItemsPerPage; + var from = ($scope.txpCurrentPage - 1) * $scope.txpItemsPerPage; var opts = { onlyPending: $scope.onlyPending, skip: !$scope.onlyPending ? [from, from + $scope.txpItemsPerPage] : null @@ -24,10 +26,10 @@ angular.module('copayApp.controllers').controller('TransactionsController', $rootScope.$digest(); }; - $scope.show = function (onlyPending) { - $scope.loading=true; + $scope.show = function(onlyPending) { + $scope.loading = true; $scope.onlyPending = onlyPending; - setTimeout(function(){ + setTimeout(function() { $scope.update(); }, 10); }; @@ -41,19 +43,19 @@ angular.module('copayApp.controllers').controller('TransactionsController', var tmp = {}; var u = 0; - for(var i=0; i < l; i++) { + for (var i = 0; i < l; i++) { var notAddr = false; // non standard input if (items[i].scriptSig && !items[i].addr) { - items[i].addr = 'Unparsed address [' + u++ + ']'; + items[i].addr = 'Unparsed address [' + u+++']'; items[i].notAddr = true; notAddr = true; } // non standard output if (items[i].scriptPubKey && !items[i].scriptPubKey.addresses) { - items[i].scriptPubKey.addresses = ['Unparsed address [' + u++ + ']']; + items[i].scriptPubKey.addresses = ['Unparsed address [' + u+++']']; items[i].notAddr = true; notAddr = true; } @@ -76,62 +78,64 @@ angular.module('copayApp.controllers').controller('TransactionsController', } tmp[addr].isSpent = items[i].spentTxId; - tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID; + tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID; tmp[addr].doubleSpentIndex = tmp[addr].doubleSpentIndex || items[i].doubleSpentIndex; tmp[addr].unconfirmedInput += items[i].unconfirmedInput; tmp[addr].dbError = tmp[addr].dbError || items[i].dbError; - tmp[addr].valueSat += (items[i].value * bitcore.util.COIN)|0; + tmp[addr].valueSat += parseInt((items[i].value * bitcore.util.COIN).toFixed(0)); tmp[addr].items.push(items[i]); tmp[addr].notAddr = notAddr; tmp[addr].count++; } angular.forEach(tmp, function(v) { - v.value = (v.valueSat|0) / bitcore.util.BIT; + v.value = (parseInt(v.valueSat || 0).toFixed(0)) * satToUnit; ret.push(v); }); return ret; }; - $scope.toogleLast = function () { + $scope.toogleLast = function() { $scope.lastShowed = !$scope.lastShowed; if ($scope.lastShowed) { $scope.getTransactions(); } }; - $scope.send = function (ntxid,cb) { + $scope.send = function(ntxid, cb) { $scope.loading = true; $rootScope.txAlertCount = 0; var w = $rootScope.wallet; w.sendTx(ntxid, function(txid) { - $rootScope.$flashMessage = txid - ? {type:'success', message: 'Transaction broadcasted. txid: ' + txid} - : {type:'error', message: 'There was an error sending the Transaction'} - ; - if (cb) return cb(); - else $scope.update(); + $rootScope.$flashMessage = txid ? { + type: 'success', + message: 'Transaction broadcasted. txid: ' + txid + } : { + type: 'error', + message: 'There was an error sending the Transaction' + }; + if (cb) return cb(); + else $scope.update(); }); }; - $scope.sign = function (ntxid) { + $scope.sign = function(ntxid) { $scope.loading = true; var w = $rootScope.wallet; - w.sign(ntxid, function(ret){ + w.sign(ntxid, function(ret) { if (!ret) { $rootScope.$flashMessage = { - type:'error', + type: 'error', message: 'There was an error signing the Transaction', }; - $scope.update(); + $scope.update(); } else { var p = w.txProposals.getTxProposal(ntxid); if (p.builder.isFullySigned()) { $scope.send(ntxid, function() { $scope.update(); }); - } - else + } else $scope.update(); } }); @@ -144,20 +148,19 @@ angular.module('copayApp.controllers').controller('TransactionsController', var addresses = w.getAddressesStr(); if (addresses.length > 0) { $scope.blockchain_txs = []; - w.blockchain.getTransactions(addresses, function(txs) { + w.blockchain.getTransactions(addresses, function(txs) { $timeout(function() { - for (var i=0; i 0) { if (availableBalanceNum < vNum) { ctrl.$setValidity('enoughAmount', false); @@ -72,7 +72,7 @@ angular.module('copayApp.directives') require: 'ngModel', link: function(scope, elem, attrs, ctrl) { var validator = function(value) { - ctrl.$setValidity('walletSecret', Boolean(walletFactory.decodeSecret(value))); + ctrl.$setValidity('walletSecret', Boolean(walletFactory.decodeSecret(value))); return value; }; @@ -88,7 +88,7 @@ angular.module('copayApp.directives') var a = element.html(); var text = attr.loading; element.on('click', function() { - element.html(' ' + text + '...'); + element.html(' ' + text + '...'); }); $scope.$watch('loading', function(val) { if (!val) { @@ -126,9 +126,11 @@ angular.module('copayApp.directives') return { restrict: 'A', link: function(scope, element, attrs) { - scope.$watch(attrs.highlightOnChange, function (newValue, oldValue) { + scope.$watch(attrs.highlightOnChange, function(newValue, oldValue) { element.addClass('highlight'); - setTimeout(function() { element.removeClass('highlight'); }, 500); + setTimeout(function() { + element.removeClass('highlight'); + }, 500); }); } } @@ -142,7 +144,7 @@ angular.module('copayApp.directives') var strength = { messages: ['very weak', 'weak', 'weak', 'medium', 'strong'], colors: ['#c0392b', '#e74c3c', '#d35400', '#f39c12', '#27ae60'], - mesureStrength: function (p) { + mesureStrength: function(p) { var force = 0; var regex = /[$-/:-?{-~!"^_`\[\]]/g; var lowerLetters = /[a-z]+/.test(p); @@ -150,37 +152,51 @@ angular.module('copayApp.directives') var numbers = /[0-9]+/.test(p); var symbols = regex.test(p); var flags = [lowerLetters, upperLetters, numbers, symbols]; - var passedMatches = flags.filter(function (el) { return !!el; }).length; - + var passedMatches = flags.filter(function(el) { + return !!el; + }).length; + force = 2 * p.length + (p.length >= 10 ? 1 : 0); force += passedMatches * 10; - + // penality (short password) force = (p.length <= 6) ? Math.min(force, 10) : force; - + // penality (poor variety of characters) force = (passedMatches == 1) ? Math.min(force, 10) : force; force = (passedMatches == 2) ? Math.min(force, 20) : force; force = (passedMatches == 3) ? Math.min(force, 40) : force; return force; }, - getColor: function (s) { + getColor: function(s) { var idx = 0; - - if (s <= 10) { idx = 0; } - else if (s <= 20) { idx = 1; } - else if (s <= 30) { idx = 2; } - else if (s <= 40) { idx = 3; } - else { idx = 4; } - - return { idx: idx + 1, col: this.colors[idx], message: this.messages[idx] }; + + if (s <= 10) { + idx = 0; + } else if (s <= 20) { + idx = 1; + } else if (s <= 30) { + idx = 2; + } else if (s <= 40) { + idx = 3; + } else { + idx = 4; + } + + return { + idx: idx + 1, + col: this.colors[idx], + message: this.messages[idx] + }; } }; - scope.$watch(attrs.ngModel, function (newValue, oldValue) { + scope.$watch(attrs.ngModel, function(newValue, oldValue) { if (newValue && newValue !== '') { var c = strength.getColor(strength.mesureStrength(newValue)); - element.css({ 'border-color': c.col }); + element.css({ + 'border-color': c.col + }); scope[attrs.checkStrength] = c.message; } }); diff --git a/js/models/core/TxProposals.js b/js/models/core/TxProposals.js index f25b2b9a7..4bc4f2fa9 100644 --- a/js/models/core/TxProposals.js +++ b/js/models/core/TxProposals.js @@ -1,22 +1,21 @@ - 'use strict'; -var imports = require('soop').imports(); -var bitcore = require('bitcore'); -var util = bitcore.util; +var imports = require('soop').imports(); +var bitcore = require('bitcore'); +var util = bitcore.util; var Transaction = bitcore.Transaction; -var Builder = bitcore.TransactionBuilder; -var Script = bitcore.Script; +var Builder = bitcore.TransactionBuilder; +var Script = bitcore.Script; var buffertools = bitcore.buffertools; function TxProposal(opts) { - this.creator = opts.creator; - this.createdTs = opts.createdTs; - this.seenBy = opts.seenBy || {}; + this.creator = opts.creator; + this.createdTs = opts.createdTs; + this.seenBy = opts.seenBy || {}; this.signedBy = opts.signedBy || {}; this.rejectedBy = opts.rejectedBy || {}; - this.builder = opts.builder; + this.builder = opts.builder; this.sentTs = opts.sentTs || null; this.sentTxid = opts.sentTxid || null; this.inputChainPaths = opts.inputChainPaths || []; @@ -53,8 +52,8 @@ module.exports = require('soop')(TxProposal); function TxProposals(opts) { opts = opts || {}; this.walletId = opts.walletId; - this.network = opts.networkName === 'livenet' ? - bitcore.networks.livenet : bitcore.networks.testnet; + this.network = opts.networkName === 'livenet' ? + bitcore.networks.livenet : bitcore.networks.testnet; this.txps = {}; } @@ -77,7 +76,7 @@ TxProposals.prototype.getNtxids = function() { TxProposals.prototype.toObj = function(onlyThisNtxid) { var ret = []; - for(var id in this.txps){ + for (var id in this.txps) { if (onlyThisNtxid && id != onlyThisNtxid) continue; @@ -86,31 +85,33 @@ TxProposals.prototype.toObj = function(onlyThisNtxid) { if (!t.sent) ret.push(t.toObj()); } - return { - txps: ret, + return { + txps: ret, walletId: this.walletId, networkName: this.network.name, }; }; TxProposals.prototype._startMerge = function(myTxps, theirTxps) { - var fromUs=0, fromTheirs=0, merged =0; - var toMerge = {}, ready={}; + var fromUs = 0, + fromTheirs = 0, + merged = 0; + var toMerge = {}, + ready = {}; - for(var hash in theirTxps){ + for (var hash in theirTxps) { if (!myTxps[hash]) { - ready[hash]=theirTxps[hash]; // only in theirs; + ready[hash] = theirTxps[hash]; // only in theirs; fromTheirs++; - } - else { - toMerge[hash]=theirTxps[hash]; // need Merging + } else { + toMerge[hash] = theirTxps[hash]; // need Merging merged++; } } - for(var hash in myTxps){ - if(!toMerge[hash]) { - ready[hash]=myTxps[hash]; // only in myTxps; + for (var hash in myTxps) { + if (!toMerge[hash]) { + ready[hash] = myTxps[hash]; // only in myTxps; fromUs++; } } @@ -130,7 +131,7 @@ TxProposals.prototype._startMerge = function(myTxps, theirTxps) { TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) { var toMerge = mergeInfo.toMerge; - var hasChanged =0; + var hasChanged = 0; Object.keys(toMerge).forEach(function(hash) { var v0 = myTxps[hash]; @@ -158,7 +159,7 @@ TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) { }); if (!v0.sentTxid && v1.sentTxid) { - v0.sentTs = v1.sentTs; + v0.sentTs = v1.sentTs; v0.sentTxid = v1.sentTxid; hasChanged++; } @@ -170,9 +171,9 @@ TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) { TxProposals.prototype._mergeBuilder = function(myTxps, theirTxps, mergeInfo) { var toMerge = mergeInfo.toMerge; - var hasChanged=0; + var hasChanged = 0; - for(var hash in toMerge){ + for (var hash in toMerge) { var v0 = myTxps[hash].builder; var v1 = toMerge[hash].builder; @@ -180,7 +181,7 @@ TxProposals.prototype._mergeBuilder = function(myTxps, theirTxps, mergeInfo) { var before = JSON.stringify(v0.toObj()); v0.merge(v1); var after = JSON.stringify(v0.toObj()); - if (after !== before) hasChanged ++; + if (after !== before) hasChanged++; } }; @@ -191,7 +192,7 @@ TxProposals.prototype.add = function(data) { }; -TxProposals.prototype.setSent = function(ntxid,txid) { +TxProposals.prototype.setSent = function(ntxid, txid) { //sent TxProposals are local an not broadcasted. this.txps[ntxid].setSent(txid); }; @@ -205,26 +206,28 @@ TxProposals.prototype.getTxProposal = function(ntxid, copayers) { i.peerActions = {}; if (copayers) { - for(var j=0; j < copayers.length; j++) { + for (var j = 0; j < copayers.length; j++) { var p = copayers[j]; i.peerActions[p] = {}; } } - for(var p in txp.seenBy){ - i.peerActions[p]={seen: txp.seenBy[p]}; + for (var p in txp.seenBy) { + i.peerActions[p] = { + seen: txp.seenBy[p] + }; } - for(var p in txp.signedBy){ - i.peerActions[p]= i.peerActions[p] || {}; + for (var p in txp.signedBy) { + i.peerActions[p] = i.peerActions[p] || {}; i.peerActions[p].sign = txp.signedBy[p]; } - var r=0; - for(var p in txp.rejectedBy){ - i.peerActions[p]= i.peerActions[p] || {}; + var r = 0; + for (var p in txp.rejectedBy) { + i.peerActions[p] = i.peerActions[p] || {}; i.peerActions[p].rejected = txp.rejectedBy[p]; r++; } - i.rejectCount=r; + i.rejectCount = r; var c = txp.creator; i.peerActions[c] = i.peerActions[c] || {}; @@ -235,30 +238,30 @@ TxProposals.prototype.getTxProposal = function(ntxid, copayers) { //returns the unspent txid-vout used in PENDING Txs TxProposals.prototype.getUsedUnspent = function(maxRejectCount) { var ret = {}; - for(var i in this.txps) { + for (var i in this.txps) { var u = this.txps[i].builder.getSelectedUnspent(); var p = this.getTxProposal(i); - if (p.rejectCount>maxRejectCount || p.sentTxid) + if (p.rejectCount > maxRejectCount || p.sentTxid) continue; for (var j in u) { - ret[u[j].txid + ',' + u[j].vout]=1; + ret[u[j].txid + ',' + u[j].vout] = 1; } } return ret; }; TxProposals.prototype.merge = function(t) { - if (this.network.name !== t.network.name) + if (this.network.name !== t.network.name) throw new Error('network mismatch in:', t); var res = []; var hasChanged = 0; - var myTxps = this.txps; - var theirTxps = t.txps; + var myTxps = this.txps; + var theirTxps = t.txps; - var mergeInfo = this._startMerge(myTxps, theirTxps); + var mergeInfo = this._startMerge(myTxps, theirTxps); hasChanged += this._mergeMetadata(myTxps, theirTxps, mergeInfo); hasChanged += this._mergeBuilder(myTxps, theirTxps, mergeInfo); @@ -268,7 +271,7 @@ TxProposals.prototype.merge = function(t) { mergeInfo.stats.hasChanged = hasChanged; - this.txps=mergeInfo.ready; + this.txps = mergeInfo.ready; return mergeInfo.stats; }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 5526e951e..4dfd7708d 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -562,20 +562,13 @@ Wallet.prototype.addressIsOwn = function(addrStr, opts) { return ret; }; +//retunrs values in SATOSHIs Wallet.prototype.getBalance = function(cb) { var balance = 0; var safeBalance = 0; var balanceByAddr = {}; - var BIT = coinUtil.BIT; var COIN = coinUtil.COIN; - if (!BIT) - throw new Error('BIT not defined. A newer version of bitcore is needed'); - - console.log('[Wallet.js.574] getBalance'); //TODO - - - this.getUnspent(function(err, safeUnspent, unspent) { if (err) { return cb(err); @@ -590,9 +583,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] = balanceByAddr[a].toFixed(0) / BIT; + balanceByAddr[a] = parseInt(balanceByAddr[a].toFixed(0)); } - balance = balance.toFixed(0) / BIT; + + balance = parseInt(balance.toFixed(0)); for (var i = 0; i < safeUnspent.length; i++) { var u = safeUnspent[i]; @@ -600,7 +594,7 @@ Wallet.prototype.getBalance = function(cb) { safeBalance += amt; } - safeBalance = safeBalance.toFixed(0) / BIT; + safeBalance = parseInt(safeBalance.toFixed(0)); return cb(null, balance, balanceByAddr, safeBalance); }); }; @@ -608,7 +602,6 @@ Wallet.prototype.getBalance = function(cb) { Wallet.prototype.getUnspent = function(cb) { var self = this; this.blockchain.getUnspent(this.getAddressesStr(), function(err, unspentList) { - console.log('[Wallet.js.606:unspentList:]', unspentList); //TODO if (err) { return cb(err); @@ -642,7 +635,6 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) } this.getUnspent(function(err, safeUnspent) { - console.log('[Wallet.js.639:safeUnspent:]', safeUnspent); //TODO var ntxid = self.createTxSync(toAddress, amountSatStr, comment, safeUnspent, opts); if (ntxid) { self.sendIndexes(); diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index f1c3f5d1d..a512d5fd6 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -36,28 +36,33 @@ angular.module('copayApp.services') root.onError(scope); if (msg) $rootScope.$flashMessage = { type: 'error', - message: msg + message: msg }; $rootScope.$digest(); }; root.installStartupHandlers = function(wallet, $scope) { wallet.on('serverError', function(msg) { - $rootScope.$flashMessage = { - message: 'There was an error connecting to the PeerJS server.' - +(msg||'Check you settings and Internet connection.'), - type: 'error', - }; - root.onErrorDigest($scope); - $location.path('addresses'); + $rootScope.$flashMessage = { + message: 'There was an error connecting to the PeerJS server.' + (msg || 'Check you settings and Internet connection.'), + type: 'error', + }; + root.onErrorDigest($scope); + $location.path('addresses'); }); wallet.on('connectionError', function() { var message = "Looks like you are already connected to this wallet, please logout from it and try importing it again."; - $rootScope.$flashMessage = { message: message, type: 'error'}; + $rootScope.$flashMessage = { + message: message, + type: 'error' + }; root.onErrorDigest($scope); }); wallet.on('serverError', function() { - $rootScope.$flashMessage = { message: 'The PeerJS server is not responding, please try again', type: 'error'}; + $rootScope.$flashMessage = { + message: 'The PeerJS server is not responding, please try again', + type: 'error' + }; root.onErrorDigest($scope); }); wallet.on('ready', function() { @@ -105,17 +110,17 @@ angular.module('copayApp.services') } }); w.on('txProposalsUpdated', function(dontDigest) { - root.updateTxs({onlyPending:true}); + root.updateTxs({ + onlyPending: true + }); // give sometime to the tx to propagate. $timeout(function() { - -console.log('[controllerUtils.js.111] UPDATE BALANCE'); //TODO - root.updateBalance(function(){ + root.updateBalance(function() { if (!dontDigest) { $rootScope.$digest(); } }); - },3000); + }, 3000); }); w.on('connectionError', function(msg) { root.onErrorDigest(null, msg); @@ -145,27 +150,30 @@ console.log('[controllerUtils.js.111] UPDATE BALANCE'); //TODO $rootScope.balanceByAddr = {}; $rootScope.updatingBalance = true; -console.log('[controllerUtils.js.147] GET'); //TODO - w.getBalance(function(err, balance, balanceByAddr, safeBalance) { - -console.log('[controllerUtils.js.150]', err, balance); //TODO + w.getBalance(function(err, balanceSat, balanceByAddrSat, safeBalanceSat) { if (err) { console.error('Error: ' + err.message); //TODO root._setCommError(); return null; - } - else { + } else { root._clearCommError(); } - - $rootScope.totalBalance = balance; - $rootScope.totalBalanceBTC = (balance / 1e6).toFixed(3) ; - $rootScope.availableBalance = safeBalance; - $rootScope.availableBalanceBTC = (safeBalance / 1e6).toFixed(3); + + var satToUnit = 1 / config.unitToSatoshi; + var COIN = bitcore.util.COIN; + + $rootScope.totalBalance = balanceSat * satToUnit; + $rootScope.totalBalanceBTC = (balanceSat / COIN).toFixed(4); + $rootScope.availableBalance = safeBalanceSat * satToUnit; + $rootScope.availableBalanceBTC = (safeBalanceSat / COIN).toFixed(4); + var balanceByAddr = {}; + for (var ii in balanceByAddrSat) { + balanceByAddr[ii] = balanceByAddrSat[ii] * satToUnit; + } $rootScope.balanceByAddr = balanceByAddr; root.updateAddressList(); $rootScope.updatingBalance = false; - return cb?cb():null; + return cb ? cb() : null; }); }; @@ -173,13 +181,16 @@ console.log('[controllerUtils.js.150]', err, balance); //TODO var w = $rootScope.wallet; if (!w) return; opts = opts || {}; - + + var satToUnit = 1 / config.unitToSatoshi; var myCopayerId = w.getMyCopayerId(); var pendingForUs = 0; - var inT = w.getTxProposals().sort(function(t1, t2) { return t2.createdTs - t1.createdTs }); - var txs = []; + var inT = w.getTxProposals().sort(function(t1, t2) { + return t2.createdTs - t1.createdTs + }); + var txs = []; - inT.forEach(function(i, index){ + inT.forEach(function(i, index) { if (opts.skip && (index < opts.skip[0] || index >= opts.skip[1])) { return txs.push(null); } @@ -188,47 +199,49 @@ console.log('[controllerUtils.js.150]', err, balance); //TODO pendingForUs++; } if (!i.finallyRejected && !i.sentTs) { - i.isPending=1; + i.isPending = 1; } if (!opts.onlyPending || i.isPending) { - var tx = i.builder.build(); + var tx = i.builder.build(); var outs = []; tx.outs.forEach(function(o) { var addr = bitcore.Address.fromScriptPubKey(o.getScript(), config.networkName)[0].toString(); - if (!w.addressIsOwn(addr, {excludeMain:true})) { + if (!w.addressIsOwn(addr, { + excludeMain: true + })) { outs.push({ - address: addr, - value: bitcore.util.valueToBigInt(o.getValue())/bitcore.util.BIT, + address: addr, + value: bitcore.util.valueToBigInt(o.getValue()) * satToUnit, }); } }); // extra fields i.outs = outs; - i.fee = i.builder.feeSat/bitcore.util.BIT; + i.fee = i.builder.feeSat * satToUnit; i.missingSignatures = tx.countInputMissingSignatures(0); txs.push(i); } }); - + $rootScope.txs = txs; //.some(function(i) {return i.isPending; } ); if ($rootScope.pendingTxCount < pendingForUs) { $rootScope.txAlertCount = pendingForUs; } $rootScope.pendingTxCount = pendingForUs; - }; + }; root._setCommError = function(e) { - if ($rootScope.insightError<0) - $rootScope.insightError=0; + if ($rootScope.insightError < 0) + $rootScope.insightError = 0; $rootScope.insightError++; }; root._clearCommError = function(e) { - if ($rootScope.insightError>0) - $rootScope.insightError=-1; + if ($rootScope.insightError > 0) + $rootScope.insightError = -1; else - $rootScope.insightError=0; + $rootScope.insightError = 0; }; root.setSocketHandlers = function() { @@ -238,16 +251,16 @@ console.log('[controllerUtils.js.150]', err, balance); //TODO Socket.sysOn('reconnect_failed', root._setCommError); Socket.sysOn('connect', root._clearCommError); Socket.sysOn('reconnect', root._clearCommError); - Socket.sysEventsSet=true; + Socket.sysEventsSet = true; } if (!$rootScope.wallet) return; - var currentAddrs= Socket.getListeners(); + var currentAddrs = Socket.getListeners(); var addrs = $rootScope.wallet.getAddressesStr(); - - var newAddrs=[]; - for(var i in addrs){ - var a=addrs[i]; + + var newAddrs = []; + for (var i in addrs) { + var a = addrs[i]; if (!currentAddrs[a]) newAddrs.push(a); } @@ -257,7 +270,7 @@ console.log('[controllerUtils.js.150]', err, balance); //TODO newAddrs.forEach(function(addr) { Socket.on(addr, function(txid) { $rootScope.receivedFund = [txid, addr]; - root.updateBalance(function(){ + root.updateBalance(function() { $rootScope.$digest(); }); }); diff --git a/test/test.TxProposals.js b/test/test.TxProposals.js index b2aae9f3b..9ae69412c 100644 --- a/test/test.TxProposals.js +++ b/test/test.TxProposals.js @@ -308,15 +308,21 @@ describe('TxProposals model', function() { it('#merge, merge signatures case 2', function() { - var o1 ={ extendedPrivateKeyString: 'tprv8ZgxMBicQKsPdSF1avR6mXyDj5Uv1XY2UyUHSDpAXQ5TvPN7prGeDppjy4562rBB9gMMAhRfFdJrNDpQ4t69kkqHNEEen3PX1zBJqSehJDH', - networkName: 'testnet', - privateKeyCache: {} }; - var o2 ={ extendedPrivateKeyString: 'tprv8ZgxMBicQKsPdVeB5RzuxS9JQcACueZYgUaM5eWzaEBkHjW5Pg6Mqez1APSqoUP1jUdbT8WVG7ZJYTXvUL7XtPzFYBXjmdKuwSor1dcNQ8j', - networkName: 'testnet', - privateKeyCache: {} }; - var o3 ={ extendedPrivateKeyString: 'tprv8ZgxMBicQKsPeHWNrPVZtQVgcCtXBr5TACNbDQ56rwqNJce9MEc64US6DJKxpWsrebEomxxWZFDtkvkZGkzA43uLvdF4XHiWqoNaL6Dq2Gd', - networkName: 'testnet', - privateKeyCache: {} }; + var o1 = { + extendedPrivateKeyString: 'tprv8ZgxMBicQKsPdSF1avR6mXyDj5Uv1XY2UyUHSDpAXQ5TvPN7prGeDppjy4562rBB9gMMAhRfFdJrNDpQ4t69kkqHNEEen3PX1zBJqSehJDH', + networkName: 'testnet', + privateKeyCache: {} + }; + var o2 = { + extendedPrivateKeyString: 'tprv8ZgxMBicQKsPdVeB5RzuxS9JQcACueZYgUaM5eWzaEBkHjW5Pg6Mqez1APSqoUP1jUdbT8WVG7ZJYTXvUL7XtPzFYBXjmdKuwSor1dcNQ8j', + networkName: 'testnet', + privateKeyCache: {} + }; + var o3 = { + extendedPrivateKeyString: 'tprv8ZgxMBicQKsPeHWNrPVZtQVgcCtXBr5TACNbDQ56rwqNJce9MEc64US6DJKxpWsrebEomxxWZFDtkvkZGkzA43uLvdF4XHiWqoNaL6Dq2Gd', + networkName: 'testnet', + privateKeyCache: {} + }; var priv = PrivateKey.fromObj(o1); diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 5ac8e947c..91f223bbd 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -450,13 +450,13 @@ describe('Wallet model', function() { done(); }); }); - it('#getBalance should return values in bits', function(done) { + it('#getBalance should return values in satoshis', function(done) { var w = createW2(); w.generateAddress(); w.getBalance(function(err, balance, balanceByAddr, safeBalance) { - balance.should.equal(25000100.00); - safeBalance.should.equal(25000100.00); - balanceByAddr.mji7zocy8QzYywQakwWf99w9bCT6orY1C1.should.equal(25000100.00); + balance.should.equal(2500010000); + safeBalance.should.equal(2500010000); + balanceByAddr.mji7zocy8QzYywQakwWf99w9bCT6orY1C1.should.equal(2500010000); Object.keys(balanceByAddr).length.should.equal(1); done(); }); @@ -464,19 +464,19 @@ describe('Wallet model', function() { var roundErrorChecks = [{ unspent: [1.0001], - balance: 1000100 + balance: 100010000 }, { unspent: [1.0002, 1.0003, 1.0004], - balance: 3000900 + balance: 300090000 }, { unspent: [0.000002, 1.000003, 2.000004], - balance: 3000009 + balance: 300000900 }, { unspent: [0.0001, 0.0003], - balance: 400 + balance: 40000 }, { unspent: [0.0001, 0.0003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0002], - balance: 1100 + balance: 110000 }, ]; diff --git a/test/unit/directives/directivesSpec.js b/test/unit/directives/directivesSpec.js index b4162aae2..d7186c41f 100644 --- a/test/unit/directives/directivesSpec.js +++ b/test/unit/directives/directivesSpec.js @@ -8,6 +8,14 @@ describe("Unit: Testing Directives", function() { beforeEach(module('copayApp.directives')); + + describe('Check config', function() { + it('unit should be set to BITS in config.js', function() { + expect(config.unitToSatoshi).to.equal(100); + expect(config.unitName).to.equal('bits'); + }); + }); + describe('Validate Address', function() { beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; @@ -15,8 +23,10 @@ describe("Unit: Testing Directives", function() { '
' + '' + '
' - ); - $scope.model = { address: null }; + ); + $scope.model = { + address: null + }; $compile(element)($scope); $scope.$digest(); form = $scope.form; @@ -35,42 +45,47 @@ describe("Unit: Testing Directives", function() { describe('Validate Amount', function() { beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; - $rootScope.availableBalance = 0.101; + $rootScope.availableBalance = 1000; var element = angular.element( '
' + '' + '
' - ); - $scope.model = { amount: null }; + ); + $scope.model = { + amount: null + }; $compile(element)($scope); $scope.$digest(); form = $scope.form; })); + + it('should validate', function() { - form.amount.$setViewValue(0.1); + form.amount.$setViewValue(100); expect(form.amount.$invalid).to.equal(false); - form.amount.$setViewValue(0.1009); + form.amount.$setViewValue(900); expect(form.amount.$invalid).to.equal(false); }); + it('should not validate', function() { form.amount.$setViewValue(0); expect(form.amount.$invalid).to.equal(true); form.amount.$setViewValue(9999999999); expect(form.amount.$invalid).to.equal(true); - form.amount.$setViewValue(2.1); + form.amount.$setViewValue(901); expect(form.amount.$invalid).to.equal(true); - form.amount.$setViewValue(0.10091); + form.amount.$setViewValue(1000); expect(form.amount.$invalid).to.equal(true); }); }); describe('Password strength', function() { - beforeEach(inject(function($compile, $rootScope) { + beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; var element = angular.element( '' - ); + ); $compile(element)($scope); $scope.$digest(); })); diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index e7ea2a98f..f272d51dd 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -1,6 +1,16 @@ // // test/unit/services/servicesSpec.js // +// +// +describe('Check config', function() { + it('unit should be set to BITS in config.js', function() { + expect(config.unitToSatoshi).to.equal(100); + expect(config.unitName).to.equal('bits'); + }); +}); + + describe("Unit: Socket Service", function() { beforeEach(angular.mock.module('copayApp.services')); @@ -20,9 +30,9 @@ describe("Unit: Socket Service", function() { it('Socket should add handlers with #on', inject(function(Socket) { - Socket.on('a', function (){}); - Socket.on('b', function (){}); - Socket.sysOn('c', function (){}); + Socket.on('a', function() {}); + Socket.on('b', function() {}); + Socket.sysOn('c', function() {}); var ret = Socket.getListeners(); expect(ret.a).to.be.equal(1); expect(ret.b).to.be.equal(1); @@ -30,9 +40,9 @@ describe("Unit: Socket Service", function() { })); it('Socket should support #removeAllListeners', inject(function(Socket) { - Socket.on('a', function (){}); - Socket.on('b', function (){}); - Socket.sysOn('c', function (){}); + Socket.on('a', function() {}); + Socket.on('b', function() {}); + Socket.sysOn('c', function() {}); var ret = Socket.getListeners(); expect(Object.keys(ret)).to.have.length(2); Socket.removeAllListeners(); @@ -57,16 +67,19 @@ describe("Unit: controllerUtils", function() { expect(controllerUtils.updateBalance).not.to.equal(null); scope = $rootScope.$new(); - $rootScope.wallet=new FakeWallet(); + $rootScope.wallet = new FakeWallet(); var addr = '1CjPR7Z5ZSyWk6WtXvSFgkptmpoi4UM9BC'; - var a = {}; a[addr]=100; - $rootScope.wallet.set(1000000,900000,a); + var a = {}; + a[addr] = 100; + //SATs + $rootScope.wallet.set(100000001, 90000002, a); + //retuns values in DEFAULT UNIT(bits) controllerUtils.updateBalance(function() { - expect($rootScope.totalBalance).to.be.equal(1000000); - expect($rootScope.totalBalanceBTC).to.be.equal('1.000'); - expect($rootScope.availableBalance).to.be.equal(900000); - expect($rootScope.availableBalanceBTC).to.be.equal('0.900'); + expect($rootScope.totalBalanceBTC).to.be.equal('1.0000'); + expect($rootScope.availableBalanceBTC).to.be.equal('0.9000'); + expect($rootScope.totalBalance).to.be.equal(1000000.01); + expect($rootScope.availableBalance).to.be.equal(900000.02); expect($rootScope.addrInfos).not.to.equal(null); expect($rootScope.addrInfos[0].address).to.equal(addr); }); @@ -74,4 +87,3 @@ describe("Unit: controllerUtils", function() { }); -