Wallet/src/js/controllers/addresses.js

247 lines
8 KiB
JavaScript

'use strict';
angular.module('copayApp.controllers').controller('addressesController', function($scope, $log, $stateParams, $state, $timeout, $ionicHistory, $ionicScrollDelegate, popupService, gettextCatalog, ongoingProcess, lodash, profileService, walletService, bwcError, platformInfo, appConfigService, txFormatService, feeService, bitcoinCashJsService) {
var UNUSED_ADDRESS_LIMIT = 5;
var BALANCE_ADDRESS_LIMIT = 5;
var withBalance, cachedWallet;
$scope.isCordova = platformInfo.isCordova;
$scope.wallet = profileService.getWallet($stateParams.walletId);
function resetValues() {
$scope.loading = false;
$scope.showInfo = false;
$scope.showMore = false;
$scope.allAddressesView = false;
$scope.latestUnused = $scope.latestWithBalance = null;
$scope.viewAll = {
value: false
};
};
$scope.init = function() {
resetValues();
$scope.loading = true;
walletService.getMainAddresses($scope.wallet, {}, function(err, addresses) {
if (err) {
$scope.loading = false;
return popupService.showAlert(bwcError.msg(err, gettextCatalog.getString('Could not update wallet')));
}
var allAddresses = addresses;
walletService.getBalance($scope.wallet, {}, function(err, resp) {
if (err) {
$scope.loading = false;
return popupService.showAlert(bwcError.msg(err, gettextCatalog.getString('Could not update wallet')));
}
withBalance = resp.byAddress;
var idx = lodash.indexBy(withBalance, 'address');
$scope.noBalance = lodash.reject(allAddresses, function(x) {
return idx[x.address];
});
processPaths($scope.noBalance);
processPaths(withBalance);
$scope.latestUnused = lodash.slice($scope.noBalance, 0, UNUSED_ADDRESS_LIMIT);
var withBalanceDict = lodash.indexBy(withBalance, 'address');
lodash.each(allAddresses, function(a) {
if(withBalanceDict[a.address]) {
withBalanceDict[a.address].createdOn = a.createdOn;
}
});
$scope.latestWithBalance = lodash.slice(withBalance, 0, BALANCE_ADDRESS_LIMIT);
lodash.each(withBalance, function(a) {
a.balanceStr = txFormatService.formatAmountStr($scope.wallet.coin, a.amount);
});
$scope.viewAll = {
value: $scope.noBalance.length > UNUSED_ADDRESS_LIMIT || withBalance.length > BALANCE_ADDRESS_LIMIT
};
$scope.allAddresses = $scope.noBalance.concat(withBalance);
if ($scope.wallet.coin == 'bch') {
lodash.each($scope.allAddresses, function(a) {
a.translatedAddresses = bitcoinCashJsService.translateAddresses(a.address);
});
$scope.addressType = {
type: 'cashaddr'
};
$scope.showAddressTypes = true;
}
cachedWallet = $scope.wallet.id;
$scope.loading = false;
$log.debug('Addresses cached for Wallet:', cachedWallet);
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$digest();
});
});
});
feeService.getFeeLevels($scope.wallet.coin, function(err, levels){
walletService.getLowUtxos($scope.wallet, levels, function(err, resp) {
if (err) return;
if (resp && resp.allUtxos && resp.allUtxos.length) {
var allSum = lodash.sum(resp.allUtxos || 0, 'satoshis');
var per = (resp.minFee / allSum) * 100;
$scope.lowWarning = resp.warning;
$scope.lowUtxosNb = resp.lowUtxos.length;
$scope.allUtxosNb = resp.allUtxos.length;
$scope.lowUtxosSum = txFormatService.formatAmountStr($scope.wallet.coin, lodash.sum(resp.lowUtxos || 0, 'satoshis'));
$scope.allUtxosSum = txFormatService.formatAmountStr($scope.wallet.coin, allSum);
$scope.minFee = txFormatService.formatAmountStr($scope.wallet.coin, resp.minFee || 0);
$scope.minFeePer = per.toFixed(2) + '%';
}
});
});
};
function processPaths(list) {
lodash.each(list, function(n) {
n.path = n.path.replace(/^m/g, 'xpub');
});
};
$scope.newAddress = function() {
if ($scope.gapReached) return;
ongoingProcess.set('generatingNewAddress', true);
walletService.getAddress($scope.wallet, true, function(err, addr) {
if (err) {
ongoingProcess.set('generatingNewAddress', false);
if (err.toString().match('MAIN_ADDRESS_GAP_REACHED')) {
$scope.gapReached = true;
} else {
popupService.showAlert(err);
}
$timeout(function() {
$scope.$digest();
});
return;
}
walletService.getMainAddresses($scope.wallet, {
limit: 1
}, function(err, _addr) {
ongoingProcess.set('generatingNewAddress', false);
if (err) return popupService.showAlert(gettextCatalog.getString('Error'), err);
if (addr != _addr[0].address) return popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('New address could not be generated. Please try again.'));
if ($scope.wallet.coin == 'bch') {
_addr[0].translatedAddresses = bitcoinCashJsService.translateAddresses(_addr[0].address);
}
$scope.noBalance = [_addr[0]].concat($scope.noBalance);
$scope.latestUnused = lodash.slice($scope.noBalance, 0, UNUSED_ADDRESS_LIMIT);
$scope.viewAll = {
value: $scope.noBalance.length > UNUSED_ADDRESS_LIMIT
};
$scope.$digest();
});
});
};
$scope.viewAllAddresses = function() {
var fromView = $ionicHistory.currentStateName();
var path;
if (fromView.indexOf('settings') !== -1) {
path = 'tabs.settings.allAddresses';
} else {
path = 'tabs.wallet.allAddresses';
}
$state.go(path, {
walletId: $scope.wallet.id
});
};
$scope.showInformation = function() {
$timeout(function() {
$scope.showInfo = !$scope.showInfo;
$ionicScrollDelegate.resize();
}, 10);
};
$scope.readMore = function() {
$timeout(function() {
$scope.showMore = !$scope.showMore;
$ionicScrollDelegate.resize();
}, 10);
};
$scope.scan = function() {
walletService.startScan($scope.wallet);
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$ionicHistory.clearHistory();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.wallet', {
walletId: $scope.wallet.credentials.walletId
});
});
};
$scope.sendByEmail = function() {
function formatDate(ts) {
var dateObj = new Date(ts * 1000);
if (!dateObj) {
$log.debug('Error formating a date');
return 'DateError';
}
if (!dateObj.toJSON()) {
return '';
}
return dateObj.toJSON();
};
ongoingProcess.set('sendingByEmail', true);
$timeout(function() {
var appName = appConfigService.nameCase;
var body = appName + ' Wallet "' + $scope.wallet.name + '" Addresses\n Only Main Addresses are shown.\n\n';
body += "\n";
body += $scope.allAddresses.map(function(v) {
return ('* ' + v.address + ' xpub' + v.path.substring(1) + ' ' + formatDate(v.createdOn));
}).join("\n");
ongoingProcess.set('sendingByEmail', false);
window.plugins.socialsharing.shareViaEmail(
body,
appName + ' Addresses',
null, // TO: must be null or an array
null, // CC: must be null or an array
null, // BCC: must be null or an array
null, // FILES: can be null, a string, or an array
function() {},
function() {}
);
});
};
function isCachedWallet(walletId) {
if (cachedWallet && cachedWallet == walletId) return true;
else return false;
};
$scope.$on("$ionicView.afterEnter", function(event, data) {
$scope.allAddressesView = data.stateName == 'tabs.receive.allAddresses' ? true : false;
if (!isCachedWallet($stateParams.walletId)) $scope.init();
else $log.debug('Addresses cached for Wallet:', $stateParams.walletId);
});
});