Wallet/src/js/services/profileService.js

735 lines
23 KiB
JavaScript
Raw Normal View History

2015-03-06 12:00:10 -03:00
'use strict';
angular.module('copayApp.services')
2016-04-07 12:19:51 -03:00
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, isChromeApp, isCordova, isMobile, gettext, gettextCatalog, nodeWebkit, bwsError, uxLanguage, bitcore) {
2015-03-06 12:00:10 -03:00
var root = {};
2016-01-22 18:16:50 -03:00
var errors = bwcService.getErrors();
var usePushNotifications = isCordova && !isMobile.Windows();
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 = {};
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);
});
};
2015-10-19 17:26:15 -03:00
root.setBaseURL = function(walletId) {
var config = configService.getSync();
var defaults = configService.getDefaults();
bwcService.setBaseUrl((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url);
2015-10-19 17:26:15 -03:00
bwcService.setTransports(['polling']);
}
2015-10-19 11:19:28 -03:00
root.setWalletClient = function(credentials) {
if (root.walletClients[credentials.walletId] &&
root.walletClients[credentials.walletId].started) {
return;
}
2015-03-06 12:00:10 -03:00
2015-10-19 17:26:15 -03:00
root.setBaseURL(credentials.walletId);
2015-03-06 12:00:10 -03:00
2015-10-19 11:19:28 -03:00
var client = bwcService.getClient(JSON.stringify(credentials));
root.walletClients[credentials.walletId] = client;
client.removeAllListeners();
client.on('report', function(n) {
$log.info('BWC Report:'+ n);
});
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,
client.credentials.walletId, client.credentials.walletName);
2015-04-13 14:58:07 -03:00
2015-10-19 11:19:28 -03:00
if (root.focusedClient.credentials.walletId == client.credentials.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');
root.updateCredentialsFC(function() {
$rootScope.$emit('Local/WalletCompleted', client.credentials.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
2015-10-19 11:19:28 -03:00
root.walletClients[credentials.walletId].started = true;
root.walletClients[credentials.walletId].doNotVerifyPayPro = isChromeApp;
2015-03-06 12:00:10 -03:00
if (client.hasPrivKeyEncrypted() && !client.isPrivKeyEncrypted()) {
$log.warn('Auto locking unlocked wallet:' + credentials.walletId);
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
2015-10-19 17:26:15 -03:00
root.setWalletClients = function() {
2015-10-19 11:19:28 -03:00
var credentials = root.profile.credentials;
lodash.each(credentials, function(credential) {
//$log.info("Credentials:", credentials);
root.setWalletClient(credential);
2015-03-06 12:00:10 -03:00
});
$rootScope.$emit('Local/WalletListUpdated');
};
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);
root.setWalletClients();
storageService.getFocusedWalletId(function(err, focusedWalletId) {
if (err) return cb(err);
2015-06-29 22:40:39 -03:00
root._setFocus(focusedWalletId, function() {
$rootScope.$emit('Local/ProfileBound');
if (usePushNotifications)
root.pushNotificationsInit();
root.isDisclaimerAccepted(function(val) {
if (!val) {
return cb(new Error('NONAGREEDDISCLAIMER: Non agreed disclaimer'));
} else {
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
});
});
};
root.pushNotificationsInit = function() {
var defaults = configService.getDefaults();
var push = pushNotificationsService.init(root.walletClients);
2016-01-04 08:55:28 -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
var walletFound = lodash.find(wallets, function(w) {
return (lodash.isEqual(walletToFind, sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(w.id))));
});
if (!walletFound) return $log.debug('Wallet not found');
root.setAndStoreFocus(walletFound.id, function() {});
}, 100);
}
});
2015-03-06 12:00:10 -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) {
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);
})
} 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 || {};
2015-10-19 17:26:15 -03:00
if (opts.bwsurl)
bwcService.setBaseUrl(opts.bwsurl);
2015-09-02 15:56:00 -03:00
var walletClient = bwcService.getClient();
var network = opts.networkName || 'livenet';
2015-08-27 12:07:13 -03:00
2015-11-05 16:00:38 -03:00
2015-09-02 15:56:00 -03:00
if (opts.mnemonic) {
try {
opts.mnemonic = root._normalizeMnemonic(opts.mnemonic);
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-11-04 17:50:05 -03:00
2015-09-02 15:56:00 -03:00
} catch (ex) {
$log.info(ex);
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 {
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-09-02 15:56:00 -03:00
} catch (ex) {
$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 {
walletClient.seedFromRandomWithMnemonic({
network: network,
passphrase: opts.passphrase,
language: lang,
account: 0,
});
2015-09-02 15:56:00 -03:00
} catch (e) {
$log.info('Error creating recovery phrase: ' + e.message);
2015-09-02 15:56:00 -03:00
if (e.message.indexOf('language') > 0) {
$log.info('Using default language for recovery phrase');
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-05-13 11:58:19 -03:00
root._createNewProfile = function(opts, cb) {
if (opts.noWallet) {
return cb(null, Profile.create());
}
2015-03-06 12:00:10 -03:00
2015-09-02 15:56:00 -03:00
root._seedWallet({}, function(err, walletClient) {
if (err) return cb(err);
2015-09-17 10:53:27 -03:00
var walletName = gettextCatalog.getString('Personal Wallet');
var me = gettextCatalog.getString('me');
walletClient.createWallet(walletName, me, 1, 1, {
2015-09-02 15:56:00 -03:00
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);
2015-03-06 12:00:10 -03:00
});
})
};
root.createWallet = function(opts, cb) {
$log.debug('Creating Wallet:', opts);
2015-09-02 15:56:00 -03:00
root._seedWallet(opts, function(err, walletClient) {
if (err) return cb(err);
2015-03-06 12:00:10 -03:00
2015-09-02 15:56:00 -03:00
walletClient.createWallet(opts.name, opts.myName || 'me', opts.m, opts.n, {
network: opts.networkName
}, function(err, secret) {
if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb);
2015-03-06 12:00:10 -03:00
2015-10-25 23:25:44 -03:00
root._addWalletClient(walletClient, opts, cb);
2015-09-02 15:56:00 -03:00
})
});
2015-03-06 12:00:10 -03:00
};
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);
try {
2015-11-11 10:53:51 -03:00
var walletData = bwcService.parseSecret(opts.secret);
2015-08-12 11:16:34 -03:00
// check if exist
if (lodash.find(root.profile.credentials, {
2016-03-11 16:50:48 -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
}
} catch (ex) {
$log.debug(ex);
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-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);
2015-10-25 23:25:44 -03:00
root._addWalletClient(walletClient, opts, 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];
};
2015-03-06 12:00:10 -03:00
root.deleteWalletFC = function(opts, cb) {
var fc = root.focusedClient;
2015-11-06 16:54:25 -03:00
var walletId = fc.credentials.walletId;
pushNotificationsService.unsubscribe(root.getClient(walletId), function(err) {
2016-01-27 16:31:11 -03:00
if (err) $log.warn('Unsubscription error: ' + err.message);
else $log.debug('Unsubscribed from push notifications service');
2015-03-06 12:00:10 -03:00
2016-01-15 17:09:50 -03:00
$log.debug('Deleting Wallet:', fc.credentials.walletName);
2015-03-06 12:00:10 -03:00
2016-01-15 17:09:50 -03:00
fc.removeAllListeners();
root.profile.credentials = lodash.reject(root.profile.credentials, {
walletId: walletId
});
2015-03-06 12:00:10 -03:00
2016-01-15 17:09:50 -03:00
delete root.walletClients[walletId];
root.focusedClient = null;
2015-11-06 16:54:25 -03:00
2016-01-15 17:09:50 -03:00
storageService.clearLastAddress(walletId, function(err) {
if (err) $log.warn(err);
});
2015-11-06 16:54:25 -03:00
2016-01-15 17:09:50 -03:00
storageService.removeTxHistory(walletId, function(err) {
if (err) $log.warn(err);
});
2015-11-06 16:54:25 -03:00
2016-01-15 17:09:50 -03:00
storageService.clearBackupFlag(walletId, function(err) {
if (err) $log.warn(err);
});
$timeout(function() {
root.setWalletClients();
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) {
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-10-20 12:03:08 -03:00
root._addWalletClient = function(walletClient, opts, cb) {
2015-03-06 12:00:10 -03:00
var walletId = walletClient.credentials.walletId;
2015-11-06 11:26:50 -03:00
// check if exist
var w = lodash.find(root.profile.credentials, {
'walletId': walletId
});
if (w) {
return cb(gettext('Wallet already in Copay' + ": ") + w.walletName);
}
2015-10-25 23:25:44 -03:00
var config = configService.getSync();
2015-11-06 11:26:50 -03:00
var defaults = configService.getDefaults();
var bwsFor = {};
bwsFor[walletId] = opts.bwsurl || defaults.bws.url;
2015-10-25 23:25:44 -03:00
2015-11-06 11:26:50 -03:00
configService.set({
bwsFor: bwsFor,
}, function(err) {
if (err) console.log(err);
2015-10-25 23:25:44 -03:00
2015-11-06 11:26:50 -03:00
root.profile.credentials.push(JSON.parse(walletClient.export()));
root.setWalletClients();
2015-10-25 23:25:44 -03:00
2015-11-14 17:29:45 -03:00
var handleImport = function(cb) {
var isImport = opts.mnemonic || opts.externalSource || opts.extendedPrivateKey;
2015-11-14 17:29:45 -03:00
if (!isImport)
2015-11-14 17:29:45 -03:00
return cb();
$rootScope.$emit('Local/BackupDone', walletId);
if (!walletClient.isComplete())
2015-11-14 17:29:45 -03:00
return cb();
storageService.setCleanAndScanAddresses(walletId, cb);
};
handleImport(function() {
root.setAndStoreFocus(walletId, function() {
storageService.storeProfile(root.profile, function(err) {
2016-02-22 19:32:24 -03:00
$rootScope.$emit('Local/ProfileCreated');
if (config.pushNotifications.enabled)
pushNotificationsService.enableNotifications(root.walletClients);
2015-11-14 17:29:45 -03:00
return cb(err, walletId);
});
2015-10-25 23:25:44 -03:00
});
});
2015-10-25 23:06:29 -03:00
});
2015-03-06 12:00:10 -03:00
};
2015-08-24 17:09:59 -03:00
root.importWallet = function(str, opts, cb) {
2015-10-19 17:26:15 -03:00
if (opts.bwsurl)
bwcService.setBaseUrl(opts.bwsurl);
2015-11-06 16:04:35 -03:00
2015-08-24 17:09:59 -03:00
var walletClient = bwcService.getClient();
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) {
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 ||  [];
root._addWalletClient(walletClient, opts, function(err, walletId) {
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);
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) {
if (opts.bwsurl)
bwcService.setBaseUrl(opts.bwsurl);
2015-09-05 00:11:14 -03:00
var walletClient = bwcService.getClient();
$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);
2015-10-20 12:03:08 -03:00
root._addWalletClient(walletClient, opts, cb);
2015-09-05 00:11:14 -03:00
});
};
root._normalizeMnemonic = function(words) {
2015-10-19 11:19:28 -03:00
var isJA = words.indexOf('\u3000') > -1;
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) {
2015-10-20 12:03:08 -03:00
if (opts.bwsurl)
bwcService.setBaseUrl(opts.bwsurl);
2015-08-24 17:09:59 -03:00
var walletClient = bwcService.getClient();
2015-09-05 01:02:01 -03:00
2015-08-24 17:09:59 -03:00
$log.debug('Importing Wallet Mnemonic');
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);
2015-10-20 12:03:08 -03:00
root._addWalletClient(walletClient, opts, cb);
2015-08-24 17:09:59 -03:00
});
};
root.importExtendedPublicKey = function(opts, cb) {
2015-10-20 12:03:08 -03:00
if (opts.bwsurl)
bwcService.setBaseUrl(opts.bwsurl);
var walletClient = bwcService.getClient();
$log.debug('Importing Wallet XPubKey');
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',
}, function(err) {
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';
return bwsError.cb(err, gettext('Could not import'), cb);
}
2015-10-20 12:03:08 -03:00
root._addWalletClient(walletClient, opts, cb);
});
};
2015-05-13 11:58:19 -03:00
root.create = function(opts, cb) {
$log.info('Creating profile');
2015-10-20 12:18:44 -03:00
var defaults = configService.getDefaults();
configService.get(function(err) {
2015-10-20 12:18:44 -03:00
bwcService.setBaseUrl(defaults.bws.url);
bwcService.setTransports(['polling']);
2015-05-13 11:58:19 -03:00
root._createNewProfile(opts, function(err, p) {
if (err) return cb(err);
root.bindProfile(p, function(err) {
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;
storageService.storeProfile(root.profile, function(err) {
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) {
if (err) return cb(gettext('Error importing wallet: ') + err);
2015-03-06 12:00:10 -03:00
if (root.walletClients[walletClient.credentials.walletId]) {
$log.debug('Wallet:' + walletClient.credentials.walletName + ' already imported');
return cb(gettext('Wallet Already Imported: ') + walletClient.credentials.walletName);
2015-03-06 12:00:10 -03:00
};
$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.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;
storageService.storeProfile(root.profile, cb);
};
root.setPrivateKeyEncryptionFC = function(password, cb) {
var fc = root.focusedClient;
$log.debug('Encrypting private key for', fc.credentials.walletName);
fc.setPrivateKeyEncryption(password);
root.lockFC();
2015-03-06 12:00:10 -03:00
root.updateCredentialsFC(function() {
$log.debug('Wallet encrypted');
return cb();
});
};
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');
return cb();
});
};
root.lockFC = function() {
var fc = root.focusedClient;
try {
fc.lock();
} catch (e) {};
};
Feat/coinbase integration (#4012) * Oauth2 and first view * Connect with Coinbase using mobile * Buy and Sell through Coinbase * Fix buy * Receive and send bitcoin to Coinbase account * Receive bitcoin from Coinbase to Copay * Complete user and account information. Connection errors * Improves error handler * Removes console.log * Coinbase background color. Send to Coinbase form validation * Fix send from different wallet * Send and receive using Coinbase * Pagination activity * Fix Buy and Sell * One option in the sidebar to Buy and Sell * Native balance on Coinbase homepage * Rename receive and send * Auto-close window after authenticate * Reorder * Get payment methods * Fix when token expired * Fix token expired * Integration: sell and send to Coinbase * Store pending transaction before sell * Sell flow completed * Removing files * Fix sell * Fix sell * Fix sell * Sell completed * Buy bitcoin through coinbase * Buy auto * Currency set to USD * Select payment methods. Limits * Removes payment methods from preferences * Fix signs. Tx ordered by updated. Minor fixes * Removes console.log * Improving ux-language things * Fix selectedpaymentmethod if not verified * Set error if tx not found * Price sensitivity. Minor fixes * Adds coinbase api key to gitignore * Coinbase production ready * Fix sell in usd * Bug fixes * New Sensitivity step * Refresh token with a simple click * Refresh token * Refactor * Fix auto reconnect if token expired Signed-off-by: Gustavo Maximiliano Cortez <cmgustavo83@gmail.com> * Fix calls if token expired
2016-04-13 14:08:03 -03:00
root.unlockFC = function(opts, cb) {
opts = opts || {};
var fc = opts.selectedClient || root.focusedClient;
if (!fc.isPrivKeyEncrypted())
return cb();
2015-03-06 12:00:10 -03:00
$log.debug('Wallet is encrypted');
$rootScope.$emit('Local/NeedsPassword', false, function(err2, password) {
2016-05-05 15:36:54 -03:00
if (err2)
return cb(err2);
2016-05-05 15:36:54 -03:00
if (!password)
return cb(gettext('Spending Password needed'));
2015-03-06 12:00:10 -03:00
try {
fc.unlock(password);
} catch (e) {
$log.warn('Error decrypting wallet:', e);
return cb(gettext('Wrong spending password'));
2015-03-06 12:00:10 -03:00
}
return cb();
});
};
2016-03-14 12:21:55 -03:00
root.isBackupNeeded = function(walletId, cb) {
2016-03-11 16:50:48 -03:00
var c = root.getClient(walletId);
2016-03-14 12:21:55 -03:00
if (c.isPrivKeyExternal()) return cb(false);
if (!c.credentials.mnemonic) return cb(false);
if (c.credentials.network == 'testnet') return cb(false);
storageService.getBackupFlag(walletId, function(err, val) {
if (err || val) return cb(false);
return cb(true);
});
2016-03-11 16:50:48 -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
};
});
2016-01-21 17:16:40 -03:00
if (network) {
ret = lodash.filter(ret, function(w) {
return (w.network == network);
});
}
return lodash.sortBy(ret, 'name');
};
2015-03-06 12:00:10 -03:00
return root;
});