mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #6373 from gabrielbazan7/feat/customfee
custom fee feature
This commit is contained in:
commit
22a2b19a70
|
@ -22,6 +22,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
var isCordova = platformInfo.isCordova;
|
||||
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
|
||||
|
||||
//custom fee flag
|
||||
var usingCustomFee = null;
|
||||
|
||||
function refresh() {
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
|
@ -202,7 +205,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
txp.inputs = tx.sendMaxInfo.inputs;
|
||||
txp.fee = tx.sendMaxInfo.fee;
|
||||
} else {
|
||||
txp.feeLevel = tx.feeLevel;
|
||||
if (usingCustomFee) {
|
||||
txp.feePerKb = tx.feeRate;
|
||||
} else txp.feeLevel = tx.feeLevel;
|
||||
}
|
||||
|
||||
txp.message = tx.description;
|
||||
|
@ -250,7 +255,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
feeService.getFeeRate(tx.network, tx.feeLevel, function(err, feeRate) {
|
||||
if (err) return cb(err);
|
||||
|
||||
tx.feeRate = feeRate;
|
||||
if (!usingCustomFee) tx.feeRate = feeRate;
|
||||
tx.feeLevelName = feeService.feeOpts[tx.feeLevel];
|
||||
|
||||
if (!wallet)
|
||||
|
@ -296,7 +301,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
txp.feeRatePerStr = per.toFixed(2) + '%';
|
||||
txp.feeToHigh = per > FEE_TOO_HIGH_LIMIT_PER;
|
||||
|
||||
|
||||
tx.txp[wallet.id] = txp;
|
||||
$log.debug('Confirm. TX Fully Updated for wallet:' + wallet.id, tx);
|
||||
refresh();
|
||||
|
@ -559,8 +563,15 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
scope.feeLevel = tx.feeLevel;
|
||||
scope.noSave = true;
|
||||
|
||||
if (usingCustomFee) {
|
||||
scope.customFeePerKB = tx.feeRate;
|
||||
scope.feePerSatByte = (tx.feeRate / 1000).toFixed();
|
||||
}
|
||||
|
||||
$ionicModal.fromTemplateUrl('views/modals/chooseFeeLevel.html', {
|
||||
scope: scope,
|
||||
backdropClickToClose: false,
|
||||
hardwareBackButtonClose: false
|
||||
}).then(function(modal) {
|
||||
scope.chooseFeeLevelModal = modal;
|
||||
scope.openModal();
|
||||
|
@ -569,18 +580,21 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
|||
scope.chooseFeeLevelModal.show();
|
||||
};
|
||||
|
||||
scope.hideModal = function(customFeeLevel) {
|
||||
scope.hideModal = function(newFeeLevel, customFeePerKB) {
|
||||
scope.chooseFeeLevelModal.hide();
|
||||
$log.debug('Custom fee level choosen:' + customFeeLevel + ' was:' + tx.feeLevel);
|
||||
if (tx.feeLevel == customFeeLevel)
|
||||
return;
|
||||
$log.debug('New fee level choosen:' + newFeeLevel + ' was:' + tx.feeLevel);
|
||||
|
||||
usingCustomFee = newFeeLevel == 'custom' ? true : false;
|
||||
|
||||
if (tx.feeLevel == newFeeLevel && !usingCustomFee) return;
|
||||
|
||||
tx.feeLevel = newFeeLevel;
|
||||
if (usingCustomFee) tx.feeRate = parseInt(customFeePerKB);
|
||||
|
||||
tx.feeLevel = customFeeLevel;
|
||||
updateTx(tx, wallet, {
|
||||
clearCache: true,
|
||||
dryRun: true,
|
||||
}, function() {
|
||||
});
|
||||
dryRun: true
|
||||
}, function() {});
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
angular.module('copayApp.controllers').controller('preferencesFeeController', function($scope, $timeout, $ionicHistory, lodash, gettextCatalog, configService, feeService, ongoingProcess, popupService) {
|
||||
|
||||
var network;
|
||||
|
||||
$scope.save = function(newFee) {
|
||||
$scope.currentFeeLevel = newFee;
|
||||
updateCurrentValues();
|
||||
|
||||
if ($scope.noSave)
|
||||
return;
|
||||
$scope.currentFeeLevel = newFee;
|
||||
|
||||
if ($scope.currentFeeLevel != 'custom') updateCurrentValues();
|
||||
else showCustomFeePrompt();
|
||||
|
||||
if ($scope.noSave) return;
|
||||
|
||||
var opts = {
|
||||
wallet: {
|
||||
|
@ -32,7 +32,6 @@ angular.module('copayApp.controllers').controller('preferencesFeeController', fu
|
|||
});
|
||||
|
||||
$scope.init = function() {
|
||||
|
||||
$scope.network = $scope.network || 'livenet';
|
||||
$scope.feeOpts = feeService.feeOpts;
|
||||
$scope.currentFeeLevel = $scope.feeLevel || feeService.getCurrentFeeLevel();
|
||||
|
@ -60,16 +59,60 @@ angular.module('copayApp.controllers').controller('preferencesFeeController', fu
|
|||
});
|
||||
|
||||
if (lodash.isEmpty(value)) {
|
||||
$scope.feePerSatByte = null;
|
||||
$scope.feePerSatByte = $scope.currentFeeLevel == 'custom' ? $scope.feePerSatByte : null;
|
||||
$scope.avgConfirmationTime = null;
|
||||
setMinWarning();
|
||||
setMaxWarning();
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.feePerSatByte = (value.feePerKB / 1000).toFixed();
|
||||
$scope.avgConfirmationTime = value.nbBlocks * 10;
|
||||
$scope.invalidCustomFeeEntered = false;
|
||||
setMinWarning();
|
||||
setMaxWarning();
|
||||
};
|
||||
|
||||
$scope.chooseNewFee = function() {
|
||||
$scope.hideModal($scope.currentFeeLevel);
|
||||
$scope.hideModal($scope.currentFeeLevel, $scope.customFeePerKB);
|
||||
};
|
||||
|
||||
var showCustomFeePrompt = function() {
|
||||
$scope.invalidCustomFeeEntered = true;
|
||||
$scope.showMaxWarning = false;
|
||||
$scope.showMinWarning = false;
|
||||
popupService.showPrompt(gettextCatalog.getString('Custom Fee'), gettextCatalog.getString('Set your own fee in satoshis/byte'), null, function(text) {
|
||||
if (!text || !parseInt(text) || parseInt(text) <= 0) return;
|
||||
$scope.feePerSatByte = parseInt(text);
|
||||
$scope.customFeePerKB = ($scope.feePerSatByte * 1000).toFixed();
|
||||
setMaxWarning();
|
||||
setMinWarning();
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getMinimumRecommeded = function() {
|
||||
var value = lodash.find($scope.feeLevels[$scope.network], {
|
||||
level: 'superEconomy'
|
||||
});
|
||||
return parseInt((value.feePerKB / 1000).toFixed());
|
||||
};
|
||||
|
||||
var setMinWarning = function() {
|
||||
if (parseInt($scope.feePerSatByte) < $scope.getMinimumRecommeded()) $scope.showMinWarning = true;
|
||||
else $scope.showMinWarning = false;
|
||||
};
|
||||
|
||||
var setMaxWarning = function() {
|
||||
if (parseInt($scope.feePerSatByte) > 1000) {
|
||||
$scope.showMaxWarning = true;
|
||||
$scope.invalidCustomFeeEntered = true;
|
||||
} else {
|
||||
$scope.showMaxWarning = false;
|
||||
$scope.invalidCustomFeeEntered = false;
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
@ -11,7 +11,8 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
priority: gettext('Priority'),
|
||||
normal: gettext('Normal'),
|
||||
economy: gettext('Economy'),
|
||||
superEconomy: gettext('Super Economy')
|
||||
superEconomy: gettext('Super Economy'),
|
||||
custom: gettext('Custom')
|
||||
};
|
||||
|
||||
var cache = {
|
||||
|
@ -24,6 +25,9 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
|||
|
||||
|
||||
root.getFeeRate = function(network, feeLevel, cb) {
|
||||
|
||||
if (feeLevel == 'custom') return cb();
|
||||
|
||||
network = network || 'livenet';
|
||||
|
||||
root.getFeeLevels(function(err, levels, fromCache) {
|
||||
|
|
|
@ -25,6 +25,15 @@
|
|||
background-color: #fff;
|
||||
font-size:0.9em;
|
||||
color: $v-mid-gray;
|
||||
.text {
|
||||
padding-left: 25px;
|
||||
}
|
||||
.icon {
|
||||
position: absolute;
|
||||
img {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-explanation, &-button-group {
|
||||
padding: 0 1rem;
|
||||
|
@ -162,6 +171,7 @@
|
|||
|
||||
#settings-fee {
|
||||
.estimates {
|
||||
min-height: 6rem;
|
||||
font-size: 15px;
|
||||
color: $v-dark-gray;
|
||||
margin-bottom: .5rem;
|
||||
|
|
|
@ -3,24 +3,25 @@
|
|||
<div class="title">
|
||||
{{'Bitcoin Network Fee Policy'|translate}}
|
||||
</div>
|
||||
<button class="button button-clear" ng-click="chooseNewFee()">
|
||||
<button ng-disabled="invalidCustomFeeEntered" class="button button-clear" ng-click="chooseNewFee()">
|
||||
OK
|
||||
</button>
|
||||
</ion-header-bar>
|
||||
<ion-content ng-init="init(network)">
|
||||
<ion-content ng-init="init()">
|
||||
<div class="settings-explanation">
|
||||
<div class="estimates">
|
||||
<div>
|
||||
<span translate>Average confirmation time</span>:
|
||||
<span class="fee-minutes" ng-if="avgConfirmationTime">{{avgConfirmationTime | amDurationFormat: 'minute'}}</span>
|
||||
<span ng-if="loadingFee">...</span>
|
||||
<span class="fee-minutes" ng-if="avgConfirmationTime && currentFeeLevel != 'custom'">{{avgConfirmationTime | amDurationFormat: 'minute'}}</span>
|
||||
<span class="fee-minutes" ng-if="currentFeeLevel == 'custom' && !invalidCustomFeeEntered && !loadingFee" translate>Could not be estimated</span>
|
||||
<span ng-if="loadingFee || invalidCustomFeeEntered">...</span>
|
||||
</div>
|
||||
<div>
|
||||
<span translate>Current fee rate for this policy</span>:
|
||||
<span class="fee-rate" ng-if="feePerSatByte">{{feePerSatByte}} satoshis/byte</span>
|
||||
<span ng-if="loadingFee">...</span>
|
||||
<span class="fee-rate" ng-if="feePerSatByte && !invalidCustomFeeEntered && !loadingFee">{{feePerSatByte}} satoshis/byte</span>
|
||||
<span ng-if="loadingFee || invalidCustomFeeEntered">...</span>
|
||||
</div>
|
||||
<div ng-if="network!='livenet'">[{{network}}]</span>
|
||||
<span ng-if="network!='livenet'">[{{network}}]</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fee-policies">
|
||||
|
@ -28,5 +29,13 @@
|
|||
{{level|translate}}
|
||||
</ion-radio>
|
||||
</div>
|
||||
<div class="comment" ng-if="showMinWarning">
|
||||
<i class="icon"><img src="img/icon-warning.png"></i>
|
||||
<span class="text" translate>Your fee is lower than the recommended super economy fee ({{getMinimumRecommeded()}} satoshis/byte). Your transaction may never get confirmed.</span>
|
||||
</div>
|
||||
<div class="comment" ng-if="showMaxWarning">
|
||||
<i class="icon"><img src="img/icon-warning.png"></i>
|
||||
<span class="text" translate>Your could not set a fee higher than 1000 satoshis/byte.</span>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-modal-view>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="fee-policies">
|
||||
<ion-radio ng-repeat="(fee, level) in feeOpts" ng-value="fee" ng-model="currentFeeLevel" ng-click="save(fee)">
|
||||
<ion-radio ng-repeat="(fee, level) in feeOpts" ng-if="fee != 'custom'" ng-value="fee" ng-model="currentFeeLevel" ng-click="save(fee)">
|
||||
{{level|translate}}
|
||||
</ion-radio>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue