2015-03-06 12:00:10 -03:00
|
|
|
|
'use strict';
|
|
|
|
|
|
angular.module('copayApp.services')
|
2016-06-06 18:26:45 -03:00
|
|
|
|
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwsError, uxLanguage, bitcore, platformInfo, walletService) {
|
2016-05-31 14:55:08 -03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var isChromeApp = platformInfo.isChromeApp;
|
|
|
|
|
|
var isCordova = platformInfo.isCordova;
|
|
|
|
|
|
var isWP = platformInfo.isWP;
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
|
|
|
|
|
var root = {};
|
2016-01-22 18:16:50 -03:00
|
|
|
|
var errors = bwcService.getErrors();
|
2016-05-31 14:55:08 -03:00
|
|
|
|
var usePushNotifications = isCordova && !isWP;
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2015-10-23 12:16:41 -03:00
|
|
|
|
var FOREGROUND_UPDATE_PERIOD = 5;
|
|
|
|
|
|
var BACKGROUND_UPDATE_PERIOD = 30;
|
|
|
|
|
|
|
2015-03-06 12:00:10 -03:00
|
|
|
|
root.profile = null;
|
|
|
|
|
|
root.focusedClient = null;
|
|
|
|
|
|
root.walletClients = {};
|
|
|
|
|
|
|
2015-11-05 17:48:56 -03:00
|
|
|
|
root.Utils = bwcService.getUtils();
|
2015-03-06 12:00:10 -03:00
|
|
|
|
root.formatAmount = function(amount) {
|
|
|
|
|
|
var config = configService.getSync().wallet.settings;
|
|
|
|
|
|
if (config.unitCode == 'sat') return amount;
|
|
|
|
|
|
|
|
|
|
|
|
//TODO : now only works for english, specify opts to change thousand separator and decimal separator
|
2015-11-11 10:53:51 -03:00
|
|
|
|
return this.Utils.formatAmount(amount, config.unitCode);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
root._setFocus = function(walletId, cb) {
|
|
|
|
|
|
$log.debug('Set focus:', walletId);
|
|
|
|
|
|
|
|
|
|
|
|
// Set local object
|
2015-05-18 10:30:09 -03:00
|
|
|
|
if (walletId)
|
|
|
|
|
|
root.focusedClient = root.walletClients[walletId];
|
2015-08-24 17:09:59 -03:00
|
|
|
|
else
|
2015-05-18 10:30:09 -03:00
|
|
|
|
root.focusedClient = [];
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
|
|
|
|
|
if (lodash.isEmpty(root.focusedClient)) {
|
|
|
|
|
|
root.focusedClient = root.walletClients[lodash.keys(root.walletClients)[0]];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-05-18 10:30:09 -03:00
|
|
|
|
// Still nothing?
|
2015-03-06 12:00:10 -03:00
|
|
|
|
if (lodash.isEmpty(root.focusedClient)) {
|
|
|
|
|
|
$rootScope.$emit('Local/NoWallets');
|
2015-05-18 10:30:09 -03:00
|
|
|
|
} else {
|
2015-03-06 12:00:10 -03:00
|
|
|
|
$rootScope.$emit('Local/NewFocusedWallet');
|
2015-10-23 12:16:41 -03:00
|
|
|
|
|
|
|
|
|
|
// Set update period
|
|
|
|
|
|
lodash.each(root.walletClients, function(client, id) {
|
|
|
|
|
|
client.setNotificationsInterval(BACKGROUND_UPDATE_PERIOD);
|
|
|
|
|
|
});
|
|
|
|
|
|
root.focusedClient.setNotificationsInterval(FOREGROUND_UPDATE_PERIOD);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return cb();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
root.setAndStoreFocus = function(walletId, cb) {
|
|
|
|
|
|
root._setFocus(walletId, function() {
|
|
|
|
|
|
storageService.storeFocusedWalletId(walletId, cb);
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
// Adds a wallet client to profileService
|
|
|
|
|
|
root.bindWalletClient = function(client, opts) {
|
|
|
|
|
|
var opts = opts || {};
|
|
|
|
|
|
var walletId = client.credentials.walletId;
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
if ((root.walletClients[walletId] && root.walletClients[walletId].started) || opts.force) {
|
2016-06-06 12:21:15 -03:00
|
|
|
|
return false;
|
2015-10-19 11:19:28 -03:00
|
|
|
|
}
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.walletClients[walletId] = client;
|
|
|
|
|
|
root.walletClients[walletId].started = true;
|
|
|
|
|
|
root.walletClients[walletId].doNotVerifyPayPro = isChromeApp;
|
2016-05-20 10:02:44 -03:00
|
|
|
|
|
|
|
|
|
|
if (client.incorrectDerivation) {
|
2016-06-06 12:21:15 -03:00
|
|
|
|
$log.warn('Key Derivation failed for wallet:' + walletId);
|
|
|
|
|
|
storageService.clearLastAddress(walletId, function() {});
|
2016-05-20 10:02:44 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-19 11:19:28 -03:00
|
|
|
|
client.removeAllListeners();
|
2016-05-03 10:42:18 -03:00
|
|
|
|
client.on('report', function(n) {
|
2016-05-20 10:02:44 -03:00
|
|
|
|
$log.info('BWC Report:' + n);
|
2016-05-03 10:42:18 -03:00
|
|
|
|
});
|
2015-04-13 14:58:07 -03:00
|
|
|
|
|
2015-10-19 11:19:28 -03:00
|
|
|
|
client.on('notification', function(n) {
|
|
|
|
|
|
$log.debug('BWC Notification:', n);
|
|
|
|
|
|
notificationService.newBWCNotification(n,
|
2016-06-06 12:21:15 -03:00
|
|
|
|
walletId, client.credentials.walletName);
|
2015-04-13 14:58:07 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (root.focusedClient.credentials.walletId == walletId) {
|
2016-01-13 12:08:13 -03:00
|
|
|
|
$rootScope.$emit(n.type, n);
|
2015-10-19 11:19:28 -03:00
|
|
|
|
} else {
|
|
|
|
|
|
$rootScope.$apply();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2015-10-19 11:19:28 -03:00
|
|
|
|
client.on('walletCompleted', function() {
|
|
|
|
|
|
$log.debug('Wallet completed');
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.updateCredentials(client.export(), function() {
|
2016-06-06 12:21:15 -03:00
|
|
|
|
$rootScope.$emit('Local/WalletCompleted', walletId);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
2015-10-19 11:19:28 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-01-21 09:55:28 -03:00
|
|
|
|
if (client.hasPrivKeyEncrypted() && !client.isPrivKeyEncrypted()) {
|
2016-06-06 12:21:15 -03:00
|
|
|
|
$log.warn('Auto locking unlocked wallet:' + walletId);
|
2016-01-21 09:55:28 -03:00
|
|
|
|
client.lock();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-23 12:16:41 -03:00
|
|
|
|
client.initialize({}, function(err) {
|
2015-10-19 11:19:28 -03:00
|
|
|
|
if (err) {
|
|
|
|
|
|
$log.error('Could not init notifications err:', err);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2015-10-23 12:16:41 -03:00
|
|
|
|
client.setNotificationsInterval(BACKGROUND_UPDATE_PERIOD);
|
2015-10-19 11:19:28 -03:00
|
|
|
|
});
|
2015-04-16 19:44:12 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
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,
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
2016-06-06 12:21:15 -03:00
|
|
|
|
|
|
|
|
|
|
if (!skipKeyValidation && !client.incorrectDerivation)
|
|
|
|
|
|
root.profile.setChecked(platformInfo.ua, credentials.walletId);
|
|
|
|
|
|
|
|
|
|
|
|
return root.bindWalletClient(client);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
root.bindProfile = function(profile, cb) {
|
|
|
|
|
|
root.profile = profile;
|
2016-01-04 08:55:28 -03:00
|
|
|
|
|
2015-03-06 12:00:10 -03:00
|
|
|
|
configService.get(function(err) {
|
2015-04-25 12:37:04 -03:00
|
|
|
|
$log.debug('Preferences read');
|
2015-03-06 12:00:10 -03:00
|
|
|
|
if (err) return cb(err);
|
2016-06-06 12:21:15 -03:00
|
|
|
|
|
|
|
|
|
|
lodash.each(root.profile.credentials, function(credentials) {
|
|
|
|
|
|
root.bindWallet(credentials);
|
|
|
|
|
|
});
|
|
|
|
|
|
$rootScope.$emit('Local/WalletListUpdated');
|
|
|
|
|
|
|
2015-03-06 12:00:10 -03:00
|
|
|
|
storageService.getFocusedWalletId(function(err, focusedWalletId) {
|
|
|
|
|
|
if (err) return cb(err);
|
2015-06-29 22:40:39 -03:00
|
|
|
|
root._setFocus(focusedWalletId, function() {
|
2016-03-10 10:58:58 -03:00
|
|
|
|
if (usePushNotifications)
|
|
|
|
|
|
root.pushNotificationsInit();
|
|
|
|
|
|
root.isDisclaimerAccepted(function(val) {
|
|
|
|
|
|
if (!val) {
|
|
|
|
|
|
return cb(new Error('NONAGREEDDISCLAIMER: Non agreed disclaimer'));
|
2016-05-29 21:20:40 -03:00
|
|
|
|
}
|
2016-05-20 11:50:55 -03:00
|
|
|
|
return cb();
|
2015-12-05 20:50:31 -03:00
|
|
|
|
});
|
2015-06-29 22:40:39 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2016-03-10 10:58:58 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
root.pushNotificationsInit = function() {
|
|
|
|
|
|
var defaults = configService.getDefaults();
|
2016-04-07 12:58:32 -03:00
|
|
|
|
var push = pushNotificationsService.init(root.walletClients);
|
2016-01-04 08:55:28 -03:00
|
|
|
|
|
2016-03-10 10:58:58 -03:00
|
|
|
|
push.on('notification', function(data) {
|
|
|
|
|
|
if (!data.additionalData.foreground) {
|
|
|
|
|
|
window.ignoreMobilePause = true;
|
|
|
|
|
|
$log.debug('Push notification event: ', data.message);
|
|
|
|
|
|
|
|
|
|
|
|
$timeout(function() {
|
|
|
|
|
|
var wallets = root.getWallets();
|
|
|
|
|
|
var walletToFind = data.additionalData.walletId;
|
2016-01-04 08:55:28 -03:00
|
|
|
|
|
2016-03-10 10:58:58 -03:00
|
|
|
|
var walletFound = lodash.find(wallets, function(w) {
|
2016-04-07 12:58:32 -03:00
|
|
|
|
return (lodash.isEqual(walletToFind, sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(w.id))));
|
2016-03-10 10:58:58 -03:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!walletFound) return $log.debug('Wallet not found');
|
|
|
|
|
|
root.setAndStoreFocus(walletFound.id, function() {});
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-03-09 11:53:47 -03:00
|
|
|
|
|
|
|
|
|
|
root.getProfile = function(cb) {
|
|
|
|
|
|
storageService.getProfile(function(err, profile) {
|
|
|
|
|
|
return cb(err, profile);
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2016-01-04 08:55:28 -03:00
|
|
|
|
root.loadAndBindProfile = function(cb) {
|
2015-11-30 12:58:52 -03:00
|
|
|
|
storageService.getProfile(function(err, profile) {
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
$rootScope.$emit('Local/DeviceError', err);
|
|
|
|
|
|
return cb(err);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!profile) {
|
|
|
|
|
|
// Migration??
|
|
|
|
|
|
storageService.tryToMigrate(function(err, migratedProfile) {
|
|
|
|
|
|
if (err) return cb(err);
|
|
|
|
|
|
if (!migratedProfile)
|
|
|
|
|
|
return cb(new Error('NOPROFILE: No profile'));
|
|
|
|
|
|
|
|
|
|
|
|
profile = migratedProfile;
|
|
|
|
|
|
return root.bindProfile(profile, cb);
|
|
|
|
|
|
})
|
2015-04-25 14:42:17 -03:00
|
|
|
|
} else {
|
2015-12-04 18:45:35 -03:00
|
|
|
|
$log.debug('Profile read');
|
|
|
|
|
|
return root.bindProfile(profile, cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-09-02 15:56:00 -03:00
|
|
|
|
root._seedWallet = function(opts, cb) {
|
|
|
|
|
|
opts = opts || {};
|
2016-06-05 16:27:49 -03:00
|
|
|
|
$log.debug('seedWallet', opts);
|
2016-06-01 15:49:20 -03:00
|
|
|
|
var walletClient = bwcService.getClient(null, opts);
|
2015-09-02 15:56:00 -03:00
|
|
|
|
var network = opts.networkName || 'livenet';
|
2015-08-27 12:07:13 -03:00
|
|
|
|
|
2015-09-02 15:56:00 -03:00
|
|
|
|
if (opts.mnemonic) {
|
|
|
|
|
|
try {
|
2015-09-15 12:07:34 -03:00
|
|
|
|
opts.mnemonic = root._normalizeMnemonic(opts.mnemonic);
|
2015-10-22 15:44:28 -03:00
|
|
|
|
walletClient.seedFromMnemonic(opts.mnemonic, {
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
passphrase: opts.passphrase,
|
2015-11-04 01:54:54 -03:00
|
|
|
|
account: opts.account || 0,
|
2015-11-10 20:05:05 -03:00
|
|
|
|
derivationStrategy: opts.derivationStrategy || 'BIP44',
|
2015-10-22 15:44:28 -03:00
|
|
|
|
});
|
2015-11-04 17:50:05 -03:00
|
|
|
|
|
2015-09-02 15:56:00 -03:00
|
|
|
|
} catch (ex) {
|
|
|
|
|
|
$log.info(ex);
|
2016-05-09 20:23:20 +02:00
|
|
|
|
return cb(gettext('Could not create: Invalid wallet recovery phrase'));
|
2015-09-02 15:56:00 -03:00
|
|
|
|
}
|
2015-09-05 00:11:14 -03:00
|
|
|
|
} else if (opts.extendedPrivateKey) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
walletClient.seedFromExtendedPrivateKey(opts.extendedPrivateKey);
|
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
|
$log.warn(ex);
|
|
|
|
|
|
return cb(gettext('Could not create using the specified extended private key'));
|
|
|
|
|
|
}
|
2015-09-02 15:56:00 -03:00
|
|
|
|
} else if (opts.extendedPublicKey) {
|
|
|
|
|
|
try {
|
2015-10-22 15:44:28 -03:00
|
|
|
|
walletClient.seedFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.entropySource, {
|
2015-11-05 16:00:38 -03:00
|
|
|
|
account: opts.account || 0,
|
2015-11-10 20:05:05 -03:00
|
|
|
|
derivationStrategy: opts.derivationStrategy || 'BIP44',
|
2015-10-22 15:44:28 -03:00
|
|
|
|
});
|
2015-09-02 15:56:00 -03:00
|
|
|
|
} catch (ex) {
|
2015-09-14 09:46:45 -03:00
|
|
|
|
$log.warn("Creating wallet from Extended Public Key Arg:", ex, opts);
|
2015-09-02 15:56:00 -03:00
|
|
|
|
return cb(gettext('Could not create using the specified extended public key'));
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
var lang = uxLanguage.getCurrentLanguage();
|
|
|
|
|
|
try {
|
2015-10-22 15:44:28 -03:00
|
|
|
|
walletClient.seedFromRandomWithMnemonic({
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
passphrase: opts.passphrase,
|
|
|
|
|
|
language: lang,
|
|
|
|
|
|
account: 0,
|
|
|
|
|
|
});
|
2015-09-02 15:56:00 -03:00
|
|
|
|
} catch (e) {
|
2016-05-09 20:23:20 +02:00
|
|
|
|
$log.info('Error creating recovery phrase: ' + e.message);
|
2015-09-02 15:56:00 -03:00
|
|
|
|
if (e.message.indexOf('language') > 0) {
|
2016-05-09 20:23:20 +02:00
|
|
|
|
$log.info('Using default language for recovery phrase');
|
2015-10-22 15:44:28 -03:00
|
|
|
|
walletClient.seedFromRandomWithMnemonic({
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
passphrase: opts.passphrase,
|
|
|
|
|
|
account: 0,
|
|
|
|
|
|
});
|
2015-09-02 15:56:00 -03:00
|
|
|
|
} else {
|
|
|
|
|
|
return cb(e);
|
|
|
|
|
|
}
|
2015-08-27 12:07:13 -03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2015-09-02 15:56:00 -03:00
|
|
|
|
return cb(null, walletClient);
|
2015-08-27 11:24:39 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
// Creates a wallet on BWC/BWS
|
|
|
|
|
|
root.doCreateWallet = function(opts, cb) {
|
|
|
|
|
|
$log.debug('Creating Wallet:', opts);
|
2016-06-05 16:27:49 -03:00
|
|
|
|
root._seedWallet(opts, function(err, walletClient) {
|
2015-09-02 15:56:00 -03:00
|
|
|
|
if (err) return cb(err);
|
2015-08-08 09:30:50 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
var name = opts.name || gettextCatalog.getString('Personal Wallet');
|
|
|
|
|
|
var myName = opts.myName || gettextCatalog.getString('me');
|
2016-06-05 16:27:49 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
walletClient.createWallet(name, myName, opts.m, opts.n, {
|
|
|
|
|
|
network: opts.networkName,
|
2016-06-05 16:27:49 -03:00
|
|
|
|
walletPrivKey: opts.walletPrivKey,
|
2016-06-06 12:21:15 -03:00
|
|
|
|
}, function(err, secret) {
|
2015-09-02 15:56:00 -03:00
|
|
|
|
if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb);
|
2016-06-06 12:21:15 -03:00
|
|
|
|
return cb(null, walletClient, secret);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
2016-06-06 12:21:15 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
// Creates the default Copay profile and its wallet
|
|
|
|
|
|
root.createDefaultProfile = function(opts, cb) {
|
|
|
|
|
|
var p = Profile.create();
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (opts.noWallet) {
|
|
|
|
|
|
return cb(null, p);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
opts.m = 1;
|
|
|
|
|
|
opts.n = 1;
|
|
|
|
|
|
opts.network = 'livenet';
|
|
|
|
|
|
|
|
|
|
|
|
root.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);
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
// create and store a wallet
|
|
|
|
|
|
root.createWallet = function(opts, cb) {
|
|
|
|
|
|
root.doCreateWallet(opts, function(err, walletClient, secret) {
|
|
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl
|
|
|
|
|
|
}, cb);
|
2015-09-02 15:56:00 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
// joins and stores a wallet
|
2015-10-19 17:58:12 -03:00
|
|
|
|
root.joinWallet = function(opts, cb) {
|
2015-03-06 12:00:10 -03:00
|
|
|
|
var walletClient = bwcService.getClient();
|
|
|
|
|
|
$log.debug('Joining Wallet:', opts);
|
2015-08-12 11:08:33 -03:00
|
|
|
|
|
|
|
|
|
|
try {
|
2015-11-11 10:53:51 -03:00
|
|
|
|
var walletData = bwcService.parseSecret(opts.secret);
|
2015-08-12 11:08:33 -03:00
|
|
|
|
|
2015-08-12 11:16:34 -03:00
|
|
|
|
// check if exist
|
|
|
|
|
|
if (lodash.find(root.profile.credentials, {
|
2016-06-01 16:44:07 -03:00
|
|
|
|
'walletId': walletData.walletId
|
|
|
|
|
|
})) {
|
2015-08-24 17:09:59 -03:00
|
|
|
|
return cb(gettext('Cannot join the same wallet more that once'));
|
2015-08-12 11:16:34 -03:00
|
|
|
|
}
|
2015-08-12 11:08:33 -03:00
|
|
|
|
} catch (ex) {
|
2015-09-29 12:45:06 -03:00
|
|
|
|
$log.debug(ex);
|
2015-08-12 11:08:33 -03:00
|
|
|
|
return cb(gettext('Bad wallet invitation'));
|
|
|
|
|
|
}
|
2015-09-02 15:56:00 -03:00
|
|
|
|
opts.networkName = walletData.network;
|
|
|
|
|
|
$log.debug('Joining Wallet:', opts);
|
|
|
|
|
|
|
|
|
|
|
|
root._seedWallet(opts, function(err, walletClient) {
|
|
|
|
|
|
if (err) return cb(err);
|
2015-08-12 11:08:33 -03:00
|
|
|
|
|
2015-09-28 10:26:57 -03:00
|
|
|
|
walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) {
|
2015-09-02 15:56:00 -03:00
|
|
|
|
if (err) return bwsError.cb(err, gettext('Could not join wallet'), cb);
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl
|
|
|
|
|
|
}, cb);
|
2015-10-19 17:26:15 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-06-27 13:22:56 -03:00
|
|
|
|
root.getClient = function(walletId) {
|
|
|
|
|
|
return root.walletClients[walletId];
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.deleteWalletClient = function(client, cb) {
|
|
|
|
|
|
var walletId = client.credentials.walletId;
|
2016-01-15 11:59:29 -03:00
|
|
|
|
|
2016-01-26 14:44:17 -03:00
|
|
|
|
pushNotificationsService.unsubscribe(root.getClient(walletId), function(err) {
|
2016-01-27 16:31:11 -03:00
|
|
|
|
if (err) $log.warn('Unsubscription error: ' + err.message);
|
2016-01-26 14:44:17 -03:00
|
|
|
|
else $log.debug('Unsubscribed from push notifications service');
|
2016-05-29 21:20:40 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-05-29 21:20:40 -03:00
|
|
|
|
$log.debug('Deleting Wallet:', fc.credentials.walletName);
|
|
|
|
|
|
fc.removeAllListeners();
|
2016-06-06 12:21:15 -03:00
|
|
|
|
|
|
|
|
|
|
root.profile.deleteWallet(walletId);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-05-29 21:20:40 -03:00
|
|
|
|
delete root.walletClients[walletId];
|
|
|
|
|
|
root.focusedClient = null;
|
2015-11-06 16:54:25 -03:00
|
|
|
|
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
storageService.removeAllWalletData(walletId, function(err) {
|
2016-05-29 21:20:40 -03:00
|
|
|
|
if (err) $log.warn(err);
|
|
|
|
|
|
});
|
2015-11-06 16:54:25 -03:00
|
|
|
|
|
2016-01-15 17:09:50 -03:00
|
|
|
|
|
2016-05-29 21:20:40 -03:00
|
|
|
|
$timeout(function() {
|
2016-06-06 12:21:15 -03:00
|
|
|
|
$rootScope.$emit('Local/WalletListUpdated');
|
|
|
|
|
|
|
2016-05-29 21:20:40 -03:00
|
|
|
|
root.setAndStoreFocus(null, function() {
|
|
|
|
|
|
storageService.storeProfile(root.profile, function(err) {
|
|
|
|
|
|
if (err) return cb(err);
|
|
|
|
|
|
return cb();
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-11-06 11:26:50 -03:00
|
|
|
|
root.setMetaData = function(walletClient, addressBook, historyCache, cb) {
|
2015-11-09 10:58:10 -03:00
|
|
|
|
storageService.getAddressbook(walletClient.credentials.network, function(err, localAddressBook) {
|
2015-11-11 10:37:07 -03:00
|
|
|
|
var localAddressBook1 = {};
|
|
|
|
|
|
try {
|
|
|
|
|
|
localAddressBook1 = JSON.parse(localAddressBook);
|
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
|
$log.warn(ex);
|
|
|
|
|
|
}
|
|
|
|
|
|
var mergeAddressBook = lodash.merge(addressBook, localAddressBook1);
|
2015-11-09 10:58:10 -03:00
|
|
|
|
storageService.setAddressbook(walletClient.credentials.network, JSON.stringify(addressBook), function(err) {
|
2015-11-05 17:48:56 -03:00
|
|
|
|
if (err) return cb(err);
|
2015-11-09 10:58:10 -03:00
|
|
|
|
storageService.setTxHistory(JSON.stringify(historyCache), walletClient.credentials.walletId, function(err) {
|
|
|
|
|
|
if (err) return cb(err);
|
|
|
|
|
|
return cb(null);
|
|
|
|
|
|
});
|
2015-11-05 17:48:56 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
// Adds and bind a new client to the profile
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient = function(client, opts, cb) {
|
|
|
|
|
|
var walletId = client.credentials.walletId
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (!root.profile.addWallet(JSON.parse(client.export())))
|
|
|
|
|
|
return cb(gettext('Wallet already in Copay'));
|
2015-10-25 23:25:44 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.bindWalletClient(client);
|
|
|
|
|
|
$rootScope.$emit('Local/WalletListUpdated', client);
|
2015-10-25 23:25:44 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
var saveBwsUrl = function(cb) {
|
|
|
|
|
|
var defaults = configService.getDefaults();
|
|
|
|
|
|
var bwsFor = {};
|
|
|
|
|
|
bwsFor[walletId] = opts.bwsurl || defaults.bws.url;
|
2015-11-14 17:29:45 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
// Dont save the default
|
|
|
|
|
|
if (bwsFor[walletId] == defaults.bws.url)
|
|
|
|
|
|
return cb();
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
configService.set({
|
|
|
|
|
|
bwsFor: bwsFor,
|
|
|
|
|
|
}, function(err) {
|
|
|
|
|
|
if (err) $log.warn(err);
|
|
|
|
|
|
return cb();
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
2015-11-14 17:29:45 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
var handleImportedClient = function(cb) {
|
|
|
|
|
|
if (!opts.isImport) return cb();
|
|
|
|
|
|
$rootScope.$emit('Local/BackupDone', walletId);
|
2015-11-14 17:29:45 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (!walletClient.isComplete())
|
|
|
|
|
|
return cb();
|
2015-11-14 17:29:45 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
storageService.setCleanAndScanAddresses(walletId, cb);
|
|
|
|
|
|
};
|
2015-11-14 17:29:45 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
walletService.updateRemotePreferences(client, {}, function() {
|
|
|
|
|
|
$log.debug('Remote preferences saved for:' + walletId)
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
saveBwsUrl(function() {
|
|
|
|
|
|
handleImportedClient(function() {
|
2015-11-14 17:29:45 -03:00
|
|
|
|
root.setAndStoreFocus(walletId, function() {
|
|
|
|
|
|
storageService.storeProfile(root.profile, function(err) {
|
2016-02-22 19:32:24 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
var config = configService.getSync();
|
2016-01-18 14:22:42 -03:00
|
|
|
|
if (config.pushNotifications.enabled)
|
2016-01-26 14:44:17 -03:00
|
|
|
|
pushNotificationsService.enableNotifications(root.walletClients);
|
2015-11-14 17:29:45 -03:00
|
|
|
|
return cb(err, walletId);
|
|
|
|
|
|
});
|
2016-06-06 12:21:15 -03:00
|
|
|
|
|
2015-10-25 23:25:44 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2015-10-25 23:06:29 -03:00
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
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();
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-08-24 17:09:59 -03:00
|
|
|
|
root.importWallet = function(str, opts, cb) {
|
2015-11-06 16:04:35 -03:00
|
|
|
|
|
2016-06-01 15:49:20 -03:00
|
|
|
|
var walletClient = bwcService.getClient(null, opts);
|
2015-10-19 17:26:15 -03:00
|
|
|
|
|
2015-08-24 17:09:59 -03:00
|
|
|
|
$log.debug('Importing Wallet:', opts);
|
|
|
|
|
|
try {
|
|
|
|
|
|
walletClient.import(str, {
|
|
|
|
|
|
compressed: opts.compressed,
|
|
|
|
|
|
password: opts.password
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (err) {
|
2016-05-09 20:23:20 +02:00
|
|
|
|
return cb(gettext('Could not import. Check input file and spending password'));
|
2015-08-24 17:09:59 -03:00
|
|
|
|
}
|
2015-11-06 17:45:23 -03:00
|
|
|
|
|
|
|
|
|
|
str = JSON.parse(str);
|
|
|
|
|
|
|
2015-11-09 10:58:10 -03:00
|
|
|
|
var addressBook = str.addressBook || {};
|
2015-11-06 16:04:35 -03:00
|
|
|
|
var historyCache = str.historyCache || [];
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (!walletClient.incorrectDerivation)
|
|
|
|
|
|
root.profile.setChecked(platformInfo.ua, walletClient.credentials.walletId);
|
|
|
|
|
|
|
|
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl,
|
|
|
|
|
|
isImport: true
|
|
|
|
|
|
}, function(err, walletId) {
|
2015-11-11 11:25:03 -03:00
|
|
|
|
if (err) return cb(err);
|
|
|
|
|
|
root.setMetaData(walletClient, addressBook, historyCache, function(error) {
|
2016-02-22 19:32:24 -03:00
|
|
|
|
if (error) $log.warn(error);
|
2015-11-11 11:25:03 -03:00
|
|
|
|
return cb(err, walletId);
|
|
|
|
|
|
});
|
2015-11-06 11:26:50 -03:00
|
|
|
|
});
|
2015-08-24 17:09:59 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-10-20 12:03:08 -03:00
|
|
|
|
root.importExtendedPrivateKey = function(xPrivKey, opts, cb) {
|
2016-06-01 16:44:07 -03:00
|
|
|
|
var walletClient = bwcService.getClient(null, opts);
|
2015-09-05 00:11:14 -03:00
|
|
|
|
$log.debug('Importing Wallet xPrivKey');
|
|
|
|
|
|
|
2016-05-09 12:03:25 -03:00
|
|
|
|
walletClient.importFromExtendedPrivateKey(xPrivKey, opts, function(err) {
|
2015-09-05 00:11:14 -03:00
|
|
|
|
if (err)
|
|
|
|
|
|
return bwsError.cb(err, gettext('Could not import'), cb);
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl,
|
|
|
|
|
|
isImport: true
|
|
|
|
|
|
}, cb);
|
2015-09-05 00:11:14 -03:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-09-15 12:07:34 -03:00
|
|
|
|
root._normalizeMnemonic = function(words) {
|
2015-10-19 11:19:28 -03:00
|
|
|
|
var isJA = words.indexOf('\u3000') > -1;
|
2015-09-15 12:07:34 -03:00
|
|
|
|
var wordList = words.split(/[\u3000\s]+/);
|
|
|
|
|
|
|
|
|
|
|
|
return wordList.join(isJA ? '\u3000' : ' ');
|
2015-09-05 01:02:01 -03:00
|
|
|
|
};
|
2015-09-05 00:11:14 -03:00
|
|
|
|
|
|
|
|
|
|
root.importMnemonic = function(words, opts, cb) {
|
2016-06-01 16:44:07 -03:00
|
|
|
|
var walletClient = bwcService.getClient(null, opts);
|
2015-09-05 01:02:01 -03:00
|
|
|
|
|
2015-08-24 17:09:59 -03:00
|
|
|
|
$log.debug('Importing Wallet Mnemonic');
|
|
|
|
|
|
|
2015-09-15 12:07:34 -03:00
|
|
|
|
words = root._normalizeMnemonic(words);
|
2015-08-24 17:09:59 -03:00
|
|
|
|
walletClient.importFromMnemonic(words, {
|
2015-09-02 15:56:00 -03:00
|
|
|
|
network: opts.networkName,
|
2015-08-24 17:09:59 -03:00
|
|
|
|
passphrase: opts.passphrase,
|
2015-11-04 17:50:05 -03:00
|
|
|
|
account: opts.account || 0,
|
2015-08-24 17:09:59 -03:00
|
|
|
|
}, function(err) {
|
|
|
|
|
|
if (err)
|
|
|
|
|
|
return bwsError.cb(err, gettext('Could not import'), cb);
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl,
|
|
|
|
|
|
isImport: true
|
|
|
|
|
|
}, cb);
|
2015-08-24 17:09:59 -03:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-09-04 21:18:20 -03:00
|
|
|
|
root.importExtendedPublicKey = function(opts, cb) {
|
2016-06-01 16:44:07 -03:00
|
|
|
|
var walletClient = bwcService.getClient(null, opts);
|
2015-09-04 21:18:20 -03:00
|
|
|
|
$log.debug('Importing Wallet XPubKey');
|
|
|
|
|
|
|
2015-10-22 15:44:28 -03:00
|
|
|
|
walletClient.importFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.entropySource, {
|
2015-11-04 01:54:54 -03:00
|
|
|
|
account: opts.account || 0,
|
2015-11-10 20:05:05 -03:00
|
|
|
|
derivationStrategy: opts.derivationStrategy || 'BIP44',
|
2015-10-22 15:44:28 -03:00
|
|
|
|
}, function(err) {
|
2015-09-04 21:18:20 -03:00
|
|
|
|
if (err) {
|
|
|
|
|
|
|
|
|
|
|
|
// in HW wallets, req key is always the same. They can't addAccess.
|
2016-01-22 18:16:50 -03:00
|
|
|
|
if (err instanceof errors.NOT_AUTHORIZED)
|
|
|
|
|
|
err.name = 'WALLET_DOES_NOT_EXIST';
|
2015-09-04 21:18:20 -03:00
|
|
|
|
|
|
|
|
|
|
return bwsError.cb(err, gettext('Could not import'), cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
bwsurl: opts.bwsurl,
|
|
|
|
|
|
isImport: true
|
|
|
|
|
|
}, cb);
|
2015-09-04 21:18:20 -03:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-05-13 11:58:19 -03:00
|
|
|
|
root.create = function(opts, cb) {
|
2016-06-05 16:27:49 -03:00
|
|
|
|
$log.info('Creating profile', opts);
|
2015-10-20 12:18:44 -03:00
|
|
|
|
var defaults = configService.getDefaults();
|
|
|
|
|
|
|
2015-04-25 14:42:17 -03:00
|
|
|
|
configService.get(function(err) {
|
2016-06-05 16:27:49 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.createDefaultProfile(opts, function(err, p) {
|
2015-04-25 14:42:17 -03:00
|
|
|
|
if (err) return cb(err);
|
|
|
|
|
|
|
|
|
|
|
|
root.bindProfile(p, function(err) {
|
2016-05-20 11:50:55 -03:00
|
|
|
|
// ignore NONAGREEDDISCLAIMER
|
2015-04-25 14:42:17 -03:00
|
|
|
|
storageService.storeNewProfile(p, function(err) {
|
|
|
|
|
|
return cb(err);
|
|
|
|
|
|
});
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-12-07 12:52:42 -03:00
|
|
|
|
root.setDisclaimerAccepted = function(cb) {
|
2016-02-22 19:32:24 -03:00
|
|
|
|
root.profile.disclaimerAccepted = true;
|
2016-06-01 19:56:47 -03:00
|
|
|
|
storageService.storeProfileThrottled(root.profile, function(err) {
|
2016-02-22 19:32:24 -03:00
|
|
|
|
return cb(err);
|
2015-11-30 13:32:54 -03:00
|
|
|
|
});
|
2015-12-04 18:45:35 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-12-07 12:52:42 -03:00
|
|
|
|
root.isDisclaimerAccepted = function(cb) {
|
2016-02-22 19:32:24 -03:00
|
|
|
|
var disclaimerAccepted = root.profile && root.profile.disclaimerAccepted;
|
|
|
|
|
|
if (disclaimerAccepted)
|
|
|
|
|
|
return cb(true);
|
|
|
|
|
|
|
|
|
|
|
|
// OLD flag
|
|
|
|
|
|
storageService.getCopayDisclaimerFlag(function(err, val) {
|
|
|
|
|
|
if (val) {
|
|
|
|
|
|
root.profile.disclaimerAccepted = true;
|
2015-12-04 18:45:35 -03:00
|
|
|
|
return cb(true);
|
2016-01-04 08:55:28 -03:00
|
|
|
|
} else {
|
2015-12-04 18:45:35 -03:00
|
|
|
|
return cb();
|
|
|
|
|
|
}
|
2016-01-04 08:55:28 -03:00
|
|
|
|
});
|
2015-12-04 18:45:35 -03:00
|
|
|
|
};
|
2015-11-30 13:32:54 -03:00
|
|
|
|
|
2015-03-06 12:00:10 -03:00
|
|
|
|
root.importLegacyWallet = function(username, password, blob, cb) {
|
|
|
|
|
|
var walletClient = bwcService.getClient();
|
|
|
|
|
|
|
|
|
|
|
|
walletClient.createWalletFromOldCopay(username, password, blob, function(err, existed) {
|
2015-04-30 13:03:30 -03:00
|
|
|
|
if (err) return cb(gettext('Error importing wallet: ') + err);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
if (root.profile.hasWallet(walletClient.credentials.walletId)) {
|
2015-03-06 12:00:10 -03:00
|
|
|
|
$log.debug('Wallet:' + walletClient.credentials.walletName + ' already imported');
|
2015-04-30 13:03:30 -03:00
|
|
|
|
return cb(gettext('Wallet Already Imported: ') + walletClient.credentials.walletName);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 12:21:15 -03:00
|
|
|
|
root.addAndBindWalletClient(walletClient, {
|
|
|
|
|
|
isImport: true
|
|
|
|
|
|
}, cb);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.updateCredentials = function(credentials, cb) {
|
|
|
|
|
|
root.profile.updateWallet(credentials);
|
2016-06-01 19:56:47 -03:00
|
|
|
|
storageService.storeProfileThrottled(root.profile, cb);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.getClients = function() {
|
|
|
|
|
|
return lodash.values(root.walletClients);
|
|
|
|
|
|
};
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.needsBackup = function(client, cb) {
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
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);
|
2015-03-06 12:00:10 -03:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.isReady = function(client, cb) {
|
|
|
|
|
|
if (!client.isComplete())
|
|
|
|
|
|
return cb('WALLET_NOT_COMPLETE');
|
2015-03-06 12:00:10 -03:00
|
|
|
|
|
2016-06-06 18:26:45 -03:00
|
|
|
|
root.needsBackup(client, function(needsBackup) {
|
|
|
|
|
|
if (needsBackup)
|
|
|
|
|
|
return cb('WALLET_NEEDS_BACKUP');
|
2015-03-06 12:00:10 -03:00
|
|
|
|
return cb();
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-06-19 21:33:27 -03:00
|
|
|
|
root.getWallets = function(network) {
|
|
|
|
|
|
if (!root.profile) return [];
|
|
|
|
|
|
|
|
|
|
|
|
var config = configService.getSync();
|
|
|
|
|
|
config.colorFor = config.colorFor || {};
|
|
|
|
|
|
config.aliasFor = config.aliasFor || {};
|
|
|
|
|
|
var ret = lodash.map(root.profile.credentials, function(c) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
m: c.m,
|
|
|
|
|
|
n: c.n,
|
|
|
|
|
|
name: config.aliasFor[c.walletId] || c.walletName,
|
|
|
|
|
|
id: c.walletId,
|
|
|
|
|
|
network: c.network,
|
2016-01-07 16:56:28 -03:00
|
|
|
|
color: config.colorFor[c.walletId] || '#4A90E2',
|
2016-03-14 12:21:55 -03:00
|
|
|
|
copayerId: c.copayerId
|
2015-06-19 21:33:27 -03:00
|
|
|
|
};
|
|
|
|
|
|
});
|
2016-01-21 17:16:40 -03:00
|
|
|
|
if (network) {
|
|
|
|
|
|
ret = lodash.filter(ret, function(w) {
|
|
|
|
|
|
return (w.network == network);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2015-06-19 21:33:27 -03:00
|
|
|
|
return lodash.sortBy(ret, 'name');
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2015-03-06 12:00:10 -03:00
|
|
|
|
return root;
|
|
|
|
|
|
});
|