diff --git a/Gruntfile.js b/Gruntfile.js index 099cd23bd..540a676b0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -43,6 +43,7 @@ module.exports = function(grunt) { scripts: { files: [ 'js/models/**/*.js', + 'js/models/*.js', 'plugins/*.js', 'copay.js', 'utils/*.js' diff --git a/config.js b/config.js index 10b5dafe7..94dc2a829 100644 --- a/config.js +++ b/config.js @@ -53,12 +53,13 @@ var defaultConfig = { verbose: 1, plugins: { - LocalStorage: true, - // GoogleDrive: true, +// LocalStorage: true, + GoogleDrive: true, }, GoogleDrive: { - clientId: '1', + clientId: '232630733383-29u1khqf5i8qubhf0homhpb2m14b5lja.apps.googleusercontent.com', + home: 'copay' }, }; if (typeof module !== 'undefined') diff --git a/js/app.js b/js/app.js index e1a3826ee..216553f20 100644 --- a/js/app.js +++ b/js/app.js @@ -37,11 +37,10 @@ var modules = [ 'copayApp.directives', ]; -if (config.plugins.length) +if (Object.keys(config.plugins).length) modules.push('angularLoad'); - var copayApp = window.copayApp = angular.module('copayApp', modules); copayApp.config(function($sceDelegateProvider) { diff --git a/js/controllers/home.js b/js/controllers/home.js index 2ac3e7381..c8a73d862 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -1,10 +1,13 @@ 'use strict'; -angular.module('copayApp.controllers').controller('HomeController', - function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { - - controllerUtils.redirIfLogged(); +angular.module('copayApp.controllers').controller('HomeController', function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { + controllerUtils.redirIfLogged(); + + $scope.loading = true; + + walletFactory.getWallets(function(ret) { $scope.loading = false; - $scope.hasWallets = (walletFactory.getWallets() && walletFactory.getWallets().length > 0) ? true : false; + $scope.hasWallets = (ret && ret.length > 0) ? true : false; }); +}); diff --git a/js/controllers/open.js b/js/controllers/open.js index 019932988..005bba83d 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -14,12 +14,18 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc }; $rootScope.fromSetup = false; $scope.loading = false; - $scope.wallets = walletFactory.getWallets().sort(cmp); - $scope.selectedWalletId = walletFactory.storage.getLastOpened() || ($scope.wallets[0] && $scope.wallets[0].id); + walletFactory.getWallets(function(wallets) { + $scope.wallets = wallets.sort(cmp); + }); + + walletFactory.storage.getLastOpened(function(ret) { + $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + }); + $scope.openPassword = ''; $scope.isMobile = !!window.cordova; - if (!$scope.wallets.length){ + if (!$scope.wallets.length) { $location.path('/'); } @@ -34,19 +40,15 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc Passphrase.getBase64Async(password, function(passphrase) { var w, errMsg; - try { - w = walletFactory.open($scope.selectedWalletId, passphrase); - } catch (e) { - errMsg = e.message; - }; - if (!w) { - $scope.loading = false; - notification.error('Error', errMsg || 'Wrong password'); - $rootScope.$digest(); - return; - } - $rootScope.updatingBalance = true; - controllerUtils.startNetwork(w, $scope); + walletFactory.open($scope.selectedWalletId, passphrase, function(err, w) { + if (!w) { + $scope.loading = false; + notification.error('Error', err.errMsg || 'Wrong password'); + $rootScope.$digest(); + } + $rootScope.updatingBalance = true; + controllerUtils.startNetwork(w, $scope); + }); }); }; diff --git a/js/models/Storage.js b/js/models/Storage.js index 6a0c378e7..17757192f 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -1,5 +1,5 @@ 'use strict'; - +var preconditions = require('preconditions').singleton(); var CryptoJS = require('node-cryptojs-aes').CryptoJS; var bitcore = require('bitcore'); var preconditions = require('preconditions').instance(); @@ -55,38 +55,50 @@ Storage.prototype._decrypt = function(base64) { }; -Storage.prototype._read = function(k) { - var ret; - ret = this.storage.getItem(k); - if (!ret) return null; - ret = this._decrypt(ret); - if (!ret) return null; - ret = ret.toString(CryptoJS.enc.Utf8); - ret = JSON.parse(ret); - return ret; +Storage.prototype._read = function(k, cb) { + preconditions.checkArgument(cb); + + var self = this; + this.storage.getItem(k, function(ret) { + if (!ret) return cb(null); + var ret = self._decrypt(ret); + if (!ret) return cb(null); + + ret = ret.toString(CryptoJS.enc.Utf8); + ret = JSON.parse(ret); + return cb(ret); + }); }; -Storage.prototype._write = function(k, v) { +Storage.prototype._write = function(k, v, cb) { + preconditions.checkArgument(cb); + v = JSON.stringify(v); v = this._encrypt(v); - - this.storage.setItem(k, v); + this.storage.setItem(k, v, cb); }; // get value by key -Storage.prototype.getGlobal = function(k) { - var item = this.storage.getItem(k); - return item == 'undefined' ? undefined : item; +Storage.prototype.getGlobal = function(k, cb) { + preconditions.checkArgument(cb); + + this.storage.getItem(k, function(item) { + cb(item == 'undefined' ? undefined : item); + }); }; // set value for key -Storage.prototype.setGlobal = function(k, v) { - this.storage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v); +Storage.prototype.setGlobal = function(k, v, cb) { + preconditions.checkArgument(cb); + + this.storage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v, cb); }; // remove value for key -Storage.prototype.removeGlobal = function(k) { - this.storage.removeItem(k); +Storage.prototype.removeGlobal = function(k, cb) { + preconditions.checkArgument(cb); + + this.storage.removeItem(k, cb); }; Storage.prototype.getSessionId = function() { @@ -102,23 +114,38 @@ Storage.prototype._key = function(walletId, k) { return walletId + '::' + k; }; // get value by key -Storage.prototype.get = function(walletId, k) { - var ret = this._read(this._key(walletId, k)); - return ret; +Storage.prototype.get = function(walletId, k, cb) { + this._read(this._key(walletId, k), cb); +}; + +Storage.prototype.getMany = function(walletId, keys, cb) { + preconditions.checkArgument(cb); + + var self = this; + var ret = {}; + + var l = keys.length - 1; + for (var ii in keys) { + var k = keys[ii]; + this._read(this._key(walletId, k), function(v) { + ret[k] = v; + if (ii == l) return cb(ret); + }); + } }; // set value for key -Storage.prototype.set = function(walletId, k, v) { - this._write(this._key(walletId, k), v); +Storage.prototype.set = function(walletId, k, v, cb) { + this._write(this._key(walletId, k), v, cb); }; // remove value for key -Storage.prototype.remove = function(walletId, k) { - this.removeGlobal(this._key(walletId, k)); +Storage.prototype.remove = function(walletId, k, cb) { + this.removeGlobal(this._key(walletId, k), cb); }; -Storage.prototype.setName = function(walletId, name) { - this.setGlobal('nameFor::' + walletId, name); +Storage.prototype.setName = function(walletId, name, cb) { + this.setGlobal('nameFor::' + walletId, name, cb); }; Storage.prototype.getName = function(walletId) { @@ -126,41 +153,54 @@ Storage.prototype.getName = function(walletId) { return ret; }; -Storage.prototype.getWalletIds = function() { +Storage.prototype.getWalletIds = function(cb) { var walletIds = []; var uniq = {}; -console.log('[Encrypted.js.144]', this.storage); //TODO -console.log('[Encrypted.js.144]', this.storage.length); //TODO - for (var i = 0; i < this.storage.length; i++) { - var key = this.storage.key(i); - var split = key.split('::'); - if (split.length == 2) { - var walletId = split[0]; + this.storage.allKeys(function(keys) { +console.log('[Storage.js.170:keys:]',keys); //TODO - if (!walletId || walletId === 'nameFor' || walletId === 'lock') - continue; + for (var ii in keys) { + var key = keys[ii]; +console.log('[Storage.js.174:key:]',key); //TODO + var split = key.split('::'); + if (split.length == 2) { + var walletId = split[0]; - if (typeof uniq[walletId] === 'undefined') { - walletIds.push(walletId); - uniq[walletId] = 1; + if (!walletId || walletId === 'nameFor' || walletId === 'lock') + continue; + + if (typeof uniq[walletId] === 'undefined') { + walletIds.push(walletId); + uniq[walletId] = 1; + } } } - } - return walletIds; + return cb(walletIds); + }); }; -Storage.prototype.getWallets = function() { +Storage.prototype.getWallets = function(cb) { var wallets = []; - var ids = this.getWalletIds(); + var self = this; - for (var i in ids) { - wallets.push({ - id: ids[i], - name: this.getName(ids[i]), - }); - } - return wallets; + this.getWalletIds(function(ids) { + var l = ids.length - 1; + if (!l) + return cb([]); + + for (var i in ids) { + self.getName(ids[i], function(name) { + wallets.push({ + id: ids[i], + name: name, + }); + if (i == l) { + return cb(wallets); + } + }) + } + }); }; Storage.prototype.deleteWallet = function(walletId) { @@ -179,25 +219,35 @@ Storage.prototype.deleteWallet = function(walletId) { } }; -Storage.prototype.setLastOpened = function(walletId) { - this.setGlobal('lastOpened', walletId); +Storage.prototype.setLastOpened = function(walletId, cb) { + this.setGlobal('lastOpened', walletId, cb); } -Storage.prototype.getLastOpened = function() { - return this.getGlobal('lastOpened'); +Storage.prototype.getLastOpened = function(cb) { + this.getGlobal('lastOpened', cb); } //obj contains keys to be set -Storage.prototype.setFromObj = function(walletId, obj) { +Storage.prototype.setFromObj = function(walletId, obj, cb) { + preconditions.checkArgument(cb); + var self = this; + + console.log('[Storage.js.241]'); //TODO + var l = Object.keys(obj).length, + i = 0; for (var k in obj) { - this.set(walletId, k, obj[k]); + console.log('[Storage.js.247]', k, i, l); //TODO + self.set(walletId, k, obj[k], function() { + if (++i == l) { + self.setName(walletId, obj.opts.name, cb); + } + }); } - this.setName(walletId, obj.opts.name); }; // remove all values -Storage.prototype.clearAll = function() { - this.storage.clear(); +Storage.prototype.clearAll = function(cb) { + this.storage.clear(cb); }; Storage.prototype.import = function(base64) { diff --git a/js/models/core/PluginManager.js b/js/models/core/PluginManager.js index 23b3c2a77..bce94e464 100644 --- a/js/models/core/PluginManager.js +++ b/js/models/core/PluginManager.js @@ -3,8 +3,9 @@ var preconditions = require('preconditions').singleton(); function PluginManager(config) { this.registered = {}; + this.scripts = []; - for(var ii in config.plugins){ + for (var ii in config.plugins) { var pluginName = ii; if (!config.plugins[pluginName]) @@ -12,7 +13,7 @@ function PluginManager(config) { console.log('Loading plugin: ' + pluginName); var pluginClass = require('../plugins/' + pluginName); - var pluginObj = new pluginClass(); + var pluginObj = new pluginClass(config[pluginName]); pluginObj.init(); this._register(pluginObj, pluginName); } @@ -25,9 +26,10 @@ PluginManager.TYPE = {}; PluginManager.TYPE['STORAGE'] = KIND_UNIQUE; PluginManager.prototype._register = function(obj, name) { - preconditions.checkArgument(obj.type,'Plugin has not type:' + name); + preconditions.checkArgument(obj.type, 'Plugin has not type:' + name); var type = obj.type; var kind = PluginManager.TYPE[type]; + preconditions.checkArgument(kind, 'Plugin has unkown type' + name); preconditions.checkState(kind !== PluginManager.KIND_UNIQUE || !this.registered[type], 'Plugin kind already registered: ' + name); @@ -37,8 +39,11 @@ PluginManager.prototype._register = function(obj, name) { this.registered[type] = this.registered[type] || []; this.registered[type].push(obj); } + + this.scripts = this.scripts.concat(obj.scripts || []); }; + PluginManager.prototype.get = function(type) { return this.registered[type]; }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 61e81b137..6ab010c5a 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -821,21 +821,28 @@ Wallet.prototype.getRegisteredPeerIds = function() { * @emits locked - in case the wallet is opened in another instance */ Wallet.prototype.keepAlive = function() { - try { - this.lock.keepAlive(); - } catch (e) { - log.debug(e); - this.emit('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); - } + var self = this; + + this.lock.keepAlive(function(err) { + if (err) { + log.debug(err); + self.emit('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); + } + }); }; /** * @desc Store the wallet's state + * @param {function} callback (err) */ -Wallet.prototype.store = function() { +Wallet.prototype.store = function(cb) { + var self = this; this.keepAlive(); - this.storage.setFromObj(this.id, this.toObj()); - log.debug('Wallet stored'); + this.storage.setFromObj(this.id, this.toObj(), function(err) { + log.debug('Wallet stored'); + if (cb) + cb(err); + }); }; /** @@ -2339,11 +2346,14 @@ Wallet.prototype.indexDiscovery = function(start, change, copayerIndex, gap, cb) /** * @desc Closes the wallet and disconnects all services */ -Wallet.prototype.close = function() { +Wallet.prototype.close = function(cb) { + var self =this; log.debug('## CLOSING'); - this.lock.release(); - this.network.cleanUp(); - this.blockchain.destroy(); + this.lock.release(function() { + self.network.cleanUp(); + self.blockchain.destroy(); + if (cb) return cb(); + }); }; /** diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 2efea81de..f164c533f 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -1,4 +1,5 @@ 'use strict'; +var preconditions = require('preconditions').singleton(); var TxProposals = require('./TxProposals'); var PublicKeyRing = require('./PublicKeyRing'); @@ -6,7 +7,7 @@ var PrivateKey = require('./PrivateKey'); var Wallet = require('./Wallet'); var _ = require('underscore'); var log = require('../../log'); -var PluginManager = require('./PluginManager'); +var PluginManager = require('./PluginManager'); var Async = module.exports.Async = require('../network/Async'); var Insight = module.exports.Insight = require('../blockchain/Insight'); var preconditions = require('preconditions').singleton(); @@ -33,16 +34,24 @@ var Storage = module.exports.Storage = require('../Storage'); * @param {string} version - the version of copay for which this wallet was generated (for example, 0.4.7) * @constructor */ -function WalletFactory(config, version) { + +function WalletFactory(config, version, pluginManager) { var self = this; config = config || {}; - this.pluginManager = new PluginManager(config); - - this.Storage = config.Storage || Storage; + this.Storage = config.Storage || Storage; this.Network = config.Network || Async; this.Blockchain = config.Blockchain || Insight; - this.storage = new this.Storage({storage: this.pluginManager.get('STORAGE')}); + + var storageOpts = {}; + + if (pluginManager) { + storageOpts = { + storage: pluginManager.get('STORAGE') + }; + } + + this.storage = new this.Storage(storageOpts); this.networks = { 'livenet': new this.Network(config.network.livenet), @@ -57,27 +66,6 @@ function WalletFactory(config, version) { this.version = version; }; -/** - * @desc - * Returns true if the storage instance can retrieve the following keys using a given walletId - * - * @param {string} walletId - * @return {boolean} true if all the keys are present in the storage instance - */ -WalletFactory.prototype._checkRead = function(walletId) { - var s = this.storage; - var ret = - s.get(walletId, 'publicKeyRing') && - s.get(walletId, 'txProposals') && - s.get(walletId, 'opts') && - s.get(walletId, 'privateKey'); - return !!ret; -}; /** * @desc obtain network name from serialized wallet @@ -100,9 +88,14 @@ WalletFactory.prototype.obtainNetworkName = function(obj) { WalletFactory.prototype.fromObj = function(obj, skipFields) { var networkName = this.obtainNetworkName(obj); preconditions.checkState(networkName); + preconditions.checkArgument(obj); + obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; + // this is only used if private key or public key ring is skipped + obj.opts.networkName = this.networkName; + skipFields = skipFields || []; skipFields.forEach(function(k) { if (obj[k]) { @@ -155,20 +148,17 @@ WalletFactory.prototype.import = function(base64, password, skipFields) { * @param {string[]} skipFields - parameters to ignore when importing * @return {Wallet} */ -WalletFactory.prototype.read = function(walletId, skipFields) { - if (!this._checkRead(walletId)) - return false; - +WalletFactory.prototype.read = function(walletId, skipFields, cb) { + var self = this; var obj = {}; - var s = this.storage; - obj.id = walletId; - _.each(Wallet.PERSISTED_PROPERTIES, function(value) { - obj[value] = s.get(walletId, value); - }); - var w = this.fromObj(obj, skipFields); - return w; + this.storage.getMany(walletId, Wallet.PERSISTED_PROPERTIES, function(ret) { + for (var ii in ret) { + obj[ii] = ret[ii]; + } + return cb(self.fromObj(obj, skipFields)); + }); }; /** @@ -269,29 +259,29 @@ WalletFactory.prototype._checkVersion = function(inVersion) { * @desc Retrieve a wallet from the storage * @param {string} walletId - the id of the wallet * @param {string} passphrase - the passphrase to decode it - * @return {Wallet} + * @param {function} callback (err, {Wallet}) + * @return */ -WalletFactory.prototype.open = function(walletId, passphrase) { - this.storage._setPassphrase(passphrase); - var w = this.read(walletId); - if (w) { - w.store(); - } - - this.storage.setLastOpened(walletId); - return w; +WalletFactory.prototype.open = function(walletId, passphrase, cb) { + var self = this, + err; + self.storage._setPassphrase(passphrase); + self.read(walletId, null, function(w) { + w.store(function() { + self.storage.setLastOpened(walletId, function() { + return cb(err, w); + }); + }); + }); }; -/** - * @desc Retrieve all wallets stored without encription in the storage instance - * @returns {Wallet[]} - */ -WalletFactory.prototype.getWallets = function() { - var ret = this.storage.getWallets(); - ret.forEach(function(i) { - i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; +WalletFactory.prototype.getWallets = function(cb) { + var ret = this.storage.getWallets(function(ret) { + ret.forEach(function(i) { + i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; + }); + return cb(ret); }); - return ret; }; /** @@ -374,30 +364,32 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras connectedOnce = true; }); - joinNetwork.on('serverError', function() { - return cb('joinError'); - }); + << << << < HEAD + joinNetwork.on('serverError', function() { === === = + self.network.on('serverError', function() { >>> >>> > wallet listing working + return cb('joinError'); + }); - joinNetwork.start(opts, function() { - joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); - joinNetwork.on('data', function(sender, data) { - if (data.type === 'walletId') { - if (data.networkName !== decodedSecret.networkName) { - return cb('badNetwork'); - } + joinNetwork.start(opts, function() { + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { + if (data.type === 'walletId') { + if (data.networkName !== decodedSecret.networkName) { + return cb('badNetwork'); + } - data.opts.privateKey = privateKey; - data.opts.nickname = nickname; - data.opts.passphrase = passphrase; - data.opts.id = data.walletId; - var w = self.create(data.opts); - w.sendWalletReady(decodedSecret.pubKey); - return cb(null, w); - } else { - return cb('walletFull', w); - } - }); - }); -}; + data.opts.privateKey = privateKey; + data.opts.nickname = nickname; + data.opts.passphrase = passphrase; + data.opts.id = data.walletId; + var w = self.create(data.opts); + w.sendWalletReady(decodedSecret.pubKey); + return cb(null, w); + } else { + return cb('walletFull', w); + } + }); + }); + }; -module.exports = WalletFactory; + module.exports = WalletFactory; diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index edd2bf67d..ef33fa196 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -10,46 +10,51 @@ function WalletLock(storage, walletId, timeoutMin) { this.storage = storage; this.timeoutMin = timeoutMin || 5; this.key = WalletLock._keyFor(walletId); - this._setLock(); + this._setLock(function() {}); } WalletLock._keyFor = function(walletId) { return 'lock' + '::' + walletId; }; -WalletLock.prototype._isLockedByOther = function() { - var json = this.storage.getGlobal(this.key); - var wl = json ? JSON.parse(json) : null; - var t = wl ? (Date.now() - wl.expireTs) : false; - // is not locked? - if (!wl || t > 0 || wl.sessionId === this.sessionId) - return false; +WalletLock.prototype._isLockedByOther = function(cb) { + var self=this; + this.storage.getGlobal(this.key, function(json) { + var wl = json ? JSON.parse(json) : null; + var t = wl ? (Date.now() - wl.expireTs) : false; + // is not locked? + if (!wl || t > 0 || wl.sessionId === self.sessionId) + return cb(false); - // Seconds remainding - return parseInt(-t/1000.); -}; - - -WalletLock.prototype._setLock = function() { - this.storage.setGlobal(this.key, { - sessionId: this.sessionId, - expireTs: Date.now() + this.timeoutMin * 60 * 1000, + // Seconds remainding + return cb(parseInt(-t / 1000.)); }); }; -WalletLock.prototype.keepAlive = function() { - preconditions.checkState(this.sessionId); - - var t = this._isLockedByOther(); - if (t) - throw new Error('Wallet is already open. Close it to proceed or wait '+ t + ' seconds if you close it already' ); - this._setLock(); +WalletLock.prototype._setLock = function(cb) { + this.storage.setGlobal(this.key, { + sessionId: this.sessionId, + expireTs: Date.now() + this.timeoutMin * 60 * 1000, + }, cb); }; -WalletLock.prototype.release = function() { - this.storage.removeGlobal(this.key); +WalletLock.prototype.keepAlive = function(cb) { + preconditions.checkState(this.sessionId); + var self = this; + + this._isLockedByOther(function(t) { + if (t) + return cb(new Error('Wallet is already open. Close it to proceed or wait ' + t + ' seconds if you close it already')); + + self._setLock(cb); + }); +}; + + +WalletLock.prototype.release = function(cb) { + this.storage.removeGlobal(this.key, cb); }; diff --git a/js/services/pluginManager.js b/js/services/pluginManager.js index c67b16846..f5e6e165c 100644 --- a/js/services/pluginManager.js +++ b/js/services/pluginManager.js @@ -1,5 +1,19 @@ 'use strict'; angular.module('copayApp.services').factory('pluginManager', function(angularLoad){ - return new copay.PluginManager(config); + var pm = new copay.PluginManager(config); + + var scripts = pm.scripts; + + for(var ii in scripts){ + var src = scripts[ii].src; + + console.log('\tLoading ',src); //TODO + angularLoad.loadScript(src) + .then(scripts[ii].then || null) + .catch(function() { + throw new Error('Loading ' + src); + }) + } + return pm; }); diff --git a/js/services/walletFactory.js b/js/services/walletFactory.js index 16580af9d..7a6b96ea6 100644 --- a/js/services/walletFactory.js +++ b/js/services/walletFactory.js @@ -1,3 +1,7 @@ 'use strict'; +angular.module('copayApp.services').factory('walletFactory', function(pluginManager){ + +console.log('[walletFactory.js.3]'); //TODO + return new copay.WalletFactory(config, copay.version, pluginManager); +}); -angular.module('copayApp.services').value('walletFactory', new copay.WalletFactory(config, copay.version)); diff --git a/plugins/LocalStorage.js b/plugins/LocalStorage.js index 3f050f64f..a811cfcf4 100644 --- a/plugins/LocalStorage.js +++ b/plugins/LocalStorage.js @@ -9,33 +9,33 @@ LocalStorage.prototype.init = function() { }; -LocalStorage.prototype.getItem = function(k) { - return localStorage.getItem(k); +LocalStorage.prototype.getItem = function(k,cb) { + return cb(localStorage.getItem(k)); }; -LocalStorage.prototype.setItem = function(k,v) { +LocalStorage.prototype.setItem = function(k,v,cb) { localStorage.setItem(k,v); + return cb(); }; -LocalStorage.prototype.removeItem = function(k) { +LocalStorage.prototype.removeItem = function(k,cb) { localStorage.removeItem(k); + return cb(); }; -LocalStorage.prototype.clear = function() { +LocalStorage.prototype.clear = function(cb) { localStorage.clear(); + return cb(); }; -delete LocalStorage.prototype.length; +LocalStorage.prototype.allKeys = function(cb) { + var l = localStorage.length; + var ret = []; -Object.defineProperty(LocalStorage.prototype, 'length', { - get: function() { - return localStorage.length; - } -}); + for(var i=0; i