diff --git a/src/js/controllers/modals/txpDetails.js b/src/js/controllers/modals/txpDetails.js index 1c45eaf56..294346ff2 100644 --- a/src/js/controllers/modals/txpDetails.js +++ b/src/js/controllers/modals/txpDetails.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('txpDetailsController', function($scope, $rootScope, $timeout, $interval, $log, ongoingProcess, platformInfo, $ionicScrollDelegate, txFormatService, bwcError, gettextCatalog, lodash, walletService, popupService, $ionicHistory, feeService, bitcoinCashJsService) { +angular.module('copayApp.controllers').controller('txpDetailsController', function($scope, $rootScope, $timeout, $interval, $log, ongoingProcess, platformInfo, $ionicScrollDelegate, txFormatService, bwcError, gettextCatalog, lodash, walletService, popupService, $ionicHistory, feeService, bitcoinCashJsService, payproService) { var isGlidera = $scope.isGlidera; var GLIDERA_LOCK_TIME = 6 * 60 * 60; var now = Math.floor(Date.now() / 1000); @@ -204,15 +204,19 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi $timeout(function() { ongoingProcess.set('broadcastingTx', true); - walletService.broadcastTx($scope.wallet, $scope.tx, function(err, txpb) { + function handleBroadcastTx(err, txpb) { ongoingProcess.set('broadcastingTx', false); - if (err) { return setError(err, gettextCatalog.getString('Could not broadcast payment')); } - $scope.close(); - }); + } + + if (txp.payProUrl && txp.coin == 'bch') { + payproService.broadcastBchTx(txp, handleBroadcastTx); + } else { + walletService.broadcastTx($scope.wallet, txp, handleBroadcastTx); + } }, 10); }; diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index b4043ad8d..34a708057 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -111,11 +111,23 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat if ((/^bitcoin(cash)?:\?r=[\w+]/).exec(data)) { var coin = data.indexOf('bitcoincash') >= 0 ? 'bch' : 'btc'; data = decodeURIComponent(data.replace(/bitcoin(cash)?:\?r=/, '')); - payproService.getPayProDetails(data, coin, function(err, details) { - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), err); - } else handlePayPro(details, coin); - }); + if (coin == 'bch') { + payproService.getPayProDetailsViaHttp(data, function(err, details) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err) + } else { + handlePayPro(createBchPayProObject(details), coin); + } + }); + } else { + payproService.getPayProDetails(data, coin, function(err, details) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err); + } else { + handlePayPro(details, coin); + } + }); + } return true; } @@ -371,6 +383,26 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat }, 100); } + function createBchPayProObject(payProData) { + var displayAddr = payProData.outputs[0].address; + var toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy; + return { + amount: payProData.outputs[0].amount, + caTrusted: true, + domain: 'bitpay.com', + expires: Math.floor(new Date(payProData.expires).getTime() / 1000), + memo: payProData.memo, + network: 'livenet', + requiredFeeRate: payProData.requiredFeeRate, + selfSigned: 0, + time: Math.ceil(new Date(payProData.time).getTime() / 1000), + displayAddress: displayAddr, + toAddress: toAddr, + url: payProData.paymentUrl, + verified: true + }; + } + function handlePayPro(payProDetails, coin) { var stateParams = { toAmount: payProDetails.amount, diff --git a/src/js/services/payproService.js b/src/js/services/payproService.js index 3e639e382..f0814cc0f 100644 --- a/src/js/services/payproService.js +++ b/src/js/services/payproService.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.services').factory('payproService', - function(profileService, platformInfo, gettextCatalog, ongoingProcess, $log) { + function(profileService, platformInfo, gettextCatalog, ongoingProcess, $log, $http) { var ret = {}; @@ -36,5 +36,34 @@ angular.module('copayApp.services').factory('payproService', }); }; + ret.getPayProDetailsViaHttp = function(uri, cb) { + var config = { + headers: {'Accept': 'application/payment-request'} + }; + $http.get(uri, config).then(function(response) { + return cb(null, response.data); + }, function(error) { + return cb(error, null); + }); + } + + ret.broadcastBchTx = function(signedTxp, cb) { + var config = { + headers: {'Content-Type': 'application/payment'} + }; + + var data = { + currency: 'BCH', + transactions: [signedTxp.raw] + }; + + $http.post(signedTxp.payProUrl, data, config).then(function(response) { + signedTxp.response = response.data; + return cb(null, signedTxp); + }, function(error) { + return cb(error.data, null); + }); + } + return ret; }); diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js index daf90aad1..641e7e612 100644 --- a/src/js/services/walletService.js +++ b/src/js/services/walletService.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.services').factory('walletService', function($log, $timeout, lodash, trezor, ledger, intelTEE, storageService, configService, rateService, uxLanguage, $filter, gettextCatalog, bwcError, $ionicPopup, fingerprintService, ongoingProcess, gettext, $rootScope, txFormatService, $ionicModal, $state, bwcService, bitcore, popupService, firebaseEventsService) { +angular.module('copayApp.services').factory('walletService', function($log, $timeout, lodash, trezor, ledger, intelTEE, storageService, configService, rateService, uxLanguage, $filter, gettextCatalog, bwcError, $ionicPopup, fingerprintService, ongoingProcess, gettext, $rootScope, txFormatService, $ionicModal, $state, bwcService, bitcore, popupService, firebaseEventsService, payproService) { // Ratio low amount warning (fee/amount) in incoming TX var LOW_AMOUNT_RATIO = 0.15; @@ -1179,13 +1179,18 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim if (signedTxp.status == 'accepted') { ongoingProcess.set('broadcastingTx', true, customStatusHandler); - root.broadcastTx(wallet, signedTxp, function(err, broadcastedTxp) { + function handleBroadcastTx(err, broadcastedTxp) { ongoingProcess.set('broadcastingTx', false, customStatusHandler); - if (err) return cb(bwcError.msg(err)); - + if (err) return cb(bwcError.msg(err)); $rootScope.$emit('Local/TxAction', wallet.id); return cb(null, broadcastedTxp); - }); + } + + if (signedTxp.payProUrl && signedTxp.coin == 'bch') { + payproService.broadcastBchTx(signedTxp, handleBroadcastTx); + } else { + root.broadcastTx(wallet, signedTxp, handleBroadcastTx); + } } else { $rootScope.$emit('Local/TxAction', wallet.id); return cb(null, signedTxp);