2014-04-17 07:46:49 -07:00
|
|
|
'use strict';
|
2014-06-12 13:42:26 -07:00
|
|
|
var bitcore = require('bitcore');
|
2014-04-17 07:46:49 -07:00
|
|
|
|
2014-06-03 13:42:36 -07:00
|
|
|
angular.module('copayApp.services')
|
2014-09-16 13:30:30 -07:00
|
|
|
.factory('controllerUtils', function($rootScope, $sce, $location, $filter, notification, $timeout, uriHandler, rateService) {
|
2014-08-22 10:13:04 -07:00
|
|
|
var root = {};
|
2014-05-07 15:04:36 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
root.redirIfLogged = function() {
|
|
|
|
if ($rootScope.wallet) {
|
2014-08-29 08:33:56 -07:00
|
|
|
$location.path('receive');
|
2014-08-22 10:13:04 -07:00
|
|
|
}
|
|
|
|
};
|
2014-08-06 14:41:37 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
root.logout = function() {
|
|
|
|
if ($rootScope.wallet)
|
2014-08-28 14:58:43 -07:00
|
|
|
$rootScope.wallet.close();
|
2014-06-24 08:57:15 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.wallet = null;
|
|
|
|
delete $rootScope['wallet'];
|
2014-04-23 14:07:20 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
// Clear rootScope
|
|
|
|
for (var i in $rootScope) {
|
|
|
|
if (i.charAt(0) != '$') {
|
|
|
|
delete $rootScope[i];
|
|
|
|
}
|
|
|
|
}
|
2014-06-12 07:03:24 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
$location.path('/');
|
|
|
|
};
|
2014-06-12 07:03:24 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
root.onError = function(scope) {
|
|
|
|
if (scope) scope.loading = false;
|
|
|
|
root.logout();
|
2014-08-12 12:26:15 -07:00
|
|
|
}
|
2014-08-22 10:13:04 -07:00
|
|
|
|
|
|
|
root.onErrorDigest = function(scope, msg) {
|
|
|
|
root.onError(scope);
|
|
|
|
if (msg) {
|
|
|
|
notification.error('Error', msg);
|
2014-08-12 12:26:15 -07:00
|
|
|
}
|
2014-08-22 10:13:04 -07:00
|
|
|
};
|
2014-07-08 04:58:24 -07:00
|
|
|
|
2014-09-09 11:30:21 -07:00
|
|
|
root.installWalletHandlers = function(w, $scope) {
|
|
|
|
w.on('connectionError', function() {
|
|
|
|
var message = "Could not connect to the Insight server. Check your settings and network configuration";
|
|
|
|
notification.error('Networking Error', message);
|
2014-08-22 10:13:04 -07:00
|
|
|
root.onErrorDigest($scope);
|
|
|
|
});
|
2014-09-09 11:30:21 -07:00
|
|
|
w.on('ready', function() {
|
2014-08-22 10:13:04 -07:00
|
|
|
$scope.loading = false;
|
|
|
|
});
|
2014-04-24 19:13:55 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
w.on('corrupt', function(peerId) {
|
2014-09-16 13:30:30 -07:00
|
|
|
notification.error('Error', $filter('translate')('Received corrupt message from ') + peerId);
|
2014-08-22 10:13:04 -07:00
|
|
|
});
|
|
|
|
w.on('ready', function(myPeerID) {
|
|
|
|
$rootScope.wallet = w;
|
2014-09-19 07:27:48 -07:00
|
|
|
if ($rootScope.initialConnection) {
|
|
|
|
$rootScope.initialConnection = false;
|
|
|
|
if ($rootScope.pendingPayment) {
|
|
|
|
$location.path('send');
|
|
|
|
} else {
|
|
|
|
$location.path('receive');
|
|
|
|
}
|
2014-08-22 10:13:04 -07:00
|
|
|
}
|
|
|
|
});
|
2014-05-16 14:48:17 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
w.on('publicKeyRingUpdated', function(dontDigest) {
|
2014-09-09 15:05:23 -07:00
|
|
|
root.updateAddressList();
|
2014-08-22 10:13:04 -07:00
|
|
|
if (!dontDigest) {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}
|
|
|
|
});
|
2014-09-09 11:30:21 -07:00
|
|
|
|
2014-09-17 13:34:00 -07:00
|
|
|
w.on('tx', function(address, isChange) {
|
|
|
|
if (!isChange) {
|
|
|
|
notification.funds('Funds received!', address);
|
|
|
|
}
|
2014-09-09 11:30:21 -07:00
|
|
|
root.updateBalance(function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
w.on('balanceUpdated', function() {
|
|
|
|
root.updateBalance(function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-09-09 16:55:51 -07:00
|
|
|
w.on('insightReconnected', function() {
|
2014-09-09 11:30:21 -07:00
|
|
|
$rootScope.reconnecting = false;
|
2014-09-09 16:55:51 -07:00
|
|
|
root.updateAddressList();
|
2014-09-09 11:30:21 -07:00
|
|
|
root.updateBalance(function() {
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-09-09 16:55:51 -07:00
|
|
|
w.on('insightError', function() {
|
2014-09-09 11:30:21 -07:00
|
|
|
$rootScope.reconnecting = true;
|
|
|
|
$rootScope.$digest();
|
|
|
|
});
|
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
w.on('txProposalsUpdated', function(dontDigest) {
|
|
|
|
root.updateTxs();
|
|
|
|
// give sometime to the tx to propagate.
|
|
|
|
$timeout(function() {
|
|
|
|
root.updateBalance(function() {
|
|
|
|
if (!dontDigest) {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, 3000);
|
|
|
|
});
|
|
|
|
w.on('txProposalEvent', function(e) {
|
2014-09-10 14:03:31 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
var user = w.publicKeyRing.nicknameForCopayer(e.cId);
|
|
|
|
switch (e.type) {
|
|
|
|
case 'signed':
|
2014-09-16 13:30:30 -07:00
|
|
|
notification.info('Transaction Update', $filter('translate')('A transaction was signed by') + ' ' + user);
|
2014-08-22 10:13:04 -07:00
|
|
|
break;
|
|
|
|
case 'rejected':
|
2014-09-16 13:30:30 -07:00
|
|
|
notification.info('Transaction Update', $filter('translate')('A transaction was rejected by') + ' ' + user);
|
2014-08-22 10:13:04 -07:00
|
|
|
break;
|
|
|
|
case 'corrupt':
|
2014-09-29 13:36:34 -07:00
|
|
|
notification.error('Transaction Error', $filter('translate')('Received corrupt transaction from') + ' ' + user);
|
2014-08-22 10:13:04 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
w.on('addressBookUpdated', function(dontDigest) {
|
|
|
|
if (!dontDigest) {
|
|
|
|
$rootScope.$digest();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
w.on('connect', function(peerID) {
|
2014-05-09 07:59:38 -07:00
|
|
|
$rootScope.$digest();
|
2014-08-22 10:13:04 -07:00
|
|
|
});
|
|
|
|
w.on('close', root.onErrorDigest);
|
|
|
|
w.on('locked', root.onErrorDigest.bind(this));
|
2014-09-19 13:12:54 -07:00
|
|
|
|
2014-09-09 11:30:21 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
root.setupRootVariables = function() {
|
|
|
|
uriHandler.register();
|
|
|
|
$rootScope.unitName = config.unitName;
|
|
|
|
$rootScope.txAlertCount = 0;
|
2014-09-19 07:27:48 -07:00
|
|
|
$rootScope.initialConnection = true;
|
2014-09-09 11:30:21 -07:00
|
|
|
$rootScope.reconnecting = false;
|
|
|
|
$rootScope.isCollapsed = true;
|
|
|
|
$rootScope.$watch('txAlertCount', function(txAlertCount) {
|
|
|
|
if (txAlertCount && txAlertCount > 0) {
|
|
|
|
|
2014-09-16 13:30:30 -07:00
|
|
|
notification.info('New Transaction', ($rootScope.txAlertCount == 1) ? 'You have a pending transaction proposal' : $filter('translate')('You have') + ' ' + $rootScope.txAlertCount + ' ' + $filter('translate')('pending transaction proposals'), txAlertCount);
|
2014-09-09 11:30:21 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
root.startNetwork = function(w, $scope) {
|
|
|
|
root.setupRootVariables();
|
|
|
|
root.installWalletHandlers(w, $scope);
|
2014-09-09 15:05:23 -07:00
|
|
|
root.updateAddressList();
|
2014-09-09 11:30:21 -07:00
|
|
|
notification.enableHtml5Mode(); // for chrome: if support, enable it
|
2014-08-22 10:13:04 -07:00
|
|
|
w.netStart();
|
2014-09-19 13:12:54 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
};
|
2014-06-16 08:44:18 -07:00
|
|
|
|
2014-09-09 11:53:47 -07:00
|
|
|
// TODO movie this to wallet
|
2014-08-22 10:13:04 -07:00
|
|
|
root.updateAddressList = function() {
|
|
|
|
var w = $rootScope.wallet;
|
2014-09-10 14:03:31 -07:00
|
|
|
if (w && w.isReady()) {
|
|
|
|
w.subscribeToAddresses();
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.addrInfos = w.getAddressesInfo();
|
2014-09-10 14:03:31 -07:00
|
|
|
}
|
2014-08-22 10:13:04 -07:00
|
|
|
};
|
2014-05-13 00:03:09 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
root.updateBalance = function(cb) {
|
|
|
|
var w = $rootScope.wallet;
|
|
|
|
if (!w) return root.onErrorDigest();
|
|
|
|
if (!w.isReady()) return;
|
|
|
|
|
|
|
|
$rootScope.balanceByAddr = {};
|
|
|
|
$rootScope.updatingBalance = true;
|
|
|
|
|
|
|
|
w.getBalance(function(err, balanceSat, balanceByAddrSat, safeBalanceSat) {
|
2014-08-29 06:50:52 -07:00
|
|
|
if (err) throw err;
|
2014-05-20 14:34:55 -07:00
|
|
|
|
2014-09-04 07:12:08 -07:00
|
|
|
var satToUnit = 1 / w.settings.unitToSatoshi;
|
2014-08-22 10:13:04 -07:00
|
|
|
var COIN = bitcore.util.COIN;
|
2014-08-06 09:59:33 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.totalBalance = balanceSat * satToUnit;
|
|
|
|
$rootScope.totalBalanceBTC = (balanceSat / COIN);
|
|
|
|
$rootScope.availableBalance = safeBalanceSat * satToUnit;
|
|
|
|
$rootScope.availableBalanceBTC = (safeBalanceSat / COIN);
|
2014-06-16 08:44:18 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.lockedBalance = (balanceSat - safeBalanceSat) * satToUnit;
|
|
|
|
$rootScope.lockedBalanceBTC = (balanceSat - safeBalanceSat) / COIN;
|
2014-05-13 00:03:09 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
var balanceByAddr = {};
|
|
|
|
for (var ii in balanceByAddrSat) {
|
|
|
|
balanceByAddr[ii] = balanceByAddrSat[ii] * satToUnit;
|
|
|
|
}
|
|
|
|
$rootScope.balanceByAddr = balanceByAddr;
|
|
|
|
root.updateAddressList();
|
|
|
|
$rootScope.updatingBalance = false;
|
2014-09-01 06:42:30 -07:00
|
|
|
|
|
|
|
rateService.whenAvailable(function() {
|
2014-09-04 07:59:26 -07:00
|
|
|
$rootScope.totalBalanceAlternative = rateService.toFiat(balanceSat, w.settings.alternativeIsoCode);
|
|
|
|
$rootScope.alternativeIsoCode = w.settings.alternativeIsoCode;
|
|
|
|
$rootScope.lockedBalanceAlternative = rateService.toFiat(balanceSat - safeBalanceSat, w.settings.alternativeIsoCode);
|
2014-09-18 07:07:07 -07:00
|
|
|
$rootScope.alternativeConversionRate = rateService.toFiat(100000000, w.settings.alternativeIsoCode);
|
2014-09-01 06:42:30 -07:00
|
|
|
return cb ? cb() : null;
|
|
|
|
});
|
2014-08-22 10:13:04 -07:00
|
|
|
});
|
|
|
|
};
|
2014-08-04 09:54:08 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
root.updateTxs = function(opts) {
|
|
|
|
var w = $rootScope.wallet;
|
|
|
|
if (!w) return;
|
|
|
|
opts = opts || $rootScope.txsOpts || {};
|
|
|
|
|
2014-09-04 07:12:08 -07:00
|
|
|
var satToUnit = 1 / w.settings.unitToSatoshi;
|
2014-08-22 10:13:04 -07:00
|
|
|
var myCopayerId = w.getMyCopayerId();
|
|
|
|
var pendingForUs = 0;
|
|
|
|
var inT = w.getTxProposals().sort(function(t1, t2) {
|
|
|
|
return t2.createdTs - t1.createdTs
|
|
|
|
});
|
|
|
|
var txs = [];
|
|
|
|
|
|
|
|
inT.forEach(function(i, index) {
|
|
|
|
if (opts.skip && (index < opts.skip[0] || index >= opts.skip[1])) {
|
|
|
|
return txs.push(null);
|
|
|
|
}
|
|
|
|
|
2014-09-29 13:36:34 -07:00
|
|
|
if (i.isPending && myCopayerId != i.creator && !i.rejectedByUs && !i.signedByUs) {
|
2014-08-22 10:13:04 -07:00
|
|
|
pendingForUs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!!opts.pending == !!i.isPending) {
|
|
|
|
var tx = i.builder.build();
|
|
|
|
var outs = [];
|
|
|
|
tx.outs.forEach(function(o) {
|
2014-09-11 11:29:45 -07:00
|
|
|
var addr = bitcore.Address.fromScriptPubKey(o.getScript(), w.getNetworkName())[0].toString();
|
2014-08-22 10:13:04 -07:00
|
|
|
if (!w.addressIsOwn(addr, {
|
|
|
|
excludeMain: true
|
|
|
|
})) {
|
|
|
|
outs.push({
|
|
|
|
address: addr,
|
|
|
|
value: bitcore.util.valueToBigInt(o.getValue()) * satToUnit,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// extra fields
|
|
|
|
i.outs = outs;
|
|
|
|
i.fee = i.builder.feeSat * satToUnit;
|
|
|
|
i.missingSignatures = tx.countInputMissingSignatures(0);
|
|
|
|
i.actionList = getActionList(i.peerActions);
|
|
|
|
txs.push(i);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-09-29 13:36:34 -07:00
|
|
|
w.removeTxWithSpentInputs();
|
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.txs = txs;
|
|
|
|
$rootScope.txsOpts = opts;
|
|
|
|
if ($rootScope.pendingTxCount < pendingForUs) {
|
|
|
|
$rootScope.txAlertCount = pendingForUs;
|
2014-08-12 12:26:15 -07:00
|
|
|
}
|
2014-08-22 10:13:04 -07:00
|
|
|
$rootScope.pendingTxCount = pendingForUs;
|
|
|
|
};
|
2014-08-12 12:26:15 -07:00
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
function getActionList(actions) {
|
|
|
|
var peers = Object.keys(actions).map(function(i) {
|
|
|
|
return {
|
|
|
|
cId: i,
|
|
|
|
actions: actions[i]
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return peers.sort(function(a, b) {
|
|
|
|
return !!b.actions.create - !!a.actions.create;
|
|
|
|
});
|
2014-08-04 09:54:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-19 13:12:54 -07:00
|
|
|
|
|
|
|
|
2014-08-22 10:13:04 -07:00
|
|
|
return root;
|
|
|
|
});
|