Bug/select wallet incomplete / Refactor wallet Services (#4159)
* Addressbook: display error if select an incomplete wallet * Check if wallet is complete/needs_backup for Glidera and Coinbase * Ref/create a walletService * Ref. walletService * Fix Glidera and Coinbase * Removes txService * Fix glidera connection for mobile. Fix bitcode for xcode * Fix duplicated entry * Revert "Bump bwc version 2.3.1" * adds karma-mocha * Refactor * Refactor lock function * Refactor reject, remove and broadcast tx * add walletService tests WIP * add walletService tests WIP 2 * merge * update tests to mocha * fix tests. Angular 1.5? * Fix test * Generate angular-bwc before testing * Rever gitignore * Wording
This commit is contained in:
parent
aee30ec151
commit
98471e952a
27 changed files with 698 additions and 628 deletions
|
|
@ -1,13 +1,21 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('backupController',
|
||||
function($rootScope, $scope, $timeout, $log, $state, $compile, go, lodash, profileService, gettext, bwcService, bwsError) {
|
||||
function($rootScope, $scope, $timeout, $log, $state, $compile, go, lodash, profileService, gettext, bwcService, bwsError, walletService) {
|
||||
|
||||
var self = this;
|
||||
var fc = profileService.focusedClient;
|
||||
var customWords = [];
|
||||
self.walletName = fc.credentials.walletName;
|
||||
|
||||
var handleEncryptedWallet = function(client, cb) {
|
||||
if (!walletService.isEncrypted(client)) return cb();
|
||||
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
|
||||
if (err) return cb(err);
|
||||
return cb(walletService.unlock(client, password));
|
||||
});
|
||||
};
|
||||
|
||||
function init() {
|
||||
$scope.passphrase = '';
|
||||
resetAllButtons();
|
||||
|
|
@ -46,7 +54,7 @@ angular.module('copayApp.controllers').controller('backupController',
|
|||
function initWords() {
|
||||
var words = fc.getMnemonic();
|
||||
self.xPrivKey = fc.credentials.xPrivKey;
|
||||
profileService.lockFC();
|
||||
walletService.lock(fc);
|
||||
self.mnemonicWords = words.split(/[\u3000\s]+/);
|
||||
self.shuffledMnemonicWords = lodash.sortBy(self.mnemonicWords);;
|
||||
self.mnemonicHasPassphrase = fc.mnemonicHasPassphrase();
|
||||
|
|
@ -74,7 +82,7 @@ angular.module('copayApp.controllers').controller('backupController',
|
|||
$scope.$apply();
|
||||
}, 1);
|
||||
|
||||
profileService.unlockFC({}, function(err) {
|
||||
handleEncryptedWallet(fc, function(err) {
|
||||
if (err) {
|
||||
self.error = bwsError.msg(err, gettext('Could not decrypt'));
|
||||
$log.warn('Error decrypting credentials:', self.error); //TODO
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('buyCoinbaseController',
|
||||
function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, txService, bwsError, addressService) {
|
||||
function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, addressService, walletService) {
|
||||
|
||||
window.ignoreMobilePause = true;
|
||||
var self = this;
|
||||
|
|
@ -71,17 +71,17 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController',
|
|||
};
|
||||
|
||||
$scope.selectWallet = function(walletId, walletName) {
|
||||
if (!profileService.getClient(walletId).isComplete()) {
|
||||
self.error = bwsError.msg({
|
||||
'code': 'WALLET_NOT_COMPLETE'
|
||||
}, 'Could not choose the wallet');
|
||||
self.error = {errors: [{ message: 'The Wallet could not be selected' }]};
|
||||
$modalInstance.dismiss('cancel');
|
||||
return;
|
||||
}
|
||||
$modalInstance.close({
|
||||
'walletId': walletId,
|
||||
'walletName': walletName,
|
||||
var client = profileService.getClient(walletId);
|
||||
walletService.isReady(client, function(err) {
|
||||
if (err) {
|
||||
self.error = {errors: [{ message: err }]};
|
||||
$modalInstance.dismiss('cancel');
|
||||
} else {
|
||||
$modalInstance.close({
|
||||
'walletId': walletId,
|
||||
'walletName': walletName,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('buyGlideraController',
|
||||
function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, isChromeApp, animationService) {
|
||||
function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, isChromeApp, animationService, walletService) {
|
||||
|
||||
var self = this;
|
||||
this.show2faCodeInput = null;
|
||||
|
|
@ -50,14 +50,17 @@ angular.module('copayApp.controllers').controller('buyGlideraController',
|
|||
};
|
||||
|
||||
$scope.selectWallet = function(walletId, walletName) {
|
||||
if (!profileService.getClient(walletId).isComplete()) {
|
||||
self.error = bwsError.msg({'code': 'WALLET_NOT_COMPLETE'}, 'Could not choose the wallet');
|
||||
$modalInstance.dismiss('cancel');
|
||||
return;
|
||||
}
|
||||
$modalInstance.close({
|
||||
'walletId': walletId,
|
||||
'walletName': walletName,
|
||||
var client = profileService.getClient(walletId);
|
||||
walletService.isReady(client, function(err) {
|
||||
if (err) {
|
||||
self.error = err;
|
||||
$modalInstance.dismiss('cancel');
|
||||
return;
|
||||
}
|
||||
$modalInstance.close({
|
||||
'walletId': walletId,
|
||||
'walletName': walletName,
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
@ -94,26 +97,24 @@ angular.module('copayApp.controllers').controller('buyGlideraController',
|
|||
self.gettingBuyPrice = false;
|
||||
if (err) {
|
||||
self.error = 'Could not get exchange information. Please, try again.';
|
||||
return;
|
||||
}
|
||||
else {
|
||||
self.buyPrice = buyPrice;
|
||||
}
|
||||
self.buyPrice = buyPrice;
|
||||
});
|
||||
};
|
||||
|
||||
this.get2faCode = function(token) {
|
||||
var self = this;
|
||||
this.loading = 'Sending 2FA code...';
|
||||
self.error = null;
|
||||
self.loading = 'Sending 2FA code...';
|
||||
$timeout(function() {
|
||||
glideraService.get2faCode(token, function(err, sent) {
|
||||
self.loading = null;
|
||||
if (err) {
|
||||
self.error = 'Could not send confirmation code to your phone';
|
||||
return;
|
||||
}
|
||||
else {
|
||||
self.error = null;
|
||||
self.show2faCodeInput = sent;
|
||||
}
|
||||
self.show2faCodeInput = sent;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
|
@ -139,11 +140,10 @@ angular.module('copayApp.controllers').controller('buyGlideraController',
|
|||
self.loading = null;
|
||||
if (err) {
|
||||
self.error = err;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
self.success = data;
|
||||
$scope.$emit('Local/GlideraTx');
|
||||
}
|
||||
self.success = data;
|
||||
$scope.$emit('Local/GlideraTx');
|
||||
});
|
||||
});
|
||||
}, 100);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
angular.module('copayApp.controllers').controller('glideraController',
|
||||
function($rootScope, $scope, $timeout, $modal, profileService, configService, storageService, glideraService, isChromeApp, animationService, lodash) {
|
||||
|
||||
window.ignoreMobilePause = true;
|
||||
|
||||
this.getAuthenticateUrl = function() {
|
||||
return glideraService.getOauthCodeUrl();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, latestReleaseService, bwcService, pushNotificationsService, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, coinbaseService, isMobile, addressbookService) {
|
||||
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, latestReleaseService, bwcService, pushNotificationsService, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, coinbaseService, isMobile, addressbookService, walletService) {
|
||||
var self = this;
|
||||
var SOFT_CONFIRMATION_LIMIT = 12;
|
||||
var errors = bwcService.getErrors();
|
||||
|
|
@ -161,7 +161,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
}
|
||||
}
|
||||
|
||||
profileService.isBackupNeeded(self.walletId, function(needsBackup) {
|
||||
walletService.isBackupNeeded(fc, function(needsBackup) {
|
||||
self.needsBackup = needsBackup;
|
||||
self.openWallet(function() {
|
||||
if (!self.isComplete) {
|
||||
|
|
|
|||
|
|
@ -1,37 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('preferencesController',
|
||||
function($scope, $rootScope, $timeout, $log, configService, profileService, txService) {
|
||||
function($scope, $rootScope, $timeout, $log, configService, profileService, fingerprintService, walletService) {
|
||||
|
||||
var fc = profileService.focusedClient;
|
||||
var config = configService.getSync();
|
||||
$scope.deleted = false;
|
||||
if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) {
|
||||
$scope.deleted = true;
|
||||
}
|
||||
|
||||
this.init = function() {
|
||||
var config = configService.getSync();
|
||||
var fc = profileService.focusedClient;
|
||||
if (fc) {
|
||||
$scope.encrypt = fc.hasPrivKeyEncrypted();
|
||||
$scope.encrypt = walletService.isEncrypted(fc);
|
||||
this.externalSource = fc.getPrivKeyExternalSourceName() == 'ledger' ? "Ledger" : null;
|
||||
// TODO externalAccount
|
||||
//this.externalIndex = fc.getExternalIndex();
|
||||
}
|
||||
|
||||
var walletId = fc.credentials.walletId;
|
||||
config.touchIdFor = config.touchIdFor || {};
|
||||
$scope.touchid = config.touchIdFor[walletId];
|
||||
this.touchidAvailable = fingerprintService.isAvailable();
|
||||
$scope.touchid = config.touchIdFor ? config.touchIdFor[fc.credentials.walletId] : null;
|
||||
};
|
||||
|
||||
if (window.touchidAvailable)
|
||||
this.touchidAvailable = true;
|
||||
var handleEncryptedWallet = function(client, cb) {
|
||||
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
|
||||
if (err) return cb(err);
|
||||
return cb(walletService.unlock(client, password));
|
||||
});
|
||||
};
|
||||
|
||||
var unwatchEncrypt = $scope.$watch('encrypt', function(val) {
|
||||
var fc = profileService.focusedClient;
|
||||
if (!fc) return;
|
||||
|
||||
if (val && !fc.hasPrivKeyEncrypted()) {
|
||||
if (val && !walletService.isEncrypted(fc)) {
|
||||
$rootScope.$emit('Local/NeedsPassword', true, function(err, password) {
|
||||
if (err || !password) {
|
||||
$scope.encrypt = false;
|
||||
|
|
@ -43,8 +45,8 @@ angular.module('copayApp.controllers').controller('preferencesController',
|
|||
});
|
||||
});
|
||||
} else {
|
||||
if (!val && fc.hasPrivKeyEncrypted()) {
|
||||
profileService.unlockFC({}, function(err) {
|
||||
if (!val && walletService.isEncrypted(fc)) {
|
||||
handleEncryptedWallet(fc, function(err) {
|
||||
if (err) {
|
||||
$scope.encrypt = true;
|
||||
return;
|
||||
|
|
@ -68,29 +70,29 @@ angular.module('copayApp.controllers').controller('preferencesController',
|
|||
$scope.touchidError = false;
|
||||
return;
|
||||
}
|
||||
var walletId = profileService.focusedClient.credentials.walletId;
|
||||
var walletId = fc.credentials.walletId;
|
||||
|
||||
var opts = {
|
||||
touchIdFor: {}
|
||||
};
|
||||
opts.touchIdFor[walletId] = newVal;
|
||||
|
||||
txService.setTouchId(function(err) {
|
||||
fingerprintService.check(fc, function(err) {
|
||||
if (err) {
|
||||
$log.debug(err);
|
||||
$timeout(function() {
|
||||
$scope.touchidError = true;
|
||||
$scope.touchid = oldVal;
|
||||
}, 100);
|
||||
} else {
|
||||
configService.set(opts, function(err) {
|
||||
if (err) {
|
||||
$log.debug(err);
|
||||
$scope.touchidError = true;
|
||||
$scope.touchid = oldVal;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
configService.set(opts, function(err) {
|
||||
if (err) {
|
||||
$log.debug(err);
|
||||
$scope.touchidError = true;
|
||||
$scope.touchid = oldVal;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
||||
function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, txService, bwsError) {
|
||||
function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, configService, walletService, fingerprintService) {
|
||||
|
||||
window.ignoreMobilePause = true;
|
||||
var self = this;
|
||||
|
|
@ -38,6 +38,14 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
|||
});
|
||||
};
|
||||
|
||||
var handleEncryptedWallet = function(client, cb) {
|
||||
if (!walletService.isEncrypted(client)) return cb();
|
||||
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
|
||||
if (err) return cb(err);
|
||||
return cb(walletService.unlock(client, password));
|
||||
});
|
||||
};
|
||||
|
||||
this.init = function(testnet) {
|
||||
self.otherWallets = otherWallets(testnet);
|
||||
// Choose focused wallet
|
||||
|
|
@ -179,6 +187,9 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
|||
var accountId = account.id;
|
||||
var dataSrc = { name : 'Received from Copay: ' + self.selectedWalletName };
|
||||
var outputs = [];
|
||||
var config = configService.getSync();
|
||||
var configWallet = config.wallet;
|
||||
var walletSettings = configWallet.settings;
|
||||
|
||||
|
||||
self.loading = 'Creating transaction...';
|
||||
|
|
@ -202,17 +213,18 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
|||
'amount': amount,
|
||||
'message': comment
|
||||
});
|
||||
|
||||
var opts = {
|
||||
selectedClient: fc,
|
||||
|
||||
var txp = {
|
||||
toAddress: address,
|
||||
amount: amount,
|
||||
outputs: outputs,
|
||||
message: comment,
|
||||
payProUrl: null
|
||||
payProUrl: null,
|
||||
excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true,
|
||||
feeLevel: walletSettings.feeLevel || 'normal'
|
||||
};
|
||||
|
||||
txService.createTx(opts, function(err, txp) {
|
||||
walletService.createTx(fc, txp, function(err, createdTxp) {
|
||||
if (err) {
|
||||
$log.debug(err);
|
||||
self.loading = null;
|
||||
|
|
@ -220,10 +232,10 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
|||
$scope.$apply();
|
||||
return;
|
||||
}
|
||||
$scope.$emit('Local/NeedsConfirmation', txp, function(accept) {
|
||||
$scope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
|
||||
self.loading = null;
|
||||
if (accept) {
|
||||
self.confirmTx(txp, function(err, tx) {
|
||||
self.confirmTx(createdTxp, function(err, tx) {
|
||||
if (err) {
|
||||
self.error = {errors: [{ message: 'Could not create transaction: ' + err.message }]};
|
||||
return;
|
||||
|
|
@ -266,34 +278,54 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController',
|
|||
};
|
||||
|
||||
this.confirmTx = function(txp, cb) {
|
||||
txService.prepare({selectedClient: fc}, function(err) {
|
||||
|
||||
fingerprintService.check(fc, function(err) {
|
||||
if (err) {
|
||||
$log.debug(err);
|
||||
return cb(err);
|
||||
}
|
||||
self.loading = 'Sending bitcoin to Coinbase...';
|
||||
txService.publishTx(txp, {selectedClient: fc}, function(err, txpPublished) {
|
||||
|
||||
handleEncryptedWallet(fc, function(err) {
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
$log.debug(err);
|
||||
return cb({errors: [{ message: 'Transaction could not be published: ' + err.message }]});
|
||||
} else {
|
||||
txService.signAndBroadcast(txpPublished, {selectedClient: fc}, function(err, txp) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
self.loading = 'Sending bitcoin to Coinbase...';
|
||||
walletService.publishTx(fc, txp, function(err, publishedTxp) {
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
$log.debug(err);
|
||||
return cb({errors: [{ message: 'Transaction could not be published: ' + err.message }]});
|
||||
}
|
||||
|
||||
walletService.signTx(fc, publishedTxp, function(err, signedTxp) {
|
||||
walletService.lock(fc);
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
$log.debug(err);
|
||||
txService.removeTx(txp, function(err) {
|
||||
walletService.removeTx(fc, signedTxp, function(err) {
|
||||
if (err) $log.debug(err);
|
||||
});
|
||||
return cb({errors: [{ message: 'The payment was created but could not be completed: ' + err.message }]});
|
||||
} else {
|
||||
}
|
||||
|
||||
walletService.broadcastTx(fc, signedTxp, function(err, broadcastedTxp) {
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
$log.debug(err);
|
||||
walletService.removeTx(fc, broadcastedTxp, function(err) {
|
||||
if (err) $log.debug(err);
|
||||
});
|
||||
return cb({errors: [{ message: 'The payment was created but could not be broadcasted: ' + err.message }]});
|
||||
}
|
||||
$timeout(function() {
|
||||
self.loading = null;
|
||||
return cb(null, txp);
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('sellGlideraController',
|
||||
function($scope, $timeout, $log, $modal, configService, profileService, addressService, feeService, glideraService, bwsError, lodash, isChromeApp, animationService, txService) {
|
||||
function($rootScope, $scope, $timeout, $log, $modal, configService, profileService, addressService, feeService, glideraService, bwsError, lodash, isChromeApp, animationService, walletService, fingerprintService) {
|
||||
|
||||
var self = this;
|
||||
var config = configService.getSync();
|
||||
|
|
@ -10,7 +10,6 @@ angular.module('copayApp.controllers').controller('sellGlideraController',
|
|||
this.success = null;
|
||||
this.error = null;
|
||||
this.loading = null;
|
||||
this.currentSpendUnconfirmed = config.wallet.spendUnconfirmed;
|
||||
var fc;
|
||||
|
||||
window.ignoreMobilePause = true;
|
||||
|
|
@ -22,6 +21,14 @@ angular.module('copayApp.controllers').controller('sellGlideraController',
|
|||
});
|
||||
};
|
||||
|
||||
var handleEncryptedWallet = function(client, cb) {
|
||||
if (!walletService.isEncrypted(client)) return cb();
|
||||
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
|
||||
if (err) return cb(err);
|
||||
return cb(walletService.unlock(client, password));
|
||||
});
|
||||
};
|
||||
|
||||
this.init = function(testnet) {
|
||||
self.otherWallets = otherWallets(testnet);
|
||||
// Choose focused wallet
|
||||
|
|
@ -92,20 +99,19 @@ angular.module('copayApp.controllers').controller('sellGlideraController',
|
|||
|
||||
this.getSellPrice = function(token, price) {
|
||||
var self = this;
|
||||
this.error = null;
|
||||
self.error = null;
|
||||
if (!price || (price && !price.qty && !price.fiat)) {
|
||||
this.sellPrice = null;
|
||||
self.sellPrice = null;
|
||||
return;
|
||||
}
|
||||
this.gettingSellPrice = true;
|
||||
self.gettingSellPrice = true;
|
||||
glideraService.sellPrice(token, price, function(err, sellPrice) {
|
||||
self.gettingSellPrice = false;
|
||||
if (err) {
|
||||
self.error = 'Could not get exchange information. Please, try again.';
|
||||
} else {
|
||||
self.error = null;
|
||||
self.sellPrice = sellPrice;
|
||||
return;
|
||||
}
|
||||
self.sellPrice = sellPrice;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -127,87 +133,112 @@ angular.module('copayApp.controllers').controller('sellGlideraController',
|
|||
this.createTx = function(token, permissions, twoFaCode) {
|
||||
var self = this;
|
||||
self.error = null;
|
||||
|
||||
|
||||
txService.prepare({selectedClient: fc}, function(err) {
|
||||
if (err) {
|
||||
self.error = err;
|
||||
var outputs = [];
|
||||
var configWallet = config.wallet;
|
||||
var walletSettings = configWallet.settings;
|
||||
|
||||
addressService.getAddress(fc.credentials.walletId, null, function(err, refundAddress) {
|
||||
if (!refundAddress) {
|
||||
self.loading = null;
|
||||
self.error = bwsError.msg(err, 'Could not create address');
|
||||
return;
|
||||
}
|
||||
self.loading = 'Selling Bitcoin...';
|
||||
$timeout(function() {
|
||||
addressService.getAddress(fc.credentials.walletId, null, function(err, refundAddress) {
|
||||
if (!refundAddress) {
|
||||
self.loading = null;
|
||||
self.error = bwsError.msg(err, 'Could not create address');
|
||||
glideraService.getSellAddress(token, function(error, sellAddress) {
|
||||
if (!sellAddress) {
|
||||
self.loading = null;
|
||||
self.error = 'Could not get the destination bitcoin address';
|
||||
return;
|
||||
}
|
||||
var amount = parseInt((self.sellPrice.qty * 100000000).toFixed(0));
|
||||
var comment = 'Glidera transaction';
|
||||
|
||||
outputs.push({
|
||||
'toAddress': sellAddress,
|
||||
'amount': amount,
|
||||
'message': comment
|
||||
});
|
||||
|
||||
var txp = {
|
||||
toAddress: sellAddress,
|
||||
amount: amount,
|
||||
outputs: outputs,
|
||||
message: comment,
|
||||
payProUrl: null,
|
||||
excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true,
|
||||
feeLevel: walletSettings.feeLevel || 'normal',
|
||||
customData: {
|
||||
'glideraToken': token
|
||||
}
|
||||
};
|
||||
|
||||
self.loading = 'Creating transaction...';
|
||||
walletService.createTx(fc, txp, function(err, createdTxp) {
|
||||
self.loading = null;
|
||||
if (err) {
|
||||
self.error = err.message || bwsError.msg(err);
|
||||
return;
|
||||
}
|
||||
glideraService.getSellAddress(token, function(error, sellAddress) {
|
||||
if (!sellAddress) {
|
||||
self.loading = null;
|
||||
self.error = 'Could not get the destination bitcoin address';
|
||||
return;
|
||||
}
|
||||
var amount = parseInt((self.sellPrice.qty * 100000000).toFixed(0));
|
||||
|
||||
feeService.getCurrentFeeValue(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) {
|
||||
$scope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
|
||||
if (accept) {
|
||||
fingerprintService.check(fc, function(err) {
|
||||
if (err) {
|
||||
profileService.lockFC();
|
||||
$log.error(err);
|
||||
$timeout(function() {
|
||||
self.loading = null;
|
||||
self.error = bwsError.msg(err, 'Error');
|
||||
}, 1);
|
||||
self.error = err.message || bwsError.msg(err);
|
||||
return;
|
||||
}
|
||||
|
||||
txService.sign(txp, {selectedClient: fc}, function(err, txp) {
|
||||
handleEncryptedWallet(fc, function(err) {
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
self.error = err;
|
||||
$scope.$apply();
|
||||
} else {
|
||||
var rawTx = txp.raw;
|
||||
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.error = err.message || bwsError.msg(err);
|
||||
return;
|
||||
}
|
||||
|
||||
self.loading = 'Signing transaction...';
|
||||
|
||||
walletService.publishTx(fc, createdTxp, function(err, publishedTxp) {
|
||||
if (err) {
|
||||
self.loading = null;
|
||||
self.error = err.message || bwsError.msg(err);
|
||||
}
|
||||
|
||||
walletService.signTx(fc, publishedTxp, function(err, signedTxp) {
|
||||
walletService.lock(fc);
|
||||
walletService.removeTx(fc, signedTxp, function(err) {
|
||||
if (err) $log.debug(err);
|
||||
});
|
||||
if (err) {
|
||||
self.error = err;
|
||||
fc.removeTxProposal(txp, function(err, txp) {
|
||||
self.loading = null;
|
||||
self.error = err.message || bwsError.msg(err);
|
||||
return;
|
||||
}
|
||||
var rawTx = signedTxp.raw;
|
||||
var data = {
|
||||
refundAddress: refundAddress,
|
||||
signedTransaction: rawTx,
|
||||
priceUuid: self.sellPrice.priceUuid,
|
||||
useCurrentPrice: self.sellPrice.priceUuid ? false : true,
|
||||
ip: null
|
||||
};
|
||||
self.loading = 'Selling bitcoin...';
|
||||
glideraService.sell(token, twoFaCode, data, function(err, data) {
|
||||
self.loading = null;
|
||||
if (err) {
|
||||
self.error = err.message || bwsError.msg(err);
|
||||
$timeout(function() {
|
||||
$scope.$emit('Local/GlideraError');
|
||||
}, 100);
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
self.success = data;
|
||||
$scope.$emit('Local/GlideraTx');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $interval, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, isMobile, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, bwsError, confirmDialog, txFormatService, animationService, addressbookService, go, feeService, txService) {
|
||||
angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $interval, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, isMobile, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, bwsError, confirmDialog, txFormatService, animationService, addressbookService, go, feeService, walletService, fingerprintService) {
|
||||
|
||||
var self = this;
|
||||
window.ignoreMobilePause = false;
|
||||
|
|
@ -127,6 +127,14 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
});
|
||||
};
|
||||
|
||||
var handleEncryptedWallet = function(client, cb) {
|
||||
if (!walletService.isEncrypted(client)) return cb();
|
||||
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
|
||||
if (err) return cb(err);
|
||||
return cb(walletService.unlock(client, password));
|
||||
});
|
||||
};
|
||||
|
||||
var accept_msg = gettextCatalog.getString('Accept');
|
||||
var cancel_msg = gettextCatalog.getString('Cancel');
|
||||
var confirm_msg = gettextCatalog.getString('Confirm');
|
||||
|
|
@ -251,28 +259,30 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
};
|
||||
|
||||
$scope.selectWallet = function(walletId, walletName) {
|
||||
profileService.isBackupNeeded(walletId, function(needsBackup) {
|
||||
$scope.needsBackup = {};
|
||||
$scope.needsBackup[walletId] = needsBackup;
|
||||
if (needsBackup) return;
|
||||
var client = profileService.getClient(walletId);
|
||||
$scope.errorSelectedWallet = {};
|
||||
|
||||
$scope.gettingAddress = true;
|
||||
$scope.selectedWalletName = walletName;
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
});
|
||||
walletService.isReady(client, function(err) {
|
||||
if (err) $scope.errorSelectedWallet[walletId] = err;
|
||||
else {
|
||||
$scope.gettingAddress = true;
|
||||
$scope.selectedWalletName = walletName;
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
addressService.getAddress(walletId, false, function(err, addr) {
|
||||
$scope.gettingAddress = false;
|
||||
addressService.getAddress(walletId, false, function(err, addr) {
|
||||
$scope.gettingAddress = false;
|
||||
|
||||
if (err) {
|
||||
self.error = err;
|
||||
$modalInstance.dismiss('cancel');
|
||||
return;
|
||||
}
|
||||
if (err) {
|
||||
self.error = err;
|
||||
$modalInstance.dismiss('cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
$modalInstance.close(addr);
|
||||
});
|
||||
$modalInstance.close(addr);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
@ -413,36 +423,60 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
};
|
||||
|
||||
$scope.sign = function(txp) {
|
||||
var fc = profileService.focusedClient;
|
||||
var client = profileService.focusedClient;
|
||||
$scope.error = null;
|
||||
$scope.loading = true;
|
||||
|
||||
txService.prepareAndSignAndBroadcast(txp, {
|
||||
reporterFn: self.setOngoingProcess.bind(self)
|
||||
}, function(err, txp) {
|
||||
$scope.loading = false;
|
||||
$scope.$emit('UpdateTx');
|
||||
|
||||
|
||||
fingerprintService.check(client, function(err) {
|
||||
if (err) {
|
||||
$scope.loading = false;
|
||||
$scope.error = err;
|
||||
$timeout(function() {
|
||||
$scope.$digest();
|
||||
});
|
||||
return;
|
||||
}
|
||||
$modalInstance.close(txp);
|
||||
return;
|
||||
|
||||
handleEncryptedWallet(client, function(err) {
|
||||
if (err) {
|
||||
$scope.loading = false;
|
||||
$scope.error = err;
|
||||
return;
|
||||
}
|
||||
|
||||
walletService.signTx(client, txp, function(err, signedTxp) {
|
||||
walletService.lock(client);
|
||||
if (err) {
|
||||
$scope.loading = false;
|
||||
$scope.error = err;
|
||||
return;
|
||||
}
|
||||
|
||||
if (signedTxp.status == 'accepted') {
|
||||
walletService.broadcastTx(client, signedTxp, function(err, broadcastedTxp) {
|
||||
$scope.loading = false;
|
||||
$scope.$emit('UpdateTx');
|
||||
$modalInstance.close(broadcastedTxp);
|
||||
if (err) {
|
||||
$scope.loading = false;
|
||||
$scope.error = err;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$scope.loading = false;
|
||||
$scope.$emit('UpdateTx');
|
||||
$modalInstance.close(signedTxp);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.reject = function(txp) {
|
||||
var client = profileService.focusedClient;
|
||||
self.setOngoingProcess(gettextCatalog.getString('Rejecting payment'));
|
||||
$scope.loading = true;
|
||||
$scope.error = null;
|
||||
|
||||
// TODO: This should be in txService
|
||||
$timeout(function() {
|
||||
fc.rejectTxProposal(txp, null, function(err, txpr) {
|
||||
walletService.rejectTx(client, txp, function(err, txpr) {
|
||||
self.setOngoingProcess();
|
||||
$scope.loading = false;
|
||||
if (err) {
|
||||
|
|
@ -458,11 +492,12 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
|
||||
|
||||
$scope.remove = function(txp) {
|
||||
var client = profileService.focusedClient;
|
||||
self.setOngoingProcess(gettextCatalog.getString('Deleting payment'));
|
||||
$scope.loading = true;
|
||||
$scope.error = null;
|
||||
$timeout(function() {
|
||||
fc.removeTxProposal(txp, function(err, txpb) {
|
||||
walletService.removeTx(client, txp, function(err) {
|
||||
self.setOngoingProcess();
|
||||
$scope.loading = false;
|
||||
|
||||
|
|
@ -479,23 +514,20 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
};
|
||||
|
||||
$scope.broadcast = function(txp) {
|
||||
var client = profileService.focusedClient;
|
||||
self.setOngoingProcess(gettextCatalog.getString('Broadcasting Payment'));
|
||||
$scope.loading = true;
|
||||
$scope.error = null;
|
||||
$timeout(function() {
|
||||
fc.broadcastTxProposal(txp, function(err, txpb, memo) {
|
||||
walletService.broadcastTx(client, txp, function(err, txpb) {
|
||||
self.setOngoingProcess();
|
||||
$scope.loading = false;
|
||||
if (err) {
|
||||
$scope.error = bwsError.msg(err, gettextCatalog.getString('Could not broadcast payment'));
|
||||
$scope.$digest();
|
||||
} else {
|
||||
|
||||
if (memo)
|
||||
$log.info(memo);
|
||||
|
||||
$modalInstance.close(txpb);
|
||||
return;
|
||||
}
|
||||
$modalInstance.close(txpb);
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
|
@ -876,7 +908,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
|
||||
this.submitForm = function() {
|
||||
if (!$scope._amount || !$scope._address) return;
|
||||
var fc = profileService.focusedClient;
|
||||
var client = profileService.focusedClient;
|
||||
var unitToSat = this.unitToSatoshi;
|
||||
var currentSpendUnconfirmed = configWallet.spendUnconfirmed;
|
||||
|
||||
|
|
@ -893,7 +925,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
var comment = form.comment.$modelValue;
|
||||
|
||||
// ToDo: use a credential's (or fc's) function for this
|
||||
if (comment && !fc.credentials.sharedEncryptingKey) {
|
||||
if (comment && !client.credentials.sharedEncryptingKey) {
|
||||
var msg = 'Could not add message to imported wallet without shared encrypting key';
|
||||
$log.warn(msg);
|
||||
return self.setSendError(gettext(msg));
|
||||
|
|
@ -912,90 +944,100 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
'message': comment
|
||||
});
|
||||
|
||||
var opts = {};
|
||||
var txp = {};
|
||||
|
||||
if (!lodash.isEmpty(self.sendMaxInfo)) {
|
||||
opts.sendMax = true;
|
||||
opts.inputs = self.sendMaxInfo.inputs;
|
||||
opts.fee = self.sendMaxInfo.fee;
|
||||
txp.sendMax = true;
|
||||
txp.inputs = self.sendMaxInfo.inputs;
|
||||
txp.fee = self.sendMaxInfo.fee;
|
||||
}else {
|
||||
opts.amount = amount;
|
||||
txp.amount = amount;
|
||||
}
|
||||
|
||||
opts.toAddress = address;
|
||||
opts.outputs = outputs;
|
||||
opts.message = comment;
|
||||
opts.payProUrl = paypro ? paypro.url : null;
|
||||
opts.lockedCurrentFeePerKb = self.lockedCurrentFeePerKb;
|
||||
txp.toAddress = address;
|
||||
txp.outputs = outputs;
|
||||
txp.message = comment;
|
||||
txp.payProUrl = paypro ? paypro.url : null;
|
||||
txp.excludeUnconfirmedUtxos = configWallet.spendUnconfirmed ? false : true;
|
||||
txp.feeLevel = walletSettings.feeLevel || 'normal';
|
||||
|
||||
self.setOngoingProcess(gettextCatalog.getString('Creating transaction'));
|
||||
txService.createTx(opts, function(err, txp) {
|
||||
walletService.createTx(client, txp, function(err, createdTxp) {
|
||||
self.setOngoingProcess();
|
||||
if (err) {
|
||||
return self.setSendError(err);
|
||||
}
|
||||
|
||||
if (!fc.canSign() && !fc.isPrivKeyExternal()) {
|
||||
self.setOngoingProcess();
|
||||
if (!client.canSign() && !client.isPrivKeyExternal()) {
|
||||
$log.info('No signing proposal: No private key');
|
||||
self.resetForm();
|
||||
txStatus.notify(txp, function() {
|
||||
txStatus.notify(createdTxp, function() {
|
||||
return $scope.$emit('Local/TxProposalAction');
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
$rootScope.$emit('Local/NeedsConfirmation', txp, function(accept) {
|
||||
if (accept) self.confirmTx(txp);
|
||||
$rootScope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
|
||||
if (accept) self.confirmTx(createdTxp);
|
||||
else self.resetForm();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}, 100);
|
||||
};
|
||||
};
|
||||
|
||||
this.confirmTx = function(txp) {
|
||||
var client = profileService.focusedClient;
|
||||
var self = this;
|
||||
|
||||
$log.info('at .confirmTx');
|
||||
txService.prepare({}, function(err) {
|
||||
$log.info('after .prepare:', err);
|
||||
fingerprintService.check(client, function(err) {
|
||||
if (err) {
|
||||
self.setOngoingProcess();
|
||||
$log.warn('confirmTx/Prepare error:', err);
|
||||
return self.setSendError(err);
|
||||
}
|
||||
self.setOngoingProcess(gettextCatalog.getString('Sending transaction'));
|
||||
txService.publishTx(txp, {}, function(err, txpPublished) {
|
||||
|
||||
$log.info('after .publishTx:', err);
|
||||
|
||||
handleEncryptedWallet(client, function(err) {
|
||||
if (err) {
|
||||
self.setOngoingProcess();
|
||||
self.setSendError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
txService.signAndBroadcast(txpPublished, {
|
||||
reporterFn: self.setOngoingProcess.bind(self)
|
||||
}, function(err, txp) {
|
||||
$log.info('after .signAndBroadcast:', err);
|
||||
self.resetForm();
|
||||
self.setOngoingProcess();
|
||||
return self.setSendError(err);
|
||||
}
|
||||
|
||||
self.setOngoingProcess(gettextCatalog.getString('Sending transaction'));
|
||||
walletService.publishTx(client, txp, function(err, publishedTxp) {
|
||||
if (err) {
|
||||
self.error = bwsError.msg(err, gettextCatalog.getString('The payment was created but could not be completed. Please try again from home screen'));
|
||||
$scope.$emit('Local/TxProposalAction');
|
||||
$timeout(function() {
|
||||
$scope.$digest();
|
||||
}, 1);
|
||||
return;
|
||||
}
|
||||
self.setOngoingProcess();
|
||||
return self.setSendError(err);
|
||||
}
|
||||
|
||||
$log.info('Transaction status:', txp.status);
|
||||
go.walletHome();
|
||||
txStatus.notify(txp, function() {
|
||||
$scope.$emit('Local/TxProposalAction', txp.status == 'broadcasted');
|
||||
self.setOngoingProcess(gettextCatalog.getString('Signing transaction'));
|
||||
walletService.signTx(client, publishedTxp, function(err, signedTxp) {
|
||||
self.setOngoingProcess();
|
||||
walletService.lock(client);
|
||||
if (err) {
|
||||
$scope.$emit('Local/TxProposalAction');
|
||||
return self.setSendError(
|
||||
err.message ?
|
||||
err.message :
|
||||
gettext('The payment was created but could not be completed. Please try again from home screen'));
|
||||
}
|
||||
|
||||
if (signedTxp.status == 'accepted') {
|
||||
self.setOngoingProcess(gettextCatalog.getString('Broadcasting transaction'));
|
||||
walletService.broadcastTx(client, signedTxp, function(err, broadcastedTxp) {
|
||||
self.setOngoingProcess();
|
||||
if (err) {
|
||||
return self.setSendError(err);
|
||||
}
|
||||
self.resetForm();
|
||||
go.walletHome();
|
||||
txStatus.notify(broadcastedTxp, function() {
|
||||
$scope.$emit('Local/TxProposalAction', broadcastedTxp.status == 'broadcasted');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
self.resetForm();
|
||||
go.walletHome();
|
||||
txStatus.notify(signedTxp, function() {
|
||||
$scope.$emit('Local/TxProposalAction');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1030,7 +1072,6 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
this.sendMaxInfo = {};
|
||||
if (this.countDown) $interval.cancel(this.countDown);
|
||||
this._paypro = null;
|
||||
this.lockedCurrentFeePerKb = null;
|
||||
|
||||
this.lockAddress = false;
|
||||
this.lockAmount = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue