copay/src/js/controllers/index.js

1546 lines
43 KiB
JavaScript
Raw Normal View History

2015-03-06 07:00:10 -08:00
'use strict';
2016-02-22 14:56:53 -08:00
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, bwcService, pushNotificationsService, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, isMobile, addressbookService) {
2015-03-06 07:00:10 -08:00
var self = this;
2015-10-23 09:26:59 -07:00
var SOFT_CONFIRMATION_LIMIT = 12;
2016-01-22 13:16:50 -08:00
var errors = bwcService.getErrors();
var historyUpdateInProgress = {};
var ret = {};
ret.isCordova = isCordova;
ret.isChromeApp = isChromeApp;
ret.isSafari = isMobile.Safari();
ret.isWindowsPhoneApp = isMobile.Windows() && isCordova;
ret.usePushNotifications = ret.isCordova && !isMobile.Windows();
ret.onGoingProcess = {};
ret.historyShowLimit = 10;
2016-02-22 12:33:41 -08:00
ret.historyShowMoreLimit = 100;
ret.prevState = 'walletHome';
ret.menu = [{
'title': gettext('Receive'),
'icon': {
false: 'icon-receive',
true: 'icon-receive-active'
},
2015-04-21 22:48:00 -07:00
'link': 'receive'
2015-12-02 13:20:22 -08:00
}, {
2015-12-04 10:43:17 -08:00
'title': gettext('Activity'),
'icon': {
false: 'icon-activity',
true: 'icon-activity-active'
},
2015-12-02 13:20:22 -08:00
'link': 'walletHome'
2015-04-21 22:48:00 -07:00
}, {
'title': gettext('Send'),
'icon': {
false: 'icon-send',
true: 'icon-send-active'
},
2015-04-21 22:48:00 -07:00
'link': 'send'
2015-04-23 11:19:30 -07:00
}];
2015-04-21 22:48:00 -07:00
ret.addonViews = addonManager.addonViews();
ret.menu = ret.menu.concat(addonManager.addonMenuItems());
ret.menuItemSize = ret.menu.length > 4 ? 2 : 4;
ret.txTemplateUrl = addonManager.txTemplateUrl() || 'views/includes/transaction.html';
ret.tab = 'walletHome';
var vanillaScope = ret;
2015-04-23 08:27:43 -07:00
function strip(number) {
return (parseFloat(number.toPrecision(12)));
};
self.goHome = function() {
go.walletHome();
};
2015-07-30 11:26:16 -07:00
2015-06-19 11:09:15 -07:00
self.setOngoingProcess = function(processName, isOn) {
2015-03-06 07:00:10 -08:00
$log.debug('onGoingProcess', processName, isOn);
self[processName] = isOn;
self.onGoingProcess[processName] = isOn;
var name;
self.anyOnGoingProcess = lodash.any(self.onGoingProcess, function(isOn, processName) {
if (isOn)
name = name || processName;
return isOn;
});
// The first one
self.onGoingProcessName = name;
2015-04-14 08:51:49 -07:00
$timeout(function() {
$rootScope.$apply();
});
2015-03-06 07:00:10 -08:00
};
self.cleanInstance = function() {
$log.debug('Cleaning Index Instance');
lodash.each(self, function(v, k) {
if (lodash.isFunction(v)) return;
// This are to prevent flicker in mobile:
if (k == 'hasProfile') return;
if (k == 'tab') return;
if (k == 'noFocusedWallet') return;
if (k == 'backgroundColor') return;
if (k == 'loadingWallet') {
self.loadingWallet = true;
return;
}
if (vanillaScope[k]) {
self[k] = vanillaScope[k];
return;
}
delete self[k];
});
};
2015-03-06 07:00:10 -08:00
self.setFocusedWallet = function() {
var fc = profileService.focusedClient;
if (!fc) return;
self.cleanInstance();
2015-12-03 12:44:02 -08:00
self.loadingWallet = true;
2015-08-11 13:45:57 -07:00
self.setSpendUnconfirmed();
2015-03-06 07:00:10 -08:00
$timeout(function() {
2015-11-11 11:23:56 -08:00
$rootScope.$apply();
2015-03-06 07:00:10 -08:00
self.hasProfile = true;
self.noFocusedWallet = false;
self.onGoingProcess = {};
2015-04-29 08:16:28 -07:00
// Credentials Shortcuts
2015-03-06 07:00:10 -08:00
self.m = fc.credentials.m;
self.n = fc.credentials.n;
self.network = fc.credentials.network;
self.copayerId = fc.credentials.copayerId;
self.copayerName = fc.credentials.copayerName;
self.requiresMultipleSignatures = fc.credentials.m > 1;
self.isShared = fc.credentials.n > 1;
self.walletName = fc.credentials.walletName;
self.walletId = fc.credentials.walletId;
self.isComplete = fc.isComplete();
self.canSign = fc.canSign();
2015-09-04 06:17:59 -07:00
self.isPrivKeyExternal = fc.isPrivKeyExternal();
self.isPrivKeyEncrypted = fc.isPrivKeyEncrypted();
2015-09-04 06:17:59 -07:00
self.externalSource = fc.getPrivKeyExternalSourceName();
2015-11-04 10:45:33 -08:00
self.account = fc.credentials.account;
if (self.externalSource == 'trezor')
self.account++;
2015-03-06 07:00:10 -08:00
self.txps = [];
self.copayers = [];
2015-04-28 16:13:28 -07:00
self.updateColor();
2015-05-14 06:39:22 -07:00
self.updateAlias();
2015-10-30 14:34:34 -07:00
self.setAddressbook();
2015-09-15 05:41:42 -07:00
self.initGlidera();
2015-03-06 07:00:10 -08:00
2015-12-10 09:52:42 -08:00
self.setCustomBWSFlag();
2016-02-19 05:27:59 -08:00
profileService.isBackupNeeded(self.walletId, function(needsBackup) {
2016-02-16 09:37:34 -08:00
self.needsBackup = needsBackup;
2015-12-05 15:50:31 -08:00
self.openWallet();
2016-02-16 09:37:34 -08:00
});
2015-03-06 07:00:10 -08:00
});
};
2015-11-10 15:05:05 -08:00
self.setCustomBWSFlag = function() {
var defaults = configService.getDefaults();
var config = configService.getSync();
2015-11-17 06:10:09 -08:00
self.usingCustomBWS = config.bwsFor && config.bwsFor[self.walletId] && (config.bwsFor[self.walletId] != defaults.bws.url);
2015-11-10 15:05:05 -08:00
};
2015-12-05 15:50:31 -08:00
self.setTab = function(tab, reset, tries, switchState) {
2015-04-28 16:13:28 -07:00
tries = tries || 0;
// check if the whole menu item passed
if (typeof tab == 'object') {
if (tab.open) {
if (tab.link) {
self.tab = tab.link;
}
tab.open();
return;
} else {
return self.setTab(tab.link, reset, tries, switchState);
}
}
2015-04-28 16:13:28 -07:00
if (self.tab === tab && !reset)
return;
2015-05-04 08:23:43 -07:00
if (!document.getElementById('menu-' + tab) && ++tries < 5) {
2015-04-28 16:13:28 -07:00
return $timeout(function() {
self.setTab(tab, reset, tries, switchState);
2015-04-28 16:13:28 -07:00
}, 300);
}
if (!self.tab || !$state.is('walletHome'))
self.tab = 'walletHome';
var changeTab = function() {
if (document.getElementById(self.tab)) {
document.getElementById(self.tab).className = 'tab-out tab-view ' + self.tab;
var old = document.getElementById('menu-' + self.tab);
if (old) {
old.className = '';
}
}
2015-04-23 10:12:32 -07:00
if (document.getElementById(tab)) {
document.getElementById(tab).className = 'tab-in tab-view ' + tab;
var newe = document.getElementById('menu-' + tab);
if (newe) {
newe.className = 'active';
}
2015-04-23 14:05:31 -07:00
}
self.tab = tab;
$rootScope.$emit('Local/TabChanged', tab);
};
if (switchState && !$state.is('walletHome')) {
go.path('walletHome', function() {
changeTab();
});
return;
2015-09-07 07:14:09 -07:00
}
2015-04-23 10:12:32 -07:00
changeTab();
2015-04-23 09:12:30 -07:00
};
2015-05-19 10:10:47 -07:00
2015-06-29 17:46:34 -07:00
self._updateRemotePreferencesFor = function(clients, prefs, cb) {
var client = clients.shift();
if (!client)
return cb();
$log.debug('Saving remote preferences', client.credentials.walletName, prefs);
client.savePreferences(prefs, function(err) {
// we ignore errors here
if (err) $log.warn(err);
2015-06-29 17:46:34 -07:00
self._updateRemotePreferencesFor(clients, prefs, cb);
});
};
self.updateRemotePreferences = function(opts, cb) {
var prefs = opts.preferences || {};
2015-05-19 10:10:47 -07:00
var fc = profileService.focusedClient;
2015-06-29 17:46:34 -07:00
2015-06-29 18:40:39 -07:00
// Update this JIC.
var config = configService.getSync().wallet.settings;
2015-06-29 17:46:34 -07:00
//prefs.email (may come from arguments)
prefs.language = self.defaultLanguageIsoCode;
2015-07-01 07:00:43 -07:00
prefs.unit = config.unitCode;
2015-06-29 17:46:34 -07:00
var clients = [];
if (opts.saveAll) {
clients = lodash.values(profileService.walletClients);
} else {
clients = [fc];
};
self._updateRemotePreferencesFor(clients, prefs, function(err) {
if (err) return cb(err);
2015-06-29 18:40:39 -07:00
if (!fc) return cb();
2015-06-29 17:46:34 -07:00
fc.getPreferences(function(err, preferences) {
if (err) {
return cb(err);
}
self.preferences = preferences;
return cb();
});
2015-05-19 10:10:47 -07:00
});
};
2015-05-30 10:28:18 -07:00
var _walletStatusHash = function(walletStatus) {
2015-05-30 18:38:08 -07:00
var bal;
2015-05-30 10:28:18 -07:00
if (walletStatus) {
2015-05-30 18:38:08 -07:00
bal = walletStatus.balance.totalAmount;
2015-05-30 10:28:18 -07:00
} else {
2015-05-30 18:38:08 -07:00
bal = self.totalBalanceSat;
2015-05-30 10:28:18 -07:00
}
2015-05-30 18:38:08 -07:00
return bal;
2015-05-30 10:28:18 -07:00
};
2015-05-19 10:10:47 -07:00
2015-06-12 22:01:02 -07:00
self.updateAll = function(opts, initStatusHash, tries) {
tries = tries || 0;
2015-06-19 11:09:15 -07:00
opts = opts || {};
2016-02-23 06:12:49 -08:00
var walletId = profileService.focusedClient.credentials.walletId
2015-06-19 11:09:15 -07:00
if (opts.untilItChanges && lodash.isUndefined(initStatusHash)) {
2015-05-30 10:28:18 -07:00
initStatusHash = _walletStatusHash();
2015-05-30 18:38:08 -07:00
$log.debug('Updating status until it changes. initStatusHash:' + initStatusHash)
}
2015-03-06 07:00:10 -08:00
var get = function(cb) {
2015-06-19 11:09:15 -07:00
if (opts.walletStatus)
2015-06-12 22:01:02 -07:00
return cb(null, opts.walletStatus);
2015-04-13 10:58:07 -07:00
else {
self.updateError = false;
2016-01-15 08:41:18 -08:00
return fc.getStatus({
twoStep: true
}, function(err, ret) {
2015-04-15 10:03:38 -07:00
if (err) {
2015-08-12 07:52:04 -07:00
self.updateError = bwsError.msg(err, gettext('Could not update Wallet'));
2015-04-15 10:03:38 -07:00
} else {
2015-06-19 11:09:15 -07:00
if (!opts.quiet)
2015-12-10 11:40:40 -08:00
self.setOngoingProcess('scanning', ret.wallet.scanStatus == 'running');
2015-04-15 10:03:38 -07:00
}
2015-04-13 10:58:07 -07:00
return cb(err, ret);
});
}
2015-03-06 07:00:10 -08:00
};
var fc = profileService.focusedClient;
if (!fc) return;
2016-02-23 06:12:49 -08:00
// If not untilItChanges...trigger history update now
if (opts.triggerTxUpdate && !opts.untilItChanges) {
$timeout(function() {
self.debounceUpdateHistory();
}, 1);
}
2015-03-06 07:00:10 -08:00
$timeout(function() {
2015-06-19 11:09:15 -07:00
if (!opts.quiet)
self.setOngoingProcess('updatingStatus', true);
$log.debug('Updating Status:', fc.credentials.walletName, tries);
2015-03-06 07:00:10 -08:00
get(function(err, walletStatus) {
2015-06-29 17:46:34 -07:00
var currentStatusHash = _walletStatusHash(walletStatus);
$log.debug('Status update. hash:' + currentStatusHash + ' Try:' + tries);
2016-02-23 06:12:49 -08:00
if (!err && opts.untilItChanges && initStatusHash == currentStatusHash && tries < 7 && walletId == profileService.focusedClient.credentials.walletId) {
return $timeout(function() {
2015-05-30 18:38:08 -07:00
$log.debug('Retrying update... Try:' + tries)
2015-06-29 17:46:34 -07:00
return self.updateAll({
walletStatus: null,
2015-07-13 09:09:52 -07:00
untilItChanges: true,
triggerTxUpdate: opts.triggerTxUpdate,
2015-06-29 17:46:34 -07:00
}, initStatusHash, ++tries);
2015-05-29 08:39:17 -07:00
}, 1400 * tries);
}
2016-02-23 06:12:49 -08:00
if (walletId != profileService.focusedClient.credentials.walletId)
return;
2015-06-19 11:09:15 -07:00
if (!opts.quiet)
self.setOngoingProcess('updatingStatus', false);
2016-02-23 06:12:49 -08:00
2015-03-06 07:00:10 -08:00
if (err) {
self.handleError(err);
return;
}
$log.debug('Wallet Status:', walletStatus);
self.setPendingTxps(walletStatus.pendingTxps);
// Status Shortcuts
self.walletName = walletStatus.wallet.name;
self.walletSecret = walletStatus.wallet.secret;
self.walletStatus = walletStatus.wallet.status;
2015-04-15 10:03:38 -07:00
self.walletScanStatus = walletStatus.wallet.scanStatus;
2015-03-06 07:00:10 -08:00
self.copayers = walletStatus.wallet.copayers;
2015-05-19 10:10:47 -07:00
self.preferences = walletStatus.preferences;
2015-03-06 07:00:10 -08:00
self.setBalance(walletStatus.balance);
2015-06-27 09:48:25 -07:00
self.otherWallets = lodash.filter(profileService.getWallets(self.network), function(w) {
return w.id != self.walletId;
2015-09-11 09:11:41 -07:00
});
// Notify external addons or plugins
$rootScope.$emit('Local/BalanceUpdated', walletStatus.balance);
$rootScope.$apply();
2015-07-06 06:40:40 -07:00
2016-02-23 06:12:49 -08:00
if (opts.triggerTxUpdate && opts.untilItChanges) {
2015-07-06 06:40:40 -07:00
$timeout(function() {
self.debounceUpdateHistory();
2015-07-06 06:40:40 -07:00
}, 1);
}
2015-03-06 07:00:10 -08:00
});
});
};
2015-12-23 13:05:22 -08:00
self.setSpendUnconfirmed = function(spendUnconfirmed) {
self.spendUnconfirmed = spendUnconfirmed || configService.getSync().wallet.spendUnconfirmed;
2016-02-19 07:26:12 -08:00
};
2015-07-24 08:11:07 -07:00
2015-03-06 07:00:10 -08:00
self.updateBalance = function() {
var fc = profileService.focusedClient;
$timeout(function() {
self.setOngoingProcess('updatingBalance', true);
$log.debug('Updating Balance');
fc.getBalance(function(err, balance) {
self.setOngoingProcess('updatingBalance', false);
if (err) {
self.handleError(err);
2015-03-06 07:00:10 -08:00
return;
}
$log.debug('Wallet Balance:', balance);
self.setBalance(balance);
});
});
};
self.updatePendingTxps = function() {
var fc = profileService.focusedClient;
$timeout(function() {
self.setOngoingProcess('updatingPendingTxps', true);
$log.debug('Updating PendingTxps');
2015-04-18 03:08:08 -07:00
fc.getTxProposals({}, function(err, txps) {
2015-03-06 07:00:10 -08:00
self.setOngoingProcess('updatingPendingTxps', false);
if (err) {
self.handleError(err);
2015-03-06 07:00:10 -08:00
} else {
$log.debug('Wallet PendingTxps:', txps);
self.setPendingTxps(txps);
}
$rootScope.$apply();
});
});
};
2016-01-16 15:04:01 -08:00
// This handles errors from BWS/index which normally
2015-11-26 08:25:38 -08:00
// trigger from async events (like updates).
// Debounce function avoids multiple popups
var _handleError = function(err) {
$log.warn('Client ERROR: ', err);
2016-01-22 13:16:50 -08:00
if (err instanceof errors.NOT_AUTHORIZED) {
self.notAuthorized = true;
go.walletHome();
2016-01-22 13:16:50 -08:00
} else if (err instanceof errors.NOT_FOUND) {
self.showErrorPopup(gettext('Could not access Wallet Service: Not found'));
2015-03-06 07:00:10 -08:00
} else {
var msg = ""
2015-04-27 10:18:22 -07:00
$scope.$emit('Local/ClientError', (err.error ? err.error : err));
var msg = bwsError.msg(err, gettext('Error at Wallet Service'));
self.showErrorPopup(msg);
2015-03-06 07:00:10 -08:00
}
};
2015-11-26 08:25:38 -08:00
self.handleError = lodash.debounce(_handleError, 1000);
2015-03-06 07:00:10 -08:00
self.openWallet = function() {
var fc = profileService.focusedClient;
$timeout(function() {
2015-04-23 11:32:11 -07:00
$rootScope.$apply();
2015-03-06 07:00:10 -08:00
self.setOngoingProcess('openingWallet', true);
2015-04-14 12:06:04 -07:00
self.updateError = false;
2015-03-06 07:00:10 -08:00
fc.openWallet(function(err, walletStatus) {
self.setOngoingProcess('openingWallet', false);
if (err) {
2015-04-14 12:06:04 -07:00
self.updateError = true;
2015-03-06 07:00:10 -08:00
self.handleError(err);
return;
}
$log.debug('Wallet Opened');
2015-06-29 17:46:34 -07:00
self.updateAll(lodash.isObject(walletStatus) ? {
walletStatus: walletStatus
} : null);
2015-03-06 07:00:10 -08:00
$rootScope.$apply();
});
});
};
self.setPendingTxps = function(txps) {
self.pendingTxProposalsCountForUs = 0;
var now = Math.floor(Date.now() / 1000);
2015-12-16 11:22:40 -08:00
/* Uncomment to test multiple outputs */
/*
var txp = {
message: 'test multi-output',
fee: 1000,
createdOn: new Date() / 1000,
outputs: []
};
function addOutput(n) {
txp.outputs.push({
amount: 600,
toAddress: '2N8bhEwbKtMvR2jqMRcTCQqzHP6zXGToXcK',
message: 'output #' + (Number(n) + 1)
});
};
lodash.times(150, addOutput);
txps.push(txp);
*/
2015-03-06 07:00:10 -08:00
lodash.each(txps, function(tx) {
2015-09-18 09:59:18 -07:00
2015-09-09 12:17:08 -07:00
tx = txFormatService.processTx(tx);
2015-03-06 07:00:10 -08:00
// no future transactions...
if (tx.createdOn > now)
tx.createdOn = now;
2015-03-06 07:00:10 -08:00
var action = lodash.find(tx.actions, {
copayerId: self.copayerId
});
if (!action && tx.status == 'pending') {
tx.pendingForUs = true;
}
if (action && action.type == 'accept') {
tx.statusForUs = 'accepted';
} else if (action && action.type == 'reject') {
tx.statusForUs = 'rejected';
} else {
tx.statusForUs = 'pending';
}
2015-06-18 07:17:35 -07:00
if (!tx.deleteLockTime)
tx.canBeRemoved = true;
2015-03-06 07:00:10 -08:00
if (tx.creatorId != self.copayerId) {
self.pendingTxProposalsCountForUs = self.pendingTxProposalsCountForUs + 1;
}
addonManager.formatPendingTxp(tx);
2015-03-06 07:00:10 -08:00
});
self.txps = txps;
};
2015-09-18 09:59:18 -07:00
var SAFE_CONFIRMATIONS = 6;
2015-11-06 08:06:08 -08:00
self.processNewTxs = function(txs) {
2015-07-17 10:30:55 -07:00
var config = configService.getSync().wallet.settings;
2015-07-13 09:31:05 -07:00
var now = Math.floor(Date.now() / 1000);
2015-11-06 08:06:08 -08:00
var txHistoryUnique = {};
var ret = [];
2015-09-18 09:59:18 -07:00
self.hasUnsafeConfirmed = false;
2015-11-06 08:06:08 -08:00
2015-03-06 07:00:10 -08:00
lodash.each(txs, function(tx) {
2015-09-09 12:17:08 -07:00
tx = txFormatService.processTx(tx);
2015-07-13 09:31:05 -07:00
// no future transactions...
if (tx.time > now)
tx.time = now;
2015-09-18 09:59:18 -07:00
if (tx.confirmations >= SAFE_CONFIRMATIONS) {
tx.safeConfirmed = SAFE_CONFIRMATIONS + '+';
} else {
tx.safeConfirmed = false;
self.hasUnsafeConfirmed = true;
}
2015-11-06 08:06:08 -08:00
if (!txHistoryUnique[tx.txid]) {
ret.push(tx);
txHistoryUnique[tx.txid] = true;
2015-10-22 06:14:57 -07:00
} else {
$log.debug('Ignoring duplicate TX in history: ' + tx.txid)
2015-03-06 07:00:10 -08:00
}
});
2015-11-06 08:06:08 -08:00
return ret;
2015-03-06 07:00:10 -08:00
};
2015-05-14 06:39:22 -07:00
self.updateAlias = function() {
var config = configService.getSync();
config.aliasFor = config.aliasFor || {};
self.alias = config.aliasFor[self.walletId];
var fc = profileService.focusedClient;
fc.alias = self.alias;
};
2015-03-06 07:00:10 -08:00
self.updateColor = function() {
var config = configService.getSync();
config.colorFor = config.colorFor || {};
2015-05-29 11:25:41 -07:00
self.backgroundColor = config.colorFor[self.walletId] || '#4A90E2';
2015-03-06 07:00:10 -08:00
var fc = profileService.focusedClient;
fc.backgroundColor = self.backgroundColor;
2015-12-01 12:16:39 -08:00
if (isCordova && StatusBar.isVisible) {
StatusBar.backgroundColorByHexString(fc.backgroundColor);
}
2015-03-06 07:00:10 -08:00
};
self.setBalance = function(balance) {
if (!balance) return;
var config = configService.getSync().wallet.settings;
var COIN = 1e8;
2015-08-11 13:11:40 -07:00
2015-03-06 07:00:10 -08:00
// Address with Balance
self.balanceByAddress = balance.byAddress;
2015-12-24 08:43:12 -08:00
// Spend unconfirmed funds
2015-08-11 13:45:57 -07:00
if (self.spendUnconfirmed) {
self.totalBalanceSat = balance.totalAmount;
self.lockedBalanceSat = balance.lockedAmount;
self.availableBalanceSat = balance.availableAmount;
2015-12-24 08:43:12 -08:00
self.totalBytesToSendMax = balance.totalBytesToSendMax;
2015-08-11 13:45:57 -07:00
self.pendingAmount = null;
} else {
self.totalBalanceSat = balance.totalConfirmedAmount;
self.lockedBalanceSat = balance.lockedConfirmedAmount;
self.availableBalanceSat = balance.availableConfirmedAmount;
2015-12-24 08:43:12 -08:00
self.totalBytesToSendMax = balance.totalBytesToSendConfirmedMax;
2015-08-11 13:45:57 -07:00
self.pendingAmount = balance.totalAmount - balance.totalConfirmedAmount;
}
2015-03-06 07:00:10 -08:00
// Selected unit
self.unitToSatoshi = config.unitToSatoshi;
self.satToUnit = 1 / self.unitToSatoshi;
self.unitName = config.unitName;
//STR
self.totalBalanceStr = profileService.formatAmount(self.totalBalanceSat) + ' ' + self.unitName;
self.lockedBalanceStr = profileService.formatAmount(self.lockedBalanceSat) + ' ' + self.unitName;
self.availableBalanceStr = profileService.formatAmount(self.availableBalanceSat) + ' ' + self.unitName;
2015-08-11 13:45:57 -07:00
if (self.pendingAmount) {
self.pendingAmountStr = profileService.formatAmount(self.pendingAmount) + ' ' + self.unitName;
} else {
self.pendingAmountStr = null;
}
2015-03-06 07:00:10 -08:00
self.alternativeName = config.alternativeName;
self.alternativeIsoCode = config.alternativeIsoCode;
// Check address
2015-06-29 17:46:34 -07:00
addressService.isUsed(self.walletId, balance.byAddress, function(err, used) {
if (used) {
2015-06-27 09:22:56 -07:00
$log.debug('Address used. Creating new');
$rootScope.$emit('Local/AddressIsUsed');
2015-06-27 09:22:56 -07:00
}
});
2015-03-06 07:00:10 -08:00
rateService.whenAvailable(function() {
2015-08-11 13:45:57 -07:00
var totalBalanceAlternative = rateService.toFiat(self.totalBalanceSat, self.alternativeIsoCode);
var lockedBalanceAlternative = rateService.toFiat(self.lockedBalanceSat, self.alternativeIsoCode);
2015-03-06 07:00:10 -08:00
var alternativeConversionRate = rateService.toFiat(100000000, self.alternativeIsoCode);
self.totalBalanceAlternative = $filter('noFractionNumber')(totalBalanceAlternative, 2);
self.lockedBalanceAlternative = $filter('noFractionNumber')(lockedBalanceAlternative, 2);
self.alternativeConversionRate = $filter('noFractionNumber')(alternativeConversionRate, 2);
self.alternativeBalanceAvailable = true;
self.isRateAvailable = true;
$rootScope.$apply();
});
if (!rateService.isAvailable()) {
$rootScope.$apply();
}
};
self.csvHistory = function() {
2015-07-03 11:35:34 -07:00
function saveFile(name, data) {
var chooser = document.querySelector(name);
chooser.addEventListener("change", function(evt) {
var fs = require('fs');
fs.writeFile(this.value, data, function(err) {
if (err) {
$log.debug(err);
}
});
}, false);
chooser.click();
}
function formatDate(date) {
var dateObj = new Date(date);
if (!dateObj) {
$log.debug('Error formating a date');
return 'DateError'
}
if (!dateObj.toJSON()) {
return '';
}
return dateObj.toJSON();
}
function formatString(str) {
if (!str) return '';
if (str.indexOf('"') !== -1) {
//replace all
str = str.replace(new RegExp('"', 'g'), '\'');
}
//escaping commas
str = '\"' + str + '\"';
return str;
}
2015-07-03 11:35:34 -07:00
var step = 6;
2015-10-21 06:37:58 -07:00
var unique = {};
2015-10-08 10:29:35 -07:00
2015-10-23 09:26:59 -07:00
function getHistory(cb) {
storageService.getTxHistory(c.walletId, function(err, txs) {
if (err) return cb(err);
2015-10-08 10:29:35 -07:00
2015-10-23 09:26:59 -07:00
var txsFromLocal = [];
try {
txsFromLocal = JSON.parse(txs);
} catch (ex) {
2015-10-23 09:26:59 -07:00
$log.warn(ex);
}
allTxs.push(txsFromLocal);
return cb(null, lodash.flatten(allTxs));
});
}
if (isCordova) {
2015-10-23 09:26:59 -07:00
$log.info('CSV generation not available in mobile');
return;
}
var isNode = nodeWebkit.isDefined();
var fc = profileService.focusedClient;
var c = fc.credentials;
if (!fc.isComplete()) return;
2015-07-03 11:35:34 -07:00
var self = this;
var allTxs = [];
$log.debug('Generating CSV from History');
self.setOngoingProcess('generatingCSV', true);
2015-10-08 10:29:35 -07:00
getHistory(function(err, txs) {
self.setOngoingProcess('generatingCSV', false);
if (err) {
self.handleError(err);
} else {
$log.debug('Wallet Transaction History:', txs);
self.satToUnit = 1 / self.unitToSatoshi;
var data = txs;
var satToBtc = 1 / 100000000;
self.csvContent = [];
self.csvFilename = 'Copay-' + (self.alias || self.walletName) + '.csv';
self.csvHeader = ['Date', 'Destination', 'Note', 'Amount', 'Currency', 'Txid', 'Creator', 'Copayers'];
var _amount, _note, _copayers, _creator;
data.forEach(function(it, index) {
var amount = it.amount;
if (it.action == 'moved')
amount = 0;
_copayers = '';
_creator = '';
if (it.actions && it.actions.length > 1) {
for (var i = 0; i < it.actions.length; i++) {
_copayers += it.actions[i].copayerName + ':' + it.actions[i].type + ' - ';
}
_creator = (it.creatorName && it.creatorName != 'undefined') ? it.creatorName : '';
}
_copayers = formatString(_copayers);
_creator = formatString(_creator);
_amount = (it.action == 'sent' ? '-' : '') + (amount * satToBtc).toFixed(8);
_note = formatString((it.message ? it.message : ''));
if (it.action == 'moved')
_note += ' Moved:' + (it.amount * satToBtc).toFixed(8)
self.csvContent.push({
'Date': formatDate(it.time * 1000),
'Destination': formatString(it.addressTo),
'Note': _note,
'Amount': _amount,
'Currency': 'BTC',
'Txid': it.txid,
'Creator': _creator,
'Copayers': _copayers
});
if (it.fees && (it.action == 'moved' || it.action == 'sent')) {
var _fee = (it.fees * satToBtc).toFixed(8)
2016-02-16 09:33:39 -08:00
self.csvContent.push({
'Date': formatDate(it.time * 1000),
'Destination': 'Bitcoin Network Fees',
'Note': '',
'Amount': '-' + _fee,
2016-02-16 09:33:39 -08:00
'Currency': 'BTC',
'Txid': '',
'Creator': '',
'Copayers': ''
2016-02-16 09:33:39 -08:00
});
}
});
return;
}
});
2015-10-08 10:29:35 -07:00
};
2015-07-03 11:35:34 -07:00
2015-10-23 09:26:59 -07:00
self.removeSoftConfirmedTx = function(txs) {
return lodash.filter(txs, function(tx) {
2015-10-23 09:26:59 -07:00
if (tx.confirmations >= SOFT_CONFIRMATION_LIMIT)
return tx;
});
}
self.getSavedTxs = function(walletId, cb) {
2015-10-09 11:23:04 -07:00
2015-11-10 15:05:05 -08:00
storageService.getTxHistory(walletId, function(err, txs) {
2015-10-08 10:29:35 -07:00
if (err) return cb(err);
2015-07-17 10:43:40 -07:00
2015-10-23 09:26:59 -07:00
var localTxs = [];
2015-10-30 13:03:08 -07:00
if (!txs) {
return cb(null, localTxs);
}
2015-10-08 10:29:35 -07:00
try {
localTxs = JSON.parse(txs);
2015-10-08 10:29:35 -07:00
} catch (ex) {
2015-10-23 09:26:59 -07:00
$log.warn(ex);
2015-10-08 10:29:35 -07:00
}
return cb(null, lodash.compact(localTxs));
2015-10-23 09:26:59 -07:00
});
}
2015-11-10 15:05:05 -08:00
self.updateLocalTxHistory = function(client, cb) {
var FIRST_LIMIT = 5;
var LIMIT = 50;
var requestLimit = FIRST_LIMIT;
2015-11-10 15:05:05 -08:00
var walletId = client.credentials.walletId;
2015-11-18 05:24:15 -08:00
var config = configService.getSync().wallet.settings;
var fixTxsUnit = function(txs) {
if (!txs || !txs[0]) return;
var cacheUnit = txs[0].amountStr.split(' ')[1];
if (cacheUnit == config.unitName)
return;
var name = ' ' + config.unitName;
$log.debug('Fixing Tx Cache Unit to:' + name)
lodash.each(txs, function(tx) {
tx.amountStr = profileService.formatAmount(tx.amount, config.unitName) + name;
tx.feeStr = profileService.formatAmount(tx.fees, config.unitName) + name;
});
};
2015-11-06 08:06:08 -08:00
self.getSavedTxs(walletId, function(err, txsFromLocal) {
2015-10-23 09:26:59 -07:00
if (err) return cb(err);
2015-11-06 08:06:08 -08:00
2015-11-18 05:24:15 -08:00
fixTxsUnit(txsFromLocal);
var confirmedTxs = self.removeSoftConfirmedTx(txsFromLocal);
var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null;
2016-02-23 06:12:49 -08:00
// First update
if (walletId == profileService.focusedClient.credentials.walletId) {
self.completeHistory = txsFromLocal;
self.setCompactTxHistory();
}
2016-02-23 06:12:49 -08:00
if (historyUpdateInProgress[walletId])
return;
historyUpdateInProgress[walletId] = true;
2015-11-06 08:06:08 -08:00
function getNewTxs(newTxs, skip, i_cb) {
2015-11-10 15:05:05 -08:00
self.getTxsFromServer(client, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
2015-11-06 08:06:08 -08:00
if (err) return i_cb(err);
2015-11-10 15:05:05 -08:00
newTxs = newTxs.concat(lodash.compact(res));
2015-11-06 08:06:08 -08:00
skip = skip + requestLimit;
$log.debug('Syncing TXs. Got:' + newTxs.length + ' Skip:' + skip, ' EndingTxid:', endingTxid, ' Continue:', shouldContinue);
if (!shouldContinue) {
newTxs = self.processNewTxs(newTxs);
$log.debug('Finish Sync: New Txs: ' + newTxs.length);
return i_cb(null, newTxs);
2015-10-23 09:26:59 -07:00
}
2015-11-06 08:06:08 -08:00
requestLimit = LIMIT;
2015-11-06 08:06:08 -08:00
getNewTxs(newTxs, skip, i_cb);
// Progress update
if (walletId == profileService.focusedClient.credentials.walletId) {
self.txProgress = newTxs.length;
if (self.completeHistory < FIRST_LIMIT && txsFromLocal.length == 0) {
$log.debug('Showing partial history');
var newHistory = self.processNewTxs(newTxs);
newHistory = lodash.compact(newHistory.concat(confirmedTxs));
self.completeHistory = newHistory;
self.setCompactTxHistory();
}
$timeout(function() {
$rootScope.$apply();
});
}
2015-10-09 11:23:04 -07:00
});
};
2015-11-06 08:06:08 -08:00
getNewTxs([], 0, function(err, txs) {
if (err) return cb(err);
2015-12-10 07:44:40 -08:00
var newHistory = lodash.compact(txs.concat(confirmedTxs));
2015-11-06 08:06:08 -08:00
$log.debug('Tx History synced. Total Txs: ' + newHistory.length);
// Final update
2015-11-17 06:10:09 -08:00
if (walletId == profileService.focusedClient.credentials.walletId) {
2015-11-10 15:05:05 -08:00
self.completeHistory = newHistory;
self.setCompactTxHistory();
2016-02-19 07:26:12 -08:00
self.txHistory = newHistory.slice(0, self.historyShowLimit);
self.historyShowMore = newHistory.length > self.historyShowLimit;
self.txHistoryToList = self.txHistory;
2015-11-10 15:05:05 -08:00
}
2015-11-06 08:06:08 -08:00
2015-11-10 15:05:05 -08:00
return storageService.setTxHistory(JSON.stringify(newHistory), walletId, function() {
$log.debug('Tx History saved.');
2015-11-06 08:06:08 -08:00
return cb();
});
});
2015-10-08 10:29:35 -07:00
});
}
2016-02-09 10:10:25 -08:00
2016-02-22 12:33:41 -08:00
self.showMore = function() {
2015-11-06 08:06:08 -08:00
$timeout(function() {
2016-02-22 12:33:41 -08:00
self.txHistory = self.completeHistory.slice(0, self.nextTxHistory);
2016-02-19 07:26:12 -08:00
self.txHistoryToList = self.txHistory;
2016-02-22 12:33:41 -08:00
$log.debug('Total txs: ', self.txHistory.length + '/' + self.completeHistory.length);
self.nextTxHistory += self.historyShowMoreLimit;
if (self.txHistory.length >= self.completeHistory.length)
self.historyShowMore = false;
2015-11-10 15:14:06 -08:00
}, 100);
2015-11-06 08:06:08 -08:00
};
2015-10-08 10:29:35 -07:00
2016-02-19 07:26:12 -08:00
self.startSearch = function(){
self.isSearching = true;
self.txHistoryToList = [];
if(self.historyShowShowAll) self.txHistory = self.completeHistory;
2016-02-19 07:26:12 -08:00
}
self.cancelSearch = function(){
self.isSearching = false;
if(self.txHistory.length > self.historyShowLimit)
self.txHistoryToList = self.txHistory.slice(0, self.historyShowLimit);
else self.txHistoryToList = self.txHistory;
2016-02-19 07:26:12 -08:00
}
self.updateSearchInput = function(search){
self.search = search;
if (isCordova)
window.plugins.toast.hide();
2016-02-19 07:26:12 -08:00
self.throttleSearch();
}
self.throttleSearch = lodash.throttle(function() {
2016-02-15 07:50:21 -08:00
2016-02-18 12:55:57 -08:00
function filter(search) {
var result = [];
function formatDate(date) {
var day = ('0' + date.getDate()).slice(-2).toString();
var month = ('0' + (date.getMonth() + 1)).slice(-2).toString();
var year = date.getFullYear();
return [month, day, year].join('/');
};
2016-02-10 11:53:34 -08:00
2016-02-18 12:55:57 -08:00
if (lodash.isEmpty(search)) return;
2016-02-15 07:50:21 -08:00
2016-02-18 12:55:57 -08:00
result = lodash.filter(self.txHistory, function(tx) {
return lodash.includes(tx.amountStr, search) ||
lodash.includes(tx.message, search) ||
lodash.includes(self.addressbook ? self.addressbook[tx.addressTo] : null, search) ||
lodash.includes(tx.addressTo, search) ||
lodash.isEqual(formatDate(new Date(tx.time * 1000)), search);
});
2016-02-18 12:55:57 -08:00
return result;
};
self.txHistoryToList = filter(self.search);
if (isCordova)
window.plugins.toast.showShortBottom(gettextCatalog.getString('Matches: ' + self.txHistoryToList.length));
$timeout(function() {
$rootScope.$apply();
});
2016-02-19 07:26:12 -08:00
},1000);
2016-02-05 08:00:40 -08:00
2015-11-10 15:05:05 -08:00
self.getTxsFromServer = function(client, skip, endingTxid, limit, cb) {
2015-11-06 08:06:08 -08:00
var res = [];
2015-10-09 11:23:04 -07:00
2015-11-10 15:05:05 -08:00
client.getTxHistory({
2015-11-06 08:06:08 -08:00
skip: skip,
limit: limit
}, function(err, txsFromServer) {
2015-10-09 11:23:04 -07:00
if (err) return cb(err);
2015-11-06 08:06:08 -08:00
if (!txsFromServer.length)
return cb();
2015-10-09 11:23:04 -07:00
2015-11-06 08:06:08 -08:00
var res = lodash.takeWhile(txsFromServer, function(tx) {
return tx.txid != endingTxid;
2015-10-09 11:23:04 -07:00
});
2015-11-06 08:06:08 -08:00
return cb(null, res, res.length == limit);
2015-10-09 11:23:04 -07:00
});
2015-11-06 08:06:08 -08:00
};
2015-10-09 11:23:04 -07:00
2015-10-22 08:31:54 -07:00
self.updateHistory = function() {
2015-11-04 07:50:25 -08:00
var fc = profileService.focusedClient;
if (!fc) return;
2015-11-10 15:05:05 -08:00
var walletId = fc.credentials.walletId;
2016-02-23 06:12:49 -08:00
if (!fc.isComplete()) {
return;
}
2015-11-04 07:50:25 -08:00
2015-10-09 11:23:04 -07:00
$log.debug('Updating Transaction History');
self.txHistoryError = false;
2016-02-23 06:12:49 -08:00
self.updatingTxHistory = true;
2015-10-09 11:23:04 -07:00
$timeout(function() {
2015-11-10 15:05:05 -08:00
self.updateLocalTxHistory(fc, function(err) {
historyUpdateInProgress[walletId] = self.updatingTxHistory = false;
2015-12-03 12:44:02 -08:00
self.loadingWallet = false;
self.txProgress = 0;
2015-11-10 15:05:05 -08:00
if (err)
2015-11-06 10:32:10 -08:00
self.txHistoryError = true;
2015-12-10 09:52:42 -08:00
$timeout(function() {
self.newTx = false
}, 1000);
2015-10-09 11:23:04 -07:00
$rootScope.$apply();
});
});
};
self.setCompactTxHistory = function() {
2016-02-22 12:33:41 -08:00
self.nextTxHistory = self.historyShowMoreLimit;
self.txHistory = self.completeHistory.slice(0, self.historyShowLimit);
2016-02-22 12:33:41 -08:00
self.historyShowMore = self.completeHistory.length > self.historyShowLimit;
};
self.debounceUpdateHistory = lodash.debounce(function() {
2015-10-22 08:31:54 -07:00
self.updateHistory();
}, 1000);
self.throttledUpdateHistory = lodash.throttle(function() {
self.updateHistory();
2016-02-23 06:12:49 -08:00
}, 5000);
2015-10-09 11:23:04 -07:00
2015-09-04 20:11:14 -07:00
self.showErrorPopup = function(msg, cb) {
$log.warn('Showing err popup:' + msg);
self.showAlert = {
msg: msg,
2015-11-26 08:25:38 -08:00
close: function() {
self.showAlert = null;
2015-11-26 08:25:38 -08:00
if (cb) return cb();
},
};
$timeout(function() {
$rootScope.$apply();
});
};
2015-03-06 07:00:10 -08:00
self.recreate = function(cb) {
var fc = profileService.focusedClient;
self.setOngoingProcess('recreating', true);
fc.recreateWallet(function(err) {
self.notAuthorized = false;
self.setOngoingProcess('recreating', false);
2015-04-14 08:51:49 -07:00
if (err) {
2015-04-27 10:14:51 -07:00
self.handleError(err);
2015-04-14 08:51:49 -07:00
$rootScope.$apply();
return;
}
2015-03-06 07:00:10 -08:00
profileService.setWalletClients();
2015-11-14 12:29:45 -08:00
self.startScan(self.walletId);
2015-03-06 07:00:10 -08:00
});
};
self.openMenu = function() {
2016-02-23 06:12:49 -08:00
profileService.isDisclaimerAccepted(function(val) {
2016-02-22 14:32:24 -08:00
if (val) go.swipe(true);
2016-02-23 06:12:49 -08:00
else
2016-02-22 14:32:24 -08:00
$log.debug('Disclaimer not accepted, cannot open menu');
});
2015-03-06 07:00:10 -08:00
};
self.closeMenu = function() {
go.swipe();
};
2015-04-15 10:03:38 -07:00
self.retryScan = function() {
var self = this;
self.startScan(self.walletId);
}
2015-03-06 07:00:10 -08:00
self.startScan = function(walletId) {
2015-09-21 06:18:43 -07:00
$log.debug('Scanning wallet ' + walletId);
2015-03-06 07:00:10 -08:00
var c = profileService.walletClients[walletId];
if (!c.isComplete()) return;
2015-03-06 07:00:10 -08:00
if (self.walletId == walletId)
self.setOngoingProcess('scanning', true);
c.startScan({
includeCopayerBranches: true,
}, function(err) {
if (err && self.walletId == walletId) {
self.setOngoingProcess('scanning', false);
2015-04-27 10:14:51 -07:00
self.handleError(err);
2015-04-14 08:51:49 -07:00
$rootScope.$apply();
2015-03-06 07:00:10 -08:00
}
});
};
2016-01-20 12:21:26 -08:00
self.setUxLanguage = function(cb) {
2015-12-21 06:31:40 -08:00
uxLanguage.update(function(lang) {
var userLang = lang;
self.defaultLanguageIsoCode = userLang;
self.defaultLanguageName = uxLanguage.getName(userLang);
2016-01-20 12:21:26 -08:00
if (cb) return cb();
2015-12-21 06:31:40 -08:00
});
2015-04-22 14:41:30 -07:00
};
2015-09-05 10:30:02 -07:00
self.initGlidera = function(accessToken) {
2015-09-11 09:11:41 -07:00
self.glideraEnabled = configService.getSync().glidera.enabled;
self.glideraTestnet = configService.getSync().glidera.testnet;
var network = self.glideraTestnet ? 'testnet' : 'livenet';
2015-09-11 09:11:41 -07:00
self.glideraToken = null;
self.glideraError = null;
self.glideraPermissions = null;
self.glideraEmail = null;
self.glideraPersonalInfo = null;
self.glideraTxs = null;
self.glideraStatus = null;
2015-10-05 11:06:53 -07:00
if (!self.glideraEnabled) return;
2015-09-11 09:11:41 -07:00
glideraService.setCredentials(network);
2015-09-05 10:30:02 -07:00
var getToken = function(cb) {
if (accessToken) {
cb(null, accessToken);
} else {
2015-09-11 09:11:41 -07:00
storageService.getGlideraToken(network, cb);
2015-09-05 10:30:02 -07:00
}
};
getToken(function(err, accessToken) {
if (err || !accessToken) return;
2015-09-02 12:02:40 -07:00
else {
2015-09-12 19:54:18 -07:00
self.glideraLoading = 'Connecting to Glidera...';
2015-09-07 07:14:09 -07:00
glideraService.getAccessTokenPermissions(accessToken, function(err, p) {
self.glideraLoading = null;
2015-09-05 10:30:02 -07:00
if (err) {
self.glideraError = err;
2015-09-18 09:59:18 -07:00
} else {
2015-09-07 07:14:09 -07:00
self.glideraToken = accessToken;
2015-09-05 10:30:02 -07:00
self.glideraPermissions = p;
2015-09-18 09:59:18 -07:00
self.updateGlidera({
fullUpdate: true
});
2015-09-05 10:30:02 -07:00
}
2015-09-02 12:02:40 -07:00
});
}
2015-08-28 14:23:24 -07:00
});
};
self.updateGlidera = function(opts) {
if (!self.glideraToken || !self.glideraPermissions) return;
var accessToken = self.glideraToken;
var permissions = self.glideraPermissions;
opts = opts || {};
2015-09-08 08:04:27 -07:00
glideraService.getStatus(accessToken, function(err, data) {
self.glideraStatus = data;
});
2015-09-08 13:36:08 -07:00
glideraService.getLimits(accessToken, function(err, limits) {
self.glideraLimits = limits;
});
if (permissions.transaction_history) {
2015-09-12 19:54:18 -07:00
self.glideraLoadingHistory = 'Getting Glidera transactions...';
glideraService.getTransactions(accessToken, function(err, data) {
self.glideraLoadingHistory = null;
self.glideraTxs = data;
});
}
2015-09-18 09:59:18 -07:00
if (permissions.view_email_address && opts.fullUpdate) {
2015-09-12 19:54:18 -07:00
self.glideraLoadingEmail = 'Getting Glidera Email...';
2015-09-05 10:30:02 -07:00
glideraService.getEmail(accessToken, function(err, data) {
2015-09-07 07:14:09 -07:00
self.glideraLoadingEmail = null;
2015-09-05 10:30:02 -07:00
self.glideraEmail = data.email;
});
}
if (permissions.personal_info && opts.fullUpdate) {
2015-09-12 19:54:18 -07:00
self.glideraLoadingPersonalInfo = 'Getting Glidera Personal Information...';
2015-09-05 10:30:02 -07:00
glideraService.getPersonalInfo(accessToken, function(err, data) {
2015-09-07 07:14:09 -07:00
self.glideraLoadingPersonalInfo = null;
2015-09-05 10:30:02 -07:00
self.glideraPersonalInfo = data;
});
}
2015-09-05 10:30:02 -07:00
};
2015-11-02 07:04:18 -08:00
self.setAddressbook = function(ab) {
if (ab) {
self.addressbook = ab;
return;
}
2015-10-30 14:34:34 -07:00
addressbookService.list(function(err, ab) {
if (err) {
$log.error('Error getting the addressbook');
return;
}
self.addressbook = ab;
2015-11-02 05:50:58 -08:00
});
2015-10-30 14:34:34 -07:00
};
2015-11-23 12:53:42 -08:00
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams) {
self.prevState = from.name || 'walletHome';
2015-11-24 05:21:29 -08:00
self.tab = 'walletHome';
2015-11-23 12:53:42 -08:00
});
2015-10-30 08:57:38 -07:00
$rootScope.$on('Local/ClearHistory', function(event) {
2015-10-30 08:55:41 -07:00
$log.debug('The wallet transaction history has been deleted');
2015-11-12 12:08:24 -08:00
self.txHistory = self.completeHistory = [];
self.debounceUpdateHistory();
2015-10-30 08:47:37 -07:00
});
2015-11-02 07:04:18 -08:00
$rootScope.$on('Local/AddressbookUpdated', function(event, ab) {
self.setAddressbook(ab);
2015-10-30 14:34:34 -07:00
});
2016-02-15 06:49:08 -08:00
$rootScope.$on('Local/Searching', function(event, val) {
2016-02-15 07:50:21 -08:00
self.isSearching = val;
2016-02-15 06:49:08 -08:00
});
2015-03-06 07:00:10 -08:00
// UX event handlers
$rootScope.$on('Local/ColorUpdated', function(event) {
self.updateColor();
2015-04-27 09:11:32 -07:00
$timeout(function() {
$rootScope.$apply();
});
2015-03-06 07:00:10 -08:00
});
2015-05-14 06:39:22 -07:00
$rootScope.$on('Local/AliasUpdated', function(event) {
self.updateAlias();
$timeout(function() {
$rootScope.$apply();
});
});
2015-12-23 13:05:22 -08:00
$rootScope.$on('Local/SpendUnconfirmedUpdated', function(event, spendUnconfirmed) {
self.setSpendUnconfirmed(spendUnconfirmed);
2015-08-11 13:45:57 -07:00
self.updateAll();
2015-08-03 16:39:09 -07:00
});
2015-06-29 18:40:39 -07:00
$rootScope.$on('Local/ProfileBound', function() {
storageService.getRemotePrefsStoredFlag(function(err, val) {
if (err || val) return;
self.updateRemotePreferences({
saveAll: true
}, function() {
2016-01-26 10:42:07 -08:00
$log.debug('Remote preferences saved');
2015-06-29 18:40:39 -07:00
storageService.setRemotePrefsStoredFlag(function() {});
});
});
});
2015-06-29 17:46:34 -07:00
$rootScope.$on('Local/LanguageSettingUpdated', function() {
2015-12-21 06:31:40 -08:00
self.setUxLanguage(function() {
self.updateRemotePreferences({
saveAll: true
}, function() {
$log.debug('Remote preferences saved')
});
2015-06-29 17:46:34 -07:00
});
});
2015-09-11 09:11:41 -07:00
$rootScope.$on('Local/GlideraUpdated', function(event, accessToken) {
2015-09-05 10:30:02 -07:00
self.initGlidera(accessToken);
});
$rootScope.$on('Local/GlideraTx', function(event, accessToken, permissions) {
self.updateGlidera();
2015-08-28 14:23:24 -07:00
});
2015-09-07 13:43:55 -07:00
$rootScope.$on('Local/GlideraError', function(event) {
self.debouncedUpdate();
});
2015-04-25 08:37:04 -07:00
$rootScope.$on('Local/UnitSettingUpdated', function(event) {
2015-11-18 05:24:15 -08:00
self.updateAll({
triggerTxUpdate: true,
});
2015-06-29 17:46:34 -07:00
self.updateRemotePreferences({
saveAll: true
}, function() {
$log.debug('Remote preferences saved')
});
2015-03-06 07:00:10 -08:00
});
2015-06-29 17:46:34 -07:00
$rootScope.$on('Local/EmailSettingUpdated', function(event, email, cb) {
self.updateRemotePreferences({
preferences: {
2015-07-14 13:29:56 -07:00
email: email || null
2015-06-29 17:46:34 -07:00
},
}, cb);
2015-05-19 10:10:47 -07:00
});
2015-03-06 07:00:10 -08:00
$rootScope.$on('Local/WalletCompleted', function(event) {
self.setFocusedWallet();
go.walletHome();
});
$rootScope.$on('Local/ProfileCreated', function(event) {
self.updateRemotePreferences({
saveAll: true
}, function() {
$log.debug('Remote preferences saved');
});
2016-01-04 11:35:34 -08:00
});
2016-01-26 10:42:07 -08:00
$rootScope.$on('Local/pushNotificationsReady', function(event) {
pushNotificationsService.enableNotifications(profileService.walletClients);
});
2015-04-28 15:26:22 -07:00
self.debouncedUpdate = lodash.throttle(function() {
2015-06-29 17:46:34 -07:00
self.updateAll({
quiet: true
});
self.debounceUpdateHistory();
2016-02-23 06:12:49 -08:00
}, 2000, {
2015-05-04 08:23:43 -07:00
leading: false,
trailing: true
});
2015-04-28 15:26:22 -07:00
2015-06-25 08:26:43 -07:00
$rootScope.$on('Local/Resume', function(event) {
$log.debug('### Resume event');
2016-02-22 14:32:24 -08:00
profileService.isDisclaimerAccepted(function(v) {
if (!v) {
$log.debug('Disclaimer not accepted, resume to home');
go.path('disclaimer');
}
});
2015-06-25 08:26:43 -07:00
self.debouncedUpdate();
2015-03-06 07:00:10 -08:00
});
2015-11-14 12:29:45 -08:00
$rootScope.$on('Local/BackupDone', function(event, walletId) {
2015-03-06 07:00:10 -08:00
self.needsBackup = false;
2015-09-21 06:18:43 -07:00
$log.debug('Backup done');
2015-11-14 12:29:45 -08:00
storageService.setBackupFlag(walletId || self.walletId, function(err) {
2016-02-16 09:15:29 -08:00
$log.debug('Backup stored');
2015-04-27 08:35:26 -07:00
});
2015-03-06 07:00:10 -08:00
});
$rootScope.$on('Local/DeviceError', function(event, err) {
2015-10-28 12:39:02 -07:00
self.showErrorPopup(err, function() {
if (self.isCordova && navigator && navigator.app) {
navigator.app.exitApp();
}
});
2015-03-06 07:00:10 -08:00
});
$rootScope.$on('Local/WalletImported', function(event, walletId) {
2015-05-04 11:47:04 -07:00
self.needsBackup = false;
2015-05-04 08:23:43 -07:00
storageService.setBackupFlag(walletId, function() {
2015-09-21 06:18:43 -07:00
$log.debug('Backup done stored');
2015-06-27 09:22:56 -07:00
addressService.expireAddress(walletId, function(err) {
2015-09-04 20:11:14 -07:00
$timeout(function() {
2015-11-12 12:08:24 -08:00
self.txHistory = self.completeHistory = [];
storageService.removeTxHistory(walletId, function() {
self.startScan(walletId);
});
2015-09-04 20:11:14 -07:00
}, 500);
2015-05-04 08:23:43 -07:00
});
2015-04-18 03:23:11 -07:00
});
2015-03-06 07:00:10 -08:00
});
2016-02-09 13:48:53 -08:00
$rootScope.$on('Local/TxModal', function(event, tx) {
self.showTx = tx;
$timeout(function() {
$rootScope.$apply();
});
});
2015-04-15 10:03:38 -07:00
$rootScope.$on('NewIncomingTx', function() {
2015-12-10 09:52:42 -08:00
self.newTx = true;
2015-07-06 06:40:40 -07:00
self.updateAll({
walletStatus: null,
untilItChanges: true,
triggerTxUpdate: true,
});
2015-03-06 07:00:10 -08:00
});
2015-08-12 04:57:44 -07:00
$rootScope.$on('NewBlock', function() {
2015-10-05 11:21:44 -07:00
if (self.glideraEnabled) {
$timeout(function() {
self.updateGlidera();
});
}
2015-08-12 04:57:44 -07:00
if (self.pendingAmount) {
2015-09-18 09:59:18 -07:00
self.updateAll({
walletStatus: null,
untilItChanges: null,
triggerTxUpdate: true,
});
} else if (self.hasUnsafeConfirmed) {
$log.debug('Wallet has transactions with few confirmations. Updating.')
if (self.network == 'testnet') {
2015-10-22 08:31:54 -07:00
self.throttledUpdateHistory();
2015-09-18 09:59:18 -07:00
} else {
self.debounceUpdateHistory();
2015-09-18 09:59:18 -07:00
}
2015-08-12 04:57:44 -07:00
}
});
2016-01-13 07:08:13 -08:00
$rootScope.$on('BalanceUpdated', function(e, n) {
self.setBalance(n.data);
});
2015-08-12 04:57:44 -07:00
2015-05-29 08:39:17 -07:00
$rootScope.$on('NewOutgoingTx', function() {
2015-12-10 09:52:42 -08:00
self.newTx = true;
2015-06-29 17:46:34 -07:00
self.updateAll({
walletStatus: null,
2015-07-06 07:12:40 -07:00
untilItChanges: true,
triggerTxUpdate: true,
2015-06-29 17:46:34 -07:00
});
2015-05-29 08:39:17 -07:00
});
lodash.each(['NewTxProposal', 'TxProposalFinallyRejected', 'TxProposalRemoved', 'NewOutgoingTxByThirdParty',
2015-11-12 12:19:18 -08:00
'Local/NewTxProposal', 'Local/TxProposalAction', 'Local/GlideraTx'
2015-03-06 07:00:10 -08:00
], function(eventName) {
$rootScope.$on(eventName, function(event, untilItChanges) {
2015-12-10 10:12:46 -08:00
self.newTx = eventName == 'Local/TxProposalAction' && untilItChanges;
2015-06-29 17:46:34 -07:00
self.updateAll({
walletStatus: null,
2015-07-06 06:40:40 -07:00
untilItChanges: untilItChanges,
triggerTxUpdate: true,
2015-06-29 17:46:34 -07:00
});
2015-03-06 07:00:10 -08:00
});
});
2015-11-12 12:08:24 -08:00
$rootScope.$on('ScanFinished', function() {
2015-11-12 12:19:18 -08:00
$log.debug('Scan Finished. Updating history');
2015-11-12 12:08:24 -08:00
storageService.removeTxHistory(self.walletId, function() {
2015-11-12 12:19:18 -08:00
self.updateAll({
walletStatus: null,
triggerTxUpdate: true,
});
2015-11-12 12:08:24 -08:00
});
});
2015-03-06 07:00:10 -08:00
lodash.each(['TxProposalRejectedBy', 'TxProposalAcceptedBy'], function(eventName) {
$rootScope.$on(eventName, function() {
var f = function() {
if (self.updatingStatus) {
return $timeout(f, 200);
};
self.updatePendingTxps();
};
f();
});
});
$rootScope.$on('Local/NoWallets', function(event) {
2015-12-14 10:18:26 -08:00
$timeout(function() {
self.hasProfile = true;
self.noFocusedWallet = true;
self.isComplete = null;
self.walletName = null;
2016-01-20 12:21:26 -08:00
self.setUxLanguage();
2015-12-14 10:18:26 -08:00
profileService.isDisclaimerAccepted(function(v) {
if (v) {
2015-12-14 09:02:27 -08:00
go.path('import');
2015-12-14 10:18:26 -08:00
}
});
2015-03-06 07:00:10 -08:00
});
});
$rootScope.$on('Local/NewFocusedWallet', function() {
2016-01-20 12:21:26 -08:00
self.setUxLanguage();
2015-03-06 07:00:10 -08:00
self.setFocusedWallet();
2016-02-23 06:12:49 -08:00
self.updateHistory();
2015-12-05 15:50:31 -08:00
storageService.getCleanAndScanAddresses(function(err, walletId) {
if (walletId && profileService.walletClients[walletId]) {
$log.debug('Clear last address cache and Scan ', walletId);
addressService.expireAddress(walletId, function(err) {
self.startScan(walletId);
2015-12-02 06:29:59 -08:00
});
2015-12-05 15:50:31 -08:00
storageService.removeCleanAndScanAddresses(function() {});
}
});
2015-03-06 07:00:10 -08:00
});
2015-04-28 16:13:28 -07:00
$rootScope.$on('Local/SetTab', function(event, tab, reset) {
self.setTab(tab, reset);
2015-04-23 10:37:44 -07:00
});
2016-02-11 11:00:03 -08:00
$rootScope.$on('Local/NeedsConfirmation', function(event, txp, cb) {
self.confirmTx = {
txp: txFormatService.processTx(txp),
callback: function(accept) {
self.confirmTx = null;
return cb(accept);
}
};
$timeout(function() {
$rootScope.$apply();
});
});
2015-03-06 07:00:10 -08:00
$rootScope.$on('Local/NeedsPassword', function(event, isSetup, cb) {
self.askPassword = {
isSetup: isSetup,
2015-04-13 10:58:07 -07:00
callback: function(err, pass) {
2015-03-06 07:00:10 -08:00
self.askPassword = null;
return cb(err, pass);
},
};
2016-01-20 10:25:54 -08:00
$timeout(function() {
$rootScope.$apply();
});
2015-03-06 07:00:10 -08:00
});
lodash.each(['NewCopayer', 'CopayerUpdated'], function(eventName) {
$rootScope.$on(eventName, function() {
2015-04-29 08:16:28 -07:00
// Re try to open wallet (will triggers)
2015-03-06 07:00:10 -08:00
self.setFocusedWallet();
});
});
2015-11-10 15:05:05 -08:00
$rootScope.$on('Local/NewEncryptionSetting', function() {
var fc = profileService.focusedClient;
self.isPrivKeyEncrypted = fc.isPrivKeyEncrypted();
$timeout(function() {
$rootScope.$apply();
});
});
/* Start setup */
lodash.assign(self, vanillaScope);
2015-11-02 07:04:18 -08:00
});