+
-
diff --git a/src/js/controllers/buyCoinbase.js b/src/js/controllers/buyCoinbase.js
index 51d37ffa8..32da90b70 100644
--- a/src/js/controllers/buyCoinbase.js
+++ b/src/js/controllers/buyCoinbase.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('buyCoinbaseController',
- function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, addressService, walletService) {
+ function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, addressService) {
window.ignoreMobilePause = true;
var self = this;
@@ -72,7 +72,7 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController',
$scope.selectWallet = function(walletId, walletName) {
var client = profileService.getClient(walletId);
- walletService.isReady(client, function(err) {
+ profileService.isReady(client, function(err) {
if (err) {
self.error = {errors: [{ message: err }]};
$modalInstance.dismiss('cancel');
diff --git a/src/js/controllers/buyGlidera.js b/src/js/controllers/buyGlidera.js
index 018d13c8d..3a8b444c8 100644
--- a/src/js/controllers/buyGlidera.js
+++ b/src/js/controllers/buyGlidera.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('buyGlideraController',
- function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, animationService, walletService) {
+ function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, animationService) {
var self = this;
this.show2faCodeInput = null;
@@ -51,7 +51,7 @@ angular.module('copayApp.controllers').controller('buyGlideraController',
$scope.selectWallet = function(walletId, walletName) {
var client = profileService.getClient(walletId);
- walletService.isReady(client, function(err) {
+ profileService.isReady(client, function(err) {
if (err) {
self.error = err;
$modalInstance.dismiss('cancel');
diff --git a/src/js/controllers/copayers.js b/src/js/controllers/copayers.js
index a4fcb5b91..f44fda311 100644
--- a/src/js/controllers/copayers.js
+++ b/src/js/controllers/copayers.js
@@ -54,15 +54,15 @@ angular.module('copayApp.controllers').controller('copayersController',
modalInstance.result.then(function(ok) {
if (ok) {
- _deleteWallet();
+ doDeleteWallet();
}
});
};
- var _deleteWallet = function() {
+ var doDeleteWallet = function() {
var fc = profileService.focusedClient;
var walletName = fc.credentials.walletName;
- profileService.deleteWalletFC({}, function(err) {
+ profileService.deleteWalletClient(fc, function(err) {
if (err) {
self.error = err.message || err;
$timeout(function() {
diff --git a/src/js/controllers/create.js b/src/js/controllers/create.js
index 815d796f9..fdb445c55 100644
--- a/src/js/controllers/create.js
+++ b/src/js/controllers/create.js
@@ -169,7 +169,7 @@ angular.module('copayApp.controllers').controller('createController',
self.loading = true;
$timeout(function() {
- profileService.createWallet(opts, function(err, walletId) {
+ profileService.createWallet(opts, function(err) {
self.loading = false;
if (err) {
$log.warn(err);
diff --git a/src/js/controllers/disclaimer.js b/src/js/controllers/disclaimer.js
index 9d56c1d26..1aaf06e07 100644
--- a/src/js/controllers/disclaimer.js
+++ b/src/js/controllers/disclaimer.js
@@ -4,45 +4,46 @@ angular.module('copayApp.controllers').controller('disclaimerController',
function($scope, $timeout, $log, $ionicSideMenuDelegate, profileService, applicationService, gettextCatalog, uxLanguage, go) {
var self = this;
self.tries = 0;
- $scope.creatingProfile = true;
-
- var create = function(noWallet) {
- profileService.create({
- noWallet: noWallet
- }, function(err) {
+ self.creatingProfile = true;
+ var create = function(opts) {
+ opts = opts || {};
+ $log.debug('Creating profile');
+ profileService.create(opts, function(err) {
if (err) {
$log.warn(err);
$scope.error = err;
$scope.$apply();
- $timeout(function() {
+
+ return $timeout(function() {
$log.warn('Retrying to create profile......');
if (self.tries == 3) {
self.tries == 0;
- create(true);
+ return create({
+ noWallet: true
+ });
} else {
self.tries += 1;
- create(false);
+ return create();
}
}, 3000);
- } else {
- $scope.error = "";
- $scope.creatingProfile = false;
- }
+ };
+
+ $scope.error = "";
+ self.creatingProfile = false;
});
};
- this.init = function() {
-
+ this.init = function(opts) {
$ionicSideMenuDelegate.canDragContent(false);
self.lang = uxLanguage.currentLanguage;
profileService.getProfile(function(err, profile) {
if (!profile) {
- create(false);
+ create(opts);
} else {
- $log.debug('There is a profile already');
- $scope.creatingProfile = false;
+ $log.info('There is already a profile');
+ self.creatingProfile = false;
profileService.bindProfile(profile, function(err) {
if (!err || !err.message || !err.message.match('NONAGREEDDISCLAIMER')) {
$log.debug('Disclaimer already accepted at #disclaimer. Redirect to Wallet Home.');
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js
index 1649519aa..bdc34c685 100644
--- a/src/js/controllers/index.js
+++ b/src/js/controllers/index.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicSideMenuDelegate, $ionicScrollDelegate, $ionicPopup, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwsError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService, walletService) {
+angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicSideMenuDelegate, $ionicScrollDelegate, $ionicPopup, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwsError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService) {
var self = this;
var SOFT_CONFIRMATION_LIMIT = 12;
var errors = bwcService.getErrors();
@@ -184,7 +184,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
}
}
- walletService.isBackupNeeded(fc, function(needsBackup) {
+ profileService.needsBackup(fc, function(needsBackup) {
self.needsBackup = needsBackup;
self.openWallet(function() {
if (!self.isComplete) {
@@ -268,53 +268,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
};
- self._updateRemotePreferencesFor = function(clients, prefs, cb) {
- var client = clients.shift();
-
- if (!client)
- return cb();
-
- $log.debug('Saving remote preferences', client.credentials.walletName, prefs);
- client.savePreferences(prefs, function(err) {
- // we ignore errors here
- if (err) $log.warn(err);
-
- self._updateRemotePreferencesFor(clients, prefs, cb);
- });
- };
-
-
- self.updateRemotePreferences = function(opts, cb) {
- var prefs = opts.preferences || {};
- var fc = profileService.focusedClient;
-
- // Update this JIC.
- var config = configService.getSync().wallet.settings;
-
- //prefs.email (may come from arguments)
- prefs.language = self.defaultLanguageIsoCode;
- prefs.unit = config.unitCode;
-
- var clients = [];
- if (opts.saveAll) {
- clients = lodash.values(profileService.walletClients);
- } else {
- clients = [fc];
- };
-
- self._updateRemotePreferencesFor(clients, prefs, function(err) {
- if (err) return cb(err);
- if (!fc) return cb();
-
- fc.getPreferences(function(err, preferences) {
- if (err) {
- return cb(err);
- }
- self.preferences = preferences;
- return cb();
- });
- });
- };
var _walletStatusHash = function(walletStatus) {
var bal;
@@ -326,6 +279,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
return bal;
};
+ // TODO move this to wallet service
self.updateAll = function(opts, initStatusHash, tries) {
$scope.$broadcast('scroll.refreshComplete');
tries = tries || 0;
@@ -1055,7 +1009,9 @@ angular.module('copayApp.controllers').controller('indexController', function($r
return;
}
- profileService.setWalletClients();
+ profileService.bindWalletClient(fc, {
+ force: true
+ });
self.startScan(self.walletId);
});
};
@@ -1092,14 +1048,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
});
};
- self.setUxLanguage = function(cb) {
- uxLanguage.update(function(lang) {
- var userLang = lang;
- self.defaultLanguageIsoCode = userLang;
- self.defaultLanguageName = uxLanguage.getName(userLang);
- if (cb) return cb();
- });
- };
self.initGlidera = function(accessToken) {
self.glideraEnabled = configService.getSync().glidera.enabled;
@@ -1510,28 +1458,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.updateAll();
});
- $rootScope.$on('Local/ProfileBound', function() {
- storageService.getRemotePrefsStoredFlag(function(err, val) {
- if (err || val) return;
- self.updateRemotePreferences({
- saveAll: true
- }, function() {
- $log.debug('Remote preferences saved');
- storageService.setRemotePrefsStoredFlag(function() {});
- });
- });
- });
-
- $rootScope.$on('Local/LanguageSettingUpdated', function() {
- self.setUxLanguage(function() {
- self.updateRemotePreferences({
- saveAll: true
- }, function() {
- $log.debug('Remote preferences saved')
- });
- });
- });
-
$rootScope.$on('Local/GlideraUpdated', function(event, accessToken) {
self.initGlidera(accessToken);
});
@@ -1558,19 +1484,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.updateAll({
triggerTxUpdate: true,
});
- self.updateRemotePreferences({
- saveAll: true
- }, function() {
- $log.debug('Remote preferences saved')
- });
- });
-
- $rootScope.$on('Local/EmailSettingUpdated', function(event, email, cb) {
- self.updateRemotePreferences({
- preferences: {
- email: email || null
- },
- }, cb);
});
$rootScope.$on('Local/WalletCompleted', function(event, walletId) {
@@ -1582,14 +1495,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
}
});
- $rootScope.$on('Local/ProfileCreated', function(event) {
- self.updateRemotePreferences({
- saveAll: true
- }, function() {
- $log.debug('Remote preferences saved');
- });
- });
-
self.debouncedUpdate = lodash.throttle(function() {
self.updateAll({
quiet: true
@@ -1743,13 +1648,13 @@ angular.module('copayApp.controllers').controller('indexController', function($r
});
$rootScope.$on('Local/NoWallets', function(event) {
-
$timeout(function() {
self.hasProfile = true;
self.noFocusedWallet = true;
self.isComplete = null;
self.walletName = null;
- self.setUxLanguage();
+ uxLanguage.update();
+
profileService.isDisclaimerAccepted(function(v) {
if (v) {
go.path('import');
@@ -1759,7 +1664,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
});
$rootScope.$on('Local/NewFocusedWallet', function() {
- self.setUxLanguage();
+ uxLanguage.update();
self.setFocusedWallet();
self.updateHistory();
storageService.getCleanAndScanAddresses(function(err, walletId) {
@@ -1868,6 +1773,10 @@ angular.module('copayApp.controllers').controller('indexController', function($r
});
+ $rootScope.$on('Local/EmailUpdated', function(event, email) {
+ self.preferences.email = email;
+ });
+
lodash.each(['NewCopayer', 'CopayerUpdated'], function(eventName) {
$rootScope.$on(eventName, function() {
// Re try to open wallet (will triggers)
diff --git a/src/js/controllers/modals/addressbook.js b/src/js/controllers/modals/addressbook.js
index 02ecb0dd2..a384eff1e 100644
--- a/src/js/controllers/modals/addressbook.js
+++ b/src/js/controllers/modals/addressbook.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('addressbookController', function($rootScope, $scope, $timeout, profileService, walletService, addressService, addressbookService) {
+angular.module('copayApp.controllers').controller('addressbookController', function($rootScope, $scope, $timeout, profileService, addressService, addressbookService) {
var self = $scope.self;
var fc = profileService.focusedClient;
@@ -118,7 +118,7 @@ angular.module('copayApp.controllers').controller('addressbookController', funct
var client = profileService.getClient(walletId);
$scope.errorSelectedWallet = {};
- walletService.isReady(client, function(err) {
+ profileService.isReady(client, function(err) {
if (err) $scope.errorSelectedWallet[walletId] = err;
else {
$scope.gettingAddress = true;
diff --git a/src/js/controllers/preferences.js b/src/js/controllers/preferences.js
index 5e60440c0..bc8203341 100644
--- a/src/js/controllers/preferences.js
+++ b/src/js/controllers/preferences.js
@@ -3,15 +3,20 @@
angular.module('copayApp.controllers').controller('preferencesController',
function($scope, $rootScope, $timeout, $log, configService, profileService, fingerprintService, walletService) {
- var fc = profileService.focusedClient;
+ var self = this;
+ var fc;
var config = configService.getSync();
- $scope.deleted = false;
- if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) {
- $scope.deleted = true;
- }
+ var disableFocusListener = $rootScope.$on('Local/NewFocusedWalletReady', function() {
+ self.init();
+ });
+
+ $scope.$on('$destroy', function() {
+ disableFocusListener();
+ });
this.init = function() {
+ fc = profileService.focusedClient;
if (fc) {
$scope.encryptEnabled = walletService.isEncrypted(fc);
this.externalSource = fc.getPrivKeyExternalSourceName() == 'ledger' ? "Ledger" : null;
@@ -21,38 +26,69 @@ angular.module('copayApp.controllers').controller('preferencesController',
this.touchidAvailable = fingerprintService.isAvailable();
$scope.touchidEnabled = config.touchIdFor ? config.touchIdFor[fc.credentials.walletId] : null;
+
+ $scope.deleted = false;
+ if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) {
+ $scope.deleted = true;
+ }
};
- var handleEncryptedWallet = function(client, cb) {
+ var handleEncryptedWallet = function(cb) {
$rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
if (err) return cb(err);
- return cb(walletService.unlock(client, password));
+ return cb(walletService.unlock(fc, password));
});
};
$scope.encryptChange = function() {
+ var self = this;
if (!fc) return;
var val = $scope.encryptEnabled;
+ var setPrivateKeyEncryption = function(password, cb) {
+ $log.debug('Encrypting private key for', fc.credentials.walletName);
+
+ fc.setPrivateKeyEncryption(password);
+ fc.lock();
+ profileService.updateCredentials(fc.export(), function() {
+ $log.debug('Wallet encrypted');
+ return cb();
+ });
+ };
+
+ var disablePrivateKeyEncryption = function(cb) {
+ $log.debug('Disabling private key encryption for', fc.credentials.walletName);
+
+ try {
+ fc.disablePrivateKeyEncryption();
+ } catch (e) {
+ return cb(e);
+ }
+ profileService.updateCredentials(fc.export(), function() {
+ $log.debug('Wallet encryption disabled');
+ return cb();
+ });
+ };
+
if (val && !walletService.isEncrypted(fc)) {
$rootScope.$emit('Local/NeedsPassword', true, function(err, password) {
if (err || !password) {
$scope.encryptEnabled = false;
return;
}
- profileService.setPrivateKeyEncryptionFC(password, function() {
+ setPrivateKeyEncryption(password, function() {
$rootScope.$emit('Local/NewEncryptionSetting');
$scope.encryptEnabled = true;
});
});
} else {
if (!val && walletService.isEncrypted(fc)) {
- handleEncryptedWallet(fc, function(err) {
+ handleEncryptedWallet(function(err) {
if (err) {
$scope.encryptEnabled = true;
return;
}
- profileService.disablePrivateKeyEncryptionFC(function(err) {
+ disablePrivateKeyEncryption(function(err) {
$rootScope.$emit('Local/NewEncryptionSetting');
if (err) {
$scope.encryptEnabled = true;
diff --git a/src/js/controllers/preferencesAltCurrency.js b/src/js/controllers/preferencesAltCurrency.js
index c62ab2281..5f6a9c2cf 100644
--- a/src/js/controllers/preferencesAltCurrency.js
+++ b/src/js/controllers/preferencesAltCurrency.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesAltCurrencyController',
- function($scope, $timeout, $log, configService, rateService, lodash, go) {
+ function($scope, $timeout, $log, configService, rateService, lodash, go, profileService, walletService) {
this.hideAdv = true;
this.hidePriv = true;
this.hideSecret = true;
@@ -51,6 +51,9 @@ angular.module('copayApp.controllers').controller('preferencesAltCurrencyControl
if (err) $log.warn(err);
go.preferencesGlobal();
$scope.$emit('Local/UnitSettingUpdated');
+ walletService.updateRemotePreferences(profileService.walletClients, {}, function() {
+ $log.debug('Remote preferences saved');
+ });
$timeout(function() {
$scope.$apply();
}, 100);
diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js
index e176fc5c6..8a0046083 100644
--- a/src/js/controllers/preferencesDelete.js
+++ b/src/js/controllers/preferencesDelete.js
@@ -40,19 +40,19 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro
modalInstance.result.then(function(ok) {
if (ok) {
- _deleteWallet();
+ doDeleteWallet();
}
});
};
- var _deleteWallet = function() {
+ var doDeleteWallet = function() {
$scope.isDeletingWallet = true;
var fc = profileService.focusedClient;
var name = fc.credentials.walletName;
var walletName = (fc.alias || '') + ' [' + name + ']';
var self = this;
- profileService.deleteWalletFC({}, function(err) {
+ profileService.deleteWalletClient(fc, function(err) {
$scope.isDeletingWallet = false;
if (err) {
self.error = err.message || err;
@@ -72,7 +72,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro
delete_msg,
function(buttonIndex) {
if (buttonIndex == 1) {
- _deleteWallet();
+ doDeleteWallet();
}
},
confirm_msg, [accept_msg, cancel_msg]
diff --git a/src/js/controllers/preferencesDeleteWords.js b/src/js/controllers/preferencesDeleteWords.js
index e810c1e74..405d5d6ca 100644
--- a/src/js/controllers/preferencesDeleteWords.js
+++ b/src/js/controllers/preferencesDeleteWords.js
@@ -13,7 +13,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWordsControl
confirmDialog.show(msg, function(ok) {
if (ok) {
fc.clearMnemonic();
- profileService.updateCredentialsFC(function() {
+ profileService.updateCredentials(fc.export(), function() {
notification.success(successMsg);
go.walletHome();
});
diff --git a/src/js/controllers/preferencesEmail.js b/src/js/controllers/preferencesEmail.js
index dbdc02158..036cb7a74 100644
--- a/src/js/controllers/preferencesEmail.js
+++ b/src/js/controllers/preferencesEmail.js
@@ -1,14 +1,22 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesEmailController',
- function($scope, go, profileService, gettext, $log) {
+ function($rootScope, go, profileService, gettext, $log, walletService) {
this.save = function(form) {
var self = this;
this.error = null;
var fc = profileService.focusedClient;
this.saving = true;
- $scope.$emit('Local/EmailSettingUpdated', self.email, function() {
+ var email = self.email || '';
+
+ walletService.updateRemotePreferences(fc, {
+ email: email,
+ }, function(err) {
+
+ if (!err)
+ $rootScope.$emit('Local/EmailUpdated', email);
+
self.saving = false;
go.path('preferences');
});
diff --git a/src/js/controllers/preferencesHistory.js b/src/js/controllers/preferencesHistory.js
index 1f7e29418..321e1ade2 100644
--- a/src/js/controllers/preferencesHistory.js
+++ b/src/js/controllers/preferencesHistory.js
@@ -51,7 +51,7 @@ angular.module('copayApp.controllers').controller('preferencesHistory',
$log.debug('Generating CSV from History');
getHistory(function(err, txs) {
- if (err || !txs || !txs[0]) {
+ if (err || !txs) {
$log.warn('Failed to generate CSV:', err);
if (cb) return cb(err);
return;
diff --git a/src/js/controllers/preferencesLanguage.js b/src/js/controllers/preferencesLanguage.js
index 8fc027bd7..acce188b5 100644
--- a/src/js/controllers/preferencesLanguage.js
+++ b/src/js/controllers/preferencesLanguage.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesLanguageController',
- function($scope, $log, $timeout, configService, uxLanguage, go) {
+ function($scope, $log, $timeout, configService, profileService, uxLanguage, walletService, go) {
this.availableLanguages = uxLanguage.getLanguages();
this.currentLanguage = uxLanguage.getCurrentLanguage();
@@ -19,10 +19,18 @@ angular.module('copayApp.controllers').controller('preferencesLanguageController
configService.set(opts, function(err) {
if (err) $log.warn(err);
go.preferencesGlobal();
- $scope.$emit('Local/LanguageSettingUpdated');
- $timeout(function() {
- $scope.$apply();
- }, 100);
+
+
+ uxLanguage.update(function() {
+ $timeout(function() {
+ $scope.$apply();
+ }, 100);
+
+ walletService.updateRemotePreferences(profileService.getClients(), {},
+ function() {
+ $log.debug('Remote preferences saved');
+ });
+ });
});
};
});
diff --git a/src/js/controllers/preferencesUnit.js b/src/js/controllers/preferencesUnit.js
index cface9b0d..b6cf17437 100644
--- a/src/js/controllers/preferencesUnit.js
+++ b/src/js/controllers/preferencesUnit.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesUnitController',
- function($scope, $timeout, $log, configService, go) {
+ function($scope, $timeout, $log, configService, go, walletService, profileService) {
var config = configService.getSync();
this.unitName = config.wallet.settings.unitName;
this.unitOpts = [
@@ -54,6 +54,9 @@ angular.module('copayApp.controllers').controller('preferencesUnitController',
if (err) $log.warn(err);
go.preferencesGlobal();
$scope.$emit('Local/UnitSettingUpdated');
+ walletService.updateRemotePreferences(profileService.getClients(), {}, function() {
+ $log.debug('Remote preferences saved');
+ });
$timeout(function() {
$scope.$apply();
}, 100);
diff --git a/src/js/models/profile.js b/src/js/models/profile.js
index 4e808fdee..aaa5f4a4c 100644
--- a/src/js/models/profile.js
+++ b/src/js/models/profile.js
@@ -27,6 +27,7 @@ Profile.fromObj = function(obj) {
x.credentials = obj.credentials;
x.disclaimerAccepted = obj.disclaimerAccepted;
x.checked = obj.checked || {};
+ x.checkedUA = obj.checkedUA || {};
if (x.credentials[0] && typeof x.credentials[0] != 'object')
throw ("credentials should be an object");
@@ -39,5 +40,63 @@ Profile.fromString = function(str) {
};
Profile.prototype.toObj = function() {
+ delete this.dirty;
return JSON.stringify(this);
};
+
+
+Profile.prototype.hasWallet = function(walletId) {
+ for (var i in this.credentials) {
+ var c = this.credentials[i];
+ if (c.walletId == walletId) return true;
+ };
+ return false;
+};
+
+Profile.prototype.isChecked = function(ua, walletId) {
+ return !!(this.checkedUA == ua && this.checked[walletId]);
+};
+
+Profile.prototype.setChecked = function(ua, walletId) {
+ if (this.checkedUA != ua) {
+ this.checkedUA = ua;
+ this.checked = {};
+ }
+ this.checked[walletId] = true;
+ this.dirty = true;
+};
+
+
+Profile.prototype.addWallet = function(credentials) {
+ if (this.hasWallet(credentials.walletId))
+ return false;
+
+ this.credentials.push(credentials);
+ this.dirty = true;
+ return true;
+};
+
+Profile.prototype.updateWallet = function(credentials) {
+ if (!this.hasWallet(credentials.walletId))
+ return false;
+
+ this.credentials = this.credentials.filter(function(c) {
+ return c.walletId != walletId;
+ });
+
+ this.addWallet(credentials);
+ this.dirty = true;
+ return true;
+};
+
+Profile.prototype.deleteWallet = function(walletId) {
+ if (!this.hasWallet(walletId))
+ return false;
+
+ this.credentials = this.credentials.filter(function(c) {
+ return c.walletId != walletId;
+ });
+
+ this.dirty = true;
+ return true;
+};
diff --git a/src/js/routes.js b/src/js/routes.js
index 46e96cee2..998ac7848 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -632,6 +632,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
throw new Error(err); // TODO
}
} else {
+ profileService.storeProfileIfDirty();
$log.debug('Profile loaded ... Starting UX.');
$state.transitionTo(toState.name || toState, toParams);
}
diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js
index f14acff19..03cba8311 100644
--- a/src/js/services/profileService.js
+++ b/src/js/services/profileService.js
@@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services')
- .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwsError, uxLanguage, bitcore, platformInfo) {
+ .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwsError, uxLanguage, bitcore, platformInfo, walletService) {
var isChromeApp = platformInfo.isChromeApp;
@@ -62,34 +62,22 @@ angular.module('copayApp.services')
});
};
- root.setWalletClient = function(credentials) {
- if (root.walletClients[credentials.walletId] &&
- root.walletClients[credentials.walletId].started) {
- return;
+ // Adds a wallet client to profileService
+ root.bindWalletClient = function(client, opts) {
+ var opts = opts || {};
+ var walletId = client.credentials.walletId;
+
+ if ((root.walletClients[walletId] && root.walletClients[walletId].started) || opts.force) {
+ return false;
}
-
- var getBaseURL = function(walletId) {
- var config = configService.getSync();
- var defaults = configService.getDefaults();
-
- return ((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url);
- };
-
- $log.debug('Importing wallet:' + credentials.walletId);
- var skipKeyValidation = root.profile.checked[credentials.walletId] == platformInfo.ua;
- var client = bwcService.getClient(JSON.stringify(credentials), {
- baseurl: getBaseURL(credentials.walletId),
- skipKeyValidation: skipKeyValidation,
- });
- root.walletClients[credentials.walletId] = client;
+ root.walletClients[walletId] = client;
+ root.walletClients[walletId].started = true;
+ root.walletClients[walletId].doNotVerifyPayPro = isChromeApp;
if (client.incorrectDerivation) {
- $log.warn('Key Derivation failed for wallet:' + credentials.walletId);
- storageService.clearLastAddress(credentials.walletId, function() {});
- } else if (!skipKeyValidation) {
- root.profile.checked[credentials.walletId] = platformInfo.ua;
- storageService.storeProfileThrottled(root.profile, function() {});
+ $log.warn('Key Derivation failed for wallet:' + walletId);
+ storageService.clearLastAddress(walletId, function() {});
}
client.removeAllListeners();
@@ -100,9 +88,9 @@ angular.module('copayApp.services')
client.on('notification', function(n) {
$log.debug('BWC Notification:', n);
notificationService.newBWCNotification(n,
- client.credentials.walletId, client.credentials.walletName);
+ walletId, client.credentials.walletName);
- if (root.focusedClient.credentials.walletId == client.credentials.walletId) {
+ if (root.focusedClient.credentials.walletId == walletId) {
$rootScope.$emit(n.type, n);
} else {
$rootScope.$apply();
@@ -112,17 +100,13 @@ angular.module('copayApp.services')
client.on('walletCompleted', function() {
$log.debug('Wallet completed');
- root.updateCredentialsFC(function() {
- $rootScope.$emit('Local/WalletCompleted', client.credentials.walletId);
+ root.updateCredentials(client.export(), function() {
+ $rootScope.$emit('Local/WalletCompleted', walletId);
});
-
});
- root.walletClients[credentials.walletId].started = true;
- root.walletClients[credentials.walletId].doNotVerifyPayPro = isChromeApp;
-
if (client.hasPrivKeyEncrypted() && !client.isPrivKeyEncrypted()) {
- $log.warn('Auto locking unlocked wallet:' + credentials.walletId);
+ $log.warn('Auto locking unlocked wallet:' + walletId);
client.lock();
}
@@ -133,15 +117,35 @@ angular.module('copayApp.services')
}
client.setNotificationsInterval(BACKGROUND_UPDATE_PERIOD);
});
- }
- root.setWalletClients = function() {
- var credentials = root.profile.credentials;
- lodash.each(credentials, function(credential) {
- //$log.info("Credentials:", credentials);
- root.setWalletClient(credential);
+ return true;
+ };
+
+
+ // Used when reading wallets from the profile
+ root.bindWallet = function(credentials) {
+ if (!credentials.walletId)
+ throw 'bindWallet should receive credentials JSON';
+
+ $log.debug('Bind wallet:' + credentials.walletId);
+
+ // Create the client
+ var getBaseURL = function(walletId) {
+ var config = configService.getSync();
+ var defaults = configService.getDefaults();
+ return ((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url);
+ };
+
+ var skipKeyValidation = root.profile.isChecked(platformInfo.ua, credentials.walletId);
+ var client = bwcService.getClient(JSON.stringify(credentials), {
+ baseurl: getBaseURL(credentials.walletId),
+ skipKeyValidation: skipKeyValidation,
});
- $rootScope.$emit('Local/WalletListUpdated');
+
+ if (!skipKeyValidation && !client.incorrectDerivation)
+ root.profile.setChecked(platformInfo.ua, credentials.walletId);
+
+ return root.bindWalletClient(client);
};
root.bindProfile = function(profile, cb) {
@@ -150,11 +154,15 @@ angular.module('copayApp.services')
configService.get(function(err) {
$log.debug('Preferences read');
if (err) return cb(err);
- root.setWalletClients();
+
+ lodash.each(root.profile.credentials, function(credentials) {
+ root.bindWallet(credentials);
+ });
+ $rootScope.$emit('Local/WalletListUpdated');
+
storageService.getFocusedWalletId(function(err, focusedWalletId) {
if (err) return cb(err);
root._setFocus(focusedWalletId, function() {
- $rootScope.$emit('Local/ProfileBound');
if (usePushNotifications)
root.pushNotificationsInit();
root.isDisclaimerAccepted(function(val) {
@@ -222,12 +230,11 @@ angular.module('copayApp.services')
});
};
- root._seedWallet = function(opts, cb) {
+ var seedWallet = function(opts, cb) {
opts = opts || {};
var walletClient = bwcService.getClient(null, opts);
var network = opts.networkName || 'livenet';
-
if (opts.mnemonic) {
try {
opts.mnemonic = root._normalizeMnemonic(opts.mnemonic);
@@ -285,45 +292,54 @@ angular.module('copayApp.services')
return cb(null, walletClient);
};
- root._createNewProfile = function(opts, cb) {
-
- if (opts.noWallet) {
- return cb(null, Profile.create());
- }
-
- root._seedWallet({}, function(err, walletClient) {
- if (err) return cb(err);
-
- var walletName = gettextCatalog.getString('Personal Wallet');
- var me = gettextCatalog.getString('me');
- walletClient.createWallet(walletName, me, 1, 1, {
- network: 'livenet'
- }, function(err) {
- if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb);
- var p = Profile.create({
- credentials: [JSON.parse(walletClient.export())],
- });
- return cb(null, p);
- });
- })
- };
-
- root.createWallet = function(opts, cb) {
+ // Creates a wallet on BWC/BWS
+ var doCreateWallet = function(opts, cb) {
$log.debug('Creating Wallet:', opts);
- root._seedWallet(opts, function(err, walletClient) {
+ seedWallet(opts, function(err, walletClient) {
if (err) return cb(err);
- walletClient.createWallet(opts.name, opts.myName || 'me', opts.m, opts.n, {
+ var name = opts.name || gettextCatalog.getString('Personal Wallet');
+ var myName = opts.myName || gettextCatalog.getString('me');
+
+ walletClient.createWallet(name, myName, opts.m, opts.n, {
network: opts.networkName,
walletPrivKey: opts.walletPrivKey,
}, function(err, secret) {
if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb);
-
- root._addWalletClient(walletClient, opts, cb);
- })
+ return cb(null, walletClient, secret);
+ });
});
};
+ // Creates the default Copay profile and its wallet
+ root.createDefaultProfile = function(opts, cb) {
+ var p = Profile.create();
+
+ if (opts.noWallet) {
+ return cb(null, p);
+ }
+
+ opts.m = 1;
+ opts.n = 1;
+ opts.network = 'livenet';
+
+ doCreateWallet(opts, function(err, walletClient) {
+ if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb);
+ p.addWallet(JSON.parse(walletClient.export()));
+ return cb(null, p);
+ });
+ };
+
+ // create and store a wallet
+ root.createWallet = function(opts, cb) {
+ doCreateWallet(opts, function(err, walletClient, secret) {
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl
+ }, cb);
+ });
+ };
+
+ // joins and stores a wallet
root.joinWallet = function(opts, cb) {
var walletClient = bwcService.getClient();
$log.debug('Joining Wallet:', opts);
@@ -344,12 +360,14 @@ angular.module('copayApp.services')
opts.networkName = walletData.network;
$log.debug('Joining Wallet:', opts);
- root._seedWallet(opts, function(err, walletClient) {
+ seedWallet(opts, function(err, walletClient) {
if (err) return cb(err);
walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) {
if (err) return bwsError.cb(err, gettext('Could not join wallet'), cb);
- root._addWalletClient(walletClient, opts, cb);
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl
+ }, cb);
});
});
};
@@ -358,39 +376,31 @@ angular.module('copayApp.services')
return root.walletClients[walletId];
};
- root.deleteWalletFC = function(opts, cb) {
- var fc = root.focusedClient;
- var walletId = fc.credentials.walletId;
+ root.deleteWalletClient = function(client, cb) {
+ var walletId = client.credentials.walletId;
pushNotificationsService.unsubscribe(root.getClient(walletId), function(err) {
if (err) $log.warn('Unsubscription error: ' + err.message);
else $log.debug('Unsubscribed from push notifications service');
});
- $log.debug('Deleting Wallet:', fc.credentials.walletName);
+ $log.debug('Deleting Wallet:', client.credentials.walletName);
+ client.removeAllListeners();
- fc.removeAllListeners();
- root.profile.credentials = lodash.reject(root.profile.credentials, {
- walletId: walletId
- });
+ root.profile.deleteWallet(walletId);
delete root.walletClients[walletId];
root.focusedClient = null;
- storageService.clearLastAddress(walletId, function(err) {
+
+ storageService.removeAllWalletData(walletId, function(err) {
if (err) $log.warn(err);
});
- storageService.removeTxHistory(walletId, function(err) {
- if (err) $log.warn(err);
- });
-
- storageService.clearBackupFlag(walletId, function(err) {
- if (err) $log.warn(err);
- });
$timeout(function() {
- root.setWalletClients();
+ $rootScope.$emit('Local/WalletListUpdated');
+
root.setAndStoreFocus(null, function() {
storageService.storeProfile(root.profile, function(err) {
if (err) return cb(err);
@@ -419,59 +429,74 @@ angular.module('copayApp.services')
});
}
- root._addWalletClient = function(walletClient, opts, cb) {
- var walletId = walletClient.credentials.walletId;
+ // Adds and bind a new client to the profile
+ root.addAndBindWalletClient = function(client, opts, cb) {
+ var walletId = client.credentials.walletId
- // check if exist
- var w = lodash.find(root.profile.credentials, {
- 'walletId': walletId
+ if (!root.profile.addWallet(JSON.parse(client.export())))
+ return cb(gettext('Wallet already in Copay'));
+
+ root.bindWalletClient(client);
+ $rootScope.$emit('Local/WalletListUpdated', client);
+
+ var saveBwsUrl = function(cb) {
+ var defaults = configService.getDefaults();
+ var bwsFor = {};
+ bwsFor[walletId] = opts.bwsurl || defaults.bws.url;
+
+ // Dont save the default
+ if (bwsFor[walletId] == defaults.bws.url)
+ return cb();
+
+ configService.set({
+ bwsFor: bwsFor,
+ }, function(err) {
+ if (err) $log.warn(err);
+ return cb();
+ });
+ };
+
+ var handleImportedClient = function(cb) {
+ if (!opts.isImport) return cb();
+ $rootScope.$emit('Local/BackupDone', walletId);
+
+ if (!client.isComplete())
+ return cb();
+
+ storageService.setCleanAndScanAddresses(walletId, cb);
+ };
+
+ walletService.updateRemotePreferences(client, {}, function() {
+ $log.debug('Remote preferences saved for:' + walletId)
});
- if (w) {
- return cb(gettext('Wallet already in Copay' + ": ") + w.walletName);
- }
- var config = configService.getSync();
- var defaults = configService.getDefaults();
- var bwsFor = {};
- bwsFor[walletId] = opts.bwsurl || defaults.bws.url;
-
- configService.set({
- bwsFor: bwsFor,
- }, function(err) {
- if (err) console.log(err);
-
- root.profile.credentials.push(JSON.parse(walletClient.export()));
- root.setWalletClients();
-
-
- var handleImport = function(cb) {
- var isImport = opts.mnemonic || opts.externalSource || opts.extendedPrivateKey;
-
- if (!isImport)
- return cb();
-
- $rootScope.$emit('Local/BackupDone', walletId);
-
- if (!walletClient.isComplete())
- return cb();
-
- storageService.setCleanAndScanAddresses(walletId, cb);
- };
-
- handleImport(function() {
+ saveBwsUrl(function() {
+ handleImportedClient(function() {
root.setAndStoreFocus(walletId, function() {
storageService.storeProfile(root.profile, function(err) {
- $rootScope.$emit('Local/ProfileCreated');
+ var config = configService.getSync();
if (config.pushNotifications.enabled)
pushNotificationsService.enableNotifications(root.walletClients);
return cb(err, walletId);
});
+
});
});
});
};
+ root.storeProfileIfDirty = function(cb) {
+ if (root.profile.dirty) {
+ storageService.storeProfile(root.profile, function(err) {
+ $log.debug('Saved modified Profile');
+ if (cb) return cb(err);
+ });
+ } else {
+ if (cb) return cb();
+ };
+ };
+
root.importWallet = function(str, opts, cb) {
var walletClient = bwcService.getClient(null, opts);
@@ -491,7 +516,13 @@ angular.module('copayApp.services')
var addressBook = str.addressBook || {};
var historyCache = str.historyCache || [];
- root._addWalletClient(walletClient, opts, function(err, walletId) {
+ if (!walletClient.incorrectDerivation)
+ root.profile.setChecked(platformInfo.ua, walletClient.credentials.walletId);
+
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl,
+ isImport: true
+ }, function(err, walletId) {
if (err) return cb(err);
root.setMetaData(walletClient, addressBook, historyCache, function(error) {
if (error) $log.warn(error);
@@ -508,7 +539,10 @@ angular.module('copayApp.services')
if (err)
return bwsError.cb(err, gettext('Could not import'), cb);
- root._addWalletClient(walletClient, opts, cb);
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl,
+ isImport: true
+ }, cb);
});
};
@@ -533,7 +567,10 @@ angular.module('copayApp.services')
if (err)
return bwsError.cb(err, gettext('Could not import'), cb);
- root._addWalletClient(walletClient, opts, cb);
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl,
+ isImport: true
+ }, cb);
});
};
@@ -554,16 +591,20 @@ angular.module('copayApp.services')
return bwsError.cb(err, gettext('Could not import'), cb);
}
- root._addWalletClient(walletClient, opts, cb);
+ root.addAndBindWalletClient(walletClient, {
+ bwsurl: opts.bwsurl,
+ isImport: true
+ }, cb);
});
};
root.create = function(opts, cb) {
- $log.info('Creating profile');
+ $log.info('Creating profile', opts);
var defaults = configService.getDefaults();
configService.get(function(err) {
- root._createNewProfile(opts, function(err, p) {
+
+ root.createDefaultProfile(opts, function(err, p) {
if (err) return cb(err);
root.bindProfile(p, function(err) {
@@ -605,59 +646,45 @@ angular.module('copayApp.services')
walletClient.createWalletFromOldCopay(username, password, blob, function(err, existed) {
if (err) return cb(gettext('Error importing wallet: ') + err);
- if (root.walletClients[walletClient.credentials.walletId]) {
+ if (root.profile.hasWallet(walletClient.credentials.walletId)) {
$log.debug('Wallet:' + walletClient.credentials.walletName + ' already imported');
return cb(gettext('Wallet Already Imported: ') + walletClient.credentials.walletName);
};
- $log.debug('Creating Wallet:', walletClient.credentials.walletName);
- root.profile.credentials.push(JSON.parse(walletClient.export()));
- root.setWalletClients();
- root.setAndStoreFocus(walletClient.credentials.walletId, function() {
- storageService.storeProfile(root.profile, function(err) {
- return cb(null, walletClient.credentials.walletId, walletClient.credentials.walletName, existed);
- });
- });
+ root.addAndBindWalletClient(walletClient, {
+ isImport: true
+ }, cb);
});
};
- root.updateCredentialsFC = function(cb) {
- var fc = root.focusedClient;
-
- var newCredentials = lodash.reject(root.profile.credentials, {
- walletId: fc.credentials.walletId
- });
- newCredentials.push(JSON.parse(fc.export()));
- root.profile.credentials = newCredentials;
-
+ root.updateCredentials = function(credentials, cb) {
+ root.profile.updateWallet(credentials);
storageService.storeProfileThrottled(root.profile, cb);
};
+ root.getClients = function() {
+ return lodash.values(root.walletClients);
+ };
- root.setPrivateKeyEncryptionFC = function(password, cb) {
- var fc = root.focusedClient;
- $log.debug('Encrypting private key for', fc.credentials.walletName);
+ root.needsBackup = function(client, cb) {
- fc.setPrivateKeyEncryption(password);
- fc.lock();
- root.updateCredentialsFC(function() {
- $log.debug('Wallet encrypted');
- return cb();
+ if (!walletService.needsBackup(client))
+ return cb(false);
+
+ storageService.getBackupFlag(client.credentials.walletId, function(err, val) {
+ if (err) $log.error(err);
+ if (val) return cb(false);
+ return cb(true);
});
};
+ root.isReady = function(client, cb) {
+ if (!client.isComplete())
+ return cb('WALLET_NOT_COMPLETE');
- root.disablePrivateKeyEncryptionFC = function(cb) {
- var fc = root.focusedClient;
- $log.debug('Disabling private key encryption for', fc.credentials.walletName);
-
- try {
- fc.disablePrivateKeyEncryption();
- } catch (e) {
- return cb(e);
- }
- root.updateCredentialsFC(function() {
- $log.debug('Wallet encryption disabled');
+ root.needsBackup(client, function(needsBackup) {
+ if (needsBackup)
+ return cb('WALLET_NEEDS_BACKUP');
return cb();
});
};
diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js
index faf7e14e9..d144c26f2 100644
--- a/src/js/services/storageService.js
+++ b/src/js/services/storageService.js
@@ -24,21 +24,6 @@ angular.module('copayApp.services')
}, cb);
};
- var encryptOnMobile = function(text, cb) {
-
- // UUID encryption is disabled.
- return cb(null, text);
- //
- // getUUID(function(uuid) {
- // if (uuid) {
- // $log.debug('Encrypting profile');
- // text = sjcl.encrypt(uuid, text);
- // }
- // return cb(null, text);
- // });
- };
-
-
var decryptOnMobile = function(text, cb) {
var json;
try {
@@ -107,18 +92,14 @@ angular.module('copayApp.services')
};
root.storeNewProfile = function(profile, cb) {
- encryptOnMobile(profile.toObj(), function(err, x) {
- storage.create('profile', x, cb);
- });
+ storage.create('profile', profile.toObj(), cb);
};
root.storeProfile = function(profile, cb) {
- encryptOnMobile(profile.toObj(), function(err, x) {
- storage.set('profile', x, cb);
- });
+ storage.set('profile', profile.toObj(), cb);
};
- root.storeProfileThrottled = lodash.throttle(root.storeProfile, 5000);
+ root.storeProfileThrottled = lodash.throttle(root.storeProfile, 5000);
root.getProfile = function(cb) {
storage.get('profile', function(err, str) {
@@ -293,5 +274,17 @@ angular.module('copayApp.services')
storage.remove('coinbaseTxs-' + network, cb);
};
+ root.removeAllWalletData = function(walletId, cb) {
+ root.clearLastAddress(walletId, function(err) {
+ if (err) return cb(err);
+ root.removeTxHistory(walletId, function(err) {
+ if (err) return cb(err);
+ root.clearBackupFlag(walletId, function(err) {
+ return cb(err);
+ });
+ });
+ });
+ };
+
return root;
});
diff --git a/src/js/services/uxLanguage.js b/src/js/services/uxLanguage.js
index 9a20320ac..8c5b6d90a 100644
--- a/src/js/services/uxLanguage.js
+++ b/src/js/services/uxLanguage.js
@@ -3,6 +3,8 @@ angular.module('copayApp.services')
.factory('uxLanguage', function languageService($log, lodash, gettextCatalog, amMoment, configService) {
var root = {};
+ root.currentLanguage = null;
+
root.availableLanguages = [{
name: 'English',
isoCode: 'en',
@@ -33,7 +35,6 @@ angular.module('copayApp.services')
isoCode: 'ru',
}];
- root.currentLanguage = null;
root._detect = function(cb) {
@@ -99,20 +100,20 @@ angular.module('copayApp.services')
var userLang = configService.getSync().wallet.settings.defaultLanguage;
if (!userLang) {
-
root._detect(function(lang) {
userLang = lang;
if (userLang != root.currentLanguage) {
root._set(lang);
}
- return cb(userLang);
+ if (cb) return cb(userLang);
});
} else {
if (userLang != root.currentLanguage) {
root._set(userLang);
}
- return cb(userLang);
+
+ if (cb) return cb(userLang);
}
};
diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js
index c2d060a53..1578a279f 100644
--- a/src/js/services/walletService.js
+++ b/src/js/services/walletService.js
@@ -1,6 +1,9 @@
'use strict';
-angular.module('copayApp.services').factory('walletService', function($log, lodash, trezor, ledger, storageService) {
+// DO NOT INCLUDE STORAGE HERE \/ \/
+angular.module('copayApp.services').factory('walletService', function($log, lodash, trezor, ledger, storageService, configService, uxLanguage) {
+// DO NOT INCLUDE STORAGE HERE ^^
+
var root = {};
var _signWithLedger = function(client, txp, cb) {
@@ -31,27 +34,14 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
});
};
- root.isBackupNeeded = function(client, cb) {
- if (client.isPrivKeyExternal()) return cb(false);
- if (!client.credentials.mnemonic) return cb(false);
- if (client.credentials.network == 'testnet') return cb(false);
+ root.needsBackup = function(client) {
+ if (client.isPrivKeyExternal()) return false;
+ if (!client.credentials.mnemonic) return false;
+ if (client.credentials.network == 'testnet') return false;
- storageService.getBackupFlag(client.credentials.walletId, function(err, val) {
- if (err) $log.error(err);
- if (val) return cb(false);
- return cb(true);
- });
+ return true;
};
- root.isReady = function(client, cb) {
- if(!client.isComplete())
- return cb('WALLET_NOT_COMPLETE');
- root.isBackupNeeded(client, function(needsBackup) {
- if (needsBackup)
- return cb('WALLET_NEEDS_BACKUP');
- return cb();
- });
- };
root.isEncrypted = function(client) {
if (lodash.isEmpty(client)) return;
@@ -82,7 +72,7 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.createTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
if (txp.sendMax) {
@@ -97,7 +87,7 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
var feeLevelValue = lodash.find(levels, {
level: txp.feeLevel
});
-
+
if (!feeLevelValue || !feeLevelValue.feePerKB)
return cb({
message: 'Could not get dynamic fee for level: ' + feeLevel
@@ -118,10 +108,12 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.publishTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
- client.publishTxProposal({txp: txp}, function(err, publishedTx) {
+ client.publishTxProposal({
+ txp: txp
+ }, function(err, publishedTx) {
if (err) return cb(err);
else {
$log.debug('Transaction published');
@@ -131,9 +123,9 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.signTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
-
+
if (client.isPrivKeyExternal()) {
switch (client.getPrivKeyExternalSourceName()) {
case 'ledger':
@@ -160,14 +152,14 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.broadcastTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
-
+
if (txp.status != 'accepted')
return cb('TX_NOT_ACCEPTED');
client.broadcastTxProposal(txp, function(err, broadcastedTxp, memo) {
- if (err)
+ if (err)
return cb(err);
$log.debug('Transaction broadcasted');
@@ -178,9 +170,9 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.rejectTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
-
+
client.rejectTxProposal(txp, null, function(err, rejectedTxp) {
$log.debug('Transaction rejected');
return cb(err, rejectedTxp);
@@ -188,14 +180,50 @@ angular.module('copayApp.services').factory('walletService', function($log, loda
};
root.removeTx = function(client, txp, cb) {
- if (lodash.isEmpty(txp) || lodash.isEmpty(client))
+ if (lodash.isEmpty(txp) || lodash.isEmpty(client))
return cb('MISSING_PARAMETER');
-
+
client.removeTxProposal(txp, function(err) {
$log.debug('Transaction removed');
return cb(err);
});
};
+ root.updateRemotePreferences = function(clients, prefs, cb) {
+ prefs = prefs || {};
+
+ if (!lodash.isArray(clients))
+ clients = [clients];
+
+ function updateRemotePreferencesFor(clients, prefs, cb) {
+ var client = clients.shift();
+ if (!client) return cb();
+ $log.debug('Saving remote preferences', client.credentials.walletName, prefs);
+
+ client.savePreferences(prefs, function(err) {
+ // we ignore errors here
+ if (err) $log.warn(err);
+
+ updateRemotePreferencesFor(clients, prefs, cb);
+ });
+ };
+
+ // Update this JIC.
+ var config = configService.getSync().wallet.settings;
+
+ //prefs.email (may come from arguments)
+ prefs.language = uxLanguage.getCurrentLanguage();
+ prefs.unit = config.unitCode;
+
+ updateRemotePreferencesFor(clients, prefs, function(err) {
+ if (err) return cb(err);
+
+ lodash.each(clients, function(c) {
+ c.preferences = lodash.assign(prefs, c.preferences);
+ });
+ return cb();
+ });
+ };
+
return root;
});
diff --git a/test/controllers/create.test.js b/test/controllers/create.test.js
index ebc87495f..bf09bfda7 100644
--- a/test/controllers/create.test.js
+++ b/test/controllers/create.test.js
@@ -1,6 +1,9 @@
describe('createController', function() {
var fixtures = {
+ // Store prefs
+ '1eda3e702196b8d5d82fae129249bc79f0d5be2f5309a4e39855e7eb4ad31428': {},
+ '31f5deeef4cf7fd8fc67297179232e8e4590532960454ad958009132fef3daae': {},
// createWallet 1-1
'56db6f58f2c212591afb4d508d03e5fb40bb786f23dc56c43b98bde42dc513e5': {
"walletId": "267bfa75-5575-4af7-8aa3-f5186bc99262"
diff --git a/test/controllers/disclaimer.test.js b/test/controllers/disclaimer.test.js
new file mode 100644
index 000000000..5502aecce
--- /dev/null
+++ b/test/controllers/disclaimer.test.js
@@ -0,0 +1,79 @@
+describe('disclaimerController', function() {
+ var walletService;
+ var storeProfile;
+
+ var fixtures = {
+ '8dc332881e99c908c655147dc6bc605e102b0bd3cf2dbee02ed2a0f4daf2925a': {
+ "walletId": "eddaef15-f412-462f-9d3e-a793a7f6f6ba"
+ },
+ '654145bc3f15f03a8b1ccf55aa1bdcd1cfd5bbe3de90e909fd4e7f9f69ec4d79': {
+ "copayerId": "1a91ead1b6d13da882a25377a20e460df557e77008ea4f60eecbf984f786cf03",
+ "wallet": {
+ "version": "1.0.0",
+ "createdOn": 1465152783,
+ "id": "eddaef15-f412-462f-9d3e-a793a7f6f6ba",
+ "name": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"/gaG7FIkhCiwsWKZUR0sL/cxH+zHMK0=\"}",
+ "m": 1,
+ "n": 1,
+ "status": "complete",
+ "publicKeyRing": [{
+ "xPubKey": "xpub6Cb7MYAX7mJR28MfFueCsoDVVHhoWkQxRC4viAeHanYwRNgDo5xMF42xmAeExzfyPXX3GaALNA8hWFMekVYvDF2BALommUhMgZ52szh88fd",
+ "requestPubKey": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd"
+ }],
+ "copayers": [{
+ "version": 2,
+ "createdOn": 1465152783,
+ "xPubKey": "xpub6Cb7MYAX7mJR28MfFueCsoDVVHhoWkQxRC4viAeHanYwRNgDo5xMF42xmAeExzfyPXX3GaALNA8hWFMekVYvDF2BALommUhMgZ52szh88fd",
+ "id": "1a91ead1b6d13da882a25377a20e460df557e77008ea4f60eecbf984f786cf03",
+ "name": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"wwZd+2LQgYR6cA==\"}",
+ "requestPubKey": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd",
+ "signature": "3045022100ac3f31ef145eabde6a125958aa9d63c2bd4aa27717d7f6905c3e3ff1e733ee8e02206a43200b775ee5c8f7a85c4d3309d155240d5de46a7d9c5e60045bf49779f40b",
+ "requestPubKeys": [{
+ "key": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd",
+ "signature": "3045022100ac3f31ef145eabde6a125958aa9d63c2bd4aa27717d7f6905c3e3ff1e733ee8e02206a43200b775ee5c8f7a85c4d3309d155240d5de46a7d9c5e60045bf49779f40b"
+ }],
+ "customData": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"9l63hoVnA71LshCC5xbOTHA+ivBzux7u8SAci56p4aaVIF4qzXQhQKFX+sAFGfBjULm/E1st6awdXnxbAgjbF7D0zsbBFLFOSCw+ko5Xc6o=\"}"
+ }],
+ "pubKey": "026d95bb5cc2a30c19e22379ae78b4757aaa2dd0ccbd15a1db054fb50cb98ed361",
+ "network": "livenet",
+ "derivationStrategy": "BIP44",
+ "addressType": "P2PKH",
+ "addressManager": {
+ "version": 2,
+ "derivationStrategy": "BIP44",
+ "receiveAddressIndex": 0,
+ "changeAddressIndex": 0,
+ "copayerIndex": 2147483647
+ },
+ "scanStatus": null
+ }
+ },
+ }; // TODO: Read from file
+
+ beforeEach(function(done) {
+ mocks.init(fixtures, 'disclaimerController', {
+ initController: true,
+ noDisclaimer: true,
+ }, done);
+ });
+
+ afterEach(function(done) {
+ mocks.clear({}, done);
+ });
+
+ it('should be defined', function() {
+ should.exist(ctrl);
+ });
+
+ it('should create the initial profile', function(done) {
+ localStorage.clear();
+ ctrl.init({
+ walletPrivKey: 'Kz4CFSTgLzoYfMkt97BTBotUbZYXjMts6Ej9HbVfCf5oLmun1BXy',
+ mnemonic: 'tunnel fork scare industry noble snow tank bullet over gesture nuclear next',
+ });
+ setTimeout(function() {
+ ctrl.creatingProfile.should.equal(false);
+ done();
+ }, 100);
+ });
+});
diff --git a/test/controllers/import.test.js b/test/controllers/import.test.js
index ec8ca9f91..7d7b8dc2f 100644
--- a/test/controllers/import.test.js
+++ b/test/controllers/import.test.js
@@ -3,6 +3,7 @@ describe('importController', function() {
var storeProfile;
var fixtures = {
+ '31f5deeef4cf7fd8fc67297179232e8e4590532960454ad958009132fef3daae': {},
'4599136eff6deb4c9c78043fa84113617a16d75c45920d662305f6227ae8f0a0': {
"wallet": {
"version": "1.0.0",
diff --git a/test/controllers/index.test.js b/test/controllers/index.test.js
index 5709b1a26..140e30b38 100644
--- a/test/controllers/index.test.js
+++ b/test/controllers/index.test.js
@@ -60,7 +60,7 @@ describe('index', function() {
});
- it('should updates remote preferences', function(done) {
+ it.skip('should updates remote preferences', function(done) {
ctrl.updateRemotePreferences({}, function() {
done();
});
diff --git a/test/controllers/walletHome.test.js b/test/controllers/walletHome.test.js
index e1f9026b2..5fa381bcc 100644
--- a/test/controllers/walletHome.test.js
+++ b/test/controllers/walletHome.test.js
@@ -12,7 +12,6 @@ describe('walletHome', function() {
mocks.clear({}, done);
});
-
it('should be defined', function() {
should.exist(ctrl);
});
diff --git a/test/fixtures.js b/test/fixtures.js
index c52086642..6d3664618 100644
--- a/test/fixtures.js
+++ b/test/fixtures.js
@@ -52,6 +52,9 @@ var walletInfo = {
var FIXTURES = {
+ // store preferences
+ '1eda3e702196b8d5d82fae129249bc79f0d5be2f5309a4e39855e7eb4ad31428': {},
+
// Incomplete wallet status
'd05582c35aa545494e3f3be9713efa9df112d36a324350f6b7141996b824bce2': walletInfo,
// ^ same thing, twostep=1
diff --git a/test/helpers.js b/test/helpers.js
index 19c15b632..01cc65ff5 100644
--- a/test/helpers.js
+++ b/test/helpers.js
@@ -82,7 +82,9 @@ mocks.init = function(fixtures, controllerName, opts, done) {
module('ionic');
module('ngLodash');
+ module('angularMoment');
module('gettext');
+ module('stateMock');
module('bwcModule', function($provide) {
$provide.decorator('bwcService', function($delegate, lodash) {
var getClient = $delegate.getClient;
@@ -154,8 +156,6 @@ mocks.init = function(fixtures, controllerName, opts, done) {
});
});
- module('angularMoment');
- module('stateMock');
module('copayApp.services', {
$modal: mocks.modal,
$timeout: mocks.$timeout,
@@ -220,6 +220,9 @@ mocks.init = function(fixtures, controllerName, opts, done) {
noWallet: true
}, function(err) {
should.not.exist(err, err);
+ if (opts.noDisclaimer){
+ return done();
+ }
_profileService_.setDisclaimerAccepted(function() {
if (!opts.initController)
startController();
diff --git a/test/walletService.test.js b/test/walletService.test.js
index 8e592770f..9dd11f549 100644
--- a/test/walletService.test.js
+++ b/test/walletService.test.js
@@ -7,6 +7,7 @@ describe('walletService', function() {
beforeEach(function() {
module('ngLodash');
module('gettext');
+ module('angularMoment');
module('bwcModule');
module('copayApp.services');
});