2014-10-24 07:37:03 -07:00
|
|
|
'use strict';
|
|
|
|
angular.module('copayApp.services')
|
2014-12-07 07:40:59 -08:00
|
|
|
.factory('identityService', function($rootScope, $location, $timeout, $filter, pluginManager, notification, pendingTxsService, balanceService, applicationService, go) {
|
2014-11-29 19:31:17 -08:00
|
|
|
notification.enableHtml5Mode(); // for chrome: if support, enable it
|
2014-10-24 07:37:03 -07:00
|
|
|
|
2014-12-03 11:01:22 -08:00
|
|
|
// TODO:
|
|
|
|
// * remove iden from rootScope
|
|
|
|
// * remove wallet from rootScope
|
|
|
|
// * create walletService
|
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
var root = {};
|
2014-10-30 14:08:50 -07:00
|
|
|
root.check = function(scope) {
|
|
|
|
copay.Identity.checkIfExistsAny({
|
2014-12-05 08:24:46 -08:00
|
|
|
pluginManager: pluginManager.getInstance(config),
|
2014-10-30 14:08:50 -07:00
|
|
|
}, function(anyProfile) {
|
|
|
|
copay.Wallet.checkIfExistsAny({
|
2014-12-05 08:24:46 -08:00
|
|
|
pluginManager: pluginManager.getInstance(config),
|
2014-10-30 14:08:50 -07:00
|
|
|
}, function(anyWallet) {
|
2014-10-31 07:24:16 -07:00
|
|
|
scope.loading = false;
|
2014-10-30 14:08:50 -07:00
|
|
|
scope.anyProfile = anyProfile ? true : false;
|
|
|
|
scope.anyWallet = anyWallet ? true : false;
|
|
|
|
|
|
|
|
if (!scope.anyProfile) {
|
|
|
|
$location.path('/createProfile');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-12-03 11:01:22 -08:00
|
|
|
// TODO should be on 'walletService'
|
2014-11-29 13:35:48 -08:00
|
|
|
root.goWalletHome = function() {
|
|
|
|
var w = $rootScope.wallet;
|
|
|
|
if (w) {
|
2014-12-06 10:30:32 -08:00
|
|
|
$rootScope.starting = false;
|
2014-11-29 19:31:17 -08:00
|
|
|
if (!w.isComplete()) {
|
2014-11-29 13:35:48 -08:00
|
|
|
$location.path('/copayers');
|
|
|
|
} else {
|
|
|
|
if ($rootScope.pendingPayment) {
|
|
|
|
$location.path('paymentIntent');
|
|
|
|
} else {
|
|
|
|
$location.path('homeWallet');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-11-29 22:58:38 -08:00
|
|
|
root.create = function(email, password, cb) {
|
2014-10-30 14:08:50 -07:00
|
|
|
copay.Identity.create({
|
2014-11-29 22:58:38 -08:00
|
|
|
email: email,
|
|
|
|
password: password,
|
2014-12-05 08:24:46 -08:00
|
|
|
pluginManager: pluginManager.getInstance(config),
|
2014-10-27 07:10:32 -07:00
|
|
|
network: config.network,
|
|
|
|
networkName: config.networkName,
|
|
|
|
walletDefaults: config.wallet,
|
|
|
|
passphraseConfig: config.passphraseConfig,
|
2014-10-30 14:08:50 -07:00
|
|
|
failIfExists: true,
|
|
|
|
}, function(err, iden) {
|
2014-11-26 07:08:26 -08:00
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
if (err) return cb(err);
|
|
|
|
preconditions.checkState(iden);
|
2014-11-29 22:58:38 -08:00
|
|
|
root.bind(iden);
|
2014-11-29 19:31:17 -08:00
|
|
|
|
2014-12-03 11:01:22 -08:00
|
|
|
return cb(null);
|
2014-10-27 07:10:32 -07:00
|
|
|
});
|
2014-12-03 11:01:22 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
root.createDefaultWallet = function(cb) {
|
|
|
|
var iden = $rootScope.iden;
|
2014-10-30 14:08:50 -07:00
|
|
|
|
2014-12-03 11:01:22 -08:00
|
|
|
var walletOptions = {
|
|
|
|
nickname: iden.fullName,
|
|
|
|
networkName: config.networkName,
|
|
|
|
requiredCopayers: 1,
|
|
|
|
totalCopayers: 1,
|
|
|
|
password: iden.password,
|
|
|
|
name: 'My wallet',
|
|
|
|
};
|
|
|
|
iden.createWallet(walletOptions, function(err, wallet) {
|
|
|
|
return cb(err);
|
|
|
|
});
|
2014-10-27 07:10:32 -07:00
|
|
|
};
|
|
|
|
|
2014-12-01 12:21:39 -08:00
|
|
|
root.setServerStatus = function(headers) {
|
2014-11-26 07:08:26 -08:00
|
|
|
if (!headers)
|
2014-12-01 12:21:39 -08:00
|
|
|
return;
|
|
|
|
|
2014-11-26 07:08:26 -08:00
|
|
|
if (headers['X-Email-Needs-Validation'])
|
|
|
|
$rootScope.needsEmailConfirmation = true;
|
2014-12-01 12:21:39 -08:00
|
|
|
else
|
2014-11-26 07:08:26 -08:00
|
|
|
$rootScope.needsEmailConfirmation = null;
|
2014-12-01 12:21:39 -08:00
|
|
|
|
2014-11-26 07:08:26 -08:00
|
|
|
if (headers['X-Quota-Per-Item'])
|
|
|
|
$rootScope.quotaPerItem = parseInt(headers['X-Quota-Per-Item']);
|
2014-12-01 12:21:39 -08:00
|
|
|
|
2014-11-26 07:08:26 -08:00
|
|
|
if (headers['X-Quota-Items-Limit'])
|
|
|
|
$rootScope.quotaItems = parseInt(headers['X-Quota-Items-Limit']);
|
2014-12-01 12:21:39 -08:00
|
|
|
};
|
2014-10-24 07:58:22 -07:00
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
root.open = function(email, password, cb) {
|
|
|
|
var opts = {
|
|
|
|
email: email,
|
|
|
|
password: password,
|
2014-12-05 08:24:46 -08:00
|
|
|
pluginManager: pluginManager.getInstance(config),
|
2014-10-27 07:10:32 -07:00
|
|
|
network: config.network,
|
|
|
|
networkName: config.networkName,
|
|
|
|
walletDefaults: config.wallet,
|
|
|
|
passphraseConfig: config.passphraseConfig,
|
2014-11-29 19:31:17 -08:00
|
|
|
};
|
2014-11-28 08:10:15 -08:00
|
|
|
|
2014-12-01 11:19:34 -08:00
|
|
|
copay.Identity.open(opts, function(err, iden, headers) {
|
2014-11-29 19:31:17 -08:00
|
|
|
if (err) return cb(err);
|
2014-12-01 12:21:39 -08:00
|
|
|
root.setServerStatus(headers);
|
2014-11-29 19:31:17 -08:00
|
|
|
root.bind(iden);
|
2014-12-01 10:33:16 -08:00
|
|
|
return cb(null, iden);
|
2014-11-29 13:35:48 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-11-26 07:08:26 -08:00
|
|
|
root.deleteProfile = function(cb) {
|
2014-12-01 09:44:36 -08:00
|
|
|
$rootScope.iden.remove(null, cb);
|
|
|
|
};
|
|
|
|
|
2014-11-30 18:08:16 -08:00
|
|
|
root.deleteWallet = function(w, cb) {
|
|
|
|
$rootScope.iden.deleteWallet(w.id, cb);
|
2014-10-30 14:08:50 -07:00
|
|
|
};
|
2014-10-24 07:37:03 -07:00
|
|
|
|
2014-11-29 13:35:48 -08:00
|
|
|
root.isFocused = function(wid) {
|
|
|
|
return $rootScope.wallet && wid === $rootScope.wallet.getId();
|
|
|
|
};
|
|
|
|
|
|
|
|
root.setupGlobalVariables = function(iden) {
|
|
|
|
$rootScope.pendingTxCount = 0;
|
|
|
|
$rootScope.reconnecting = false;
|
|
|
|
$rootScope.iden = iden;
|
|
|
|
};
|
|
|
|
|
|
|
|
root.setPaymentWallet = function(w) {
|
|
|
|
root.setFocusedWallet(w);
|
|
|
|
$location.path('/send');
|
|
|
|
};
|
|
|
|
|
2014-12-02 11:53:24 -08:00
|
|
|
root.noFocusedWallet = function() {
|
|
|
|
$rootScope.wallet = null;
|
|
|
|
$timeout(function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2014-11-29 20:02:18 -08:00
|
|
|
root.setFocusedWallet = function(w, dontUpdateIt) {
|
2014-11-29 13:35:48 -08:00
|
|
|
if (!_.isObject(w))
|
|
|
|
w = $rootScope.iden.getWalletById(w);
|
|
|
|
preconditions.checkState(w && _.isObject(w));
|
2014-11-29 19:31:17 -08:00
|
|
|
|
|
|
|
copay.logger.debug('Set focus:', w.getName());
|
2014-11-29 13:35:48 -08:00
|
|
|
$rootScope.wallet = w;
|
2014-11-29 19:31:17 -08:00
|
|
|
|
2014-11-29 20:02:18 -08:00
|
|
|
if (!dontUpdateIt)
|
|
|
|
$rootScope.iden.updateFocusedTimestamp(w.getId());
|
2014-11-29 13:35:48 -08:00
|
|
|
|
2014-11-29 20:02:18 -08:00
|
|
|
pendingTxsService.update();
|
2014-11-29 19:31:17 -08:00
|
|
|
$timeout(function() {
|
2014-11-29 13:35:48 -08:00
|
|
|
$rootScope.$digest();
|
2014-11-29 19:31:17 -08:00
|
|
|
})
|
2014-11-29 13:35:48 -08:00
|
|
|
};
|
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
root.installWalletHandlers = function(w) {
|
2014-11-29 13:35:48 -08:00
|
|
|
var wid = w.getId();
|
|
|
|
w.on('connectionError', function() {
|
|
|
|
if (root.isFocused(wid)) {
|
|
|
|
var message = "Could not connect to the Insight server. Check your settings and network configuration";
|
|
|
|
notification.error('Networking Error', message);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('corrupt', function(peerId) {
|
|
|
|
if (root.isFocused(wid)) {
|
|
|
|
notification.error('Error', $filter('translate')('Received corrupt message from ') + peerId);
|
|
|
|
}
|
|
|
|
});
|
2014-12-02 12:32:32 -08:00
|
|
|
|
|
|
|
w.on('publicKeyRingUpdated', function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
|
2014-11-29 13:35:48 -08:00
|
|
|
w.on('ready', function() {
|
2014-11-29 19:31:17 -08:00
|
|
|
var isFocused = root.isFocused(wid);
|
2014-11-29 20:02:18 -08:00
|
|
|
copay.logger.debug('Wallet:' + w.getName() + ' is ready. Focused:', isFocused);
|
2014-11-29 19:31:17 -08:00
|
|
|
|
|
|
|
balanceService.update(w, function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, isFocused);
|
2014-11-29 13:35:48 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
w.on('tx', function(address, isChange) {
|
|
|
|
if (!isChange) {
|
|
|
|
notification.funds('Funds received on ' + w.getName(), address);
|
|
|
|
}
|
|
|
|
balanceService.update(w, function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, root.isFocused(wid));
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('balanceUpdated', function() {
|
|
|
|
balanceService.update(w, function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, root.isFocused(wid));
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('insightReconnected', function() {
|
|
|
|
$rootScope.reconnecting = false;
|
|
|
|
balanceService.update(w, function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, root.isFocused(wid));
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('insightError', function() {
|
|
|
|
if (root.isFocused(wid)) {
|
|
|
|
$rootScope.reconnecting = true;
|
|
|
|
$rootScope.$digest();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
w.on('newAddresses', function() {
|
2014-11-30 13:35:30 -08:00
|
|
|
// Nothing yet
|
2014-11-29 13:35:48 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
w.on('txProposalsUpdated', function() {
|
|
|
|
if (root.isFocused(wid)) {
|
|
|
|
pendingTxsService.update();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('paymentACK', function(memo) {
|
|
|
|
notification.success('Payment Acknowledged', memo);
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('txProposalEvent', function(e) {
|
|
|
|
if (root.isFocused(wid)) {
|
2014-12-06 10:30:32 -08:00
|
|
|
pendingTxsService.update();
|
2014-11-29 13:35:48 -08:00
|
|
|
}
|
|
|
|
|
2014-12-05 10:20:11 -08:00
|
|
|
balanceService.update(w, function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, root.isFocused(wid));
|
|
|
|
|
2014-11-29 13:35:48 -08:00
|
|
|
// TODO: add wallet name notification
|
|
|
|
var user = w.publicKeyRing.nicknameForCopayer(e.cId);
|
|
|
|
var name = w.getName();
|
|
|
|
switch (e.type) {
|
|
|
|
case 'new':
|
|
|
|
notification.info('[' + name + '] New Transaction',
|
|
|
|
$filter('translate')('You received a transaction proposal from') + ' ' + user);
|
|
|
|
break;
|
|
|
|
case 'signed':
|
2014-12-04 13:12:29 -08:00
|
|
|
notification.success('[' + name + '] Transaction Signed',
|
2014-11-29 13:35:48 -08:00
|
|
|
$filter('translate')('A transaction was signed by') + ' ' + user);
|
|
|
|
break;
|
|
|
|
case 'signedAndBroadcasted':
|
2014-12-04 13:12:29 -08:00
|
|
|
notification.success('[' + name + '] Transaction Approved',
|
2014-11-29 13:35:48 -08:00
|
|
|
$filter('translate')('A transaction was signed and broadcasted by') + ' ' + user);
|
|
|
|
break;
|
|
|
|
case 'rejected':
|
2014-12-04 13:12:29 -08:00
|
|
|
notification.warning('[' + name + '] Transaction Rejected',
|
2014-11-29 13:35:48 -08:00
|
|
|
$filter('translate')('A transaction was rejected by') + ' ' + user);
|
|
|
|
break;
|
|
|
|
case 'corrupt':
|
|
|
|
notification.error('[' + name + '] Transaction Error',
|
|
|
|
$filter('translate')('Received corrupt transaction from') + ' ' + user);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
w.on('addressBookUpdated', function(dontDigest) {
|
|
|
|
if (root.isFocused(wid)) {
|
|
|
|
if (!dontDigest) {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
w.on('connect', function(peerID) {
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
// TODO?
|
|
|
|
// w.on('close', );
|
|
|
|
// w.on('locked',);
|
|
|
|
};
|
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
root.bind = function(iden) {
|
|
|
|
preconditions.checkArgument(_.isObject(iden));
|
2014-11-29 19:44:25 -08:00
|
|
|
copay.logger.debug('Binding profile...');
|
2014-11-29 19:31:17 -08:00
|
|
|
|
|
|
|
var self = this;
|
2014-11-29 13:35:48 -08:00
|
|
|
root.setupGlobalVariables(iden);
|
2014-11-29 19:31:17 -08:00
|
|
|
iden.on('newWallet', function(wid) {
|
|
|
|
var w = iden.getWalletById(wid);
|
2014-11-29 20:02:18 -08:00
|
|
|
copay.logger.debug('newWallet:', w.getName(), wid, iden.getLastFocusedWalletId());
|
2014-11-29 19:31:17 -08:00
|
|
|
root.installWalletHandlers(w);
|
|
|
|
if (wid == iden.getLastFocusedWalletId()) {
|
2014-11-29 20:02:18 -08:00
|
|
|
copay.logger.debug('GOT Focused wallet:', w.getName());
|
|
|
|
root.setFocusedWallet(w, true);
|
2014-11-29 19:31:17 -08:00
|
|
|
root.goWalletHome();
|
|
|
|
}
|
2014-12-06 10:30:32 -08:00
|
|
|
|
2014-11-29 20:02:18 -08:00
|
|
|
// At the end (after all handlers are in place)...start the wallet.
|
|
|
|
w.netStart();
|
2014-11-29 19:31:17 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
iden.on('noWallets', function() {
|
2014-12-06 12:58:07 -08:00
|
|
|
notification.warning('No Wallets','Your profile has no wallets. Create one here');
|
2014-12-06 10:30:32 -08:00
|
|
|
$rootScope.starting = false;
|
2014-11-29 13:35:48 -08:00
|
|
|
$location.path('/create');
|
2014-12-06 10:30:32 -08:00
|
|
|
$timeout(function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}, 1);
|
2014-11-29 19:31:17 -08:00
|
|
|
});
|
2014-11-29 13:35:48 -08:00
|
|
|
|
2014-12-02 11:53:24 -08:00
|
|
|
iden.on('walletDeleted', function(wid) {
|
|
|
|
// do nothing. this is handled 'on sync' on controller.
|
2014-11-29 19:31:17 -08:00
|
|
|
});
|
2014-11-29 13:35:48 -08:00
|
|
|
|
2014-12-06 10:30:32 -08:00
|
|
|
iden.on('walletStorageError', function(wid, message) {
|
2014-12-04 10:55:50 -08:00
|
|
|
notification.error('Error storing wallet', message);
|
|
|
|
});
|
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
iden.on('closed', function() {
|
|
|
|
delete $rootScope['wallet'];
|
|
|
|
delete $rootScope['iden'];
|
|
|
|
applicationService.restart();
|
|
|
|
});
|
|
|
|
};
|
2014-11-29 13:35:48 -08:00
|
|
|
|
2014-11-29 19:31:17 -08:00
|
|
|
root.signout = function() {
|
2014-12-06 16:07:26 -08:00
|
|
|
$rootScope.signingOut = true;
|
2014-11-29 19:31:17 -08:00
|
|
|
if ($rootScope.iden) {
|
2014-12-04 07:25:21 -08:00
|
|
|
$rootScope.iden.store({
|
|
|
|
noWallets: true
|
|
|
|
}, function() {
|
2014-12-06 16:07:26 -08:00
|
|
|
$rootScope.signingOut = false;
|
2014-12-07 07:40:59 -08:00
|
|
|
$rootScope.iden.close(); // Will trigger 'closed'
|
2014-12-04 07:25:21 -08:00
|
|
|
});
|
2014-11-29 13:35:48 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
root.createWallet = function(opts, cb) {
|
2014-11-29 19:31:17 -08:00
|
|
|
$rootScope.iden.createWallet(opts, cb);
|
2014-11-29 13:35:48 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
root.importWallet = function(encryptedObj, pass, opts, cb) {
|
2014-12-02 12:38:31 -08:00
|
|
|
copay.Compatibility.importEncryptedWallet($rootScope.iden, encryptedObj, pass, opts, cb);
|
2014-11-29 13:35:48 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
root.joinWallet = function(opts, cb) {
|
|
|
|
$rootScope.iden.joinWallet(opts, function(err, w) {
|
|
|
|
return cb(err);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-11-29 20:02:18 -08:00
|
|
|
root.importProfile = function(str, password, cb) {
|
2014-11-29 19:31:17 -08:00
|
|
|
copay.Identity.importFromEncryptedFullJson(str, password, {
|
2014-12-05 08:24:46 -08:00
|
|
|
pluginManager: pluginManager.getInstance(config),
|
2014-11-29 19:31:17 -08:00
|
|
|
network: config.network,
|
|
|
|
networkName: config.networkName,
|
|
|
|
walletDefaults: config.wallet,
|
|
|
|
passphraseConfig: config.passphraseConfig,
|
2014-11-29 23:42:39 -08:00
|
|
|
}, function(err, iden, walletObjs) {
|
2014-11-29 19:31:17 -08:00
|
|
|
if (err) return cb(err);
|
2014-11-29 22:58:38 -08:00
|
|
|
root.bind(iden);
|
2014-11-29 23:42:39 -08:00
|
|
|
iden.importMultipleWalletsFromObj(walletObjs);
|
2014-11-29 22:58:38 -08:00
|
|
|
return cb();
|
2014-11-29 19:31:17 -08:00
|
|
|
});
|
|
|
|
};
|
2014-11-29 13:35:48 -08:00
|
|
|
|
2014-10-27 07:10:32 -07:00
|
|
|
return root;
|
|
|
|
});
|