diff --git a/public/views/includes/confirm-tx.html b/public/views/includes/confirm-tx.html
index 8dc2268b2..98b507b19 100644
--- a/public/views/includes/confirm-tx.html
+++ b/public/views/includes/confirm-tx.html
@@ -1,42 +1,40 @@
+
-
-
+
-
-
-
-
+ Confirm transaction
- --
-
- - Amount - {{home.confirmTxPopup.amountStr}} - {{home.confirmTxPopup.alternativeAmountStr}} - - -
- - Fee - {{home.confirmTxPopup.feeStr}} - -
+
- Confirm transaction
-
-
+
+
diff --git a/public/views/includes/password.html b/public/views/includes/password.html
index 6df98bbce..3866c86f4 100644
--- a/public/views/includes/password.html
+++ b/public/views/includes/password.html
@@ -1,5 +1,5 @@
-{{tx.amountStr}}
+ {{tx.alternativeAmountStr}}
+
+
+
+
+
+ Multiple recipients
+
-
-
+
+ Fee: {{tx.feeStr}}
+
+
+
+
+
+
+
+
+
-
+
{{error|translate}}
-
- The payment was removed by creator
+
+
-
+ The payment was removed by creator
+
+
-
-
diff --git a/src/css/main.css b/src/css/main.css
index c3ee54f83..ea456aad2 100644
--- a/src/css/main.css
+++ b/src/css/main.css
@@ -1373,9 +1373,30 @@ input.ng-invalid-match, input.ng-invalid-match:focus {
}
}
+/* Confirmation popup */
+
+.confirmTxModal {
+ background: white;
+ border-radius: 5px;
+ position: absolute;
+ width: 90%;
+ left: 0;
+ right: 0;
+ margin: 15% auto;
+ z-index: 1100;
+ text-align: center;
+}
+
+.confirmHead {
+ padding: 10px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+/*******************/
+
.alertModal {
background: #FFFFFF;
- box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.50);
border-radius: 5px;
position: absolute;
width: 90%;
@@ -1386,7 +1407,6 @@ input.ng-invalid-match, input.ng-invalid-match:focus {
.passModal {
background: #FFFFFF;
- box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.50);
border-radius: 5px;
position: absolute;
width: 90%;
@@ -1395,12 +1415,12 @@ input.ng-invalid-match, input.ng-invalid-match:focus {
z-index: 1100;
}
-.passModalMask {
+.modalMask {
position: absolute;
width: 100%;
height: 100%;
z-index: 1099;
- opacity:0.3;
+ opacity:0.8;
background: black;
}
diff --git a/src/js/controllers/confirmTx.js b/src/js/controllers/confirmTx.js
new file mode 100644
index 000000000..05dfa8b02
--- /dev/null
+++ b/src/js/controllers/confirmTx.js
@@ -0,0 +1,13 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('confirmTxController', function() {
+
+ this.close = function(cb) {
+ return cb();
+ };
+
+ this.accept = function(cb) {
+ return cb(true);
+ };
+
+});
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js
index 928c830e9..2df9bb817 100644
--- a/src/js/controllers/index.js
+++ b/src/js/controllers/index.js
@@ -391,7 +391,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.setFeeAndSendMax = function(cb) {
- self.feeToSendMaxStr = null;
self.availableMaxBalance = null;
self.currentFeePerKb = null;
@@ -1453,6 +1452,19 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.setTab(tab, reset);
});
+ $rootScope.$on('Local/NeedConfirmation', function(event, txp, cb) {
+ self.confirmTx = {
+ txp : txFormatService.processTx(txp),
+ callback: function(accept) {
+ self.confirmTx = null;
+ return cb(accept);
+ }
+ };
+ $timeout(function() {
+ $rootScope.$apply();
+ });
+ });
+
$rootScope.$on('Local/NeedsPassword', function(event, isSetup, cb) {
self.askPassword = {
isSetup: isSetup,
diff --git a/src/js/controllers/walletHome.js b/src/js/controllers/walletHome.js
index 737849652..688f4566a 100644
--- a/src/js/controllers/walletHome.js
+++ b/src/js/controllers/walletHome.js
@@ -771,6 +771,8 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
var currentSpendUnconfirmed = configWallet.spendUnconfirmed;
var currentFeeLevel = walletSettings.feeLevel || 'normal';
+ var outputs = [];
+
this.resetError();
if (isCordova && this.isWindowsPhoneApp) {
@@ -793,14 +795,6 @@ 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(currentFeeLevel, cb);
- }
- };
-
$timeout(function() {
var paypro = self._paypro;
var address, amount;
@@ -808,57 +802,88 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
address = form.address.$modelValue;
amount = parseInt((form.amount.$modelValue * unitToSat).toFixed(0));
+ outputs.push({
+ 'toAddress' : address,
+ 'amount': amount,
+ 'message': comment
+ });
+
txSignService.prepare(function(err) {
if (err) {
return self.setSendError(err);
}
+
+ var opts = {
+ toAddress: address,
+ amount: amount,
+ outputs: outputs,
+ message: comment,
+ payProUrl: paypro ? paypro.url : null,
+ lockedCurrentFeePerKb: self.lockedCurrentFeePerKb
+ };
+
self.setOngoingProcess(gettextCatalog.getString('Creating transaction'));
- 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.setOngoingProcess();
- return self.setSendError(err);
- }
+ txSignService.createTx(opts, function(err, txp) {
+ self.setOngoingProcess();
+ if (err) {
+ return self.setSendError(err);
+ }
- if (!fc.canSign() && !fc.isPrivKeyExternal()) {
- self.setOngoingProcess();
- $log.info('No signing proposal: No private key')
- self.resetForm();
- txStatus.notify(txp, function() {
- return $scope.$emit('Local/TxProposalAction');
- });
- return;
- }
-
- txSignService.signAndBroadcast(txp, {
- reporterFn: self.setOngoingProcess.bind(self)
- }, function(err, txp) {
- 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();
- txStatus.notify(txp, function() {
- $scope.$emit('Local/TxProposalAction', txp.status == 'broadcasted');
- });
- };
+ if (!fc.canSign() && !fc.isPrivKeyExternal()) {
+ self.setOngoingProcess();
+ $log.info('No signing proposal: No private key');
+ self.resetForm();
+ txStatus.notify(txp, function() {
+ return $scope.$emit('Local/TxProposalAction');
});
- });
+ return;
+ } else {
+ $rootScope.$emit('Local/NeedConfirmation', txp, function(accept) {
+ if (accept) self.acceptTx(txp);
+ else self.resetForm();
+ });
+ }
});
+
});
}, 100);
+ };
+
+ this.acceptTx = function(txp) {
+ var self = this;
+ this.confirmTxPopup = null;
+ this.setOngoingProcess(gettextCatalog.getString('Sending transaction'));
+ txSignService.publishTx(txp.id, function(err) {
+ self.setOngoingProcess();
+ if (err) {
+ $log.debug(err);
+ self.setSendError(err);
+ } else {
+ self.resetForm();
+ // self.signAndBroadcastTx(txp);
+ }
+ });
+ };
+
+ this.signAndBroadcastTx = function() {
+ var self = this;
+ txSignService.signAndBroadcast(txp, {
+ reporterFn: self.setOngoingProcess.bind(self)
+ }, function(err, txp) {
+ 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();
+ txStatus.notify(txp, function() {
+ $scope.$emit('Local/TxProposalAction', txp.status == 'broadcasted');
+ });
+ };
+ });
};
this.setForm = function(to, amount, comment) {
diff --git a/src/js/services/txFormatService.js b/src/js/services/txFormatService.js
index 71bd41825..ede78468c 100644
--- a/src/js/services/txFormatService.js
+++ b/src/js/services/txFormatService.js
@@ -30,6 +30,7 @@ angular.module('copayApp.services').factory('txFormatService', function(profileS
tx.hasMultiplesOutputs = true;
tx.recipientCount = outputs;
}
+ tx.toAddress = tx.outputs[0].toAddress;
tx.amount = lodash.reduce(tx.outputs, function(total, o) {
o.amountStr = formatAmountStr(o.amount);
o.alternativeAmountStr = formatAlternativeStr(o.amount);
diff --git a/src/js/services/txSignService.js b/src/js/services/txSignService.js
index e32f79920..daf9e0ca1 100644
--- a/src/js/services/txSignService.js
+++ b/src/js/services/txSignService.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.services').factory('txSignService', function($rootScope, profileService, gettextCatalog, lodash, trezor, ledger, configService, bwsError, $log) {
+angular.module('copayApp.services').factory('txSignService', function($rootScope, profileService, gettextCatalog, lodash, trezor, ledger, configService, bwsError, $log, feeService) {
var root = {};
var reportSigningStatus = function(opts) {
@@ -85,8 +85,43 @@ angular.module('copayApp.services').factory('txSignService', function($rootScope
};
return cb();
+
});
});
+ };
+
+ root.createTx = function(opts, cb) {
+ var fc = profileService.focusedClient;
+ var config = configService.getSync();
+ var configWallet = config.wallet;
+ var walletSettings = configWallet.settings;
+
+ var currentSpendUnconfirmed = configWallet.spendUnconfirmed;
+ var currentFeeLevel = walletSettings.feeLevel || 'normal';
+
+ var getFee = function(cb) {
+ if (opts.lockedCurrentFeePerKb) {
+ cb(null, opts.lockedCurrentFeePerKb);
+ } else {
+ feeService.getCurrentFeeValue(currentFeeLevel, cb);
+ }
+ };
+
+ getFee(function(err, feePerKb) {
+ if (err) $log.debug(err);
+ fc.createTxProposal(opts, function(err, txp) {
+ if (err) return cb(err);
+ else return cb(null, txp);
+ });
+ });
+ };
+
+ root.publishTx = function(txId, cb) {
+ var fc = profileService.focusedClient;
+ fc.publishTxProposal(txId, function(err) {
+ if (err) return cb(err);
+ else return cb();
+ });
};
var _signWithLedger = function(txp, cb) {