From d183077a203d36a1482631fc167bb4092ca77a4b Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Tue, 7 Aug 2018 09:39:48 +1200 Subject: [PATCH] Countdown timer for BIP70 invoices. --- src/js/controllers/review.controller.js | 154 ++++++++++++++---------- src/js/services/incomingData.js | 2 +- www/views/review.html | 2 +- 3 files changed, 94 insertions(+), 64 deletions(-) diff --git a/src/js/controllers/review.controller.js b/src/js/controllers/review.controller.js index 19bab5a2e..5785ee831 100644 --- a/src/js/controllers/review.controller.js +++ b/src/js/controllers/review.controller.js @@ -4,7 +4,7 @@ angular .module('copayApp.controllers') .controller('reviewController', reviewController); -function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $ionicHistory, $ionicLoading, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) { +function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicLoading, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) { var vm = this; vm.buttonText = ''; @@ -33,19 +33,27 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit currencyColor: '', }; vm.originWallet = null; + vm.paymentExpired = false; vm.primaryAmount = ''; vm.primaryCurrency = ''; vm.usingMerchantFee = false; vm.readyToSend = false; + vm.remainingTimeStr = ''; vm.secondaryAmount = ''; vm.secondaryCurrency = ''; vm.sendingTitle = gettextCatalog.getString('You are sending'); vm.sendStatus = ''; + vm.showAddress = true; vm.thirdParty = false; vm.wallet = null; vm.memoExpanded = false; + + // Functions + vm.onSuccessConfirm = onSuccessConfirm; + var config = null; + var countDown = null; var defaults = {}; var coin = ''; var countDown = null; @@ -57,6 +65,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit var satoshis = null; var toAddress = ''; var tx = {}; + var txPayproData = null; var unitFromSat = 0; var FEE_TOO_HIGH_LIMIT_PERCENTAGE = 15; @@ -77,32 +86,8 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit if (data.stateParams.thirdParty) { vm.thirdParty = JSON.parse(data.stateParams.thirdParty); // Parse stringified JSON-object if (vm.thirdParty) { - if (vm.thirdParty.id === 'shapeshift') { - vm.sendingTitle = gettextCatalog.getString('You are shifting'); - if (!vm.thirdParty.data) { - vm.thirdParty.data = {}; - } - - var toWallet = profileService.getWallet(data.stateParams.toWalletId); - $ionicLoading.show(); - walletService.getAddress(vm.originWallet, false, function onWalletAddress(err, returnAddr) { - walletService.getAddress(toWallet, false, function onWalletAddress(err, withdrawalAddr) { - $ionicLoading.hide(); - shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function(shapeshiftData) { - vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/'+shapeshiftData.orderId; - toAddress = shapeshiftData.toAddress; - vm.destination.address = toAddress; - vm.destination.kind = 'shapeshift'; - }); - }); - }); - } - if (vm.thirdParty.id === 'bip70') { - if (vm.thirdParty.memo) { - vm.memo = 'Payment request for BitPay invoice.\n' + toAddress + ' for merchant'; - vm.memoExpanded = true; - } - } + handleThirdPartyInitIfBip70(); + handleThirdPartyInitIfShapeshift(); } } @@ -240,6 +225,8 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit sendMax: data.stateParams.sendMax === 'true' ? true : false, fromWalletId: data.stateParams.fromWalletId, toAddress: data.stateParams.toAddress, + paypro: txPayproData, + feeLevel: configFeeLevel, spendUnconfirmed: config.wallet.spendUnconfirmed, @@ -253,6 +240,8 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit txp: {}, }; + + if (data.stateParams.requiredFeeRate) { vm.usingMerchantFee = true; tx.feeRate = parseInt(data.stateParams.requiredFeeRate); @@ -454,6 +443,80 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit vm.destination.balanceCurrency = balanceText.currency; } + function handleThirdPartyInitIfBip70() { + if (vm.thirdParty.id === 'bip70') { + if (vm.thirdParty.memo) { + // Why not the whole memo? + vm.memo = 'Payment request for BitPay invoice.\n' + toAddress + ' for merchant'; + vm.memoExpanded = true; + } + txPayproData = { + caTrusted: vm.thirdParty.caTrusted, + domain: vm.thirdParty.domain, + expires: vm.thirdParty.expires, + toAddress: toAddress, + url: vm.thirdParty.url, + verified: vm.thirdParty.verified, + }; + } + } + + function handleThirdPartyInitIfShapeshift() { + if (vm.thirdParty.id === 'shapeshift') { + vm.sendingTitle = gettextCatalog.getString('You are shifting'); + if (!vm.thirdParty.data) { + vm.thirdParty.data = {}; + } + + var toWallet = profileService.getWallet(data.stateParams.toWalletId); + $ionicLoading.show(); + walletService.getAddress(vm.originWallet, false, function onWalletAddress(err, returnAddr) { + walletService.getAddress(toWallet, false, function onWalletAddress(err, withdrawalAddr) { + $ionicLoading.hide(); + shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function(shapeshiftData) { + vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId; + toAddress = shapeshiftData.toAddress; + vm.destination.address = toAddress; + vm.destination.kind = 'shapeshift'; + }); + }); + }); + } + } + + function startExpirationTimer(expirationTime) { + vm.paymentExpired = false; + setExpirationTime(); + + countDown = $interval(function() { + setExpirationTime(); + }, 1000); + + function setExpirationTime() { + console.log('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; + vm.remainingTimeStr = m + ":" + ('0' + s).slice(-2); + }; + + function setExpiredValues() { + vm.paymentExpired = true; + vm.remainingTimeStr = gettextCatalog.getString('Expired'); + if (countDown) $interval.cancel(countDown); + $timeout(function() { + $scope.$apply(); + }); + }; + }; + function updateSendAmounts() { if (typeof satoshis !== 'number') { return; @@ -497,7 +560,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit }); } - vm.onSuccessConfirm = function() { + function onSuccessConfirm() { vm.sendStatus = ''; $ionicHistory.nextViewOptions({ disableAnimate: true, @@ -565,14 +628,13 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit } }); - // Other Scope vars vm.showAddress = false; setButtonText(vm.originWallet.credentials.m > 1, !!tx.paypro); if (tx.paypro) - _paymentTimeControl(tx.paypro.expires); + startExpirationTimer(tx.paypro.expires); updateTx(tx, vm.originWallet, { dryRun: true @@ -765,36 +827,4 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit }); } - function _paymentTimeControl(expirationTime) { - $scope.paymentExpired = false; - setExpirationTime(); - - 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; - $scope.remainingTimeStr = ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2); - }; - - function setExpiredValues() { - $scope.paymentExpired = true; - $scope.remainingTimeStr = gettextCatalog.getString('Expired'); - if (countDown) $interval.cancel(countDown); - $timeout(function() { - $scope.$apply(); - }); - }; - }; - } diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index be391edc3..703056f03 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -134,7 +134,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat } }); } else { - payproService.getPayProDetails(data, coin, function(err, details) { + payproService.getPayProDetails(data, coin, function onGetPayProDetails(err, details) { if (err) { popupService.showAlert(gettextCatalog.getString('Error'), err); } else { diff --git a/www/views/review.html b/www/views/review.html index 7317d7b68..c401b8c34 100644 --- a/www/views/review.html +++ b/www/views/review.html @@ -51,7 +51,7 @@ ng-if="vm.thirdParty && vm.thirdParty.id === 'bip70' && vm.thirdParty.name === 'bitpay'">

BitPay

-

Payment expired in XX:XX

+

Payment expires: {{vm.remainingTimeStr}}