mirror of https://github.com/BTCPrivate/copay.git
add to low amount to incoming TXs
This commit is contained in:
parent
f6245652d9
commit
c54b38a9a9
|
@ -4,6 +4,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
|
||||
var countDown = null;
|
||||
var CONFIRM_LIMIT_USD = 20;
|
||||
var FEE_TOO_HIGH_LIMIT_PER = 15;
|
||||
|
||||
var tx = {};
|
||||
|
||||
|
@ -286,7 +287,10 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
txFormatService.formatAlternativeStr(txp.fee, function(v) {
|
||||
txp.alternativeFeeStr = v;
|
||||
});
|
||||
txp.feeRatePerStr = (txp.fee / (txp.amount + txp.fee) * 100).toFixed(2) + '%';
|
||||
|
||||
var per = (txp.fee / (txp.amount + txp.fee) * 100);
|
||||
txp.feeRatePerStr = per.toFixed(2) + '%';
|
||||
txp.feeToHigh = per > FEE_TOO_HIGH_LIMIT_PER;
|
||||
|
||||
|
||||
tx.txp[wallet.id] = txp;
|
||||
|
|
|
@ -14,8 +14,6 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
|
|||
$scope.canSign = $scope.wallet.canSign() || $scope.wallet.isPrivKeyExternal();
|
||||
$scope.color = $scope.wallet.color;
|
||||
$scope.data = {};
|
||||
$scope.displayAmount = getDisplayAmount($scope.tx.amountStr);
|
||||
$scope.displayUnit = getDisplayUnit($scope.tx.amountStr);
|
||||
displayFeeValues();
|
||||
initActionList();
|
||||
checkPaypro();
|
||||
|
@ -43,14 +41,6 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
|
|||
$scope.buttonText += gettextCatalog.getString('to accept');
|
||||
};
|
||||
|
||||
function getDisplayAmount(amountStr) {
|
||||
return amountStr.split(' ')[0];
|
||||
};
|
||||
|
||||
function getDisplayUnit(amountStr) {
|
||||
return amountStr.split(' ')[1];
|
||||
};
|
||||
|
||||
function initActionList() {
|
||||
$scope.actionList = [];
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('txDetailsController', function($rootScope, $log, $ionicHistory, $scope, $timeout, walletService, lodash, gettextCatalog, profileService, externalLinkService, popupService, ongoingProcess, txFormatService, txConfirmNotification) {
|
||||
angular.module('copayApp.controllers').controller('txDetailsController', function($rootScope, $log, $ionicHistory, $scope, $timeout, walletService, lodash, gettextCatalog, profileService, externalLinkService, popupService, ongoingProcess, txFormatService, txConfirmNotification, feeService) {
|
||||
|
||||
var txId;
|
||||
var listeners = [];
|
||||
|
@ -40,14 +40,6 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
|
|||
});
|
||||
});
|
||||
|
||||
function getDisplayAmount(amountStr) {
|
||||
return amountStr.split(' ')[0];
|
||||
}
|
||||
|
||||
function getDisplayUnit(amountStr) {
|
||||
return amountStr.split(' ')[1];
|
||||
}
|
||||
|
||||
function updateMemo() {
|
||||
walletService.getTxNote($scope.wallet, $scope.btx.txid, function(err, note) {
|
||||
if (err) {
|
||||
|
@ -122,12 +114,14 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
|
|||
if ($scope.btx.action == 'moved') $scope.title = gettextCatalog.getString('Moved Funds');
|
||||
}
|
||||
|
||||
$scope.displayAmount = getDisplayAmount($scope.btx.amountStr);
|
||||
$scope.displayUnit = getDisplayUnit($scope.btx.amountStr);
|
||||
|
||||
updateMemo();
|
||||
initActionList();
|
||||
getFiatRate();
|
||||
|
||||
feeService.getLowAmount($scope.wallet, function(err, amount) {
|
||||
$scope.btx.lowAmount = tx.amount< amount;
|
||||
});
|
||||
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService) {
|
||||
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService) {
|
||||
|
||||
var HISTORY_SHOW_LIMIT = 10;
|
||||
var currentTxHistoryPage = 0;
|
||||
|
@ -154,9 +154,10 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
|||
});
|
||||
};
|
||||
|
||||
$timeout(function() {
|
||||
feeService.getLowAmount($scope.wallet, function(err, lowAmount){
|
||||
walletService.getTxHistory($scope.wallet, {
|
||||
progressFn: progressFn,
|
||||
lowAmount: lowAmount,
|
||||
}, function(err, txHistory) {
|
||||
$scope.updatingTxHistory = false;
|
||||
if (err) {
|
||||
|
|
|
@ -4,6 +4,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
var root = {};
|
||||
|
||||
var CACHE_TIME_TS = 60; // 1 min
|
||||
var LOW_AMOUNT_RATIO = 0.15; //Ratio low amount warning (econ fee/amount)
|
||||
|
||||
// Constant fee options to translate
|
||||
root.feeOpts = {
|
||||
|
@ -43,7 +44,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
|
||||
var feeRate = feeLevelRate.feePerKB;
|
||||
|
||||
if (!fromCache) $log.debug('Dynamic fee: ' + feeLevel + '/' + network +' ' + (feeLevelRate.feePerKB / 1000).toFixed() + ' SAT/B');
|
||||
if (!fromCache) $log.debug('Dynamic fee: ' + feeLevel + '/' + network + ' ' + (feeLevelRate.feePerKB / 1000).toFixed() + ' SAT/B');
|
||||
|
||||
return cb(null, feeRate);
|
||||
});
|
||||
|
@ -55,8 +56,8 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
|
||||
root.getFeeLevels = function(cb) {
|
||||
|
||||
if (cache.updateTs > Date.now() - CACHE_TIME_TS * 1000 ) {
|
||||
$timeout( function() {
|
||||
if (cache.updateTs > Date.now() - CACHE_TIME_TS * 1000) {
|
||||
$timeout(function() {
|
||||
return cb(null, cache.data, true);
|
||||
}, 1);
|
||||
}
|
||||
|
@ -70,7 +71,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
return cb(gettextCatalog.getString('Could not get dynamic fee'));
|
||||
}
|
||||
|
||||
cache.updateTs =Date.now();
|
||||
cache.updateTs = Date.now();
|
||||
cache.data = {
|
||||
'livenet': levelsLivenet,
|
||||
'testnet': levelsTestnet
|
||||
|
@ -81,5 +82,52 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
// These 2 functions were taken from
|
||||
// https://github.com/bitpay/bitcore-wallet-service/blob/master/lib/model/txproposal.js#L243
|
||||
|
||||
function getEstimatedSizeForSingleInput(wallet) {
|
||||
switch (wallet.credentials.addressType) {
|
||||
case 'P2PKH':
|
||||
return 147;
|
||||
default:
|
||||
case 'P2SH':
|
||||
return wallet.m * 72 + wallet.n * 36 + 44;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function getEstimatedSize(wallet) {
|
||||
// Note: found empirically based on all multisig P2SH inputs and within m & n allowed limits.
|
||||
var safetyMargin = 0.02;
|
||||
|
||||
var overhead = 4 + 4 + 9 + 9;
|
||||
var inputSize = getEstimatedSizeForSingleInput(wallet);
|
||||
var outputSize = 34;
|
||||
var nbInputs = 1; //Assume 1 input
|
||||
var nbOutputs = 2; // Assume 2 outputs
|
||||
|
||||
var size = overhead + inputSize * nbInputs + outputSize * nbOutputs;
|
||||
return parseInt((size * (1 + safetyMargin)).toFixed(0));
|
||||
};
|
||||
|
||||
|
||||
// Approx utxo amount, from which the uxto is economically redeemable
|
||||
root.getLowAmount = function(wallet, cb) {
|
||||
root.getFeeLevels(function(err, levels) {
|
||||
if (err) return cb(err);
|
||||
|
||||
var lowLevelRate = (lodash.find(levels[wallet.network], {
|
||||
level: 'economy',
|
||||
}).feePerKB / 1000).toFixed(0);
|
||||
|
||||
var size = getEstimatedSize(wallet);
|
||||
|
||||
var minFee = size * lowLevelRate;
|
||||
|
||||
return cb(null, parseInt(minFee / (LOW_AMOUNT_RATIO)));
|
||||
});
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
@ -90,6 +90,8 @@ angular.module('copayApp.services')
|
|||
wallet.m = wallet.credentials.m;
|
||||
wallet.n = wallet.credentials.n;
|
||||
|
||||
wallet.lowAmount =
|
||||
|
||||
root.updateWalletSettings(wallet);
|
||||
root.wallet[walletId] = wallet;
|
||||
|
||||
|
|
|
@ -93,6 +93,11 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
|
|||
tx.alternativeAmountStr = root.formatAlternativeStr(tx.amount);
|
||||
tx.feeStr = root.formatAmountStr(tx.fee || tx.fees);
|
||||
|
||||
if (tx.amountStr) {
|
||||
tx.amountValueStr = tx.amountStr.split(' ')[0];
|
||||
tx.amountUnitStr = tx.amountStr.split(' ')[1];
|
||||
}
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
|
|
|
@ -413,7 +413,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
$log.debug('Fixing Tx Cache Unit to:' + name)
|
||||
lodash.each(txs, function(tx) {
|
||||
|
||||
tx.amountStr = txFormatService.formatAmount(tx.amount) + name;
|
||||
tx.feeStr = txFormatService.formatAmount(tx.fees) + name;
|
||||
});
|
||||
|
@ -511,6 +510,15 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
}
|
||||
|
||||
function updateLowAmount(txs) {
|
||||
if (!opts.lowAmount) return;
|
||||
lodash.each(txs, function(tx) {
|
||||
tx.lowAmount = tx.amount < opts.lowAmount;
|
||||
});
|
||||
};
|
||||
|
||||
updateLowAmount(txs);
|
||||
|
||||
updateNotes(function() {
|
||||
|
||||
// <HACK>
|
||||
|
@ -567,9 +575,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
root.getTx = function(wallet, txid, cb) {
|
||||
|
||||
function finish(list){
|
||||
function finish(list) {
|
||||
var tx = lodash.find(list, {
|
||||
txid: txid
|
||||
txid: txid
|
||||
});
|
||||
|
||||
if (!tx) return cb('Could not get transaction');
|
||||
|
@ -602,7 +610,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
root.getTxHistory = function(wallet, opts, cb) {
|
||||
opts = opts || {};
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
float: none;
|
||||
.fee-rate {
|
||||
display: inline-block;
|
||||
.warn {
|
||||
color: red;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.icon-amazon {
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
&.low-fees {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: #aaa;
|
||||
color: #777;
|
||||
align-items: center;
|
||||
i {
|
||||
padding-right: 20px;
|
||||
|
|
|
@ -81,8 +81,15 @@
|
|||
<span class="label">{{'Fee:' | translate}} {{tx.feeLevelName | translate}}</span>
|
||||
<span class="m10l">{{tx.txp[wallet.id].feeStr || '...'}}</span>
|
||||
<span class="item-note m10l">
|
||||
<span>{{tx.txp[wallet.id].alternativeFeeStr || '...'}} <span class="fee-rate" ng-if="tx.txp[wallet.id].feeRatePerStr" translate>- {{tx.txp[wallet.id].feeRatePerStr}} of the transaction</span></span>
|
||||
<span>{{tx.txp[wallet.id].alternativeFeeStr || '...'}}
|
||||
<span class="fee-rate" ng-if="tx.txp[wallet.id].feeRatePerStr"> ·
|
||||
<i class="ion-alert-circled warn" ng-show="tx.txp[wallet.id].feeToHigh"></i>
|
||||
<span class="fee-rate" ng-class="{'warn':tx.txp[wallet.id].feeToHigh}" translate> {{tx.txp[wallet.id].feeRatePerStr}} of the sending amount </span>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<i class="icon bp-arrow-right"></i>
|
||||
</div>
|
||||
<a class="item item-icon-right" ng-if="wallet" ng-click="showDescriptionPopup(tx)">
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
<i class="icon"><img src="img/icon-warning.png" width="20px"></i>
|
||||
<span class="comment" translate>Low fees</span>
|
||||
</div>
|
||||
<div class="low-fees" ng-if="btx.lowAmount">
|
||||
<i class="icon"><img src="img/icon-warning.png" width="20px"></i>
|
||||
<span class="comment" translate>Amount too low to spend</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div ng-show="btx.action == 'sent'" class="ellipsis">
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<span translate>Sending</span>
|
||||
</div>
|
||||
<div class="amount-label">
|
||||
<div class="amount">{{displayAmount}} <span class="unit">{{displayUnit}}</span></div>
|
||||
<div class="amount">{{tx.amountValueStr}} <span class="unit">{{tx.amountUnitStr}}</span></div>
|
||||
<div class="alternative" ng-show="tx.alternativeAmountStr">{{tx.alternativeAmountStr}}</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<span ng-if="btx.action == 'received'" translate>Receiving</span>
|
||||
</div>
|
||||
<div class="amount-label">
|
||||
<div class="amount">{{displayAmount}} <span class="unit">{{displayUnit}}</span></div>
|
||||
<div class="amount">{{btx.amountValueStr}} <span class="unit">{{btx.amountUnitStr}}</span></div>
|
||||
<div class="alternative" ng-click="showRate = !showRate">
|
||||
<span ng-if="!showRate">{{btx.alternativeAmountStr}}</span>
|
||||
<span ng-if="showRate">
|
||||
|
@ -88,6 +88,11 @@
|
|||
<i class="icon"><img src="img/icon-warning.png" width="20px"></i>
|
||||
<span translate>This transaction could take a long time to confirm or could be dropped due to the low fees set by the sender</span>
|
||||
</div>
|
||||
<div class="item low-fees" ng-if="btx.lowAmount">
|
||||
<i class="icon"><img src="img/icon-warning.png" width="20px"></i>
|
||||
<span translate>This transaction amount is too small given current Bitcoin network fees. Spending these funds will incur in fees comparable to the amount itself. </span>
|
||||
</div>
|
||||
|
||||
<div class="item single-line">
|
||||
<span class="label" translate>Confirmations</span>
|
||||
<span class="item-note">
|
||||
|
|
Loading…
Reference in New Issue