From d125a14483cb41337016674a5ffa9ea6c3a81ef8 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Sun, 20 Dec 2015 19:02:38 -0300 Subject: [PATCH 1/6] Fix txp and tx with multiple and single outputs --- src/js/controllers/index.js | 1 + src/js/services/txFormatService.js | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 575b29eae..51290d830 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -501,6 +501,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r message: 'test multi-output', fee: 1000, createdOn: new Date() / 1000, + type: 'multiple_output', outputs: [] }; function addOutput(n) { diff --git a/src/js/services/txFormatService.js b/src/js/services/txFormatService.js index 1061ede76..71bd41825 100644 --- a/src/js/services/txFormatService.js +++ b/src/js/services/txFormatService.js @@ -24,9 +24,12 @@ angular.module('copayApp.services').factory('txFormatService', function(profileS root.processTx = function(tx) { if (!tx) return; - if (lodash.isArray(tx.outputs) && tx.outputs.length > 0 && tx.action != 'received') { - tx.hasMultiplesOutputs = true; - tx.recipientCount = tx.outputs.length; + var outputs = lodash.isArray(tx.outputs) ? tx.outputs.length : 0; + if (outputs && tx.action != 'received') { + if ((tx.type && tx.type == 'multiple_output') || (tx.proposalType && tx.proposalType == 'multiple_output')) { + tx.hasMultiplesOutputs = true; + tx.recipientCount = outputs; + } tx.amount = lodash.reduce(tx.outputs, function(total, o) { o.amountStr = formatAmountStr(o.amount); o.alternativeAmountStr = formatAlternativeStr(o.amount); From 2ea591a675e55675da40c6bcdc04a4a286c543b7 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Sun, 20 Dec 2015 19:21:06 -0300 Subject: [PATCH 2/6] Fix margin on modals --- public/views/create.html | 6 +++--- src/css/mobile.css | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/views/create.html b/public/views/create.html index 3f2e0fcb2..98d3e88a8 100644 --- a/public/views/create.html +++ b/public/views/create.html @@ -99,7 +99,7 @@
-
+
- - diff --git a/src/css/mobile.css b/src/css/mobile.css index 0d042ad18..b7e05c87d 100644 --- a/src/css/mobile.css +++ b/src/css/mobile.css @@ -630,7 +630,7 @@ to prevent collapsing during animation*/ height: 100%; width: 100%; top: 45px; - padding-bottom: 33px; + padding-bottom: 50px; -webkit-transform: translate3d(0,0,0); background: #f6f7f9; } From 66b7fa8f7acab4bc1cca625536abbdf76cce3e18 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Wed, 23 Dec 2015 18:05:22 -0300 Subject: [PATCH 3/6] Fix fee for send all --- public/views/walletHome.html | 4 +- src/js/controllers/index.js | 24 +++-- src/js/controllers/preferencesGlobal.js | 2 +- src/js/controllers/sellGlidera.js | 112 ++++++++++++------------ src/js/controllers/walletHome.js | 102 ++++++++++++--------- 5 files changed, 136 insertions(+), 108 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index 1bfe709cf..79cb80367 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -388,7 +388,7 @@ Send All @@ -403,7 +403,7 @@
-
+
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 575b29eae..87c80f7fa 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -371,14 +371,15 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }; - self.setSpendUnconfirmed = function() { - self.spendUnconfirmed = configService.getSync().wallet.spendUnconfirmed; + self.setSpendUnconfirmed = function(spendUnconfirmed) { + self.spendUnconfirmed = spendUnconfirmed || configService.getSync().wallet.spendUnconfirmed; }; - self.setSendMax = function() { + self.setFeeAndSendMax = function(cb) { self.feeToSendMaxStr = null; - self.feeRateToSendMax = null; + self.availableMaxBalance = null; + self.currentFeePerKb = null; // Set Send max if (self.currentFeeLevel && self.totalBytesToSendMax) { @@ -386,12 +387,14 @@ angular.module('copayApp.controllers').controller('indexController', function($r // KB to send max var feeToSendMaxSat = parseInt(((self.totalBytesToSendMax * feePerKb) / 1000.).toFixed(0)); - self.feeRateToSendMax = feePerKb; + self.currentFeePerKb = feePerKb; if (self.availableBalanceSat > feeToSendMaxSat) { self.availableMaxBalance = strip((self.availableBalanceSat - feeToSendMaxSat) * self.satToUnit); self.feeToSendMaxStr = profileService.formatAmount(feeToSendMaxSat) + ' ' + self.unitName; } + + if (cb) return cb(self.currentFeePerKb, self.availableMaxBalance, self.feeToSendMaxStr); }); } @@ -399,7 +402,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.setCurrentFeeLevel = function(level) { self.currentFeeLevel = level || configService.getSync().wallet.settings.feeLevel || 'normal'; - self.setSendMax(); + self.setFeeAndSendMax(); }; @@ -1185,8 +1188,8 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }); - $rootScope.$on('Local/SpendUnconfirmedUpdated', function(event) { - self.setSpendUnconfirmed(); + $rootScope.$on('Local/SpendUnconfirmedUpdated', function(event, spendUnconfirmed) { + self.setSpendUnconfirmed(spendUnconfirmed); self.updateAll(); }); @@ -1194,6 +1197,10 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.setCurrentFeeLevel(level); }); + $rootScope.$on('Local/SetFeeSendMax', function(event, cb) { + self.setFeeAndSendMax(cb); + }); + $rootScope.$on('Local/ProfileBound', function() { storageService.getRemotePrefsStoredFlag(function(err, val) { if (err || val) return; @@ -1449,4 +1456,5 @@ angular.module('copayApp.controllers').controller('indexController', function($r $rootScope.$apply(); }); }); + }); diff --git a/src/js/controllers/preferencesGlobal.js b/src/js/controllers/preferencesGlobal.js index a3733882b..741d37963 100644 --- a/src/js/controllers/preferencesGlobal.js +++ b/src/js/controllers/preferencesGlobal.js @@ -24,7 +24,7 @@ angular.module('copayApp.controllers').controller('preferencesGlobalController', } }; configService.set(opts, function(err) { - $rootScope.$emit('Local/SpendUnconfirmedUpdated'); + $rootScope.$emit('Local/SpendUnconfirmedUpdated', newVal); if (err) $log.debug(err); }); }); diff --git a/src/js/controllers/sellGlidera.js b/src/js/controllers/sellGlidera.js index 4904d4c21..48d466bb9 100644 --- a/src/js/controllers/sellGlidera.js +++ b/src/js/controllers/sellGlidera.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('sellGlideraController', - function($scope, $timeout, $log, $modal, configService, profileService, addressService, glideraService, bwsError, lodash, isChromeApp, animationService) { + function($scope, $timeout, $log, $modal, configService, profileService, addressService, feeService, glideraService, bwsError, lodash, isChromeApp, animationService) { var self = this; var config = configService.getSync(); @@ -11,6 +11,7 @@ angular.module('copayApp.controllers').controller('sellGlideraController', this.error = null; this.loading = null; this.currentSpendUnconfirmed = config.wallet.spendUnconfirmed; + this.currentFeeLevel = config.wallet.settings.feeLevel || 'normal'; var fc; var otherWallets = function(testnet) { @@ -142,62 +143,65 @@ angular.module('copayApp.controllers').controller('sellGlideraController', } var amount = parseInt((self.sellPrice.qty * 100000000).toFixed(0)); - fc.sendTxProposal({ - toAddress: sellAddress, - amount: amount, - message: 'Glidera transaction', - customData: {'glideraToken': token}, - payProUrl: null, - feePerKb: currentFeePerKb, - excludeUnconfirmedUtxos: self.currentSpendUnconfirmed ? false : true - }, function(err, txp) { - if (err) { - profileService.lockFC(); - $log.error(err); - $timeout(function() { - self.loading = null; - self.error = bwsError.msg(err, 'Error'); - }, 1); - return; - } - - if (!fc.canSign()) { - self.loading = null; - $log.info('No signing proposal: No private key'); - return; - } - - _signTx(txp, function(err, txp, rawTx) { - profileService.lockFC(); + feeService.getCurrentFeeValue(self.currentFeeLevel, function(err, feePerKb) { + if (err) $log.debug(err); + fc.sendTxProposal({ + toAddress: sellAddress, + amount: amount, + message: 'Glidera transaction', + customData: {'glideraToken': token}, + payProUrl: null, + feePerKb: feePerKb, + excludeUnconfirmedUtxos: self.currentSpendUnconfirmed ? false : true + }, function(err, txp) { if (err) { - self.loading = null; - self.error = err; - $scope.$apply(); - } - else { - var data = { - refundAddress: refundAddress, - signedTransaction: rawTx, - priceUuid: self.sellPrice.priceUuid, - useCurrentPrice: self.sellPrice.priceUuid ? false : true, - ip: null - }; - glideraService.sell(token, twoFaCode, data, function(err, data) { + profileService.lockFC(); + $log.error(err); + $timeout(function() { self.loading = null; - if (err) { - self.error = err; - fc.removeTxProposal(txp, function(err, txpb) { - $timeout(function() { - $scope.$emit('Local/GlideraError'); - }, 100); - }); - } - else { - self.success = data; - $scope.$emit('Local/GlideraTx'); - } - }); + self.error = bwsError.msg(err, 'Error'); + }, 1); + return; } + + if (!fc.canSign()) { + self.loading = null; + $log.info('No signing proposal: No private key'); + return; + } + + _signTx(txp, function(err, txp, rawTx) { + profileService.lockFC(); + if (err) { + self.loading = null; + self.error = err; + $scope.$apply(); + } + else { + var data = { + refundAddress: refundAddress, + signedTransaction: rawTx, + priceUuid: self.sellPrice.priceUuid, + useCurrentPrice: self.sellPrice.priceUuid ? false : true, + ip: null + }; + glideraService.sell(token, twoFaCode, data, function(err, data) { + self.loading = null; + if (err) { + self.error = err; + fc.removeTxProposal(txp, function(err, txpb) { + $timeout(function() { + $scope.$emit('Local/GlideraError'); + }, 100); + }); + } + else { + self.success = data; + $scope.$emit('Local/GlideraTx'); + } + }); + } + }); }); }); }); diff --git a/src/js/controllers/walletHome.js b/src/js/controllers/walletHome.js index f911b7e34..5e3b3d905 100644 --- a/src/js/controllers/walletHome.js +++ b/src/js/controllers/walletHome.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, bwsError, confirmDialog, txFormatService, animationService, addressbookService, go) { +angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, bwsError, confirmDialog, txFormatService, animationService, addressbookService, go, feeService) { var self = this; $rootScope.hideMenuBar = false; @@ -26,6 +26,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi this.showScanner = false; this.isMobile = isMobile.any(); this.addr = {}; + this.lockedCurrentFeePerKb = null; var disableScannerListener = $rootScope.$on('dataScanned', function(event, data) { self.setForm(data); @@ -826,7 +827,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi }; }; - this.submitForm = function(currentFeePerKb) { + this.submitForm = function() { var fc = profileService.focusedClient; var unitToSat = this.unitToSatoshi; var currentSpendUnconfirmed = configWallet.spendUnconfirmed; @@ -859,6 +860,14 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi return self.setSendError(gettext(msg)); } + var getFee = function(cb) { + if (self.lockedCurrentFeePerKb) { + cb(null, self.lockedCurrentFeePerKb); + } else { + feeService.getCurrentFeeValue(self.currentFeeLevel, cb); + } + }; + self.setOngoingProcess(gettext('Creating transaction')); $timeout(function() { var paypro = self._paypro; @@ -878,40 +887,43 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi return; } - fc.sendTxProposal({ - toAddress: address, - amount: amount, - message: comment, - payProUrl: paypro ? paypro.url : null, - feePerKb: currentFeePerKb, - excludeUnconfirmedUtxos: currentSpendUnconfirmed ? false : true - }, function(err, txp) { - if (err) { - self.setOngoingProcess(); - profileService.lockFC(); - return self.setSendError(err); - } - - if (!fc.canSign() && !fc.isPrivKeyExternal()) { - $log.info('No signing proposal: No private key') - self.setOngoingProcess(); - self.resetForm(); - txStatus.notify(txp, function() { - return $scope.$emit('Local/TxProposalAction'); - }); - return; - } - - self.signAndBroadcast(txp, function(err) { - self.setOngoingProcess(); - self.resetForm(); + getFee(function(err, feePerKb) { + if (err) $log.debug(err); + fc.sendTxProposal({ + toAddress: address, + amount: amount, + message: comment, + payProUrl: paypro ? paypro.url : null, + feePerKb: feePerKb, + excludeUnconfirmedUtxos: currentSpendUnconfirmed ? false : true + }, function(err, txp) { if (err) { - self.error = err.message ? err.message : gettext('The payment was created but could not be completed. Please try again from home screen'); - $scope.$emit('Local/TxProposalAction'); - $timeout(function() { - $scope.$digest(); - }, 1); - } else go.walletHome(); + self.setOngoingProcess(); + profileService.lockFC(); + return self.setSendError(err); + } + + if (!fc.canSign() && !fc.isPrivKeyExternal()) { + $log.info('No signing proposal: No private key') + self.setOngoingProcess(); + self.resetForm(); + txStatus.notify(txp, function() { + return $scope.$emit('Local/TxProposalAction'); + }); + return; + } + + self.signAndBroadcast(txp, function(err) { + self.setOngoingProcess(); + self.resetForm(); + if (err) { + self.error = err.message ? err.message : gettext('The payment was created but could not be completed. Please try again from home screen'); + $scope.$emit('Local/TxProposalAction'); + $timeout(function() { + $scope.$digest(); + }, 1); + } else go.walletHome(); + }); }); }); }); @@ -996,6 +1008,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi this.resetForm = function() { this.resetError(); this._paypro = null; + this.lockedCurrentFeePerKb = null; this.lockAddress = false; this.lockAmount = false; @@ -1257,16 +1270,19 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi this.setForm(null, amount, null); }; - this.sendAll = function(amount, feeStr) { + this.sendAll = function() { var self = this; - var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees", { - fee: feeStr - }); + $rootScope.$emit('Local/SetFeeSendMax', function(currentFeePerKb, availableMaxBalance, feeToSendMaxStr) { + self.lockedCurrentFeePerKb = currentFeePerKb; + var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees", { + fee: feeToSendMaxStr + }); - confirmDialog.show(msg, function(confirmed) { - if (confirmed) { - self._doSendAll(amount); - } + confirmDialog.show(msg, function(confirmed) { + if (confirmed) { + self._doSendAll(availableMaxBalance); + } + }); }); }; From d48711d3fb978915e82c1ca45a73da2d4f1688c4 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Wed, 23 Dec 2015 18:15:59 -0300 Subject: [PATCH 4/6] Get fee rate to sell throught Glidera --- public/views/sellGlidera.html | 2 +- src/js/controllers/sellGlidera.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/views/sellGlidera.html b/public/views/sellGlidera.html index bf948a1ef..2ea8829f4 100644 --- a/public/views/sellGlidera.html +++ b/public/views/sellGlidera.html @@ -106,7 +106,7 @@ Please, enter the code below

+ ng-submit="sell.createTx(index.glideraToken, index.glideraPermissions, twoFaCode)" novalidate> Date: Thu, 24 Dec 2015 11:08:49 -0300 Subject: [PATCH 5/6] Error getting fee --- public/views/walletHome.html | 2 +- src/js/controllers/walletHome.js | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index 79cb80367..794f5eb06 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -387,7 +387,7 @@

Send All diff --git a/src/js/controllers/walletHome.js b/src/js/controllers/walletHome.js index 5e3b3d905..c2bccb017 100644 --- a/src/js/controllers/walletHome.js +++ b/src/js/controllers/walletHome.js @@ -831,6 +831,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi var fc = profileService.focusedClient; var unitToSat = this.unitToSatoshi; var currentSpendUnconfirmed = configWallet.spendUnconfirmed; + var currentFeeLevel = walletSettings.feeLevel || 'normal'; if (isCordova && this.isWindowsPhoneApp) { this.hideAddress = false; @@ -864,7 +865,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi if (self.lockedCurrentFeePerKb) { cb(null, self.lockedCurrentFeePerKb); } else { - feeService.getCurrentFeeValue(self.currentFeeLevel, cb); + feeService.getCurrentFeeValue(currentFeeLevel, cb); } }; @@ -1272,16 +1273,27 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi this.sendAll = function() { var self = this; + self.error = null; + self.setOngoingProcess(gettext('Getting fee')); $rootScope.$emit('Local/SetFeeSendMax', function(currentFeePerKb, availableMaxBalance, feeToSendMaxStr) { + self.setOngoingProcess(); + if (lodash.isNull(currentFeePerKb)) { + self.error = gettext('Could not calculate fee'); + $scope.$apply(); + return; + } self.lockedCurrentFeePerKb = currentFeePerKb; var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees", { fee: feeToSendMaxStr }); + $scope.$apply(); confirmDialog.show(msg, function(confirmed) { if (confirmed) { self._doSendAll(availableMaxBalance); - } + } else { + self.resetForm(); + } }); }); }; From c4e9fb94a8d768dcdf7adc03f04b9029cc142b3e Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Thu, 24 Dec 2015 13:43:12 -0300 Subject: [PATCH 6/6] Adds total bytes to send confirmex max --- src/js/controllers/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 87c80f7fa..da2263648 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -614,16 +614,18 @@ angular.module('copayApp.controllers').controller('indexController', function($r // Address with Balance self.balanceByAddress = balance.byAddress; - // SAT + // Spend unconfirmed funds if (self.spendUnconfirmed) { self.totalBalanceSat = balance.totalAmount; self.lockedBalanceSat = balance.lockedAmount; self.availableBalanceSat = balance.availableAmount; + self.totalBytesToSendMax = balance.totalBytesToSendMax; self.pendingAmount = null; } else { self.totalBalanceSat = balance.totalConfirmedAmount; self.lockedBalanceSat = balance.lockedConfirmedAmount; self.availableBalanceSat = balance.availableConfirmedAmount; + self.totalBytesToSendMax = balance.totalBytesToSendConfirmedMax; self.pendingAmount = balance.totalAmount - balance.totalConfirmedAmount; } @@ -646,8 +648,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.alternativeName = config.alternativeName; self.alternativeIsoCode = config.alternativeIsoCode; - // Other - self.totalBytesToSendMax = balance.totalBytesToSendMax; + // Set fee level and max value to send all self.setCurrentFeeLevel(); // Check address