diff --git a/old/go.js b/old/go.js
deleted file mode 100644
index 932b9d9ae..000000000
--- a/old/go.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-angular.module('copayApp.services').factory('go', function($window, $ionicSideMenuDelegate, $rootScope, $location, $state, $timeout, $log, profileService, platformInfo, nodeWebkit) {
- var root = {};
-
- root.openExternalLink = function(url, target) {
- if (platformInfo.isNW) {
- nodeWebkit.openExternalLink(url);
- } else {
- target = target || '_blank';
- var ref = window.open(url, target, 'location=no');
- }
- };
-
- root.is = function(name) {
- return $state.is(name);
- };
-
- root.path = function(path, cb) {
- $state.transitionTo(path)
- .then(function() {
- if (cb) return cb();
- }, function() {
- if (cb) return cb('animation in progress');
- });
- };
-
- root.toggleLeftMenu = function() {
- $ionicSideMenuDelegate.toggleLeft();
- };
-
- root.walletHome = function() {
- var wallet = profileService.getWallet($stateParams.walletId);
- if (wallet && !wallet.isComplete()) {
- $log.debug("Wallet not complete at startup... redirecting");
- $state.transitionTo('wallet.details', {
- walletId: wallet.credentials.walletId
- })
- } else {
- root.path('tabs.home');
- }
- };
-
- root.confirm = function(params) {
- $state.transitionTo('send.confirm', params)
- };
-
- root.send = function() {
- root.path('tabs.send');
- };
-
- root.addWallet = function() {
- $state.transitionTo('add');
- };
-
- root.preferences = function() {
- $state.transitionTo('preferences');
- };
-
- root.preferencesGlobal = function() {
- $state.transitionTo('tabs.settings');
- };
-
- root.reload = function() {
- $state.reload();
- };
-
-
- // Global go. This should be in a better place TODO
- // We don't do a 'go' directive, to use the benefits of ng-touch with ng-click
- $rootScope.go = function(path) {
- root.path(path);
- };
-
- $rootScope.openExternalLink = function(url, target) {
- root.openExternalLink(url, target);
- };
-
-
-
- return root;
-});
diff --git a/old/index.js b/old/index.js
deleted file mode 100644
index 71cdeed98..000000000
--- a/old/index.js
+++ /dev/null
@@ -1,1338 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicScrollDelegate, $ionicPopup, $ionicSideMenuDelegate, $httpBackend, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwcError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService, openURLService, ongoingProcess) {
-
- var self = this;
- var SOFT_CONFIRMATION_LIMIT = 12;
- var errors = bwcService.getErrors();
- var historyUpdateInProgress = {};
- var isChromeApp = platformInfo.isChromeApp;
- var isCordova = platformInfo.isCordova;
- var isNW = platformInfo.isNW;
-
- var ret = {};
- ret.isCordova = isCordova;
- ret.isChromeApp = isChromeApp;
- ret.isSafari = platformInfo.isSafari;
- ret.isWindowsPhoneApp = platformInfo.isWP;
- ret.historyShowLimit = 10;
- ret.historyShowMoreLimit = 10;
- ret.isSearching = false;
- ret.prevState = 'walletHome';
- ret.physicalScreenWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width);
-
- ret.appConfig = window.appConfig;
-
- // Only for testing
- //storageService.checkQuota();
-
- ret.menu = [{
- 'title': gettext('Receive'),
- 'icon': {
- false: 'icon-receive',
- true: 'icon-receive-active'
- },
- 'link': 'receive'
- }, {
- 'title': gettext('Activity'),
- 'icon': {
- false: 'icon-activity',
- true: 'icon-activity-active'
- },
- 'link': 'walletHome'
- }, {
- 'title': gettext('Send'),
- 'icon': {
- false: 'icon-send',
- true: 'icon-send-active'
- },
- 'link': 'send'
- }];
-
- ret.addonViews = addonManager.addonViews();
- ret.txTemplateUrl = addonManager.txTemplateUrl() || 'views/includes/transaction.html';
-
- ret.tab = 'walletHome';
- var vanillaScope = ret;
-
- if (isNW) {
- latestReleaseService.checkLatestRelease(function(err, newRelease) {
- if (err) {
- $log.warn(err);
- return;
- }
-
- if (newRelease)
- $scope.newRelease = gettext('There is a new version of Copay. Please update');
- });
- }
-
- function strip(number) {
- return (parseFloat(number.toPrecision(12)));
- };
-
- self.goHome = function() {
- go.walletHome();
- };
-
- self.allowRefresher = function() {
- if ($ionicSideMenuDelegate.getOpenRatio() != 0) self.allowPullToRefresh = false;
- }
-
- self.hideBalance = function() {
- storageService.getHideBalanceFlag(self.walletId, function(err, shouldHideBalance) {
- if (err) self.shouldHideBalance = false;
- else self.shouldHideBalance = (shouldHideBalance == 'true') ? true : false;
- });
- }
-
- self.onHold = function() {
- self.shouldHideBalance = !self.shouldHideBalance;
- storageService.setHideBalanceFlag(self.walletId, self.shouldHideBalance.toString(), function() {});
- }
-
- self.setWalletPreferencesTitle = function() {
- return gettext("Wallet Preferences");
- }
-
- 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 == 'physicalScreenWidth') return;
- if (k == 'loadingWallet') {
- self.loadingWallet = true;
- return;
- }
- if (!lodash.isUndefined(vanillaScope[k])) {
- self[k] = vanillaScope[k];
- return;
- }
-
- delete self[k];
- });
- };
-
- self.setFocusedWallet = function() {
- var fc = profileService.focusedClient;
- if (!fc) return;
-
- self.cleanInstance();
- self.loadingWallet = true;
- self.setSpendUnconfirmed();
-
- $timeout(function() {
- $rootScope.$apply();
-
- self.hasProfile = true;
- self.isSingleAddress = false;
- self.noFocusedWallet = false;
- self.updating = false;
-
- // Credentials Shortcuts
- 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();
- self.isPrivKeyExternal = fc.isPrivKeyExternal();
- self.isPrivKeyEncrypted = fc.isPrivKeyEncrypted();
- self.externalSource = fc.getPrivKeyExternalSourceName();
- self.account = fc.credentials.account;
- self.incorrectDerivation = fc.keyDerivationOk === false;
-
- if (self.externalSource == 'trezor')
- self.account++;
-
- self.txps = [];
- self.copayers = [];
- self.updateColor();
- self.updateAlias();
- self.setAddressbook();
-
- self.initGlidera();
- self.initCoinbase();
-
- self.hideBalance();
-
- self.setCustomBWSFlag();
-
- if (!self.isComplete) {
- $log.debug('Wallet not complete BEFORE update... redirecting');
- go.path('copayers');
- } else {
- if (go.is('copayers')) {
- $log.debug('Wallet Complete BEFORE update... redirect to home');
- go.walletHome();
- }
- }
-
- profileService.needsBackup(fc, function(needsBackup) {
- self.needsBackup = needsBackup;
- self.openWallet(function() {
- if (!self.isComplete) {
- $log.debug('Wallet not complete after update... redirecting');
- go.path('copayers');
- } else {
- if (go.is('copayers')) {
- $log.debug('Wallet Complete after update... redirect to home');
- go.walletHome();
- }
- }
- });
- });
- });
- };
-
- self.setCustomBWSFlag = function() {
- var defaults = configService.getDefaults();
- var config = configService.getSync();
-
- self.usingCustomBWS = config.bwsFor && config.bwsFor[self.walletId] && (config.bwsFor[self.walletId] != defaults.bws.url);
- };
-
-
- self.setTab = function(tab, reset, tries, switchState) {
- 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);
- }
- }
- if (self.tab === tab && !reset)
- return;
-
- if (!document.getElementById('menu-' + tab) && ++tries < 5) {
- return $timeout(function() {
- self.setTab(tab, reset, tries, switchState);
- }, 300);
- }
-
- if (!self.tab || !go.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 = '';
- }
- }
-
- if (document.getElementById(tab)) {
- document.getElementById(tab).className = 'tab-in tab-view ' + tab;
- var newe = document.getElementById('menu-' + tab);
- if (newe) {
- newe.className = 'active';
- }
- }
-
- self.tab = tab;
- $rootScope.$emit('Local/TabChanged', tab);
- };
-
- if (switchState && !go.is('walletHome')) {
- go.path('walletHome', function() {
- changeTab();
- });
- return;
- }
-
- changeTab();
- };
-
-
- self.setSpendUnconfirmed = function(spendUnconfirmed) {
- self.spendUnconfirmed = spendUnconfirmed || configService.getSync().wallet.spendUnconfirmed;
- };
-
- self.updateBalance = function() {
- var fc = profileService.focusedClient;
- $timeout(function() {
- ongoingProcess.set('updatingBalance', true);
- $log.debug('Updating Balance');
- fc.getBalance(function(err, balance) {
- ongoingProcess.set('updatingBalance', false);
- if (err) {
- self.handleError(err);
- return;
- }
- $log.debug('Wallet Balance:', balance);
- self.setBalance(balance);
- });
- });
- };
-
- self.updatePendingTxps = function() {
- var fc = profileService.focusedClient;
- $timeout(function() {
- self.updating = true;
- $log.debug('Updating PendingTxps');
- fc.getTxProposals({}, function(err, txps) {
- self.updating = false;
- if (err) {
- self.handleError(err);
- } else {
- $log.debug('Wallet PendingTxps:', txps);
- self.setPendingTxps(txps);
- }
- $rootScope.$apply();
- });
- });
- };
-
- // This handles errors from BWS/index which normally
- // trigger from async events (like updates).
- // Debounce function avoids multiple popups
- var _handleError = function(err) {
- $log.warn('Client ERROR: ', err);
- if (err instanceof errors.NOT_AUTHORIZED) {
- self.notAuthorized = true;
- go.walletHome();
- } else if (err instanceof errors.NOT_FOUND) {
- self.showErrorPopup(gettext('Could not access Wallet Service: Not found'));
- } else {
- var msg = ""
- $scope.$emit('Local/ClientError', (err.error ? err.error : err));
- var msg = bwcError.msg(err, gettext('Error at Wallet Service'));
- self.showErrorPopup(msg);
- }
- };
-
- self.handleError = lodash.debounce(_handleError, 1000);
-
- self.openWallet = function(cb) {
- var fc = profileService.focusedClient;
- $timeout(function() {
- $rootScope.$apply();
- self.updating = true;
- self.updateError = false;
- fc.openWallet(function(err, walletStatus) {
- self.updating = false;
- if (err) {
- self.updateError = true;
- self.handleError(err);
- return;
- }
- $log.debug('Wallet Opened');
-
- self.updateAll(lodash.isObject(walletStatus) ? {
- walletStatus: walletStatus,
- cb: cb,
- } : {
- cb: cb
- });
- $rootScope.$apply();
- });
- });
- };
-
- self.setPendingTxps = function(txps) {
- self.pendingTxProposalsCountForUs = 0;
- var now = Math.floor(Date.now() / 1000);
-
- /* 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);
- */
-
- lodash.each(txps, function(tx) {
-
- tx = txFormatService.processTx(tx);
-
- // no future transactions...
- if (tx.createdOn > now)
- tx.createdOn = now;
-
- 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';
- }
-
- if (!tx.deleteLockTime)
- tx.canBeRemoved = true;
-
- if (tx.creatorId != self.copayerId) {
- self.pendingTxProposalsCountForUs = self.pendingTxProposalsCountForUs + 1;
- }
- addonManager.formatPendingTxp(tx);
- });
- self.txps = txps;
- };
-
- var SAFE_CONFIRMATIONS = 6;
-
- self.processNewTxs = function(txs) {
- var config = configService.getSync().wallet.settings;
- var now = Math.floor(Date.now() / 1000);
- var txHistoryUnique = {};
- var ret = [];
- self.hasUnsafeConfirmed = false;
-
- lodash.each(txs, function(tx) {
- tx = txFormatService.processTx(tx);
-
- // no future transactions...
- if (tx.time > now)
- tx.time = now;
-
- if (tx.confirmations >= SAFE_CONFIRMATIONS) {
- tx.safeConfirmed = SAFE_CONFIRMATIONS + '+';
- } else {
- tx.safeConfirmed = false;
- self.hasUnsafeConfirmed = true;
- }
-
- if (tx.note) {
- delete tx.note.encryptedEditedByName;
- delete tx.note.encryptedBody;
- }
-
- if (!txHistoryUnique[tx.txid]) {
- ret.push(tx);
- txHistoryUnique[tx.txid] = true;
- } else {
- $log.debug('Ignoring duplicate TX in history: ' + tx.txid)
- }
- });
-
- return ret;
- };
-
- 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;
- };
-
- self.updateColor = function() {
- var config = configService.getSync();
- config.colorFor = config.colorFor || {};
- self.backgroundColor = config.colorFor[self.walletId] || '#4A90E2';
- var fc = profileService.focusedClient;
- fc.backgroundColor = self.backgroundColor;
- if (isCordova && StatusBar.isVisible) {
- StatusBar.backgroundColorByHexString(fc.backgroundColor);
- }
- };
-
- self.setBalance = function(balance) {
- if (!balance) return;
- var config = configService.getSync().wallet.settings;
- var COIN = 1e8;
-
-
- // Address with Balance
- self.balanceByAddress = balance.byAddress;
-
- // Spend unconfirmed funds
- if (self.spendUnconfirmed) {
- self.totalBalanceSat = balance.totalAmount;
- self.lockedBalanceSat = balance.lockedAmount;
- self.availableBalanceSat = balance.availableAmount;
- self.totalBytesToSendMax = balance.totalBytesToSendMax;
- self.pendingAmount = null;
- } else {
- self.totalBalanceSat = balance.totalConfirmedAmount;
- self.lockedBalanceSat = balance.lockedConfirmedAmount;
- self.availableBalanceSat = balance.availableConfirmedAmount;
- self.totalBytesToSendMax = balance.totalBytesToSendConfirmedMax;
- self.pendingAmount = balance.totalAmount - balance.totalConfirmedAmount;
- }
-
- // 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;
-
- if (self.pendingAmount) {
- self.pendingAmountStr = profileService.formatAmount(self.pendingAmount) + ' ' + self.unitName;
- } else {
- self.pendingAmountStr = null;
- }
-
- self.alternativeName = config.alternativeName;
- self.alternativeIsoCode = config.alternativeIsoCode;
-
- // Check address
- addressService.isUsed(self.walletId, balance.byAddress, function(err, used) {
- if (used) {
- $log.debug('Address used. Creating new');
- $rootScope.$emit('Local/AddressIsUsed');
- }
- });
-
- rateService.whenAvailable(function() {
-
- var totalBalanceAlternative = rateService.toFiat(self.totalBalanceSat, self.alternativeIsoCode);
- var lockedBalanceAlternative = rateService.toFiat(self.lockedBalanceSat, self.alternativeIsoCode);
- var alternativeConversionRate = rateService.toFiat(100000000, self.alternativeIsoCode);
-
- self.totalBalanceAlternative = $filter('formatFiatAmount')(totalBalanceAlternative);
- self.lockedBalanceAlternative = $filter('formatFiatAmount')(lockedBalanceAlternative);
- self.alternativeConversionRate = $filter('formatFiatAmount')(alternativeConversionRate);
-
- self.alternativeBalanceAvailable = true;
-
- self.isRateAvailable = true;
- $rootScope.$apply();
- });
-
- if (!rateService.isAvailable()) {
- $rootScope.$apply();
- }
- };
-
-
- self.showMore = function() {
- $timeout(function() {
- if (self.isSearching) {
- self.txHistorySearchResults = self.result.slice(0, self.nextTxHistory);
- $log.debug('Total txs: ', self.txHistorySearchResults.length + '/' + self.result.length);
- if (self.txHistorySearchResults.length >= self.result.length)
- self.historyShowMore = false;
- } else {
- self.txHistory = self.completeHistory.slice(0, self.nextTxHistory);
- $log.debug('Total txs: ', self.txHistory.length + '/' + self.completeHistory.length);
- if (self.txHistory.length >= self.completeHistory.length)
- self.historyShowMore = false;
- }
- self.nextTxHistory += self.historyShowMoreLimit;
- $scope.$broadcast('scroll.infiniteScrollComplete');
- }, 100);
- };
-
-
-
-
- self.toggleLeftMenu = function() {
- profileService.isDisclaimerAccepted(function(val) {
- if (val) go.toggleLeftMenu();
- else
- $log.debug('Disclaimer not accepted, cannot open menu');
- });
- };
-
- self.initGlidera = function(accessToken) {
- self.glideraEnabled = configService.getSync().glidera.enabled;
- self.glideraTestnet = configService.getSync().glidera.testnet;
- var network = self.glideraTestnet ? 'testnet' : 'livenet';
-
- self.glideraToken = null;
- self.glideraError = null;
- self.glideraPermissions = null;
- self.glideraEmail = null;
- self.glideraPersonalInfo = null;
- self.glideraTxs = null;
- self.glideraStatus = null;
-
- if (!self.glideraEnabled) return;
-
- glideraService.setCredentials(network);
-
- var getToken = function(cb) {
- if (accessToken) {
- cb(null, accessToken);
- } else {
- storageService.getGlideraToken(network, cb);
- }
- };
-
- getToken(function(err, accessToken) {
- if (err || !accessToken) return;
- else {
- glideraService.getAccessTokenPermissions(accessToken, function(err, p) {
- if (err) {
- self.glideraError = err;
- } else {
- self.glideraToken = accessToken;
- self.glideraPermissions = p;
- self.updateGlidera({
- fullUpdate: true
- });
- }
- });
- }
- });
- };
-
- self.updateGlidera = function(opts) {
- if (!self.glideraToken || !self.glideraPermissions) return;
- var accessToken = self.glideraToken;
- var permissions = self.glideraPermissions;
-
- opts = opts || {};
-
- glideraService.getStatus(accessToken, function(err, data) {
- self.glideraStatus = data;
- });
-
- glideraService.getLimits(accessToken, function(err, limits) {
- self.glideraLimits = limits;
- });
-
- if (permissions.transaction_history) {
- glideraService.getTransactions(accessToken, function(err, data) {
- self.glideraTxs = data;
- });
- }
-
- if (permissions.view_email_address && opts.fullUpdate) {
- glideraService.getEmail(accessToken, function(err, data) {
- self.glideraEmail = data.email;
- });
- }
- if (permissions.personal_info && opts.fullUpdate) {
- glideraService.getPersonalInfo(accessToken, function(err, data) {
- self.glideraPersonalInfo = data;
- });
- }
-
- };
-
- self.initCoinbase = function(accessToken) {
- self.coinbaseEnabled = configService.getSync().coinbase.enabled;
- self.coinbaseTestnet = configService.getSync().coinbase.testnet;
- var network = self.coinbaseTestnet ? 'testnet' : 'livenet';
-
- self.coinbaseToken = null;
- self.coinbaseError = null;
- self.coinbasePermissions = null;
- self.coinbaseEmail = null;
- self.coinbasePersonalInfo = null;
- self.coinbaseTxs = null;
- self.coinbaseStatus = null;
-
- if (!self.coinbaseEnabled) return;
-
- coinbaseService.setCredentials(network);
-
- var getToken = function(cb) {
- if (accessToken) {
- cb(null, accessToken);
- } else {
- storageService.getCoinbaseToken(network, cb);
- }
- };
-
- getToken(function(err, accessToken) {
- if (err || !accessToken) return;
- else {
- coinbaseService.getAccounts(accessToken, function(err, a) {
- if (err) {
- self.coinbaseError = err;
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- }
- } else {
- self.coinbaseToken = accessToken;
- lodash.each(a.data, function(account) {
- if (account.primary && account.type == 'wallet') {
- self.coinbaseAccount = account;
- self.updateCoinbase();
- }
- });
- }
- });
- }
- });
- };
-
- self.updateCoinbase = lodash.debounce(function(opts) {
- if (!self.coinbaseToken || !self.coinbaseAccount) return;
- var accessToken = self.coinbaseToken;
- var accountId = self.coinbaseAccount.id;
-
- opts = opts || {};
-
- if (opts.updateAccount) {
- coinbaseService.getAccount(accessToken, accountId, function(err, a) {
- if (err) {
- self.coinbaseError = err;
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- }
- return;
- }
- self.coinbaseAccount = a.data;
- });
- }
-
- coinbaseService.getCurrentUser(accessToken, function(err, u) {
- if (err) {
- self.coinbaseError = err;
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- }
- return;
- }
- self.coinbaseUser = u.data;
- });
-
- coinbaseService.getPendingTransactions(function(err, txs) {
- self.coinbasePendingTransactions = lodash.isEmpty(txs) ? null : txs;
- lodash.forEach(txs, function(dataFromStorage, txId) {
- if ((dataFromStorage.type == 'sell' && dataFromStorage.status == 'completed') ||
- (dataFromStorage.type == 'buy' && dataFromStorage.status == 'completed') ||
- dataFromStorage.status == 'error' ||
- (dataFromStorage.type == 'send' && dataFromStorage.status == 'completed')) return;
- coinbaseService.getTransaction(accessToken, accountId, txId, function(err, tx) {
- if (err) {
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- return;
- }
- coinbaseService.savePendingTransaction(dataFromStorage, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- return;
- }
- _updateCoinbasePendingTransactions(dataFromStorage, tx.data);
- self.coinbasePendingTransactions[txId] = dataFromStorage;
- if (tx.data.type == 'send' && tx.data.status == 'completed' && tx.data.from) {
- coinbaseService.sellPrice(accessToken, dataFromStorage.sell_price_currency, function(err, s) {
- if (err) {
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- return;
- }
- coinbaseService.savePendingTransaction(dataFromStorage, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- return;
- }
- var newSellPrice = s.data.amount;
- var variance = Math.abs((newSellPrice - dataFromStorage.sell_price_amount) / dataFromStorage.sell_price_amount * 100);
- if (variance < dataFromStorage.price_sensitivity.value) {
- self.sellPending(tx.data);
- } else {
- var error = {
- errors: [{
- message: 'Price falls over the selected percentage'
- }]
- };
- coinbaseService.savePendingTransaction(dataFromStorage, {
- status: 'error',
- error: error
- }, function(err) {
- if (err) $log.debug(err);
- });
- }
- });
- } else if (tx.data.type == 'buy' && tx.data.status == 'completed' && tx.data.buy) {
- self.sendToCopay(dataFromStorage);
- } else {
- coinbaseService.savePendingTransaction(dataFromStorage, {}, function(err) {
- if (err) $log.debug(err);
- });
- }
- });
- });
- });
-
- }, 1000);
-
- var _updateCoinbasePendingTransactions = function(obj /*, …*/ ) {
- for (var i = 1; i < arguments.length; i++) {
- for (var prop in arguments[i]) {
- var val = arguments[i][prop];
- if (typeof val == "object")
- _updateCoinbasePendingTransactions(obj[prop], val);
- else
- obj[prop] = val ? val : obj[prop];
- }
- }
- return obj;
- };
-
- self.refreshCoinbaseToken = function() {
- var network = self.coinbaseTestnet ? 'testnet' : 'livenet';
- storageService.getCoinbaseRefreshToken(network, function(err, refreshToken) {
- if (!refreshToken) return;
- coinbaseService.refreshToken(refreshToken, function(err, data) {
- if (err) {
- self.coinbaseError = err;
- } else if (data && data.access_token && data.refresh_token) {
- storageService.setCoinbaseToken(network, data.access_token, function() {
- storageService.setCoinbaseRefreshToken(network, data.refresh_token, function() {
- $timeout(function() {
- self.initCoinbase(data.access_token);
- }, 100);
- });
- });
- }
- });
- });
- };
-
- self.sendToCopay = function(tx) {
- if (!tx) return;
- var data = {
- to: tx.toAddr,
- amount: tx.amount.amount,
- currency: tx.amount.currency,
- description: 'To Copay Wallet'
- };
- coinbaseService.sendTo(self.coinbaseToken, self.coinbaseAccount.id, data, function(err, res) {
- if (err) {
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- return;
- }
- coinbaseService.savePendingTransaction(tx, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- } else {
- if (!res.data.id) {
- coinbaseService.savePendingTransaction(tx, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- return;
- }
- coinbaseService.getTransaction(self.coinbaseToken, self.coinbaseAccount.id, res.data.id, function(err, sendTx) {
- coinbaseService.savePendingTransaction(tx, {
- remove: true
- }, function(err) {
- coinbaseService.savePendingTransaction(sendTx.data, {}, function(err) {
- $timeout(function() {
- self.updateCoinbase({
- updateAccount: true
- });
- }, 1000);
- });
- });
- });
- }
- });
- };
-
- self.sellPending = function(tx) {
- if (!tx) return;
- var data = tx.amount;
- data['commit'] = true;
- coinbaseService.sellRequest(self.coinbaseToken, self.coinbaseAccount.id, data, function(err, res) {
- if (err) {
- if (err.errors[0] && err.errors[0].id == 'expired_token') {
- self.refreshCoinbaseToken();
- return;
- }
- coinbaseService.savePendingTransaction(tx, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- } else {
- if (!res.data.transaction) {
- coinbaseService.savePendingTransaction(tx, {
- status: 'error',
- error: err
- }, function(err) {
- if (err) $log.debug(err);
- });
- return;
- }
- coinbaseService.savePendingTransaction(tx, {
- remove: true
- }, function(err) {
- coinbaseService.getTransaction(self.coinbaseToken, self.coinbaseAccount.id, res.data.transaction.id, function(err, updatedTx) {
- coinbaseService.savePendingTransaction(updatedTx.data, {}, function(err) {
- if (err) $log.debug(err);
- $timeout(function() {
- self.updateCoinbase({
- updateAccount: true
- });
- }, 1000);
- });
- });
- });
- }
- });
- };
-
- self.isInFocus = function(walletId) {
- var fc = profileService.focusedClient;
- return fc && fc.credentials.walletId == walletId;
- };
-
- self.setAddressbook = function(ab) {
- if (ab) {
- self.addressbook = ab;
- return;
- }
-
- addressbookService.list(function(err, ab) {
- if (err) {
- $log.error('Error getting the addressbook');
- return;
- }
- self.addressbook = ab;
- });
- };
-
- $rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams) {
- self.prevState = from.name || 'walletHome';
- self.tab = 'walletHome';
- });
-
- $rootScope.$on('Local/ValidatingWalletEnded', function(ev, walletId, isOK) {
-
- if (self.isInFocus(walletId)) {
- // NOTE: If the user changed the wallet, the flag is already turn off.
- self.incorrectDerivation = isOK === false;
- }
- });
-
- $rootScope.$on('Local/ClearHistory', function(event) {
- $log.debug('The wallet transaction history has been deleted');
- self.txHistory = self.completeHistory = self.txHistorySearchResults = [];
- self.debounceUpdateHistory();
- });
-
- $rootScope.$on('Local/AddressbookUpdated', function(event, ab) {
- self.setAddressbook(ab);
- });
-
- // UX event handlers
- $rootScope.$on('Local/ColorUpdated', function(event) {
- self.updateColor();
- $timeout(function() {
- $rootScope.$apply();
- });
- });
-
- $rootScope.$on('Local/AliasUpdated', function(event) {
- self.updateAlias();
- $timeout(function() {
- $rootScope.$apply();
- });
- });
-
- $rootScope.$on('Local/SpendUnconfirmedUpdated', function(event, spendUnconfirmed) {
- self.setSpendUnconfirmed(spendUnconfirmed);
- self.updateAll();
- });
-
- $rootScope.$on('Local/GlideraUpdated', function(event, accessToken) {
- self.initGlidera(accessToken);
- });
-
- $rootScope.$on('Local/CoinbaseUpdated', function(event, accessToken) {
- self.initCoinbase(accessToken);
- });
-
- $rootScope.$on('Local/GlideraTx', function(event, accessToken, permissions) {
- self.updateGlidera();
- });
-
- $rootScope.$on('Local/CoinbaseTx', function(event) {
- self.updateCoinbase({
- updateAccount: true
- });
- });
-
- $rootScope.$on('Local/GlideraError', function(event) {
- self.debouncedUpdate();
- });
-
- $rootScope.$on('Local/UnitSettingUpdated', function(event) {
- self.updateAll({
- triggerTxUpdate: true,
- });
- });
-
- $rootScope.$on('Local/WalletCompleted', function(event, walletId) {
- if (self.isInFocus(walletId)) {
- // reset main wallet variables
- self.setFocusedWallet();
- go.walletHome();
- }
- });
-
- self.debouncedUpdate = function() {
- var now = Date.now();
- var oneHr = 1000 * 60 * 60;
-
- if (!self.lastUpdate || (now - self.lastUpdate) > oneHr) {
- self.updateAll({
- quiet: true,
- triggerTxUpdate: true
- });
- }
- };
-
- $rootScope.$on('Local/Resume', function(event) {
- $log.debug('### Resume event');
- profileService.isDisclaimerAccepted(function(v) {
- if (!v) {
- $log.debug('Disclaimer not accepted, resume to home');
- go.path('disclaimer');
- }
- });
- self.debouncedUpdate();
- });
-
- $rootScope.$on('Local/BackupDone', function(event, walletId) {
- self.needsBackup = false;
- $log.debug('Backup done');
- storageService.setBackupFlag(walletId || self.walletId, function(err) {
- $log.debug('Backup stored');
- });
- });
-
- $rootScope.$on('Local/DeviceError', function(event, err) {
- self.showErrorPopup(err, function() {
- if (isCordova && navigator && navigator.app) {
- navigator.app.exitApp();
- }
- });
- });
-
- $rootScope.$on('Local/WalletImported', function(event, walletId) {
-console.log('[index.js:1063] walletImported'); //TODO
- return;
- self.needsBackup = false;
- storageService.setBackupFlag(walletId, function() {
- $log.debug('Backup done stored');
- addressService.expireAddress(walletId, function(err) {
- $timeout(function() {
- self.txHistory = self.completeHistory = self.txHistorySearchResults = [];
- storageService.removeTxHistory(walletId, function() {
- self.startScan(walletId);
- });
- }, 500);
- });
- });
- });
-
- $rootScope.$on('NewIncomingTx', function() {
- self.newTx = true;
- self.updateAll({
- walletStatus: null,
- untilItChanges: true,
- triggerTxUpdate: true,
- });
- });
-
-
- $rootScope.$on('NewBlock', function() {
- if (self.glideraEnabled) {
- $timeout(function() {
- self.updateGlidera();
- });
- }
- if (self.coinbaseEnabled) {
- $timeout(function() {
- self.updateCoinbase();
- });
- }
- if (self.pendingAmount) {
- 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') {
- self.throttledUpdateHistory();
- } else {
- self.debounceUpdateHistory();
- }
- }
- });
-
- $rootScope.$on('BalanceUpdated', function(e, n) {
- self.setBalance(n.data);
- });
-
-
- //untilItChange TRUE
- lodash.each(['NewOutgoingTx', 'NewOutgoingTxByThirdParty'], function(eventName) {
- $rootScope.$on(eventName, function(event) {
- self.newTx = true;
- self.updateAll({
- walletStatus: null,
- untilItChanges: true,
- triggerTxUpdate: true,
- });
- });
- });
-
- //untilItChange FALSE
- lodash.each(['NewTxProposal', 'TxProposalFinallyRejected', 'TxProposalRemoved', 'NewOutgoingTxByThirdParty',
- 'Local/GlideraTx'
- ], function(eventName) {
- $rootScope.$on(eventName, function(event) {
- self.updateAll({
- walletStatus: null,
- untilItChanges: null,
- triggerTxUpdate: true,
- });
- });
- });
-
-
- //untilItChange Maybe
- $rootScope.$on('Local/TxProposalAction', function(event, untilItChanges) {
- self.newTx = untilItChanges;
- self.updateAll({
- walletStatus: null,
- untilItChanges: untilItChanges,
- triggerTxUpdate: true,
- });
- });
-
- $rootScope.$on('ScanFinished', function() {
- $log.debug('Scan Finished. Updating history');
- storageService.removeTxHistory(self.walletId, function() {
- self.updateAll({
- walletStatus: null,
- triggerTxUpdate: true,
- });
- });
- });
-
- lodash.each(['TxProposalRejectedBy', 'TxProposalAcceptedBy'], function(eventName) {
- $rootScope.$on(eventName, function() {
- var f = function() {
- if (self.updating) {
- return $timeout(f, 200);
- };
- self.updatePendingTxps();
- };
- f();
- });
- });
-
- $rootScope.$on('Local/NoWallets', function(event) {
- $timeout(function() {
- self.hasProfile = true;
- self.noFocusedWallet = true;
- self.isComplete = null;
- self.walletName = null;
- uxLanguage.update();
- });
- });
-
- $rootScope.$on('Local/NewFocusedWallet', function() {
- console.log('[index.js.1200:NewFocusedWallet:] TODO'); //TODO
-
- return;
-
-
- uxLanguage.update();
- self.setFocusedWallet();
- self.updateHistory();
- 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);
- });
- storageService.removeCleanAndScanAddresses(function() {
- $rootScope.$emit('Local/NewFocusedWalletReady');
- });
- } else {
- $rootScope.$emit('Local/NewFocusedWalletReady');
- }
- });
- });
-
- $rootScope.$on('Local/SetTab', function(event, tab, reset) {
- self.setTab(tab, reset);
- });
-
- $rootScope.$on('disclaimerAccepted', function(event) {
- $scope.isDisclaimerAccepted = true;
- });
-
- $rootScope.$on('Local/WindowResize', function() {
- self.physicalScreenWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width);
- });
-
- $rootScope.$on('Local/NeedsConfirmation', function(event, txp, cb) {
-
- function openConfirmationPopup(txp, cb) {
-
- var config = configService.getSync();
-
- $scope.color = config.colorFor[txp.walletId] || '#4A90E2';
- $scope.tx = txFormatService.processTx(txp);
-
- self.confirmationPopup = $ionicPopup.show({
- templateUrl: 'views/includes/confirm-tx.html',
- scope: $scope,
- });
-
- $scope.processFee = function(amount, fee) {
- var walletSettings = configService.getSync().wallet.settings;
- var feeAlternativeIsoCode = walletSettings.alternativeIsoCode;
-
- $scope.feeLevel = feeService.feeOpts[feeService.getCurrentFeeLevel()];
- $scope.feeAlternativeStr = parseFloat((rateService.toFiat(fee, feeAlternativeIsoCode)).toFixed(2), 10) + ' ' + feeAlternativeIsoCode;
- $scope.feeRateStr = (fee / (amount + fee) * 100).toFixed(2) + '%';
- };
-
- $scope.cancel = function() {
- return cb();
- };
-
- $scope.accept = function() {
- return cb(true);
- };
- }
-
- openConfirmationPopup(txp, function(accept) {
- self.confirmationPopup.close();
- return cb(accept);
- });
- });
-
- $rootScope.$on('Local/NeedsPassword', function(event, isSetup, cb) {
-
- function openPasswordPopup(isSetup, cb) {
- $scope.data = {};
- $scope.data.password = null;
- $scope.isSetup = isSetup;
- $scope.isVerification = false;
- $scope.loading = false;
- var pass = null;
-
- self.passwordPopup = $ionicPopup.show({
- templateUrl: 'views/includes/password.html',
- scope: $scope,
- });
-
- $scope.cancel = function() {
- return cb('No spending password given');
- };
-
- $scope.keyPress = function(event) {
- if (!$scope.data.password || $scope.loading) return;
- if (event.keyCode == 13) $scope.set();
- }
-
- $scope.set = function() {
- $scope.loading = true;
- $scope.error = null;
-
- $timeout(function() {
- if (isSetup && !$scope.isVerification) {
- $scope.loading = false;
- $scope.isVerification = true;
- pass = $scope.data.password;
- $scope.data.password = null;
- return;
- }
- if (isSetup && pass != $scope.data.password) {
- $scope.loading = false;
- $scope.error = gettext('Spending Passwords do not match');
- $scope.isVerification = false;
- $scope.data.password = null;
- pass = null;
- return;
- }
- return cb(null, $scope.data.password);
- }, 100);
- };
- };
-
- openPasswordPopup(isSetup, function(err, pass) {
- self.passwordPopup.close();
- return cb(err, pass);
- });
-
- });
-
- $rootScope.$on('Local/EmailUpdated', function(event, email) {
- self.preferences.email = email;
- });
-
- lodash.each(['NewCopayer', 'CopayerUpdated'], function(eventName) {
- $rootScope.$on(eventName, function() {
-console.log('[index.js:1324] NewCopayer, CopayerUpdated'); //TODO
- return;
- // Re try to open wallet (will triggers)
- self.setFocusedWallet();
- });
- });
-
- $rootScope.$on('Local/NewEncryptionSetting', function() {
- var fc = profileService.focusedClient;
- self.isPrivKeyEncrypted = fc.isPrivKeyEncrypted();
- $timeout(function() {
- $rootScope.$apply();
- });
- });
-
-
- /* Start setup */
- lodash.assign(self, vanillaScope);
- openURLService.init();
-});
diff --git a/old/menu-item.html b/old/menu-item.html
deleted file mode 100644
index 68a2d96d9..000000000
--- a/old/menu-item.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/old/notifications.html b/old/notifications.html
deleted file mode 100644
index 943d9dec7..000000000
--- a/old/notifications.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
{{noti.title|translate}}
-
{{noti.content|translate}}
-
-
{{noti.content|translate}}
-
-
-
-
-
diff --git a/old/notifications.js b/old/notifications.js
deleted file mode 100644
index b87dddb28..000000000
--- a/old/notifications.js
+++ /dev/null
@@ -1,260 +0,0 @@
-'use strict';
-
-angular.module('copayApp.services').
-factory('notification', function($timeout, platformInfo) {
-
- var isCordova = platformInfo.isCordova;
- var notifications = [];
-
- /*
- ls.getItem('notifications', function(err, data) {
- if (data) {
- notifications = JSON.parse(data);
- }
- });
- */
-
- var queue = [];
- var settings = {
- info: {
- duration: 6000,
- enabled: true
- },
- funds: {
- duration: 7000,
- enabled: true
- },
- version: {
- duration: 60000,
- enabled: true
- },
- warning: {
- duration: 7000,
- enabled: true
- },
- error: {
- duration: 7000,
- enabled: true
- },
- success: {
- duration: 5000,
- enabled: true
- },
- progress: {
- duration: 0,
- enabled: true
- },
- custom: {
- duration: 35000,
- enabled: true
- },
- details: true,
- localStorage: false,
- html5Mode: false,
- html5DefaultIcon: 'img/favicon.ico'
- };
-
- function html5Notify(icon, title, content, ondisplay, onclose) {
- if (window.webkitNotifications && window.webkitNotifications.checkPermission() === 0) {
- if (!icon) {
- icon = 'img/favicon.ico';
- }
- var noti = window.webkitNotifications.createNotification(icon, title, content);
- if (typeof ondisplay === 'function') {
- noti.ondisplay = ondisplay;
- }
- if (typeof onclose === 'function') {
- noti.onclose = onclose;
- }
- noti.show();
- } else {
- settings.html5Mode = false;
- }
- }
-
-
- return {
-
- /* ========== SETTINGS RELATED METHODS =============*/
-
- disableHtml5Mode: function() {
- settings.html5Mode = false;
- },
-
- disableType: function(notificationType) {
- settings[notificationType].enabled = false;
- },
-
- enableHtml5Mode: function() {
- // settings.html5Mode = true;
- settings.html5Mode = this.requestHtml5ModePermissions();
- },
-
- enableType: function(notificationType) {
- settings[notificationType].enabled = true;
- },
-
- getSettings: function() {
- return settings;
- },
-
- toggleType: function(notificationType) {
- settings[notificationType].enabled = !settings[notificationType].enabled;
- },
-
- toggleHtml5Mode: function() {
- settings.html5Mode = !settings.html5Mode;
- },
-
- requestHtml5ModePermissions: function() {
- if (window.webkitNotifications) {
- if (window.webkitNotifications.checkPermission() === 0) {
- return true;
- } else {
- window.webkitNotifications.requestPermission(function() {
- if (window.webkitNotifications.checkPermission() === 0) {
- settings.html5Mode = true;
- } else {
- settings.html5Mode = false;
- }
- });
- return false;
- }
- } else {
- return false;
- }
- },
-
-
- /* ============ QUERYING RELATED METHODS ============*/
-
- getAll: function() {
- // Returns all notifications that are currently stored
- return notifications;
- },
-
- getQueue: function() {
- return queue;
- },
-
- /* ============== NOTIFICATION METHODS ==============*/
-
- info: function(title, content, userData) {
- return this.awesomeNotify('info', 'fi-info', title, content, userData);
- },
-
- funds: function(title, content, userData) {
- return this.awesomeNotify('funds', 'icon-receive', title, content, userData);
- },
-
- version: function(title, content, severe) {
- return this.awesomeNotify('version', severe ? 'fi-alert' : 'fi-flag', title, content);
- },
-
- error: function(title, content, userData) {
- return this.awesomeNotify('error', 'fi-x', title, content, userData);
- },
-
- success: function(title, content, userData) {
- return this.awesomeNotify('success', 'fi-check', title, content, userData);
- },
-
- warning: function(title, content, userData) {
- return this.awesomeNotify('warning', 'fi-alert', title, content, userData);
- },
-
- new: function(title, content, userData) {
- return this.awesomeNotify('warning', 'fi-plus', title, content, userData);
- },
-
- sent: function(title, content, userData) {
- return this.awesomeNotify('warning', 'icon-paperplane', title, content, userData);
- },
-
- awesomeNotify: function(type, icon, title, content, userData) {
- /**
- * Supposed to wrap the makeNotification method for drawing icons using font-awesome
- * rather than an image.
- *
- * Need to find out how I'm going to make the API take either an image
- * resource, or a font-awesome icon and then display either of them.
- * Also should probably provide some bits of color, could do the coloring
- * through classes.
- */
- // image = ' ';
- return this.makeNotification(type, false, icon, title, content, userData);
- },
-
- notify: function(image, title, content, userData) {
- // Wraps the makeNotification method for displaying notifications with images
- // rather than icons
- return this.makeNotification('custom', image, true, title, content, userData);
- },
-
- makeNotification: function(type, image, icon, title, content, userData) {
- var notification = {
- 'type': type,
- 'image': image,
- 'icon': icon,
- 'title': title,
- 'content': content,
- 'timestamp': +new Date(),
- 'userData': userData
- };
-
- notifications.push(notification);
-
- if (settings.html5Mode) {
- html5Notify(image, title, content, function() {
- // inner on display function
- }, function() {
- // inner on close function
- });
- }
-
- //this is done because html5Notify() changes the variable settings.html5Mode
- if (!settings.html5Mode) {
- queue.push(notification);
- $timeout(function removeFromQueueTimeout() {
- queue.splice(queue.indexOf(notification), 1);
- }, settings[type].duration);
- }
-
- // Mobile notification
- if (window && window.navigator && window.navigator.vibrate) {
- window.navigator.vibrate([200, 100, 200]);
- };
-
- if (document.hidden && (type == 'info' || type == 'funds') && !isCordova) {
- new window.Notification(title, {
- body: content,
- icon: 'img/notification.png'
- });
- }
-
- this.save();
- return notification;
- },
-
-
- /* ============ PERSISTENCE METHODS ============ */
-
- save: function() {
- // Save all the notifications into localStorage
- if (settings.localStorage) {
- localStorage.setItem('notifications', JSON.stringify(notifications));
- }
- },
-
- restore: function() {
- // Load all notifications from localStorage
- },
-
- clear: function() {
- notifications = [];
- this.save();
- }
-
- };
- }
-);
diff --git a/old/notificationsService.js b/old/notificationsService.js
deleted file mode 100644
index d71bea4ee..000000000
--- a/old/notificationsService.js
+++ /dev/null
@@ -1,115 +0,0 @@
-'use strict';
-angular.module('copayApp.services')
- .factory('notificationService', function profileServiceFactory($filter, notification, lodash, configService, gettext) {
-
- var root = {};
-
- var groupingTime = 5000;
- var lastNotificationOnWallet = {};
-
- root.getLast = function(walletId) {
- var last = lastNotificationOnWallet[walletId];
- if (!last) return null;
-
- return Date.now() - last.ts < groupingTime ? last : null;
- };
-
- root.storeLast = function(notificationData, walletId) {
-
- if (notificationData.type == 'NewAddress')
- return;
-
- lastNotificationOnWallet[walletId] = {
- creatorId: notificationData.creatorId,
- type: notificationData.type,
- ts: Date.now(),
- };
- };
-
- root.shouldSkip = function(notificationData, last) {
- if (!last) return false;
-
- // rules...
- if (last.type === 'NewTxProposal' &&
- notificationData.type === 'TxProposalAcceptedBy')
- return true;
-
- if (last.type === 'TxProposalFinallyAccepted' &&
- notificationData.type === 'NewOutgoingTx')
- return true;
-
- if (last.type === 'TxProposalRejectedBy' &&
- notificationData.type === 'TxProposalFinallyRejected')
- return true;
-
- return false;
- };
-
-
- root.newBWCNotification = function(notificationData, walletId, walletName) {
- var last = root.getLast(walletId);
- root.storeLast(notificationData, walletId);
-
- if (root.shouldSkip(notificationData, last))
- return;
-
- var config = configService.getSync();
- config.colorFor = config.colorFor || {};
- var color = config.colorFor[walletId] || '#4A90E2';
- var name = config.aliasFor[walletId] || walletName;
-
- switch (notificationData.type) {
- case 'NewTxProposal':
- notification.new(gettext('New Payment Proposal'),
- name, {
- color: color
- });
- break;
- case 'TxProposalAcceptedBy':
- notification.success(gettext('Payment Proposal Signed by Copayer'),
- name, {
- color: color
- });
- break;
- case 'TxProposalRejectedBy':
- notification.error(gettext('Payment Proposal Rejected by Copayer'),
- name, {
- color: color
- });
- break;
- case 'TxProposalFinallyRejected':
- notification.error(gettext('Payment Proposal Rejected'),
- name, {
- color: color
- });
- break;
- case 'NewOutgoingTx':
- notification.sent(gettext('Payment Sent'),
- name, {
- color: color
- });
- break;
- case 'NewIncomingTx':
- notification.funds(gettext('Funds received'),
- name, {
- color: color
- });
- break;
- case 'ScanFinished':
- notification.success(gettext('Scan Finished'),
- name, {
- color: color
- });
- break;
-
- case 'NewCopayer':
- // No UX notification
- break;
- case 'BalanceUpdated':
- // No UX notification
- break;
- }
- };
-
- return root;
- });
diff --git a/old/preferencesGlobal.html b/old/preferencesGlobal.html
deleted file mode 100644
index 35af966ad..000000000
--- a/old/preferencesGlobal.html
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Use Unconfirmed Funds
-
-
-
-
-
- Enable push notifications
-
-
-
-
-
Push notifications for Copay are currently disabled. Enable them in the Settings app.
-
-
-
-
-
-
- Enable Glidera Service
-
-
-
-
- Enable Coinbase Service
-
-
-
-
-
-
-
diff --git a/old/preferencesGlobal.js b/old/preferencesGlobal.js
deleted file mode 100644
index dbedb3389..000000000
--- a/old/preferencesGlobal.js
+++ /dev/null
@@ -1,94 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('preferencesGlobalController',
- function($scope, $rootScope, $log, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {
-
- $scope.init = function() {
- var config = configService.getSync();
- var isCordova = platformInfo.isCordova;
-
- if (isCordova && StatusBar.isVisible) {
- StatusBar.backgroundColorByHexString("#4B6178");
- }
-
- $scope.unitName = config.wallet.settings.unitName;
- $scope.currentLanguageName = uxLanguage.getCurrentLanguageName();
- $scope.selectedAlternative = {
- name: config.wallet.settings.alternativeName,
- isoCode: config.wallet.settings.alternativeIsoCode
- };
- $scope.feeOpts = feeService.feeOpts;
- $scope.currentFeeLevel = feeService.getCurrentFeeLevel();
- $scope.usePushNotifications = isCordova && !platformInfo.isWP;
- $scope.PNEnabledByUser = true;
- $scope.isIOSApp = platformInfo.isIOS && isCordova;
- if ($scope.isIOSApp) {
- cordova.plugins.diagnostic.isRemoteNotificationsEnabled(function(isEnabled) {
- $scope.PNEnabledByUser = isEnabled;
- $scope.$digest();
- });
- }
- $scope.spendUnconfirmed = config.wallet.spendUnconfirmed;
- $scope.glideraEnabled = config.glidera.enabled;
- $scope.coinbaseEnabled = config.coinbase.enabled;
- $scope.pushNotifications = config.pushNotifications.enabled;
- };
-
- $scope.openSettings = function() {
- cordova.plugins.diagnostic.switchToSettings(function() {
- $log.debug('switched to settings');
- }, function(err) {
- $log.debug(err);
- });
- }
-
- $scope.spendUnconfirmedChange = function() {
- var opts = {
- wallet: {
- spendUnconfirmed: $scope.spendUnconfirmed
- }
- };
- configService.set(opts, function(err) {
- if (err) $log.debug(err);
- });
- };
-
- $scope.pushNotificationsChange = function() {
- var opts = {
- pushNotifications: {
- enabled: $scope.pushNotifications
- }
- };
- configService.set(opts, function(err) {
- if (opts.pushNotifications.enabled)
- pushNotificationsService.enableNotifications(profileService.walletClients);
- else
- pushNotificationsService.disableNotifications(profileService.walletClients);
- if (err) $log.debug(err);
- });
- };
-
- $scope.glideraChange = function() {
- var opts = {
- glidera: {
- enabled: $scope.glideraEnabled
- }
- };
- configService.set(opts, function(err) {
- $rootScope.$emit('Local/GlideraUpdated');
- if (err) $log.debug(err);
- });
- };
-
- $scope.coinbaseChange = function() {
- var opts = {
- coinbase: {
- enabled: $scope.coinbaseEnabled
- }
- };
- configService.set(opts, function(err) {
- $rootScope.$emit('Local/CoinbaseUpdated');
- if (err) $log.debug(err);
- });
- };
- });
diff --git a/old/sidebar.html b/old/sidebar.html
deleted file mode 100644
index 9345ac9d0..000000000
--- a/old/sidebar.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
diff --git a/old/tab-scan.js b/old/tab-scan.js
deleted file mode 100644
index 423fc30d9..000000000
--- a/old/tab-scan.js
+++ /dev/null
@@ -1,194 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('tabScanController', function($scope, $timeout, $ionicModal, $log, $ionicPopup, configService, gettextCatalog, platformInfo, bitcore, lodash, $state, incomingData) {
-
- var isCordova = platformInfo.isCordova;
- var isWP = platformInfo.isWP;
- var isIOS = platformInfo.isIOS;
-
-
-
- var _showAlert = function(title, msg, cb) {
- $log.warn(title + ":"+ msg);
- var alertPopup = $ionicPopup.alert({
- title: title,
- template: msg
- });
-
- if (!cb) cb = function(res) {};
-
- alertPopup.then(cb);
- };
-
- var _dataScanned = function(data) {
- $log.debug('Scanned:' + data);
- if (!incomingData.redir(data)) {
- $log.warn('Fail to process scanned data');
- _showAlert('Bad bitcoin address', 'Could not recognize the bitcoin address', function(res) {
- $scope.init();
- });
- }
- };
-
- var onSuccess = function(result) {
- $timeout(function() {
- window.plugins.spinnerDialog.hide();
- }, 100);
- if (isWP && result.cancelled) return;
-
- $timeout(function() {
- var data = isIOS ? result : result.text;
- // Check if the current page is tabs.scan
- if ($state.is('tabs.scan')) {
- _dataScanned(data);
- return;
- }
- }, 1000);
- };
-
- var onError = function(error) {
- $timeout(function() {
- window.plugins.spinnerDialog.hide();
- }, 100);
- };
-
- $scope.cordovaOpenScanner = function() {
- window.plugins.spinnerDialog.show(null, gettextCatalog.getString('Preparing camera...'), true);
- $timeout(function() {
- if (isIOS) {
- cloudSky.zBar.scan({}, onSuccess, onError);
- } else {
- cordova.plugins.barcodeScanner.scan(onSuccess, onError);
- }
- if ($scope.beforeScan) {
- $scope.beforeScan();
- }
- }, 100);
- };
-
- $scope.modalOpenScanner = function() {
- $ionicModal.fromTemplateUrl('views/modals/scanner.html', {
- scope: $scope,
- animation: 'slide-in-up'
- }).then(function(modal) {
- $scope.scannerModal = modal;
- $scope.scannerModal.show();
- });
- };
-
- $scope.openScanner = function() {
- if (isCordova) {
- $scope.cordovaOpenScanner();
- } else {
- $scope.modalOpenScanner();
- }
- };
-
- // QR code Scanner
- var video;
- var canvas;
- var $video;
- var context;
- var localMediaStream;
- var prevResult;
- var scanTimer;
-
- var _scan = function(evt) {
- if (localMediaStream) {
- context.drawImage(video, 0, 0, 300, 225);
- try {
- qrcode.decode();
- } catch (e) {
- //qrcodeError(e);
- }
- }
- scanTimer = $timeout(_scan, 800);
- };
-
- var _scanStop = function() {
- $timeout.cancel(scanTimer);
- if (localMediaStream && localMediaStream.active) {
- var localMediaStreamTrack = localMediaStream.getTracks();
- for (var i = 0; i < localMediaStreamTrack.length; i++) {
- localMediaStreamTrack[i].stop();
- }
- } else {
- try {
- localMediaStream.stop();
- } catch (e) {
- // Older Chromium not support the STOP function
- };
- }
- localMediaStream = null;
- if (video && video.src) video.src = '';
- };
-
- qrcode.callback = function(data) {
- if (prevResult != data) {
- prevResult = data;
- return;
- }
- // Check if the current page is tabs.scan
- _scanStop();
- if ($state.is('tabs.scan')) {
- _dataScanned(data);
- return;
- }
- $scope.cancel();
- };
-
- var _successCallback = function(stream) {
- video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
- localMediaStream = stream;
- video.play();
- $timeout(_scan, 1000);
- };
-
- var _videoError = function(err) {
- $scope.cancel();
- };
-
- var setScanner = function() {
- navigator.getUserMedia = navigator.getUserMedia ||
- navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
- navigator.msGetUserMedia;
- window.URL = window.URL || window.webkitURL ||
- window.mozURL || window.msURL;
- };
-
- $scope.init = function() {
- if (isCordova) {
- $scope.cordovaOpenScanner();
- return;
- }
- setScanner();
- $timeout(function() {
- if ($scope.beforeScan) {
- $scope.beforeScan();
- }
- canvas = document.getElementById('qr-canvas');
- context = canvas.getContext('2d');
-
- video = document.getElementById('qrcode-scanner-video');
- $video = angular.element(video);
- canvas.width = 300;
- canvas.height = 225;
- context.clearRect(0, 0, 300, 225);
-
- navigator.getUserMedia({
- video: true
- }, _successCallback, _videoError);
- }, 500);
- };
-
- $scope.cancel = function() {
- _scanStop();
- $scope.scannerModal.hide();
- $scope.scannerModal.remove();
- };
-
- $scope.$on("$destroy", function(){
- _scanStop();
- });
-
-});
diff --git a/old/topbar.html b/old/topbar.html
deleted file mode 100644
index e47b1c061..000000000
--- a/old/topbar.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
- {{(titleSection|translate) || (index.alias || index.walletName)}}
-
-
-
diff --git a/old/topbar.js b/old/topbar.js
deleted file mode 100644
index b3f58ad0e..000000000
--- a/old/topbar.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('topbarController', function(go) {
-
- this.goHome = function() {
- go.walletHome();
- };
-
- this.goPreferences = function() {
- go.preferences();
- };
-
-});
diff --git a/old/uri.html b/old/uri.html
deleted file mode 100644
index 212aaf41e..000000000
--- a/old/uri.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
- Please wait to be redirected...
-
-
-
diff --git a/old/uri.js b/old/uri.js
deleted file mode 100644
index 5a54eb254..000000000
--- a/old/uri.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict';
-angular.module('copayApp.controllers').controller('uriController',
- function($stateParams, $log, openURLService) {
-
-
- /* This is only for BROWSER links, it is not excecuted on mobile devices */
-
- $log.info('DEEP LINK from Browser:' + $stateParams.url);
- openURLService.handleURL({
- url: $stateParams.url
- });
- });
diff --git a/old/walletHome.html b/old/walletHome.html
deleted file mode 100644
index 91e2c217e..000000000
--- a/old/walletHome.html
+++ /dev/null
@@ -1,534 +0,0 @@
-
-
-
-
-
-
-
- You do not have any wallet
-
-
Create
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{index.updateError|translate}}
- Tap to retry
-
-
-
- Scan status finished with error
- Tap to retry
-
-
-
-
{{index.totalBalanceStr}}
-
{{index.totalBalanceAlternative}} {{index.alternativeIsoCode}}
-
- Pending Confirmation : {{index.pendingAmountStr}}
-
-
-
-
-
[Balance Hidden]
-
- Tap and hold to show
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WARNING: Key derivation is not working on this device/wallet. Actions cannot be performed on this wallet.
-
-
-
-
-
-
-
- WARNING: Wallet not registered
-
-
-
- This wallet is not registered at the given Bitcore Wallet Service (BWS). You can recreate it from the local information.
-
-
-
- Recreate
-
-
-
-
-
- {{newRelease}}
-
-
-
-
Payment Proposals
-
Unsent transactions
-
-
-
- Total Locked Balance :
- {{index.lockedBalanceStr}}
- {{index.lockedBalanceAlternative}}
- {{index.alternativeIsoCode}}
-
-
-
-
-
-
- Activity
-
-
-
-
No transactions yet
-
-
-
-
-
-
-
-
-
-
-
{{index.txProgress}} transactions downloaded
-
Updating transaction history. Please stand by.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{btx.note.body}}
- Received
-
-
-
-
- {{btx.message}}
- {{btx.note.body}}
- {{index.addressbook[btx.addressTo]}}
- Sent
-
-
-
-
- {{btx.note.body}}
- Moved
-
-
-
- Invalid
-
-
-
-
-
- +
- -
-
- (possible double spend)
-
-
- {{btx.amountStr}}
-
-
-
- {{btx.time * 1000 | amTimeAgo}}
-
- Unconfirmed
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Backup Needed
-
- Before receiving funds, you must backup your wallet. If this device is lost, it is impossible to access your funds without a backup.
-
-
- Backup now
-
-
-
-
-
- {{home.addrError|translate}}
-
-
-
-
-
-
My Bitcoin address
-
-
-
-
-
- {{home.generatingAddress ? '...' : home.addr}}
-
-
-
-
-
-
-
-
- Share address
-
-
-
-
- Request a specific amount
-
-
-
-
-
-
-
Share this wallet address to receive payments. To protect your privacy, new addresses are generated automatically once you use them.
-
Generate new address
-
-
- Share this wallet address to receive payments .
-
-
-
-
-
-
-
-
-
-
-
-
-
- Send Max
- Send Max
-
-
- Payment expires
- {{home.remainingTimeStr}}
-
-
-
-
-
-
-
-
- {{home.error|translate}}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/old/walletHome.js b/old/walletHome.js
deleted file mode 100644
index 2cbd4d59d..000000000
--- a/old/walletHome.js
+++ /dev/null
@@ -1,944 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, notification, txStatus, profileService, lodash, configService, rateService, storageService, bitcore, gettext, gettextCatalog, platformInfo, addressService, ledger, bwcError, confirmDialog, txFormatService, addressbookService, go, feeService, walletService, fingerprintService, nodeWebkit, ongoingProcess) {
-
- var isCordova = platformInfo.isCordova;
- var isWP = platformInfo.isWP;
- var isAndroid = platformInfo.isAndroid;
- var isChromeApp = platformInfo.isChromeApp;
-
- var self = this;
- $rootScope.shouldHideMenuBar = false;
- $rootScope.wpInputFocused = false;
- var config = configService.getSync();
- var configWallet = config.wallet;
- var walletSettings = configWallet.settings;
- var ret = {};
-
- // INIT. Global value
- ret.unitToSatoshi = walletSettings.unitToSatoshi;
- ret.satToUnit = 1 / ret.unitToSatoshi;
- ret.unitName = walletSettings.unitName;
- ret.alternativeIsoCode = walletSettings.alternativeIsoCode;
- ret.alternativeName = walletSettings.alternativeName;
- ret.alternativeAmount = 0;
- ret.unitDecimals = walletSettings.unitDecimals;
- ret.isCordova = isCordova;
- ret.addresses = [];
- ret.isMobile = platformInfo.isMobile;
- ret.isWindowsPhoneApp = platformInfo.isWP;
- ret.countDown = null;
- ret.sendMaxInfo = {};
- ret.showAlternative = false;
- ret.fromInputAmount = null;
- var vanillaScope = ret;
-
- var disableScannerListener = $rootScope.$on('dataScanned', function(event, data) {
- if (!data) return;
-
- self.setForm(data);
- $rootScope.$emit('Local/SetTab', 'send');
- var form = $scope.sendForm;
- if (form.address.$invalid && !ongoingProcess.get('fetchingPayPro')) {
- self.resetForm();
- self.error = gettext('Could not recognize a valid Bitcoin QR Code');
- }
- });
-
- var disablePaymentUriListener = $rootScope.$on('paymentUri', function(event, uri) {
- $rootScope.$emit('Local/SetTab', 'send');
- $timeout(function() {
- self.setForm(uri);
- }, 100);
- });
-
- var disableAddrListener = $rootScope.$on('Local/AddressIsUsed', function() {
- self.setAddress(true);
- });
-
- var disableFocusListener = $rootScope.$on('Local/NewFocusedWalletReady', function() {
- self.addr = null;
- self.resetForm();
- $scope.search = '';
-
- if (profileService.focusedClient && profileService.focusedClient.isComplete()) {
- self.setAddress();
- self.setSendFormInputs();
- }
-
- $log.debug('Cleaning WalletHome Instance');
- lodash.each(self, function(v, k) {
- if (lodash.isFunction(v)) return;
- if (!lodash.isUndefined(vanillaScope[k])) {
- self[k] = vanillaScope[k];
- return;
- }
- if (k == 'isRateAvailable') return;
-
- delete self[k];
- });
- });
-
- var disableResumeListener = $rootScope.$on('Local/Resume', function() {
- // This is needed then the apps go to sleep
- self.bindTouchDown();
- });
-
- var disableTabListener = $rootScope.$on('Local/TabChanged', function(e, tab) {
- // This will slow down switch, do not add things here!
- switch (tab) {
- case 'receive':
- // just to be sure we have an address
- self.setAddress();
- break;
- case 'send':
- self.resetError();
- };
- });
-
- $scope.$on('$destroy', function() {
- disableAddrListener();
- disableScannerListener();
- disablePaymentUriListener();
- disableTabListener();
- disableFocusListener();
- disableResumeListener();
- $rootScope.shouldHideMenuBar = false;
- });
-
- if (isCordova && StatusBar.isVisible) {
- var backgroundColor = profileService.focusedClient ? profileService.focusedClient.backgroundColor : "#4B6178";
- StatusBar.backgroundColorByHexString(backgroundColor);
- }
-
- this.onQrCodeScanned = function(data) {
- if (data) go.send();
- $rootScope.$emit('dataScanned', data);
- };
-
- rateService.whenAvailable(function() {
- self.isRateAvailable = true;
- $rootScope.$digest();
- });
-
- var getClipboard = function(cb) {
- if (!isCordova || platformInfo.isWP) return cb();
-
- window.cordova.plugins.clipboard.paste(function(value) {
- var fc = profileService.focusedClient;
- var Address = bitcore.Address;
- var networkName = fc.credentials.network;
- if (Address.isValid(value, networkName) && !$scope.newAddress) {
- return cb(value);
- }
- });
- };
-
- var handleEncryptedWallet = function(client, cb) {
- if (!walletService.isEncrypted(client)) return cb();
- $rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
- if (err) return cb(err);
- return cb(walletService.unlock(client, password));
- });
- };
-
- var accept_msg = gettextCatalog.getString('Accept');
- var cancel_msg = gettextCatalog.getString('Cancel');
- var confirm_msg = gettextCatalog.getString('Confirm');
-
- this.openAddressbookModal = function(wallets, address) {
- $scope.wallets = wallets;
- $scope.address = address;
- $scope.self = self;
-
- $ionicModal.fromTemplateUrl('views/modals/addressbook.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.addressbookModal = modal;
- $scope.addressbookModal.show();
- });
- };
-
- var GLIDERA_LOCK_TIME = 6 * 60 * 60;
- // isGlidera flag is a security measure so glidera status is not
- // only determined by the tx.message
- this.openTxpModal = function(tx, copayers, isGlidera) {
- $scope.self = self;
- $scope.tx = tx;
- $scope.copayers = copayers;
- $scope.isGlidera = isGlidera;
- $scope.error = null;
- $scope.loading = null;
- $scope.paymentExpired = null;
- $scope.currentSpendUnconfirmed = configWallet.spendUnconfirmed;
-
- $ionicModal.fromTemplateUrl('views/modals/txp-details.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.txpDetailsModal = modal;
- $scope.txpDetailsModal.show();
- });
- };
-
- this.setAddress = function(forceNew) {
- self.addrError = null;
- var client = profileService.focusedClient;
- if (!client || !client.isComplete()) return;
-
- // Address already set?
- if (!forceNew && self.addr) {
- return;
- }
-
- self.generatingAddress = true;
- $timeout(function() {
- addressService.getAddress(client.credentials.walletId, forceNew, function(err, addr) {
- self.generatingAddress = false;
-
- if (err) {
- self.addrError = err;
- } else {
- if (addr)
- self.addr = addr;
- }
-
- $scope.$digest();
- });
- });
- };
-
- this.copyToClipboard = function(addr, $event) {
-
- var showPopover = function() {
-
- $ionicPopover.fromTemplateUrl('views/includes/copyToClipboard.html', {
- scope: $scope
- }).then(function(popover) {
- $scope.popover = popover;
- $scope.popover.show($event);
- });
-
- $scope.close = function() {
- $scope.popover.hide();
- }
-
- $timeout(function() {
- $scope.popover.hide(); //close the popover after 0.7 seconds
- }, 700);
-
- $scope.$on('$destroy', function() {
- $scope.popover.remove();
- });
- };
-
- if (isCordova) {
- window.cordova.plugins.clipboard.copy(addr);
- window.plugins.toast.showShortCenter(gettextCatalog.getString('Copied to clipboard'));
- } else if (platformInfo.isNW) {
- nodeWebkit.writeToClipboard(addr);
- showPopover($event);
- }
- };
-
- this.shareAddress = function(addr) {
- if (isCordova) {
- window.plugins.socialsharing.share('bitcoin:' + addr, null, null, null);
- }
- };
-
- // Send
-
- this.resetError = function() {
- this.error = this.success = null;
- };
-
- this.bindTouchDown = function(tries) {
- var self = this;
- tries = tries || 0;
- if (tries > 5) return;
- var e = document.getElementById('menu-walletHome');
- if (!e) return $timeout(function() {
- self.bindTouchDown(++tries);
- }, 500);
-
- // on touchdown elements
- $log.debug('Binding touchstart elements...');
- ['hamburger', 'menu-walletHome', 'menu-send', 'menu-receive'].forEach(function(id) {
- var e = document.getElementById(id);
- if (e) e.addEventListener('touchstart', function() {
- try {
- event.preventDefault();
- } catch (e) {};
- angular.element(e).triggerHandler('click');
- }, true);
- });
- }
-
- this.hideMenuBar = lodash.debounce(function(hide) {
- if (hide) {
- $rootScope.shouldHideMenuBar = true;
- } else {
- $rootScope.shouldHideMenuBar = false;
- }
- $rootScope.$digest();
- }, 100);
-
- this.formFocus = function(what) {
- if (isCordova && this.isWindowsPhoneApp) {
- this.hideMenuBar(what);
- }
- var self = this;
- if (isCordova && !this.isWindowsPhoneApp && what == 'address') {
- getClipboard(function(value) {
- if (value) {
- document.getElementById("amount").focus();
- $timeout(function() {
- window.plugins.toast.showShortCenter(gettextCatalog.getString('Pasted from clipboard'));
- self.setForm(value);
- }, 100);
- }
- });
- }
- };
-
- this.setSendFormInputs = function() {
- var unitToSat = this.unitToSatoshi;
- var satToUnit = 1 / unitToSat;
- /**
- * Setting the two related amounts as properties prevents an infinite
- * recursion for watches while preserving the original angular updates
- *
- */
- Object.defineProperty($scope,
- "_alternative", {
- get: function() {
- return $scope.__alternative;
- },
- set: function(newValue) {
- $scope.__alternative = newValue;
- if (self.isRateAvailable) {
- $scope._amount = parseFloat((rateService.fromFiat(newValue, self.alternativeIsoCode) * satToUnit).toFixed(self.unitDecimals), 10);
- } else {
- $scope.__amount = null;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty($scope,
- "_amount", {
- get: function() {
- return $scope.__amount;
- },
- set: function(newValue) {
- $scope.__amount = newValue;
- if (self.isRateAvailable) {
- $scope.__alternative = parseFloat((rateService.toFiat(newValue * self.unitToSatoshi, self.alternativeIsoCode)).toFixed(2), 10);
- } else {
- $scope.__alternative = null;
- }
- self.alternativeAmount = $scope.__alternative;
- self.resetError();
- },
- enumerable: true,
- configurable: true
- });
-
- Object.defineProperty($scope,
- "_address", {
- get: function() {
- return $scope.__address;
- },
- set: function(newValue) {
- $scope.__address = self.onAddressChange(newValue);
- if ($scope.sendForm && $scope.sendForm.address.$valid) {
- self.lockAddress = true;
- }
- },
- enumerable: true,
- configurable: true
- });
-
- var fc = profileService.focusedClient;
- // ToDo: use a credential's (or fc's) function for this
- this.hideNote = !fc.credentials.sharedEncryptingKey;
- };
-
- this.setSendError = function(err) {
- var fc = profileService.focusedClient;
- var prefix =
- fc.credentials.m > 1 ? gettextCatalog.getString('Could not create payment proposal') : gettextCatalog.getString('Could not send payment');
-
- this.error = bwcError.msg(err, prefix);
-
- $timeout(function() {
- $scope.$digest();
- }, 1);
- };
-
- this.setAmount = function(amount, useAlternativeAmount) {
- $scope.showAlternative = useAlternativeAmount;
-
- self.fromInputAmount = true;
- self.setForm(null, amount, null);
- };
-
- this.submitForm = function() {
- if (!$scope._amount || !$scope._address) return;
- var client = profileService.focusedClient;
- var unitToSat = this.unitToSatoshi;
- var currentSpendUnconfirmed = configWallet.spendUnconfirmed;
-
- var outputs = [];
-
- this.resetError();
-
- if (isCordova && this.isWindowsPhoneApp)
- $rootScope.shouldHideMenuBar = true;
-
- var form = $scope.sendForm;
- var comment = form.comment.$modelValue;
-
- // ToDo: use a credential's (or fc's) function for this
- if (comment && !client.credentials.sharedEncryptingKey) {
- var msg = 'Could not add message to imported wallet without shared encrypting key';
- $log.warn(msg);
- return self.setSendError(gettext(msg));
- }
-
- if (form.amount.$modelValue * unitToSat > Number.MAX_SAFE_INTEGER) {
- var msg = 'Amount too big';
- $log.warn(msg);
- return self.setSendError(gettext(msg));
- };
-
- $timeout(function() {
- var paypro = self._paypro;
- var address, amount;
-
- address = form.address.$modelValue;
- amount = parseInt((form.amount.$modelValue * unitToSat).toFixed(0));
-
- outputs.push({
- 'toAddress': address,
- 'amount': amount,
- 'message': comment
- });
-
- var txp = {};
-
- if (!lodash.isEmpty(self.sendMaxInfo)) {
- txp.sendMax = true;
- txp.inputs = self.sendMaxInfo.inputs;
- txp.fee = self.sendMaxInfo.fee;
- } else {
- txp.amount = amount;
- }
-
- txp.toAddress = address;
- txp.outputs = outputs;
- txp.message = comment;
- txp.payProUrl = paypro ? paypro.url : null;
- txp.excludeUnconfirmedUtxos = configWallet.spendUnconfirmed ? false : true;
- txp.feeLevel = walletSettings.feeLevel || 'normal';
-
- ongoingProcess.set('creatingTx', true);
- walletService.createTx(client, txp, function(err, createdTxp) {
- ongoingProcess.set('creatingTx', false);
- if (err) {
- return self.setSendError(err);
- }
-
- if (!client.canSign() && !client.isPrivKeyExternal()) {
- $log.info('No signing proposal: No private key');
- ongoingProcess.set('sendingTx', true);
- walletService.publishTx(client, createdTxp, function(err, publishedTxp) {
- ongoingProcess.set('sendingTx', false);
- if (err) {
- return self.setSendError(err);
- }
- self.resetForm();
- go.walletHome();
- var type = txStatus.notify(createdTxp);
- $scope.openStatusModal(type, createdTxp, function() {
- return $scope.$emit('Local/TxProposalAction');
- });
- });
- } else {
- $rootScope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
- if (accept) self.confirmTx(createdTxp);
- else self.resetForm();
- });
- }
- });
-
- }, 100);
- };
-
- this.confirmTx = function(txp) {
- var client = profileService.focusedClient;
- var self = this;
-
- fingerprintService.check(client, function(err) {
- if (err) {
- return self.setSendError(err);
- }
-
- handleEncryptedWallet(client, function(err) {
- if (err) {
- return self.setSendError(err);
- }
-
- ongoingProcess.set('sendingTx', true);
- walletService.publishTx(client, txp, function(err, publishedTxp) {
- ongoingProcess.set('sendingTx', false);
- if (err) {
- return self.setSendError(err);
- }
-
- ongoingProcess.set('signingTx', true);
- walletService.signTx(client, publishedTxp, function(err, signedTxp) {
- ongoingProcess.set('signingTx', false);
- walletService.lock(client);
- if (err) {
- $scope.$emit('Local/TxProposalAction');
- return self.setSendError(
- err.message ?
- err.message :
- gettext('The payment was created but could not be completed. Please try again from home screen'));
- }
-
- if (signedTxp.status == 'accepted') {
- ongoingProcess.set('broadcastingTx', true);
- walletService.broadcastTx(client, signedTxp, function(err, broadcastedTxp) {
- ongoingProcess.set('broadcastingTx', false);
- if (err) {
- return self.setSendError(err);
- }
- self.resetForm();
- go.walletHome();
- var type = txStatus.notify(broadcastedTxp);
- $scope.openStatusModal(type, broadcastedTxp, function() {
- $scope.$emit('Local/TxProposalAction', broadcastedTxp.status == 'broadcasted');
- });
- });
- } else {
- self.resetForm();
- go.walletHome();
- var type = txStatus.notify(signedTxp);
- $scope.openStatusModal(type, signedTxp, function() {
- $scope.$emit('Local/TxProposalAction');
- });
- }
- });
- });
- });
- });
- };
-
- $scope.openStatusModal = function(type, txp, cb) {
- var fc = profileService.focusedClient;
- $scope.type = type;
- $scope.tx = txFormatService.processTx(txp);
- $scope.color = fc.backgroundColor;
- $scope.cb = cb;
-
- $ionicModal.fromTemplateUrl('views/modals/tx-status.html', {
- scope: $scope,
- animation: 'slide-in-up'
- }).then(function(modal) {
- $scope.txStatusModal = modal;
- $scope.txStatusModal.show();
- });
- };
-
- $scope.openSearchModal = function() {
- var fc = profileService.focusedClient;
- $scope.color = fc.backgroundColor;
- $scope.self = self;
-
- $ionicModal.fromTemplateUrl('views/modals/search.html', {
- scope: $scope,
- focusFirstInput: true
- }).then(function(modal) {
- $scope.searchModal = modal;
- $scope.searchModal.show();
- });
- };
-
- $scope.openCustomInputAmountModal = function(addr) {
- var fc = profileService.focusedClient;
- $scope.color = fc.backgroundColor;
- $scope.self = self;
- $scope.addr = addr;
-
- $ionicModal.fromTemplateUrl('views/modals/customAmount.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.customAmountModal = modal;
- $scope.customAmountModal.show();
- });
- };
-
- $scope.openAmountModal = function(addr) {
- if (isCordova)
- $scope.openInputAmountModal(addr);
- else
- $scope.openCustomInputAmountModal(addr);
- };
-
- $scope.openInputAmountModal = function(addr) {
- var fc = profileService.focusedClient;
- $scope.color = fc.backgroundColor;
- $scope.showAlternativeAmount = $scope.showAlternative || null;
- if ($scope.showAlternativeAmount) {
- $scope.amount = $scope.sendForm.alternative.$viewValue || null;
- } else {
- $scope.amount = $scope.sendForm.amount.$viewValue || null;
- }
- $scope.self = self;
- $scope.addr = addr;
-
- $ionicModal.fromTemplateUrl('views/modals/inputAmount.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.inputAmountModal = modal;
- $scope.inputAmountModal.show();
- });
- };
-
- this.setForm = function(to, amount, comment) {
- var form = $scope.sendForm;
- if (to) {
- form.address.$setViewValue(to);
- form.address.$isValid = true;
- form.address.$render();
- this.lockAddress = true;
- }
-
- if (amount) {
- form.amount.$setViewValue("" + amount);
- form.amount.$isValid = true;
- form.amount.$render();
- if (!this.fromInputAmount)
- this.lockAmount = true;
- this.fromInputAmount = false;
- }
-
- if (comment) {
- form.comment.$setViewValue(comment);
- form.comment.$isValid = true;
- form.comment.$render();
- }
- };
-
- this.resetForm = function() {
- this.resetError();
- this.sendMaxInfo = {};
- if (this.countDown) $interval.cancel(this.countDown);
- this._paypro = null;
-
- this.lockAddress = false;
- this.lockAmount = false;
-
- this._amount = this._address = null;
-
- var form = $scope.sendForm;
-
- if (form && form.amount) {
- form.amount.$pristine = true;
- form.amount.$setViewValue('');
- form.amount.$render();
-
- form.comment.$setViewValue('');
- form.comment.$render();
- form.$setPristine();
-
- if (form.address) {
- form.address.$pristine = true;
- form.address.$setViewValue('');
- form.address.$render();
- }
- }
- $timeout(function() {
- $rootScope.$digest();
- }, 1);
- };
-
- this.setFromPayPro = function(uri, cb) {
- if (!cb) cb = function() {};
-
- var fc = profileService.focusedClient;
- if (isChromeApp) {
- this.error = gettext('Payment Protocol not supported on Chrome App');
- return cb(true);
- }
-
- var satToUnit = 1 / this.unitToSatoshi;
- var self = this;
- /// Get information of payment if using Payment Protocol
- ongoingProcess.set('fetchingPayPro', true);
-
- $log.debug('Fetch PayPro Request...', uri);
- $timeout(function() {
- fc.fetchPayPro({
- payProUrl: uri,
- }, function(err, paypro) {
- ongoingProcess.set('fetchingPayPro', false);
-
- if (err) {
- $log.warn('Could not fetch payment request:', err);
- self.resetForm();
- var msg = err.toString();
- if (msg.match('HTTP')) {
- msg = gettext('Could not fetch payment information');
- }
- self.error = msg;
- $timeout(function() {
- $rootScope.$digest();
- }, 1);
- return cb(true);
- }
-
- if (!paypro.verified) {
- self.resetForm();
- $log.warn('Failed to verify payment protocol signatures');
- self.error = gettext('Payment Protocol Invalid');
- $timeout(function() {
- $rootScope.$digest();
- }, 1);
- return cb(true);
- }
-
- self._paypro = paypro;
- self.setForm(paypro.toAddress, (paypro.amount * satToUnit).toFixed(self.unitDecimals), paypro.memo);
- _paymentTimeControl(paypro.expires);
- return cb();
- });
- }, 1);
- };
-
- function _paymentTimeControl(expirationTime) {
- self.paymentExpired = false;
- setExpirationTime();
-
- self.countDown = $interval(function() {
- setExpirationTime();
- }, 1000);
-
- function setExpirationTime() {
- var now = Math.floor(Date.now() / 1000);
- if (now > expirationTime) {
- setExpiredValues();
- return;
- }
-
- var totalSecs = expirationTime - now;
- var m = Math.floor(totalSecs / 60);
- var s = totalSecs % 60;
- self.remainingTimeStr = ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2);
- };
-
- function setExpiredValues() {
- self.paymentExpired = true;
- self.remainingTimeStr = null;
- self._paypro = null;
- self.error = gettext('Cannot sign: The payment request has expired');
- if (self.countDown) $interval.cancel(self.countDown);
- };
- };
-
- this.setFromUri = function(uri) {
- var self = this;
-
- function sanitizeUri(uri) {
- // Fixes when a region uses comma to separate decimals
- var regex = /[\?\&]amount=(\d+([\,\.]\d+)?)/i;
- var match = regex.exec(uri);
- if (!match || match.length === 0) {
- return uri;
- }
- var value = match[0].replace(',', '.');
- var newUri = uri.replace(regex, value);
- return newUri;
- };
-
- var satToUnit = 1 / this.unitToSatoshi;
-
- // URI extensions for Payment Protocol with non-backwards-compatible request
- if ((/^bitcoin:\?r=[\w+]/).exec(uri)) {
- uri = decodeURIComponent(uri.replace('bitcoin:?r=', ''));
- this.setFromPayPro(uri, function(err) {
- if (err) {
- return err;
- }
- });
- } else {
- uri = sanitizeUri(uri);
-
- if (!bitcore.URI.isValid(uri)) {
- return uri;
- }
- var parsed = new bitcore.URI(uri);
-
- var addr = parsed.address ? parsed.address.toString() : '';
- var message = parsed.message;
-
- var amount = parsed.amount ?
- (parsed.amount.toFixed(0) * satToUnit).toFixed(this.unitDecimals) : 0;
-
-
- if (parsed.r) {
- this.setFromPayPro(parsed.r, function(err) {
- if (err && addr && amount) {
- self.setForm(addr, amount, message);
- return addr;
- }
- });
- } else {
- this.setForm(addr, amount, message);
- return addr;
- }
- }
-
- };
-
- this.onAddressChange = function(value) {
- this.resetError();
- if (!value) return '';
-
- if (this._paypro)
- return value;
-
- if (value.indexOf('bitcoin:') === 0) {
- return this.setFromUri(value);
- } else if (/^https?:\/\//.test(value)) {
- return this.setFromPayPro(value);
- } else {
- return value;
- }
- };
-
- // History
-
- function strip(number) {
- return (parseFloat(number.toPrecision(12)));
- }
-
- this.getUnitName = function() {
- return this.unitName;
- };
-
- this.getAlternativeIsoCode = function() {
- return this.alternativeIsoCode;
- };
-
- this.openTxModal = function(btx) {
- var self = this;
-
- $scope.btx = lodash.cloneDeep(btx);
- $scope.self = self;
-
- $ionicModal.fromTemplateUrl('views/modals/tx-details.html', {
- scope: $scope,
- hideDelay: 500
- }).then(function(modal) {
- $scope.txDetailsModal = modal;
- $scope.txDetailsModal.show();
- });
- };
-
- this.hasAction = function(actions, action) {
- return actions.hasOwnProperty('create');
- };
-
- this.sendMax = function(availableBalanceSat) {
- if (availableBalanceSat == 0) {
- this.error = gettext("Cannot create transaction. Insufficient funds");
- return;
- }
-
- var self = this;
- var fc = profileService.focusedClient;
- this.error = null;
- ongoingProcess.set('calculatingFee', true);
-
- $timeout(function() {
-
- feeService.getCurrentFeeValue(function(err, feePerKb) {
- ongoingProcess.set('calculatingFee', false);
- if (err || !lodash.isNumber(feePerKb)) {
- self.error = gettext('Could not get fee value');
- return;
- }
-
- var opts = {};
- opts.feePerKb = feePerKb;
- opts.returnInputs = true;
- var config = configService.getSync();
- opts.excludeUnconfirmedUtxos = !config.wallet.spendUnconfirmed;
- ongoingProcess.set('retrivingInputs', true);
-
- fc.getSendMaxInfo(opts, function(err, resp) {
- ongoingProcess.set('retrivingInputs', false);
-
- if (err) {
- self.error = err;
- $scope.$apply();
- return;
- }
-
- if (resp.amount == 0) {
- self.error = gettext("Not enough funds for fee");
- $scope.$apply();
- return;
- }
-
- var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees", {
- fee: profileService.formatAmount(resp.fee) + ' ' + self.unitName
- });
-
- var warningMsg = verifyExcludedUtxos();
-
- if (!lodash.isEmpty(warningMsg))
- msg += '. \n' + warningMsg;
-
- confirmDialog.show(msg, function(confirmed) {
- if (confirmed) {
- self.sendMaxInfo = resp;
- var amount = parseFloat((resp.amount * self.satToUnit).toFixed(self.unitDecimals));
- self.setForm(null, amount, null);
- } else {
- self.resetForm();
- }
- });
-
- function verifyExcludedUtxos() {
- var warningMsg = [];
- if (resp.utxosBelowFee > 0) {
- warningMsg.push(gettextCatalog.getString("Note: a total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
- amountBelowFeeStr: profileService.formatAmount(resp.amountBelowFee) + ' ' + self.unitName
- }));
- }
- if (resp.utxosAboveMaxSize > 0) {
- warningMsg.push(gettextCatalog.getString("Note: a total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded", {
- amountAboveMaxSizeStr: profileService.formatAmount(resp.amountAboveMaxSize) + ' ' + self.unitName
- }));
- }
- return warningMsg.join('\n');
- }
- });
- });
- }, 10);
- };
-
- /* Start setup */
- lodash.assign(self, vanillaScope);
-
- this.bindTouchDown();
- if (profileService.focusedClient) {
- this.setAddress();
- this.setSendFormInputs();
- }
-
-});