diff --git a/src/js/controllers/export.js b/src/js/controllers/export.js index a5a90766b..27ebf6705 100644 --- a/src/js/controllers/export.js +++ b/src/js/controllers/export.js @@ -15,6 +15,53 @@ angular.module('copayApp.controllers').controller('exportController', }); }; + function prepareWallet(cb) { + if ($scope.password) return cb(null, $scope.password); + + walletService.prepare(wallet, function(err, password) { + if (err) return cb(err); + $scope.password = password; + + walletService.getEncodedWalletInfo(wallet, $scope.password, function(err, code) { + if (err) return cb(err); + + if (!code) + $scope.formData.supported = false; + else { + $scope.formData.supported = true; + $scope.formData.exportWalletInfo = code; + } + + return cb(null, password); + }); + }); + }; + + $scope.generateQrCode = function() { + if ($scope.formData.exportWalletInfo) { + $scope.file.value = false; + $timeout(function() { + $scope.$apply(); + }); + return; + } + + prepareWallet(function(err, password) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err); + return; + } + if (!password) return; + + $scope.file.value = false; + $scope.password = password; + + $timeout(function() { + $scope.$apply(); + }); + }); + }; + var init = function() { $scope.formData = {}; $scope.isEncrypted = wallet.isPrivKeyEncrypted(); @@ -24,24 +71,6 @@ angular.module('copayApp.controllers').controller('exportController', $scope.showAdvanced = false; $scope.wallet = wallet; $scope.canSign = wallet.canSign(); - - walletService.getEncodedWalletInfo(wallet, function(err, code) { - if (err || !code) { - $log.warn(err); - return $ionicHistory.goBack(); - } - - if (!code) - $scope.formData.supported = false; - else { - $scope.formData.supported = true; - $scope.formData.exportWalletInfo = code; - } - - $timeout(function() { - $scope.$apply(); - }, 1); - }); }; /* @@ -67,23 +96,32 @@ angular.module('copayApp.controllers').controller('exportController', }; $scope.downloadWalletBackup = function() { - $scope.getAddressbook(function(err, localAddressBook) { + prepareWallet(function(err, password) { if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); + popupService.showAlert(gettextCatalog.getString('Error'), err); return; } - var opts = { - noSign: $scope.formData.noSignEnabled, - addressBook: localAddressBook - }; + if (!password) return; - backupService.walletDownload($scope.formData.password, opts, function(err) { + $scope.getAddressbook(function(err, localAddressBook) { if (err) { popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); return; } - $ionicHistory.removeBackView(); - $state.go('tabs.home'); + var opts = { + noSign: $scope.formData.noSignEnabled, + addressBook: localAddressBook, + password: password + }; + + backupService.walletDownload($scope.formData.password, opts, function(err) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); + return; + } + $ionicHistory.removeBackView(); + $state.go('tabs.home'); + }); }); }); }; @@ -104,21 +142,30 @@ angular.module('copayApp.controllers').controller('exportController', }; $scope.getBackup = function(cb) { - $scope.getAddressbook(function(err, localAddressBook) { + prepareWallet(function(err, password) { if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); - return cb(null); + popupService.showAlert(gettextCatalog.getString('Error'), err); + return; } - var opts = { - noSign: $scope.formData.noSignEnabled, - addressBook: localAddressBook - }; + if (!password) return; - var ew = backupService.walletExport($scope.formData.password, opts); - if (!ew) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); - } - return cb(ew); + $scope.getAddressbook(function(err, localAddressBook) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); + return cb(null); + } + var opts = { + noSign: $scope.formData.noSignEnabled, + addressBook: localAddressBook, + password: password + }; + + var ew = backupService.walletExport($scope.formData.password, opts); + if (!ew) { + popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); + } + return cb(ew); + }); }); }; @@ -171,6 +218,11 @@ angular.module('copayApp.controllers').controller('exportController', $scope.$on("$ionicView.beforeEnter", function(event, data) { init(); + $scope.file = { + value: true + }; + $scope.formData.exportWalletInfo = null; + $scope.password = null; }); }); diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js index 60c1a4c2d..9c30fda2e 100644 --- a/src/js/controllers/preferencesDelete.js +++ b/src/js/controllers/preferencesDelete.js @@ -21,7 +21,8 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro if (err) { popupService.showAlert(gettextCatalog.getString('Error'), err.message || err); } else { - $ionicHistory.removeBackView(); + $ionicHistory.clearHistory(); + $ionicHistory.clearCache(); $state.go('tabs.home'); } }); diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index 659f9dd8f..de2c29e98 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -134,8 +134,7 @@ angular.module('copayApp.services') if (n.type == "NewBlock" && n.data.network == "testnet") { throttledBwsEvent(n, wallet); - } - else newBwsEvent(n, wallet); + } else newBwsEvent(n, wallet); }); wallet.on('walletCompleted', function() { @@ -600,6 +599,7 @@ angular.module('copayApp.services') var walletClient = bwcService.getClient(null, opts); $log.debug('Importing Wallet:', opts); + try { walletClient.import(str, { compressed: opts.compressed, @@ -611,6 +611,12 @@ angular.module('copayApp.services') str = JSON.parse(str); + if (str.xPrivKey && str.xPrivKeyEncrypted) { + $log.warn('Found both encrypted and decrypted key. Deleting the encrypted version'); + delete str.xPrivKeyEncrypted; + delete str.mnemonicEncrypted; + } + var addressBook = str.addressBook || {}; addAndBindWalletClient(walletClient, { diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js index 216df83d8..4ea415b0f 100644 --- a/src/js/services/walletService.js +++ b/src/js/services/walletService.js @@ -869,9 +869,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim if (!root.isEncrypted(wallet)) return cb(); askPassword(wallet.name, gettext('Enter Spending Password'), function(password) { - if (!password) return cb('no password'); - if (!wallet.checkPassword(password)) return cb('wrong password'); - + if (!password) return cb('No password'); + if (!wallet.checkPassword(password)) return cb('Wrong password'); return cb(null, password); }); @@ -990,8 +989,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim }); }; - root.getEncodedWalletInfo = function(wallet, cb) { - + root.getEncodedWalletInfo = function(wallet, password, cb) { var derivationPath = wallet.credentials.getBaseAddressDerivationPath(); var encodingType = { mnemonic: 1, @@ -1002,25 +1000,23 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim // not supported yet if (wallet.credentials.derivationStrategy != 'BIP44' || !wallet.canSign()) - return null; + return cb(gettextCatalog.getString('Exporting via QR not supported for this wallet')); - root.getKeys(wallet, function(err, keys) { - if (err || !keys) return cb(err); + var keys = root.getKeysWithPassword(wallet, password); - if (keys.mnemonic) { - info = { - type: encodingType.mnemonic, - data: keys.mnemonic, - } - } else { - info = { - type: encodingType.xpriv, - data: keys.xPrivKey - } + if (keys.mnemonic) { + info = { + type: encodingType.mnemonic, + data: keys.mnemonic, } - return cb(null, info.type + '|' + info.data + '|' + wallet.credentials.network.toLowerCase() + '|' + derivationPath + '|' + (wallet.credentials.mnemonicHasPassphrase)); + } else { + info = { + type: encodingType.xpriv, + data: keys.xPrivKey + } + } - }); + return cb(null, info.type + '|' + info.data + '|' + wallet.credentials.network.toLowerCase() + '|' + derivationPath + '|' + (wallet.credentials.mnemonicHasPassphrase)); }; root.setTouchId = function(wallet, enabled, cb) { @@ -1055,6 +1051,12 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim }); }; + root.getKeysWithPassword = function(wallet, password) { + try { + return wallet.getKeys(password); + } catch (e) {} + } + root.getViewStatus = function(wallet, txp) { var status = txp.status; var type; diff --git a/www/views/export.html b/www/views/export.html index b6117ced1..805a84e1c 100644 --- a/www/views/export.html +++ b/www/views/export.html @@ -5,17 +5,17 @@ - -
-
+ +
+
File/Text
-
+
QR Code
-
-
+
+