'use strict'; var bitcore = require('bitcore'); angular.module('copayApp.controllers').controller('TransactionsController', function($scope, $rootScope, $timeout, controllerUtils, notification) { $scope.title = 'Transactions'; $scope.loading = false; $scope.onlyPending = true; $scope.lastShowed = false; $scope.txpCurrentPage = 1; $scope.txpItemsPerPage = 4; $scope.blockchain_txs = []; var satToUnit = 1 / config.unitToSatoshi; $scope.update = function() { $scope.loading = false; var from = ($scope.txpCurrentPage - 1) * $scope.txpItemsPerPage; var opts = { onlyPending: $scope.onlyPending, skip: !$scope.onlyPending ? [from, from + $scope.txpItemsPerPage] : null }; controllerUtils.updateTxs(opts); $rootScope.$digest(); }; $scope.show = function(onlyPending) { $scope.loading = true; $scope.onlyPending = onlyPending; setTimeout(function() { $scope.update(); }, 10); }; var _aggregateItems = function(items) { if (!items) return []; var l = items.length; var ret = []; var tmp = {}; var u = 0; for (var i = 0; i < l; i++) { var notAddr = false; // non standard input if (items[i].scriptSig && !items[i].addr) { items[i].addr = 'Unparsed address [' + u+++']'; items[i].notAddr = true; notAddr = true; } // non standard output if (items[i].scriptPubKey && !items[i].scriptPubKey.addresses) { items[i].scriptPubKey.addresses = ['Unparsed address [' + u+++']']; items[i].notAddr = true; notAddr = true; } // multiple addr at output if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) { items[i].addr = items[i].scriptPubKey.addresses.join(','); ret.push(items[i]); continue; } var addr = items[i].addr || (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0]); if (!tmp[addr]) { tmp[addr] = {}; tmp[addr].valueSat = 0; tmp[addr].count = 0; tmp[addr].addr = addr; tmp[addr].items = []; } tmp[addr].isSpent = items[i].spentTxId; tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID; tmp[addr].doubleSpentIndex = tmp[addr].doubleSpentIndex || items[i].doubleSpentIndex; tmp[addr].unconfirmedInput += items[i].unconfirmedInput; tmp[addr].dbError = tmp[addr].dbError || items[i].dbError; tmp[addr].valueSat += parseInt((items[i].value * bitcore.util.COIN).toFixed(0)); tmp[addr].items.push(items[i]); tmp[addr].notAddr = notAddr; tmp[addr].count++; } angular.forEach(tmp, function(v) { v.value = (parseInt(v.valueSat || 0).toFixed(0)) * satToUnit; ret.push(v); }); return ret; }; $scope.toogleLast = function() { $scope.lastShowed = !$scope.lastShowed; if ($scope.lastShowed) { $scope.getTransactions(); } }; $scope.send = function(ntxid, cb) { $scope.loading = true; $rootScope.txAlertCount = 0; var w = $rootScope.wallet; w.sendTx(ntxid, function(txid) { if (!txid) { notification.error('Error', 'There was an error sending the transaction'); } else { notification.success('Transaction broadcast', 'Transaction id: '+txid); } if (cb) return cb(); else $scope.update(); }); }; $scope.sign = function(ntxid) { $scope.loading = true; var w = $rootScope.wallet; w.sign(ntxid, function(ret) { if (!ret) { notification.error('Error', 'There was an error signing the transaction'); $scope.update(); } else { var p = w.txProposals.getTxProposal(ntxid); if (p.builder.isFullySigned()) { $scope.send(ntxid, function() { $scope.update(); }); } else $scope.update(); } }); }; $scope.getTransactions = function() { var w = $rootScope.wallet; $scope.loading = true; if (w) { var addresses = w.getAddressesStr(); if (addresses.length > 0) { $scope.blockchain_txs = $scope.wallet.txCache || []; w.blockchain.getTransactions(addresses, function(txs) { $timeout(function() { $scope.blockchain_txs = []; for (var i = 0; i < txs.length; i++) { txs[i].vinSimple = _aggregateItems(txs[i].vin); txs[i].voutSimple = _aggregateItems(txs[i].vout); txs[i].valueOut = ((txs[i].valueOut * bitcore.util.COIN).toFixed(0)) * satToUnit; txs[i].fees = ((txs[i].fees * bitcore.util.COIN).toFixed(0)) * satToUnit; $scope.blockchain_txs.push(txs[i]); } $scope.wallet.txCache = $scope.blockchain_txs; $scope.loading = false; }, 10); }); } else { $timeout(function() { $scope.loading = false; $scope.lastShowed = false; }, 1); } } }; $scope.getShortNetworkName = function() { return config.networkName.substring(0, 4); }; $scope.reject = function(ntxid) { $scope.loading = true; $rootScope.txAlertCount = 0; var w = $rootScope.wallet; w.reject(ntxid); notification.warning('Transaction rejected', 'You rejected the transaction successfully'); $scope.loading = false; }; // Autoload transactions on 1-of-1 if ($rootScope.wallet && $rootScope.wallet.totalCopayers == 1) { $scope.lastShowed = true; $scope.getTransactions(); } });